LyogRGlyZWN0RHJhdyBTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IChjKSAyMDA2IFN0ZWZhbiBE9nNpbmdlcgogKgogKiBUaGlzIGZpbGUgY29udGFpbnMgdGhlIChpbnRlcm5hbCkgZHJpdmVyIHJlZ2lzdHJhdGlvbiBmdW5jdGlvbnMsCiAqIGRyaXZlciBlbnVtZXJhdGlvbiBBUElzIGFuZCBEaXJlY3REcmF3IGNyZWF0aW9uIGZ1bmN0aW9ucy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIEEgbm9ybWFsIFF1ZXJ5SW50ZXJmYWNlIGltcGxlbWVudGF0aW9uLiBGb3IgUXVlcnlJbnRlcmZhY2UgcnVsZXMKICogc2VlIGRkcmF3LmMsIElEaXJlY3REcmF3Nzo6UXVlcnlJbnRlcmZhY2UuIFRoaXMgbWV0aG9kCiAqIGNhbiBRdWVyeSBJRGlyZWN0RHJhd1N1cmZhY2UgaW50ZXJmYWNlcyBpbiBhbGwgdmVyc2lvbiwgSURpcmVjdDNEVGV4dHVyZQogKiBpbiBhbGwgdmVyc2lvbnMsIHRoZSBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCBpbnRlcmZhY2UgYW5kIGl0IGNhbgogKiBjcmVhdGUgYW4gSURpcmVjdDNERGV2aWNlLiAoVXNlcyBJRGlyZWN0M0Q3OjpDcmVhdGVEZXZpY2UpCiAqCiAqIFBhcmFtczoKICogIHJpaWQ6IFRoZSBpbnRlcmZhY2UgaWQgcXVlcmllZCBmb3IKICogIG9iajogQWRkcmVzcyB0byB3cml0ZSB0aGUgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU19PSyBvbiBzdWNjZXNzCiAqICBFX05PSU5URVJGQUNFIGlmIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlIHdhc24ndCBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKCiAgICAvKiBBY2NvcmRpbmcgdG8gQ09NIGRvY3MsIGlmIHRoZSBRdWVyeUludGVyZmFjZSBmYWlscywgb2JqIHNob3VsZCBiZSBzZXQgdG8gTlVMTCAqLwogICAgKm9iaiA9IE5VTEw7CgogICAgaWYoIXJpaWQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lEaXJlY3REcmF3U3VyZmFjZTcpCiAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0RHJhd1N1cmZhY2U0KSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMykKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMikKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlKSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlMyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTMgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdHYW1tYUNvbnRyb2wpICkKICAgIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3R2FtbWFDb250cm9sIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICBlbHNlIGlmKCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0QzRERFVklDRV9XaW5lRDNEKSB8fAogICAgICAgICAgICAgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0M0RIQUxEZXZpY2UpfHwKICAgICAgICAgICAgIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdDNEUkdCRGV2aWNlKSApCiAgICB7CiAgICAgICAgSURpcmVjdDNERGV2aWNlNyAqZDNkOwoKICAgICAgICAvKiBDYWxsIGludG8gSURpcmVjdDNENyBmb3IgY3JlYXRpb24gKi8KICAgICAgICBJRGlyZWN0M0Q3X0NyZWF0ZURldmljZShJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdDNENyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZDNkKTsKCiAgICAgICAgKm9iaiA9IENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBJRGlyZWN0M0REZXZpY2UsIGQzZCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3QzRERldmljZSBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwoKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYgKElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRFRleHR1cmUsIHJpaWQgKSB8fAogICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVGV4dHVyZTIsIHJpaWQgKSkKICAgIHsKICAgICAgICBpZiAoSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVGV4dHVyZSwgcmlpZCApKQogICAgICAgIHsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFRleHR1cmUpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRFRleHR1cmUgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RUZXh0dXJlMik7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEVGV4dHVyZTIgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIElVbmtub3duX0FkZFJlZiggKElVbmtub3duICopICpvYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIEVSUigiTm8gaW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6QWRkUmVmCiAqCiAqIEEgbm9ybWFsIGFkZHJlZiBpbXBsZW1lbnRhdGlvbgogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRSZWYoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRSZWYgaW5jcmVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwogICAgcmV0dXJuIHJlZkNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95CiAqCiAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlCiAqCiAqIEZyZWVzIHRoZSBzdXJmYWNlLCByZWdhcmRsZXNzIG9mIGl0cyByZWZjb3VudC4KICogIFNlZSBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlIGZvciBtb3JlIGluZm9ybWF0aW9uCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IFN1cmZhY2UgdG8gZnJlZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRGVzdHJveShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUaGlzKQp7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogQ2hlY2sgdGhlIHJlZmNvdW50IGFuZCBnaXZlIGEgd2FybmluZyAqLwogICAgaWYoVGhpcy0+cmVmID4gMSkKICAgIHsKICAgICAgICAvKiBUaGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbXBsZXggc3VyZmFjZSBpcyBkZXN0cm95ZWQsCiAgICAgICAgICogYmVjYXVzZSB0aGUgMm5kIHN1cmZhY2Ugd2FzIGFkZHJlZigpZWQgd2hlbiB0aGUgYXBwCiAgICAgICAgICogY2FsbGVkIEdldEF0dGFjaGVkU3VyZmFjZQogICAgICAgICAqLwogICAgICAgIFdBUk4oIiglcCk6IERlc3Ryb3lpbmcgc3VyZmFjZSB3aXRoIHJlZm91bnQgJWRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CiAgICB9CgogICAgLyogQ2hlY2sgZm9yIGF0dGFjaGVkIHN1cmZhY2VzIGFuZCBkZXRhY2ggdGhlbSAqLwogICAgaWYoVGhpcy0+Zmlyc3RfYXR0YWNoZWQgIT0gVGhpcykKICAgIHsKICAgICAgICAvKiBXZWxsLCB0aGlzIHNob3VsZG4ndCBoYXBwZW46IFRoZSBzdXJmYWNlIGJlaW5nIGF0dGFjaGVkIGlzIGFkZHJlZigpZWQKICAgICAgICAgICogaW4gQWRkQXR0YWNoZWRTdXJmYWNlLCBzbyBpdCBzaG91bGRuJ3QgYmUgcmVsZWFzZWQgdW50aWwgRGVsZXRlQXR0YWNoZWRTdXJmYWNlCiAgICAgICAgICAqIGlzIGNhbGxlZCwgYmVjYXVzZSB0aGUgcmVmY291bnQgaXMgaGVsZC4gSXQgbG9va3MgbGlrZSB0aGUgYXBwIHJlbGVhc2VkKCkKICAgICAgICAgICogaXQgb2Z0ZW4gZW5vdWdoIHRvIGZvcmNlIHRoaXMKICAgICAgICAgICovCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqcm9vdCA9IElDT01fSU5URVJGQUNFKFRoaXMtPmZpcnN0X2F0dGFjaGVkLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpkZXRhY2ggPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKCiAgICAgICAgRklYTUUoIiglcCkgRnJlZWluZyBhIHN1cmZhY2UgdGhhdCBpcyBhdHRhY2hlZCB0byBzdXJmYWNlICVwXG4iLCBUaGlzLCBUaGlzLT5maXJzdF9hdHRhY2hlZCk7CgogICAgICAgIC8qIFRoZSByZWZjb3VudCB3aWxsIGRyb3AgdG8gLTEgaGVyZSAqLwogICAgICAgIGlmKElEaXJlY3REcmF3U3VyZmFjZTdfRGVsZXRlQXR0YWNoZWRTdXJmYWNlKHJvb3QsIDAsIGRldGFjaCkgIT0gRERfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgRGVsZXRlQXR0YWNoZWRTdXJmYWNlIGZhaWxlZCFcbiIsIFRoaXMpOwogICAgICAgIH0KICAgIH0KCiAgICB3aGlsZShUaGlzLT5uZXh0X2F0dGFjaGVkICE9IE5VTEwpCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqcm9vdCA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRldGFjaCA9IElDT01fSU5URVJGQUNFKFRoaXMtPm5leHRfYXR0YWNoZWQsIElEaXJlY3REcmF3U3VyZmFjZTcpOwoKICAgICAgICBpZihJRGlyZWN0RHJhd1N1cmZhY2U3X0RlbGV0ZUF0dGFjaGVkU3VyZmFjZShyb290LCAwLCBkZXRhY2gpICE9IEREX09LKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCIoJXApIERlbGV0ZUF0dGFjaGVkU3VyZmFjZSBmYWlsZWQhXG4iLCBUaGlzKTsKICAgICAgICAgICAgYXNzZXJ0KDApOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBOb3cgZGVzdHJveSB0aGUgc3VyZmFjZS4gV2FpdDogSXQgY291bGQgaGF2ZSBiZWVuIHJlbGVhc2VkIGlmIHdlIGFyZSBhIHRleHR1cmUgKi8KICAgIGlmKFRoaXMtPldpbmVEM0RTdXJmYWNlKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFRoaXMtPldpbmVEM0RTdXJmYWNlKTsKCiAgICAvKiBIYXZpbmcgYSB0ZXh0dXJlIGhhbmRsZSBzZXQgaW1wbGllcyB0aGF0IHRoZSBkZXZpY2Ugc3RpbGwgZXhpc3RzICovCiAgICBpZihUaGlzLT5IYW5kbGUpCiAgICB7CiAgICAgICAgVGhpcy0+ZGRyYXctPmQzZGRldmljZS0+SGFuZGxlc1tUaGlzLT5IYW5kbGUgLSAxXS5wdHIgPSBOVUxMOwogICAgICAgIFRoaXMtPmRkcmF3LT5kM2RkZXZpY2UtPkhhbmRsZXNbVGhpcy0+SGFuZGxlIC0gMV0udHlwZSA9IEREcmF3SGFuZGxlX1Vua25vd247CiAgICB9CgogICAgLyogUmVkdWNlIHRoZSBkZHJhdyBzdXJmYWNlIGNvdW50ICovCiAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+ZGRyYXctPnN1cmZhY2VzKTsKICAgIGxpc3RfcmVtb3ZlKCZUaGlzLT5zdXJmYWNlX2xpc3RfZW50cnkpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UmVsZWFzZQogKgogKiBSZWR1Y2VzIHRoZSBzdXJmYWNlJ3MgcmVmY291bnQgYnkgMS4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZQogKiBzdXJmYWNlIGlzIGRlc3Ryb3llZC4KICoKICogRGVzdHJveWluZyB0aGUgc3VyZmFjZSBpcyBhIGJpdCB0cmlja3kuIEZvciB0aGUgY29ubmVjdGlvbiBiZXR3ZWVuCiAqIFdpbmVEM0RTdXJmYWNlcyBhbmQgRGlyZWN0RHJhd1N1cmZhY2VzIHNlZSBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICogSXQgaGFzIGEgbmljZSBncmFwaCBleHBsYWluaW5nIHRoZSBjb25uZWN0aW9uLgogKgogKiBXaGF0IGhhcHBlbnMgaGVyZSBpcyBiYXNpY2FsbHkgdGhpczoKICogV2hlbiBhIHN1cmZhY2UgaXMgZGVzdHJveWVkLCBpdHMgV2luZUQzRFN1cmZhY2UgaXMgcmVsZWFzZWQsCiAqIGFuZCB0aGUgcmVmY291bnQgb2YgdGhlIERpcmVjdERyYXcgaW50ZXJmYWNlIGlzIHJlZHVjZWQgYnkgMS4gSWYgaXQgaGFzCiAqIGNvbXBsZXggc3VyZmFjZXMgYXR0YWNoZWQgdG8gaXQsIHRoZW4gdGhlc2Ugc3VyZmFjZXMgYXJlIGRlc3Ryb3llZCB0b28sCiAqIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgcmVmY291bnQuIElmIGFueSBzdXJmYWNlIGJlaW5nIGRlc3Ryb3llZCBoYXMgYW5vdGhlcgogKiBzdXJmYWNlIGF0dGFjaGVkIHRvIGl0ICh3aXRoIGEgInNvZnQiIGF0dGFjaG1lbnQsIG5vdCBjb21wbGV4KSwgdGhlbgogKiB0aGlzIHN1cmZhY2UgaXMgZGV0YWNoZWQgd2l0aCBEZWxldGVBdHRhY2hlZFN1cmZhY2UuCiAqCiAqIFdoZW4gdGhlIHN1cmZhY2UgaXMgYSB0ZXh0dXJlLCB0aGUgV2luZUQzRFRleHR1cmUgaXMgcmVsZWFzZWQuCiAqIElmIHRoZSBzdXJmYWNlIGlzIHRoZSBEaXJlY3QzRCByZW5kZXIgdGFyZ2V0LCB0aGVuIHRoZSBEM0QKICogY2FwYWJpbGl0aWVzIG9mIHRoZSBXaW5lRDNERGV2aWNlIGFyZSB1bmluaXRpYWxpemVkLCB3aGljaCBjYXVzZXMgdGhlCiAqIHN3YXBjaGFpbiB0byBiZSByZWxlYXNlZC4KICoKICogV2hlbiBhIGNvbXBsZXggc3VibGV2ZWwgZmFsbHMgdG8gcmVmIHplcm8sIHRoZW4gdGhpcyBpcyBpZ25vcmVkLgogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZWxlYXNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBVTE9ORyByZWY7CiAgICBUUkFDRSgiKCVwKSA6IFJlbGVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwogICAgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgaWYgKHJlZiA9PSAwKQogICAgewoKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXc7CiAgICAgICAgSVVua25vd24gKmlmYWNlVG9SZWxlYXNlID0gVGhpcy0+aWZhY2VUb1JlbGVhc2U7CiAgICAgICAgaW50IGk7CgogICAgICAgIC8qIENvbXBsZXggYXR0YWNoZWQgc3VyZmFjZXMgYXJlIGRlc3Ryb3llZCBpbXBsaWNpdGVseSB3aGVuIHRoZSByb290IGlzIHJlbGVhc2VkICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICBpZighVGhpcy0+aXNfY29tcGxleF9yb290KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiKCVwKSBBdHRlbXB0IHRvIGRlc3Ryb3kgYSBzdXJmYWNlIHRoYXQgaXMgbm90IGEgY29tcGxleCByb290XG4iLCBUaGlzKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIHJlZjsKICAgICAgICB9CiAgICAgICAgZGRyYXcgPSBUaGlzLT5kZHJhdzsKCiAgICAgICAgLyogSWYgaXQncyBhIHRleHR1cmUsIGRlc3Ryb3kgdGhlIFdpbmVEM0RUZXh0dXJlLgogICAgICAgICAqIFdpbmVEM0Qgd2lsbCBkZXN0cm95IHRoZSBJUGFyZW50IGludGVyZmFjZXMKICAgICAgICAgKiBvZiB0aGUgc3VibGV2ZWxzLCB3aGljaCBkZXN0cm95cyB0aGUgV2luZUQzRFN1cmZhY2VzLgogICAgICAgICAqIFNldCB0aGUgc3VyZmFjZXMgdG8gTlVMTCB0byBhdm9pZCBkZXN0cm95aW5nIHRoZW0gYWdhaW4gbGF0ZXIKICAgICAgICAgKi8KICAgICAgICBpZihUaGlzLT53aW5lRDNEVGV4dHVyZSkKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShUaGlzLT53aW5lRDNEVGV4dHVyZSk7CiAgICAgICAgfQogICAgICAgIC8qIElmIGl0J3MgdGhlIFJlbmRlclRhcmdldCwgZGVzdHJveSB0aGUgZDNkZGV2aWNlICovCiAgICAgICAgZWxzZSBpZiggKGRkcmF3LT5kM2RfaW5pdGlhbGl6ZWQpICYmIChUaGlzID09IGRkcmF3LT5kM2RfdGFyZ2V0KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIERlc3Ryb3lpbmcgdGhlIHJlbmRlciB0YXJnZXQsIHVuaW5pdGlhbGl6aW5nIEQzRFxuIiwgVGhpcyk7CgogICAgICAgICAgICAvKiBVbnNldCBhbnkgaW5kZXggYnVmZmVyLCBqdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SW5kaWNlcyhkZHJhdy0+d2luZUQzRERldmljZSwgTlVMTCk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoZGRyYXctPndpbmVEM0REZXZpY2UsIE5VTEwpOwogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRWZXJ0ZXhEZWNsYXJhdGlvbihkZHJhdy0+d2luZUQzRERldmljZSwgTlVMTCk7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGRkcmF3LT5udW1Db252ZXJ0ZWREZWNsczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX1JlbGVhc2UoZGRyYXctPmRlY2xzW2ldLmRlY2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRkcmF3LT5kZWNscyk7CiAgICAgICAgICAgIGRkcmF3LT5udW1Db252ZXJ0ZWREZWNscyA9IDA7CgogICAgICAgICAgICBpZihJV2luZUQzRERldmljZV9VbmluaXQzRChkZHJhdy0+d2luZUQzRERldmljZSwgRDNEN0NCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlLCBEM0Q3Q0JfRGVzdHJveVN3YXBDaGFpbikgIT0gRDNEX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBOb3QgZ29vZCAqLwogICAgICAgICAgICAgICAgRVJSKCIoJXApIEZhaWxlZCB0byB1bmluaXQgM0RcbiIsIFRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRnJlZSB0aGUgZDNkIHdpbmRvdyBpZiBvbmUgd2FzIGNyZWF0ZWQgKi8KICAgICAgICAgICAgICAgIGlmKGRkcmF3LT5kM2Rfd2luZG93ICE9IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIiAoJXApIERlc3Ryb3lpbmcgdGhlIGhpZGRlbiByZW5kZXIgd2luZG93ICVwXG4iLCBUaGlzLCBkZHJhdy0+ZDNkX3dpbmRvdyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdHJveVdpbmRvdyhkZHJhdy0+ZDNkX3dpbmRvdyk7CiAgICAgICAgICAgICAgICAgICAgZGRyYXctPmQzZF93aW5kb3cgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyogVW5zZXQgdGhlIHBvaW50ZXJzICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRkcmF3LT5kM2RfaW5pdGlhbGl6ZWQgPSBGQUxTRTsKICAgICAgICAgICAgZGRyYXctPmQzZF90YXJnZXQgPSBOVUxMOwoKICAgICAgICAgICAgLyogUmVzZXQgdG8gdGhlIGRlZmF1bHQgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB0eXBlLiBUaGlzIGlzIG5lZWRlZCBpZiBhcHBzIHVzZQogICAgICAgICAgICAgKiBub24gcmVuZGVyIHRhcmdldCBzdXJmYWNlcyBhbmQgZXhwZWN0IGJsaXRzIHRvIHdvcmsgYWZ0ZXIgZGVzdHJveWluZyB0aGUgcmVuZGVyCiAgICAgICAgICAgICAqIHRhcmdldC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVE9ETzogUmVjcmVhdGUgZXhpc3Rpbmcgb2Zmc2NyZWVuIHN1cmZhY2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkZHJhdy0+SW1wbFR5cGUgPSBEZWZhdWx0U3VyZmFjZVR5cGU7CgogICAgICAgICAgICAvKiBXcml0ZSBhIHRyYWNlIGJlY2F1c2UgRDNEIHVubG9hZGluZyB3YXMgdGhlIHJlYXNvbiBmb3IgbWFueQogICAgICAgICAgICAgKiBjcmFzaGVzIGR1cmluZyBkZXZlbG9wbWVudC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIEQzRCB1bmxvYWRlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfM0RERVZJQ0UgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVEVYVFVSRSAgICAgICAgKSApCiAgICAgICAgewogICAgICAgICAgICAvKiBJdCdzIGEgcmVuZGVyIHRhcmdldCwgYnV0IG5vIHN3YXBjaGFpbiB3YXMgY3JlYXRlZC4KICAgICAgICAgICAgICogVGhlIElQYXJlbnQgaW50ZXJmYWNlcyBoYXZlIHRvIGJlIHJlbGVhc2VkIG1hbnVhbGx5LgogICAgICAgICAgICAgKiBUaGUgc2FtZSBhcHBsaWVzIGZvciB0ZXh0dXJlcyB3aXRob3V0IGFuCiAgICAgICAgICAgICAqIElXaW5lRDNEVGV4dHVyZSBvYmplY3QgYXR0YWNoZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIElQYXJlbnQgKlBhcmVudDsKCiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPmNvbXBsZXhfYXJyYXlbaV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogT25seSB0aGUgdG9wbW9zdCBsZXZlbCBjYW4gaGF2ZSBtb3JlIHRoYW4gMSBzdXJmYWNlcyBpbiB0aGUgY29tcGxleAogICAgICAgICAgICAgICAgICAgICAqIGF0dGFjaG1lbnQgYXJyYXkoQ3ViZSB0ZXh0dXJlIHJvb3RzKSwgZm9yIGFsbCBvdGhlcnMgdGhlcmUgaXMgb25seQogICAgICAgICAgICAgICAgICAgICAqIG9uZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKHN1cmYpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHN1cmYtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJlBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIElQYXJlbnRfUmVsZWFzZShQYXJlbnQpOyAgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBUbyByZWxlYXNlIGl0ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHN1cmYgPSBzdXJmLT5jb21wbGV4X2FycmF5WzBdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogTm93IHRoZSB0b3AtbGV2ZWwgc3VyZmFjZSAqLwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJlBhcmVudCk7CiAgICAgICAgICAgIElQYXJlbnRfUmVsZWFzZShQYXJlbnQpOyAgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBUbyByZWxlYXNlIGl0ICovCiAgICAgICAgfQoKICAgICAgICAvKiBUaGUgcmVmY291bnQgdGVzdCBzaG93cyB0aGF0IHRoZSBwYWxldHRlIGlzIGRldGFjaGVkIHdoZW4gdGhlIHN1cmZhY2UgaXMgZGVzdHJveWVkICovCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19TZXRQYWxldHRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCiAgICAgICAgLyogTG9vcCB0aHJvdWdoIGFsbCBjb21wbGV4IGF0dGFjaGVkIHN1cmZhY2VzLAogICAgICAgICAqIGFuZCBkZXN0cm95IHRoZW0uCiAgICAgICAgICoKICAgICAgICAgKiBZZXQgYWdhaW4sIG9ubHkgdGhlIHJvb3QgY2FuIGhhdmUgbW9yZSB0aGFuIG9uZSBjb21wbGV4bHkgYXR0YWNoZWQgc3VyZmFjZSwgYWxsIHRoZSBvdGhlcnMKICAgICAgICAgKiBoYXZlIGEgdG90YWwgb2Ygb25lOwogICAgICAgICAqLwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZighVGhpcy0+Y29tcGxleF9hcnJheVtpXSkgYnJlYWs7CgogICAgICAgICAgICBzdXJmID0gVGhpcy0+Y29tcGxleF9hcnJheVtpXTsKICAgICAgICAgICAgVGhpcy0+Y29tcGxleF9hcnJheVtpXSA9IE5VTEw7CiAgICAgICAgICAgIHdoaWxlKHN1cmYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3Ryb3kgPSBzdXJmOwogICAgICAgICAgICAgICAgc3VyZiA9IHN1cmYtPmNvbXBsZXhfYXJyYXlbMF07ICAgICAgICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggdGhlICJ0cmVlIiAqLwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95KGRlc3Ryb3kpOyAgICAvKiBEZXN0cm95IGl0ICovCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIERlc3Ryb3kgdGhlIHJvb3Qgc3VyZmFjZS4KICAgICAgICAgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0Rlc3Ryb3koVGhpcyk7CgogICAgICAgIC8qIFJlZHVjZSB0aGUgZGRyYXcgcmVmY291bnQgKi8KICAgICAgICBpZihpZmFjZVRvUmVsZWFzZSkgSVVua25vd25fUmVsZWFzZShpZmFjZVRvUmVsZWFzZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0QXR0YWNoZWRTdXJmYWNlCiAqCiAqIFJldHVybnMgYW4gYXR0YWNoZWQgc3VyZmFjZSB3aXRoIHRoZSByZXF1ZXN0ZWQgY2Fwcy4gU3VyZmFjZSBhdHRhY2htZW50CiAqIGFuZCBjb21wbGV4IHN1cmZhY2VzIGFyZSBub3QgY2xlYXJseSBkZXNjcmliZWQgYnkgdGhlIE1TRE4gb3Igc2RrLAogKiBzbyB0aGlzIG1ldGhvZCBpcyB0cmlja3kgYW5kIGxpa2VseSB0byBjb250YWluIHByb2JsZW1zLgogKiBUaGlzIGltcGxlbWVudGF0aW9uIHNlYXJjaGVzIHRoZSBjb21wbGV4IGxpc3QgZmlyc3QsIHRoZW4gdGhlCiAqIGF0dGFjaG1lbnQgY2hhaW4uCiAqCiAqIFRoZSBjaGFpbnMgYXJlIHNlYXJjaGVkIGZyb20gVGhpcyBkb3duIHRvIHRoZSBsYXN0IHN1cmZhY2UgaW4gdGhlIGNoYWluLAogKiBub3QgZnJvbSB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgY2hhaW4uIFRoZSBmaXJzdCBzdXJmYWNlIGZvdW5kIGlzCiAqIHJldHVybmVkLiBUaGUgTVNETiBzYXlzIHRoYXQgdGhpcyBtZXRob2QgZmFpbHMgaWYgbW9yZSB0aGFuIG9uZSBzdXJmYWNlCiAqIG1hdGNoZXMgdGhlIGNhcHMsIGJ1dCBpdCBpcyBub3Qgc3VyZSBpZiB0aGF0IGlzIHJpZ2h0LiBUaGUgYXR0YWNobWVudAogKiBzdHJ1Y3R1cmUgbWF5IG5vdCBldmVuIGFsbG93IHR3byBtYXRjaGluZyBzdXJmYWNlcy4KICoKICogVGhlIGZvdW5kIHN1cmZhY2UgaXMgQWRkUmVmLWVkIGJlZm9yZSBpdCBpcyByZXR1cm5lZC4KICoKICogUGFyYW1zOgogKiAgQ2FwczogUG9pbnRlciB0byBhIEREQ0FQUzIgc3RydWN0dXJlIGRlc2NyaWJpbmcgdGhlIGNhcHMgYXNrZWQgZm9yCiAqICBTdXJmYWNlOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBmb3VuZCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhcHMgb3IgU3VyZmFjZSBpcyBOVUxMCiAqICBEREVSUl9OT1RGT1VORCBpZiBubyBzdXJmYWNlIHdhcyBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQUzIgKkNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgRERTQ0FQUzIgb3VyX2NhcHM7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgQ2FwcywgU3VyZmFjZSk7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIG91cl9jYXBzID0gKkNhcHM7CgogICAgaWYoVGhpcy0+dmVyc2lvbiA8IDcpCiAgICB7CiAgICAgICAgLyogRWFybGllciBkeCBhcHBzIHB1dCBnYXJiYWdlIGludG8gdGhlc2UgbWVtYmVycywgY2xlYXIgdGhlbSAqLwogICAgICAgIG91cl9jYXBzLmR3Q2FwczIgPSAwOwogICAgICAgIG91cl9jYXBzLmR3Q2FwczMgPSAwOwogICAgICAgIG91cl9jYXBzLmR3Q2FwczQgPSAwOwogICAgfQoKICAgIFRSQUNFKCIoJXApOiBMb29raW5nIGZvciBjYXBzOiAleCwleCwleCwleFxuIiwgVGhpcywgb3VyX2NhcHMuZHdDYXBzLCBvdXJfY2Fwcy5kd0NhcHMyLCBvdXJfY2Fwcy5kd0NhcHMzLCBvdXJfY2Fwcy5kd0NhcHM0KTsgLyogRklYTUU6IEJldHRlciBkZWJ1Z2dpbmcgKi8KCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NUExFWF9BVFRBQ0hFRDsgaSsrKQogICAgewogICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgIGlmKCFzdXJmKSBicmVhazsKCiAgICAgICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlOiAoJXApIGNhcHM6ICV4LCV4LCV4LCV4XG4iLCBzdXJmLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMiwKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczMsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHM0KTsKICAgICAgICB9CgogICAgICAgIGlmICgoKHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIG91cl9jYXBzLmR3Q2FwcykgPT0gb3VyX2NhcHMuZHdDYXBzKSAmJgogICAgICAgICAgICAoKHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBvdXJfY2Fwcy5kd0NhcHMyKSA9PSBvdXJfY2Fwcy5kd0NhcHMyKSkgewoKICAgICAgICAgICAgLyogTVNETjogIlRoaXMgbWV0aG9kIGZhaWxzIGlmIG1vcmUgdGhhbiBvbmUgc3VyZmFjZSBpcyBhdHRhY2hlZAogICAgICAgICAgICAgKiB0aGF0IG1hdGNoZXMgdGhlIGNhcGFiaWxpdGllcyByZXF1ZXN0ZWQuIgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBOb3Qgc3VyZSBob3cgdG8gdGVzdCB0aGlzLgogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIFRSQUNFKCIoJXApOiBSZXR1cm5pbmcgc3VyZmFjZSAlcFxuIiwgVGhpcywgc3VyZik7CiAgICAgICAgICAgIFRSQUNFKCIoJXApOiBtaXBtYXBjb3VudD0lZFxuIiwgVGhpcywgc3VyZi0+bWlwbWFwX2xldmVsKTsKICAgICAgICAgICAgKlN1cmZhY2UgPSBJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoKlN1cmZhY2UpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5leHQsIGxvb2sgYXQgdGhlIGF0dGFjaG1lbnQgY2hhaW4gKi8KICAgIHN1cmYgPSBUaGlzOwoKICAgIHdoaWxlKCAoc3VyZiA9IHN1cmYtPm5leHRfYXR0YWNoZWQpICkKICAgIHsKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2U6ICglcCkgY2FwczogJXgsJXgsJXgsJXhcbiIsIHN1cmYsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMywKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgb3VyX2NhcHMuZHdDYXBzKSA9PSBvdXJfY2Fwcy5kd0NhcHMpICYmCiAgICAgICAgICAgICgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMiAmIG91cl9jYXBzLmR3Q2FwczIpID09IG91cl9jYXBzLmR3Q2FwczIpKSB7CgogICAgICAgICAgICBUUkFDRSgiKCVwKTogUmV0dXJuaW5nIHN1cmZhY2UgJXBcbiIsIFRoaXMsIHN1cmYpOwogICAgICAgICAgICAqU3VyZmFjZSA9IElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZigqU3VyZmFjZSk7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIiglcCkgRGlkbid0IGZpbmQgYSB2YWxpZCBzdXJmYWNlXG4iLCBUaGlzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERFUlJfTk9URk9VTkQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpMb2NrCiAqCiAqIExvY2tzIHRoZSBzdXJmYWNlIGFuZCByZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgc3VyZmFjZSdzIG1lbW9yeQogKgogKiBQYXJhbXM6CiAqICBSZWN0OiBSZWN0YW5nbGUgdG8gbG9jay4gSWYgTlVMTCwgdGhlIHdob2xlIHN1cmZhY2UgaXMgbG9ja2VkCiAqICBERFNEOiBQb2ludGVyIHRvIGEgRERTVVJGQUNFREVTQzIgd2hpY2ggc2hhbGwgcmVjZWl2ZSB0aGUgc3VyZmFjZSdzIGRlc2MuCiAqICBGbGFnczogTG9ja2luZyBmbGFncywgZS5nIFJlYWQgb25seSBvciB3cml0ZSBvbmx5CiAqICBoOiBBbiBldmVudCBoYW5kbGUgdGhhdCdzIG5vdCB1c2VkIGFuZCBtdXN0IGJlIE5VTEwKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRERTRCBpcyBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpMb2NrUmVjdAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0xvY2soSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgTG9ja2VkUmVjdDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCV4LCVwKVxuIiwgVGhpcywgUmVjdCwgRERTRCwgRmxhZ3MsIGgpOwoKICAgIGlmKCFERFNEKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIFRoaXMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoIGFuZCBkd0hlaWdodCBhcmUgY2hhbmdlYWJsZSwgdGh1cyBsb2NrICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKFJlY3QpCiAgICB7CiAgICAgICAgaWYgKChSZWN0LT5sZWZ0IDwgMCkKICAgICAgICAgICAgICAgIHx8IChSZWN0LT50b3AgPCAwKQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPmxlZnQgPiBSZWN0LT5yaWdodCkKICAgICAgICAgICAgICAgIHx8IChSZWN0LT50b3AgPiBSZWN0LT5ib3R0b20pCiAgICAgICAgICAgICAgICB8fCAoUmVjdC0+cmlnaHQgPiBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aCkKICAgICAgICAgICAgICAgIHx8IChSZWN0LT5ib3R0b20gPiBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiVHJ5aW5nIHRvIGxvY2sgYW4gaW52YWxpZCByZWN0YW5nbGUsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFNob3VsZCBJIGNoZWNrIGZvciB0aGUgaGFuZGxlIHRvIGJlIE5VTEw/CiAgICAgKgogICAgICogVGhlIERETE9DSyBmbGFncyBhbmQgdGhlIEQzRExPQ0sgZmxhZ3MgYXJlIGVxdWFsCiAgICAgKiBmb3IgdGhlIHN1cHBvcnRlZCB2YWx1ZXMuIFRoZSBvdGhlcnMgYXJlIGlnbm9yZWQgYnkgV2luZUQzRAogICAgICovCgogICAgaWYoRERTRC0+ZHdTaXplICE9IHNpemVvZihERFNVUkZBQ0VERVNDKSAmJgogICAgICAgRERTRC0+ZHdTaXplICE9IHNpemVvZihERFNVUkZBQ0VERVNDMikpCiAgICB7CiAgICAgICAgV0FSTigiSW52YWxpZCBzdHJ1Y3R1cmUgc2l6ZSAlZCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIsIERERVJSX0lOVkFMSURQQVJBTVMpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTG9ja2VkUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICBzd2l0Y2goaHIpCiAgICAgICAgewogICAgICAgICAgICAvKiBEM0Q4IGFuZCBEM0Q5IHJldHVybiB0aGUgZ2VuZXJhbCBEM0RFUlJfSU5WQUxJRENBTEwgZXJyb3IsIGJ1dCBkZHJhdyBoYXMgYSBtb3JlCiAgICAgICAgICAgICAqIHNwZWNpZmljIGVycm9yLiBCdXQgc2luY2UgSVdpbmVEM0RTdXJmYWNlOjpMb2NrUmVjdCByZXR1cm5zIHRoYXQgZXJyb3IgaW4gdGhpcwogICAgICAgICAgICAgKiBvbmx5IG9jY2FzaW9uLCBrZWVwIGQzZDggYW5kIGQzZDkgZnJlZSBmcm9tIHRoZSByZXR1cm4gdmFsdWUgb3ZlcnJpZGUuIFRoZXJlIGFyZQogICAgICAgICAgICAgKiBtYW55IGRpZmZlcmVudCBwbGFjZXMgd2hlcmUgZDNkOC85IHdvdWxkIGhhdmUgdG8gY2F0Y2ggdGhlIERERVJSX1NVUkZBQ0VCVVNZLCBpdAogICAgICAgICAgICAgKiBpcyBtdWNoIGVhc2llciB0byBkbyBpdCBpbiBvbmUgcGxhY2UgaW4gZGRyYXcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNhc2UgV0lORUQzREVSUl9JTlZBTElEQ0FMTDogICAgcmV0dXJuIERERVJSX1NVUkZBQ0VCVVNZOwogICAgICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgLyogT3ZlcnJpZGUgdGhlIG1lbW9yeSBhcmVhLiBUaGUgcGl0Y2ggc2hvdWxkIGJlIHNldCBhbHJlYWR5LiBTdHJhbmdlbHkgd2luZG93cwogICAgICogZG9lcyBub3Qgc2V0IHRoZSBMUFNVUkZBQ0UgZmxhZyBvbiBsb2NrZWQgc3VyZmFjZXMgIT8hLgogICAgICogRERTRC0+ZHdGbGFncyB8PSBERFNEX0xQU1VSRkFDRTsKICAgICAqLwogICAgVGhpcy0+c3VyZmFjZV9kZXNjLmxwU3VyZmFjZSA9IExvY2tlZFJlY3QucEJpdHM7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoRERTRCwmKFRoaXMtPnN1cmZhY2VfZGVzYykpOwoKICAgIFRSQUNFKCJsb2NrZWQgc3VyZmFjZSByZXR1cm5pbmcgZGVzY3JpcHRpb24gOlxuIik7CiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKSBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6VW5sb2NrCiAqCiAqIFVubG9ja3MgYW4gbG9ja2VkIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgUmVjdDogTm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OlVubG9ja1JlY3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VbmxvY2soSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKnBSZWN0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHBSZWN0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChUaGlzLT5XaW5lRDNEU3VyZmFjZSk7CiAgICBpZihTVUNDRUVERUQoaHIpKQogICAgewogICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5scFN1cmZhY2UgPSBOVUxMOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkZsaXAKICoKICogRmxpcHMgYSBzdXJmYWNlIHdpdGggdGhlIEREU0NBUFNfRkxJUCBmbGFnLiBUaGUgZmxpcCBpcyByZWxheWVkIHRvCiAqIElXaW5lRDNEU3VyZmFjZTo6RmxpcC4gQmVjYXVzZSBXaW5lRDNEIGRvZXNuJ3QgaGFuZGxlIGF0dGFjaGVkIHN1cmZhY2VzLAogKiB0aGUgZmxpcCB0YXJnZXQgaXMgcGFzc2VkIHRvIFdpbmVEM0QsIGV2ZW4gaWYgdGhlIGFwcCBkaWRuJ3Qgc3BlY2lmeSBvbmUKICoKICogUGFyYW1zOgogKiAgRGVzdE92ZXJyaWRlOiBTcGVjaWZpZXMgdGhlIHN1cmZhY2UgdGhhdCB3aWxsIGJlY29tZSB0aGUgbmV3IGZyb250CiAqICAgICAgICAgICAgICAgIGJ1ZmZlci4gSWYgTlVMTCwgdGhlIGN1cnJlbnQgYmFjayBidWZmZXIgaXMgdXNlZAogKiAgRmxhZ3M6IHNvbWUgRGlyZWN0RHJhdyBmbGFncywgc2VlIGluY2x1ZGUvZGRyYXcuaAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfTk9URkxJUFBBQkxFIGlmIG5vIGZsaXAgdGFyZ2V0IGNvdWxkIGJlIGZvdW5kCiAqICBEREVSUl9JTlZBTElET0JKRUNUIGlmIHRoZSBzdXJmYWNlIGlzbid0IGEgZnJvbnQgYnVmZmVyCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpGbGlwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRmxpcChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RPdmVycmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpPdmVycmlkZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIERlc3RPdmVycmlkZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpPdmVycmlkZTc7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIERlc3RPdmVycmlkZSwgRmxhZ3MpOwoKICAgIC8qIEZsaXAgaGFzIHRvIGJlIGNhbGxlZCBmcm9tIGEgZnJvbnQgYnVmZmVyCiAgICAgKiBXaGF0IGFib3V0IG92ZXJsYXkgc3VyZmFjZXMsIEFGQUlLIHRoZXkgY2FuIGZsaXAgdG9vPwogICAgICovCiAgICBpZiggIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0ZST05UQlVGRkVSKSApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURPQkpFQ1Q7IC8qIFVuY2tlY2tlZCAqLwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgLyogV2luZUQzRCBkb2Vzbid0IGtlZXAgdHJhY2sgb2YgYXR0YWNoZWQgc3VyZmFjZSwgc28gZmluZCB0aGUgdGFyZ2V0ICovCiAgICBpZighT3ZlcnJpZGUpCiAgICB7CiAgICAgICAgRERTQ0FQUzIgQ2FwczsKCiAgICAgICAgbWVtc2V0KCZDYXBzLCAwLCBzaXplb2YoQ2FwcykpOwogICAgICAgIENhcHMuZHdDYXBzIHw9IEREU0NBUFNfQkFDS0JVRkZFUjsKICAgICAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKGlmYWNlLCAmQ2FwcywgJk92ZXJyaWRlNyk7CiAgICAgICAgaWYoaHIgIT0gRERfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIkNhbid0IGZpbmQgYSBmbGlwIHRhcmdldFxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9OT1RGTElQUEFCTEU7IC8qIFVuY2hlY2tlZCAqLwogICAgICAgIH0KICAgICAgICBPdmVycmlkZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIE92ZXJyaWRlNyk7CgogICAgICAgIC8qIEZvciB0aGUgR2V0QXR0YWNoZWRTdXJmYWNlICovCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKE92ZXJyaWRlNyk7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfRmxpcChUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3ZlcnJpZGUtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6Qmx0CiAqCiAqIFBlcmZvcm1zIGEgYmxpdCBvbiB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBEZXN0UmVjdDogRGVzdGluYXRpb24gcmVjdGFuZ2xlLCBjYW4gYmUgTlVMTAogKiAgU3JjU3VyZmFjZTogU291cmNlIHN1cmZhY2UsIGNhbiBiZSBOVUxMCiAqICBTcmNSZWN0OiBTb3VyY2UgcmVjdGFuZ2UsIGNhbiBiZSBOVUxMCiAqICBGbGFnczogQmx0IGZsYWdzCiAqICBEREJsdEZ4OiBTb21lIGV4dGVuZGVkIGJsdCBwYXJhbWV0ZXJzLCBjb25uZWN0ZWQgdG8gdGhlIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6Qmx0IGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHQoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKkRlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmNTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgRERCTFRGWCAqRERCbHRGeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyY1N1cmZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWRpdHkgb2YgdGhlIGZsYWdzIGhlcmUuIFdpbmVEM0QgSGFzIHRoZSBzb2Z0d2FyZS1vcGVuZ2wgc2VsZWN0aW9uIHBhdGggYW5kIHdvdWxkIGhhdmUKICAgICAqIHRvIGNoZWNrIGF0IDIgcGxhY2VzLCBhbmQgc29tZXRpbWVzIGRvIGRvdWJsZSBjaGVja3MuIFRoaXMgYWxzbyBzYXZlcyB0aGUgY2FsbCB0byB3aW5lZDNkIDotKQogICAgICovCiAgICBpZigoRmxhZ3MgJiBEREJMVF9LRVlTUkNPVkVSUklERSkgJiYgKCFEREJsdEZ4IHx8IEZsYWdzICYgRERCTFRfS0VZU1JDKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgc291cmNlIGNvbG9yIGtleSBwYXJhbWV0ZXJzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoKEZsYWdzICYgRERCTFRfS0VZREVTVE9WRVJSSURFKSAmJiAoIUREQmx0RnggfHwgRmxhZ3MgJiBEREJMVF9LRVlERVNUKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgZGVzdGluYXRpb24gY29sb3Iga2V5IHBhcmFtZXRlcnMsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBTaXplcyBjYW4gY2hhbmdlLCB0aGVyZWZvcmUgaG9sZCB0aGUgbG9jayB3aGVuIHRlc3RpbmcgdGhlIHJlY3RhbmdsZXMgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihEZXN0UmVjdCkKICAgIHsKICAgICAgICBpZihEZXN0UmVjdC0+dG9wID49IERlc3RSZWN0LT5ib3R0b20gfHwgRGVzdFJlY3QtPmxlZnQgPj0gRGVzdFJlY3QtPnJpZ2h0IHx8CiAgICAgICAgICAgRGVzdFJlY3QtPnJpZ2h0ID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICBEZXN0UmVjdC0+Ym90dG9tID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiU291cmNlIHJlY3RhbmdsZSBpcyBpbnZhbGlkLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFJFQ1RcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgfQogICAgfQogICAgaWYoU3JjICYmIFNyY1JlY3QpCiAgICB7CiAgICAgICAgaWYoU3JjUmVjdC0+dG9wID49IFNyY1JlY3QtPmJvdHRvbSB8fCBTcmNSZWN0LT5sZWZ0ID49U3JjUmVjdC0+cmlnaHQgfHwKICAgICAgICAgICBTcmNSZWN0LT5yaWdodCA+IFNyYy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICBTcmNSZWN0LT5ib3R0b20gPiBTcmMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIlNvdXJjZSByZWN0YW5nbGUgaXMgaW52YWxpZCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURSRUNUXG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURSRUNUOwogICAgICAgIH0KICAgIH0KCiAgICBpZihGbGFncyAmIEREQkxUX0tFWVNSQyAmJiAoIVNyYyB8fCAhKFNyYy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkpIHsKICAgICAgICBXQVJOKCJEREJMVF9LRVlERVNUIGJsaXQgd2l0aG91dCBjb2xvciBrZXkgaW4gc3VyZmFjZSwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogVE9ETzogQ2hlY2sgaWYgdGhlIEREQmx0RnggY29udGFpbnMgYW55IGRkcmF3IHN1cmZhY2UgcG9pbnRlcnMuIElmIGl0IGRvZXMsIGNvcHkgdGhlIHN0cnVjdCwKICAgICAqIGFuZCByZXBsYWNlIHRoZSBkZHJhdyBzdXJmYWNlcyB3aXRoIHRoZSB3aW5lZDNkIHN1cmZhY2VzCiAgICAgKiBTbyBmYXIgbm8gYmxpdHRpbmcgb3BlcmF0aW9ucyB1c2luZyBzdXJmYWNlcyBpbiB0aGUgYmx0Znggc3RydWN0IGFyZSBzdXBwb3J0ZWQgYW55d2F5LgogICAgICovCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9CbHQoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjID8gU3JjLT5XaW5lRDNEU3VyZmFjZSA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQkxURlggKikgRERCbHRGeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVEVYRl9QT0lOVCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOiAgICAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX1dST05HVEVYVFVSRUZPUk1BVDogcmV0dXJuIERERVJSX0lOVkFMSURQSVhFTEZPUk1BVDsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpBZGRBdHRhY2hlZFN1cmZhY2UKICoKICogQXR0YWNoZXMgYSBzdXJmYWNlIHRvIGFub3RoZXIgc3VyZmFjZS4gSG93IHRoZSBzdXJmYWNlIGF0dGFjaG1lbnRzIHdvcmsKICogaXMgbm90IHRvdGFsbHkgdW5kZXJzdG9vZCB5ZXQsIGFuZCB0aGlzIG1ldGhvZCBpcyBwcm9uZSB0byBwcm9ibGVtcy4KICogaGUgc3VyZmFjZSB0aGF0IGlzIGF0dGFjaGVkIGlzIEFkZFJlZi1lZC4KICoKICogVGVzdHMgd2l0aCBjb21wbGV4IHN1cmZhY2VzIHN1Z2dlc3QgdGhhdCB0aGUgc3VyZmFjZSBhdHRhY2htZW50cyBmb3JtIGEKICogdHJlZSwgYnV0IG5vIG1ldGhvZCB0byB0ZXN0IHRoaXMgaGFzIGJlZW4gZm91bmQgeWV0LgogKgogKiBUaGUgYXR0YWNobWVudCBsaXN0IGNvbnNpc3RzIG9mIGEgZmlyc3Qgc3VyZmFjZSAoZmlyc3RfYXR0YWNoZWQpIGFuZAogKiBmb3IgZWFjaCBzdXJmYWNlIGEgcG9pbnRlciB0byB0aGUgbmV4dCBhdHRhY2hlZCBzdXJmYWNlIChuZXh0X2F0dGFjaGVkKS4KICogRm9yIHRoZSBmaXJzdCBzdXJmYWNlLCBhbmQgYSBzdXJmYWNlIHRoYXQgaGFzIG5vIGF0dGFjaG1lbnRzCiAqIGZpcnN0X2F0dGFjaGVkIHBvaW50cyB0byB0aGUgc3VyZmFjZSBpdHNlbGYuIEEgc3VyZmFjZSB0aGF0IGhhcwogKiBubyBzdWNjZXNzb3JzIGluIHRoZSBjaGFpbiBoYXMgbmV4dF9hdHRhY2hlZCBzZXQgdG8gTlVMTC4KICoKICogTmV3bHkgYXR0YWNoZWQgc3VyZmFjZXMgYXJlIGF0dGFjaGVkIHJpZ2h0IGFmdGVyIHRoZSByb290IHN1cmZhY2UuCiAqIElmIGEgc3VyZmFjZSBpcyBhdHRhY2hlZCB0byBhIGNvbXBsZXggc3VyZmFjZSBjb21wb3VuZCwgaXQncyBhdHRhY2hlZCB0bwogKiB0aGUgc3VyZmFjZSB0aGF0IHRoZSBhcHAgcmVxdWVzdGVkLCBub3QgdGhlIGNvbXBsZXggcm9vdC4gU2VlCiAqIEdldEF0dGFjaGVkU3VyZmFjZSBmb3IgYSBkZXNjcmlwdGlvbiBob3cgc3VyZmFjZXMgYXJlIGZvdW5kLgogKgogKiBUaGlzIGlzIGhvdyB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiB3b3JrcywgYW5kIGl0IHdhcyBjb2RlZCBieSBsb29raW5nCiAqIGF0IHRoZSBuZWVkcyBvZiB0aGUgYXBwbGljYXRpb25zLgogKgogKiBTbyBmYXIgb25seSBaLUJ1ZmZlciBhdHRhY2htZW50cyBhcmUgdGVzdGVkLCBhbmQgdGhleSBhcmUgYWN0aXZhdGVkIGluCiAqIFdpbmVEM0QuIE1pcG1hcHMgY291bGQgYmUgdHJpY2t5IHRvIGFjdGl2YXRlIGluIFdpbmVEM0QuCiAqIEJhY2sgYnVmZmVycyBzaG91bGQgd29yayBpbiAyRCBtb2RlLCBidXQgdGhleSBhcmUgbm90IHRlc3RlZChUaGV5IGNhbiBiZQogKiBhdHRhY2hlZCBpbiBvbGRlciBpZmFjZSB2ZXJzaW9ucykuIFJlbmRlcmluZyB0byB0aGUgZnJvbnQgYnVmZmVyIGFuZAogKiBzd2l0Y2hpbmcgYmV0d2VlbiB0aGF0IGFuZCBkb3VibGUgYnVmZmVyaW5nIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQgaW4KICogV2luZUQzRCwgc28gZm9yIDNEIGl0IG1pZ2h0IGhhdmUgdW5leHBlY3RlZCByZXN1bHRzLgogKgogKiBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZSBpcyB0aGUgcmVhbCB0aGluZywKICogSURpcmVjdERyYXdTdXJmYWNlN0ltcGxfQWRkQXR0YWNoZWRTdXJmYWNlIGlzIGEgd3JhcHBlciBhcm91bmQgaXQgdGhhdAogKiBwZXJmb3JtcyBhZGRpdGlvbmFsIGNoZWNrcy4gVmVyc2lvbiA3IG9mIHRoaXMgaW50ZXJmYWNlIGlzIG11Y2ggbW9yZSByZXN0cmljdGl2ZQogKiB0aGFuIGl0cyBwcmVkZWNlc3NvcnMuCiAqCiAqIFBhcmFtczoKICogIEF0dGFjaDogU3VyZmFjZSB0byBhdHRhY2ggdG8gaWZhY2UKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0NBTk5PVEFUVEFDSFNVUkZBQ0UgaWYgdGhlIHN1cmZhY2UgY2FuJ3QgYmUgYXR0YWNoZWQgZm9yIHNvbWUgcmVhc29uCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRBdHRhY2hlZFN1cmZhY2UoSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZikKewogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFN1cmYpOwoKICAgIGlmKFN1cmYgPT0gVGhpcykKICAgICAgICByZXR1cm4gRERFUlJfQ0FOTk9UQVRUQUNIU1VSRkFDRTsgLyogdW5jaGVja2VkICovCgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBDaGVjayBpZiB0aGUgc3VyZmFjZSBpcyBhbHJlYWR5IGF0dGFjaGVkIHNvbWV3aGVyZSAqLwogICAgaWYoIChTdXJmLT5uZXh0X2F0dGFjaGVkICE9IE5VTEwpIHx8CiAgICAgICAgKFN1cmYtPmZpcnN0X2F0dGFjaGVkICE9IFN1cmYpICkKICAgIHsKICAgICAgICAvKiBUT0RPOiBUZXN0IGZvciB0aGUgc3RydWN0dXJlIG9mIHRoZSBtYW51YWwgYXR0YWNobWVudC4gSXMgaXQgYSBjaGFpbiBvciBhIGxpc3Q/CiAgICAgICAgICogV2hhdCBoYXBwZW5zIGlmIG9uZSBzdXJmYWNlIGlzIGF0dGFjaGVkIHRvIDIgZGlmZmVyZW50IHN1cmZhY2VzPwogICAgICAgICAqLwogICAgICAgIEZJWE1FKCIoJXApIFRoZSBTdXJmYWNlICVwIGlzIGFscmVhZHkgYXR0YWNoZWQgc29tZXdoZXJlIGVsc2U6IG5leHRfYXR0YWNoZWQgPSAlcCwgZmlyc3RfYXR0YWNoZWQgPSAlcCwgY2FuJ3QgaGFuZGxlIGJ5IG5vd1xuIiwgVGhpcywgU3VyZiwgU3VyZi0+bmV4dF9hdHRhY2hlZCwgU3VyZi0+Zmlyc3RfYXR0YWNoZWQpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX1NVUkZBQ0VBTFJFQURZQVRUQUNIRUQ7CiAgICB9CgogICAgLyogVGhpcyBpbnNlcnRzIHRoZSBuZXcgc3VyZmFjZSBhdCB0aGUgMm5kIHBvc2l0aW9uIGluIHRoZSBjaGFpbiwgcmlnaHQgYWZ0ZXIgdGhlIHJvb3Qgc3VyZmFjZSAqLwogICAgU3VyZi0+bmV4dF9hdHRhY2hlZCA9IFRoaXMtPm5leHRfYXR0YWNoZWQ7CiAgICBTdXJmLT5maXJzdF9hdHRhY2hlZCA9IFRoaXMtPmZpcnN0X2F0dGFjaGVkOwogICAgVGhpcy0+bmV4dF9hdHRhY2hlZCA9IFN1cmY7CgogICAgLyogQ2hlY2sgaWYgdGhlIFdpbmVEM0QgZGVwdGggc3RlbmNpbCBuZWVkcyB1cGRhdGluZyAqLwogICAgaWYoVGhpcy0+ZGRyYXctPmQzZGRldmljZSkKICAgIHsKICAgICAgICBJRGlyZWN0M0REZXZpY2VJbXBsX1VwZGF0ZURlcHRoU3RlbmNpbChUaGlzLT5kZHJhdy0+ZDNkZGV2aWNlKTsKICAgIH0KCiAgICAvKiBNU0ROOiAKICAgICAqICJUaGlzIG1ldGhvZCBpbmNyZW1lbnRzIHRoZSByZWZlcmVuY2UgY291bnQgb2YgdGhlIHN1cmZhY2UgYmVpbmcgYXR0YWNoZWQuIgogICAgICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlN0ltcGxfQWRkQXR0YWNoZWRTdXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqQXR0YWNoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgQXR0YWNoKTsKCiAgICAvKiBWZXJzaW9uIDcgb2YgdGhpcyBpbnRlcmZhY2Ugc2VlbXMgdG8gcmVmdXNlIGV2ZXJ5dGhpbmcgZXhjZXB0IHogYnVmZmVycywgYXMgcGVyIG1zZG4gKi8KICAgIGlmKCEoU3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19aQlVGRkVSKSkKICAgIHsKCiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gdHJpZXMgdG8gYXR0YWNoIGEgbm9uIFogYnVmZmVyIHN1cmZhY2UuIGNhcHMgJTA4eFxuIiwKICAgICAgICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMpOwogICAgICAgIHJldHVybiBEREVSUl9DQU5OT1RBVFRBQ0hTVVJGQUNFOwogICAgfQoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZShUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1cmYpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpEZWxldGVBdHRhY2hlZFN1cmZhY2UKICoKICogUmVtb3ZlcyBhIHN1cmZhY2UgZnJvbSB0aGUgYXR0YWNobWVudCBjaGFpbi4gVGhlIHN1cmZhY2UncyByZWZjb3VudAogKiBpcyBkZWNyZWFzZWQgYnkgb25lIGFmdGVyIGl0IGhhcyBiZWVuIHJlbW92ZWQKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MsIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24KICogIEF0dGFjaDogU3VyZmFjZSB0byBkZXRhY2gKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX1NVUkZBQ0VOT1RBVFRBQ0hFRCBpZiB0aGUgc3VyZmFjZSBpc24ndCBhdHRhY2hlZCB0bwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0RlbGV0ZUF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkF0dGFjaCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIEF0dGFjaCk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpQcmV2ID0gVGhpczsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEZsYWdzLCBTdXJmKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKCFTdXJmIHx8IChTdXJmLT5maXJzdF9hdHRhY2hlZCAhPSBUaGlzKSB8fCAoU3VyZiA9PSBUaGlzKSApCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfQ0FOTk9UREVUQUNIU1VSRkFDRTsKICAgIH0KCiAgICAvKiBSZW1vdmUgTUlQTUFQU1VCTEVWRUwgaWYgdGhpcyBzZWVtZWQgdG8gYmUgb25lICovCiAgICBpZiAoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYKICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgIHsKICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9NSVBNQVBTVUJMRVZFTDsKICAgICAgICAvKiBGSVhNRTogd2Ugc2hvdWxkIHByb2JhYmx5IGFsc28gc3VidHJhY3QgZnJvbSBkd01pcE1hcENvdW50IG9mIHRoaXMKICAgICAgICAgKiBhbmQgYWxsIHBhcmVudCBzdXJmYWNlcyAqLwogICAgfQoKICAgIC8qIEZpbmQgdGhlIHByZWRlY2Vzc29yIG9mIHRoZSBkZXRhY2hlZCBzdXJmYWNlICovCiAgICB3aGlsZShQcmV2KQogICAgewogICAgICAgIGlmKFByZXYtPm5leHRfYXR0YWNoZWQgPT0gU3VyZikgYnJlYWs7CiAgICAgICAgUHJldiA9IFByZXYtPm5leHRfYXR0YWNoZWQ7CiAgICB9CgogICAgLyogVGhlcmUgbXVzdCBiZSBhIHN1cmZhY2UsIG90aGVyd2lzZSB0aGVyZSdzIGEgYnVnICovCiAgICBhc3NlcnQoUHJldiAhPSBOVUxMKTsKCiAgICAvKiBVbmNoYWluIHRoZSBzdXJmYWNlICovCiAgICBQcmV2LT5uZXh0X2F0dGFjaGVkID0gU3VyZi0+bmV4dF9hdHRhY2hlZDsKICAgIFN1cmYtPm5leHRfYXR0YWNoZWQgPSBOVUxMOwogICAgU3VyZi0+Zmlyc3RfYXR0YWNoZWQgPSBTdXJmOwoKICAgIC8qIENoZWNrIGlmIHRoZSBXaW5lRDNEIGRlcHRoIHN0ZW5jaWwgbmVlZHMgdXBkYXRpbmcgKi8KICAgIGlmKFRoaXMtPmRkcmF3LT5kM2RkZXZpY2UpCiAgICB7CiAgICAgICAgSURpcmVjdDNERGV2aWNlSW1wbF9VcGRhdGVEZXB0aFN0ZW5jaWwoVGhpcy0+ZGRyYXctPmQzZGRldmljZSk7CiAgICB9CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKEF0dGFjaCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6QWRkT3ZlcmxheURpcnR5UmVjdAogKgogKiAiVGhpcyBtZXRob2QgaXMgbm90IGN1cnJlbnRseSBpbXBsZW1lbnRlZCIKICoKICogUGFyYW1zOgogKiAgUmVjdDogPwogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfVU5TVVBQT1JURUQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRPdmVybGF5RGlydHlSZWN0KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSRUNUIFJlY3QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsUmVjdCk7CgogICAgLyogTVNETiBzYXlzIGl0J3Mgbm90IGltcGxlbWVudGVkLiBJIGNvdWxkIGZvcndhcmQgaXQgdG8gV2luZUQzRCwgCiAgICAgKiB0aGVuIHdlJ2QgaW1wbGVtZW50IGl0LCBidXQgSSBkb24ndCB0aGluayB0aGF0J3MgYSBnb29kIGlkZWEKICAgICAqIChTdGVmYW4gRPZzaW5nZXIpCiAgICAgKi8KI2lmIDAKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfQWRkT3ZlcmxheURpcnR5UmVjdChUaGlzLT5XaW5lRDNEU3VyZmFjZSwgcFJlY3QpOwojZW5kaWYKICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsgLyogdW5jaGVja2VkICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXREQwogKgogKiBSZXR1cm5zIGEgR0RJIGRldmljZSBjb250ZXh0IGZvciB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBoZGM6IEFkZHJlc3Mgb2YgYSBIREMgdmFyaWFibGUgdG8gc3RvcmUgdGhlIGRjIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIGhkYyBpcyBOVUxMCiAqICBGb3IgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6R2V0REMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXREQyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIREMgKmhkYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgaGRjKTsKCiAgICBpZighaGRjKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREQyhUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhkYyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UmVsZWFzZURDCiAqCiAqIFJlbGVhc2VzIHRoZSBEQyB0aGF0IHdhcyBjb25zdHJ1Y3RlZCB3aXRoIEdldERDCiAqCiAqIFBhcmFtczoKICogIGhkYzogSERDIHRvIHJlbGVhc2UKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OlJlbGVhc2VEQwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2VEQyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSERDIGhkYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgaGRjKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZURDKFRoaXMtPldpbmVEM0RTdXJmYWNlLCBoZGMpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldENhcHMKICoKICogUmV0dXJucyB0aGUgc3VyZmFjZSdzIGNhcHMKICoKICogUGFyYW1zOgogKiAgQ2FwczogQWRkcmVzcyB0byB3cml0ZSB0aGUgY2FwcyB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDYXBzIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDYXBzKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQUzIgKkNhcHMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsQ2Fwcyk7CgogICAgaWYoIUNhcHMpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgKkNhcHMgPSBUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2FwczsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldFByaW9yaXR5CiAqCiAqIFNldHMgYSB0ZXh0dXJlIHByaW9yaXR5IGZvciBtYW5hZ2VkIHRleHR1cmVzLgogKgogKiBQYXJhbXM6CiAqICBQcmlvcml0eTogVGhlIG5ldyBwcmlvcml0eQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6U2V0UHJpb3JpdHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQcmlvcml0eShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwgRFdPUkQgUHJpb3JpdHkpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVkKTogUmVsYXkhXG4iLFRoaXMsUHJpb3JpdHkpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRQcmlvcml0eShUaGlzLT5XaW5lRDNEU3VyZmFjZSwgUHJpb3JpdHkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldFByaW9yaXR5CiAqCiAqIFJldHVybnMgdGhlIHN1cmZhY2UncyBwcmlvcml0eQogKgogKiBQYXJhbXM6CiAqICBQcmlvcml0eTogQWRkcmVzcyBvZiBhIHZhcmlhYmxlIHRvIHdyaXRlIHRoZSBwcmlvcml0eSB0bwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgUHJpb3JpdHkgPT0gTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6R2V0UHJpb3JpdHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqUHJpb3JpdHkpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIixUaGlzLFByaW9yaXR5KTsKCiAgICBpZighUHJpb3JpdHkpCiAgICB7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpQcmlvcml0eSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQcmlvcml0eShUaGlzLT5XaW5lRDNEU3VyZmFjZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0UHJpdmF0ZURhdGEKICoKICogU3RvcmVzIHNvbWUgZGF0YSBpbiB0aGUgc3VyZmFjZSB0aGF0IGlzIGludGVuZGVkIGZvciB0aGUgYXBwbGljYXRpb24ncwogKiB1c2UuCiAqCiAqIFBhcmFtczoKICogIHRhZzogR1VJRCB0aGF0IGlkZW50aWZpZXMgdGhlIGRhdGEKICogIERhdGE6IFBvaW50ZXIgdG8gdGhlIHByaXZhdGUgZGF0YQogKiAgU2l6ZTogU2l6ZSBvZiB0aGUgcHJpdmF0ZSBkYXRhCiAqICBGbGFnczogU29tZSBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OlNldFByaXZhdGVEYXRhCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGR1VJRCB0YWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcywlcCwlZCwleCk6IFJlbGF5XG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHRhZyksIERhdGEsIFNpemUsIEZsYWdzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0UHJpdmF0ZURhdGEoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0UHJpdmF0ZURhdGEKICoKICogUmV0dXJucyB0aGUgcHJpdmF0ZSBkYXRhIHNldCB3aXRoIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldFByaXZhdGVEYXRhCiAqCiAqIFBhcmFtczoKICogIHRhZzogR1VJRCBvZiB0aGUgZGF0YSB0byByZXR1cm4KICogIERhdGE6IEFkZHJlc3Mgd2hlcmUgdG8gd3JpdGUgdGhlIGRhdGEgdG8KICogIFNpemU6IFNpemUgb2YgdGhlIGJ1ZmZlciBhdCBEYXRhCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6R2V0UHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpTaXplKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcywlcCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHRhZyksIERhdGEsIFNpemUpOwoKICAgIGlmKCFEYXRhKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRQcml2YXRlRGF0YShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaXplKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpGcmVlUHJpdmF0ZURhdGEKICoKICogRnJlZXMgcHJpdmF0ZSBkYXRhIHN0b3JlZCBpbiB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICB0YWc6IFRhZyBvZiB0aGUgZGF0YSB0byBmcmVlCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6RnJlZVByaXZhdGVEYXRhCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHRhZykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXMpOiBSZWxheVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZCh0YWcpKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfRnJlZVByaXZhdGVEYXRhKFRoaXMtPldpbmVEM0RTdXJmYWNlLCB0YWcpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlBhZ2VMb2NrCiAqCiAqIFByZXZlbnRzIGEgc3lzbWVtIHN1cmZhY2UgZnJvbSBiZWluZyBwYWdlZCBvdXQKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IE5vdCB1c2VkLCBtdXN0IGJlIDAodW5jaGVja2VkKQogKgogKiBSZXR1cm5zOgogKiAgRERfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9QYWdlTG9jayhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgVFJBQ0UoIiglcCktPigleClcbiIsIGlmYWNlLCBGbGFncyk7CgogICAgLyogVGhpcyBpcyBXaW5kb3dzIG1lbW9yeSBtYW5hZ2VtZW50IHJlbGF0ZWQgLSB3ZSBkb24ndCBuZWVkIHRoaXMgKi8KICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlBhZ2VVbmxvY2sKICoKICogQWxsb3dzIGEgc3lzbWVtIHN1cmZhY2UgdG8gYmUgcGFnZWQgb3V0CiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBOb3QgdXNlZCwgbXVzdCBiZSAwKHVuY2tlY2hlZCkKICoKICogUmV0dXJuczoKICogIEREX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfUGFnZVVubG9jayhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgaWZhY2UsIEZsYWdzKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpCbHRCYXRjaAogKgogKiBBbiB1bmltcGxlbWVudGVkIGZ1bmN0aW9uCiAqCiAqIFBhcmFtczoKICogID8KICoKICogUmV0dXJuczoKICogIERERVJSX1VOU1VQUE9SVEVECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQmx0QmF0Y2goSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsIEREQkxUQkFUQ0ggKkJhdGNoLCBEV09SRCBDb3VudCwgRFdPUkQgRmxhZ3MpCnsKICAgIFRSQUNFKCIoJXApLT4oJXAsJWQsJTA4eClcbiIsaWZhY2UsQmF0Y2gsQ291bnQsRmxhZ3MpOwoKICAgIC8qIE1TRE46ICJub3QgY3VycmVudGx5IGltcGxlbWVudGVkIiAqLwogICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6RW51bUF0dGFjaGVkU3VyZmFjZXMKICoKICogRW51bWVyYXRlcyBhbGwgc3VyZmFjZXMgYXR0YWNoZWQgdG8gdGhpcyBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIGNvbnRleHQ6IFBvaW50ZXIgdG8gcGFzcyB1bm1vZGlmaWVkIHRvIHRoZSBjYWxsYmFjawogKiAgY2I6IENhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggc3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBjYiBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRW51bUF0dGFjaGVkU3VyZmFjZXMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERERU5VTVNVUkZBQ0VTQ0FMTEJBQ0s3IGNiKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgIGludCBpOwoKICAgIC8qIEF0dGFjaGVkIHN1cmZhY2VzIGFyZW4ndCBoYW5kbGVkIGluIFdpbmVEM0QgKi8KICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLFRoaXMsY29udGV4dCxjYik7CgogICAgaWYoIWNiKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NUExFWF9BVFRBQ0hFRDsgaSsrKQogICAgewogICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgIGlmKCFzdXJmKSBicmVhazsKCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgIGRlc2MgPSBzdXJmLT5zdXJmYWNlX2Rlc2M7CiAgICAgICAgLyogY2hlY2s6ICE9IERERU5VTVJFVF9PSyBvciA9PSBEREVOVU1SRVRfQ0FOQ0VMPyAqLwogICAgICAgIGlmIChjYihJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRlc2MsIGNvbnRleHQpID09IERERU5VTVJFVF9DQU5DRUwpCiAgICAgICAgewogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQoKICAgIGZvciAoc3VyZiA9IFRoaXMtPm5leHRfYXR0YWNoZWQ7IHN1cmYgIT0gTlVMTDsgc3VyZiA9IHN1cmYtPm5leHRfYXR0YWNoZWQpCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgIGRlc2MgPSBzdXJmLT5zdXJmYWNlX2Rlc2M7CiAgICAgICAgLyogY2hlY2s6ICE9IERERU5VTVJFVF9PSyBvciA9PSBEREVOVU1SRVRfQ0FOQ0VMPyAqLwogICAgICAgIGlmIChjYiggSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyksICZkZXNjLCBjb250ZXh0KSA9PSBEREVOVU1SRVRfQ0FOQ0VMKQogICAgICAgIHsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIEREX09LOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgiIGVuZCBvZiBlbnVtZXJhdGlvbi5cbiIpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpFbnVtT3ZlcmxheVpPcmRlcnMKICoKICogIkVudW1lcmF0ZXMgdGhlIG92ZXJsYXkgc3VyZmFjZXMgb24gdGhlIHNwZWNpZmllZCBkZXN0aW5hdGlvbiIKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IERERU5VTU9WRVJMQVlaX0JBQ0tUT0ZST05UICBvciBEREVOVU1PVkVSTEFZWl9GUk9OVFRPQkFDSwogKiAgY29udGV4dDogY29udGV4dCB0byBwYXNzIGJhY2sgdG8gdGhlIGNhbGxiYWNrCiAqICBjYjogY2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBlbnVtZXJhdGVkIHN1cmZhY2UKICoKICogUmV0dXJuczoKICogIEREX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRW51bU92ZXJsYXlaT3JkZXJzKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEREVOVU1TVVJGQUNFU0NBTExCQUNLNyBjYikKewogICAgIEZJWE1FKCIoJXApLT4oJXgsJXAsJXApOiBTdHViIVxuIiwgaWZhY2UsIEZsYWdzLCBjb250ZXh0LCBjYik7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0Qmx0U3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIGJsaXR0aW5nIHN0YXR1cwogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERHQlNfQ0FOQkxUIG9yIERER0JTX0lTQkxURE9ORQogKgogKiBSZXR1cm5zOgogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6Qmx0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Qmx0U3RhdHVzKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXgpOiBSZWxheVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRCbHRTdGF0dXMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIEZsYWdzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0Q29sb3JLZXkKICoKICogUmV0dXJucyB0aGUgY29sb3Iga2V5IGFzc2lnbmVkIHRvIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBTb21lIGZsYWdzCiAqICBDS2V5OiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBrZXkgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgQ0tleSBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Q29sb3JLZXkoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDT0xPUktFWSAqQ0tleSkKewogICAgLyogVGhlcmUgaXMgYSBEREVSUl9OT0NPTE9SS0VZIGVycm9yLCBidXQgaG93IGRvIHdlIGtub3cgaWYgYSBjb2xvciBrZXkKICAgICAqIGlzbid0IHRoZXJlPyBUaGF0J3MgbGlrZSBzYXlpbmcgdGhhdCBhbiBpbnQgaXNuJ3QgdGhlcmUuIChXaGljaCBNUwogICAgICogaGFzIGRvbmUgaW4gb3RoZXIgZG9jcy4pICovCiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLCBGbGFncywgQ0tleSk7CgogICAgaWYoIUNLZXkpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICBjYXNlIEREQ0tFWV9ERVNUQkxUOgogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS0Rlc3RCbHQ7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgKkNLZXkgPSBUaGlzLT5zdXJmYWNlX2Rlc2MudTMuZGRja0NLRGVzdE92ZXJsYXk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY0JsdDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY092ZXJsYXk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRGbGlwU3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIGZsaXBwaW5nIHN0YXR1cyBvZiB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERHRlNfQ0FORkxJUCBvZiBEREdGU19JU0ZMSVBET05FCiAqCiAqIFJldHVybnM6CiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXRGbGlwU3RhdHVzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPigleCk6IFJlbGF5XG4iLCBUaGlzLCBGbGFncyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldEZsaXBTdGF0dXMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIEZsYWdzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0T3ZlcmxheVBvc2l0aW9uCiAqCiAqIFJldHVybnMgdGhlIGRpc3BsYXkgY29vcmRpbmF0ZXMgb2YgYSB2aXNpYmxlIGFuZCBhY3RpdmUgb3ZlcmxheSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFgKICogIFkKICoKICogUmV0dXJuczoKICogIERERVJSX05PVEFPVkVSTEFZU1VSRkFDRSwgYmVjYXVzZSBpdCdzIGEgc3R1YgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyAqWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyAqWSkgewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApOiBSZWxheVxuIiwgVGhpcywgWCwgWSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldE92ZXJsYXlQb3NpdGlvbihUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldFBpeGVsRm9ybWF0CiAqCiAqIFJldHVybnMgdGhlIHBpeGVsIGZvcm1hdCBvZiB0aGUgU3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBQaXhlbEZvcm1hdDogUG9pbnRlciB0byBhIEREUElYRUxGT1JNQVQgc3RydWN0dXJlIHRvIHdoaWNoIHRoZSBwaXhlbAogKiAgICAgICAgICAgICAgIGZvcm1hdCBzaG91bGQgYmUgd3JpdHRlbgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQaXhlbEZvcm1hdCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UGl4ZWxGb3JtYXQoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERQSVhFTEZPUk1BVCAqUGl4ZWxGb3JtYXQpCnsKICAgIC8qIFdoYXQgaXMgRERFUlJfSU5WQUxJRFNVUkZBQ0VUWVBFIGZvciBoZXJlPyAqLwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxQaXhlbEZvcm1hdCk7CgogICAgaWYoIVBpeGVsRm9ybWF0KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoUGl4ZWxGb3JtYXQsJlRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0U3VyZmFjZURlc2MKICoKICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhpcyBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IEFkZHJlc3Mgb2YgYSBERFNVUkZBQ0VERVNDMiBzdHJ1Y3R1cmUgdGhhdCBpcyB0byBiZSBmaWxsZWQgd2l0aCB0aGUKICogICAgICAgIHN1cmZhY2UgZGVzYwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBERFNEIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRTdXJmYWNlRGVzYyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsRERTRCk7CgogICAgaWYoIUREU0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgaWYgKEREU0QtPmR3U2l6ZSAhPSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgewogICAgICAgIFdBUk4oIkluY29ycmVjdCBzdHJ1Y3Qgc2l6ZSAlZCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIsRERTRC0+ZHdTaXplKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKEREU0QsJlRoaXMtPnN1cmZhY2VfZGVzYyk7CiAgICBUUkFDRSgiUmV0dXJuaW5nIHN1cmZhY2UgZGVzYzpcbiIpOwogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MoRERTRCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkluaXRpYWxpemUKICoKICogSW5pdGlhbGl6ZXMgdGhlIHN1cmZhY2UuIFRoaXMgaXMgYSBuby1vcCBpbiBXaW5lCiAqCiAqIFBhcmFtczoKICogIEREOiBQb2ludGVyIHRvIGFuIERpcmVjdERyYXcgaW50ZXJmYWNlCiAqICBERFNEOiBTdXJmYWNlIGRlc2NyaXB0aW9uIGZvciBpbml0aWFsaXphdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfSW5pdGlhbGl6ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICpERCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd0ltcGwgKmRkaW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXcsIEREKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLFRoaXMsZGRpbXBsLEREU0QpOwoKICAgIHJldHVybiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpJc0xvc3QKICoKICogQ2hlY2tzIGlmIHRoZSBzdXJmYWNlIGlzIGxvc3QKICoKICogUmV0dXJuczoKICogIEREX09LLCBpZiB0aGUgc3VyZmFjZSBpcyB1c2VhYmxlCiAqICBEREVSUl9JU0xPU1QgaWYgdGhlIHN1cmZhY2UgaXMgbG9zdAogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6SXNMb3N0IGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Jc0xvc3QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIFdlIGxvc2UgdGhlIHN1cmZhY2UgaWYgdGhlIGltcGxlbWVudGF0aW9uIHdhcyBjaGFuZ2VkICovCiAgICBpZihUaGlzLT5JbXBsVHlwZSAhPSBUaGlzLT5kZHJhdy0+SW1wbFR5cGUpCiAgICB7CiAgICAgICAgLyogQnV0IHRoaXMgc2hvdWxkbid0IGhhcHBlbi4gV2hlbiB3ZSBjaGFuZ2UgdGhlIGltcGxlbWVudGF0aW9uLAogICAgICAgICAqIGFsbCBzdXJmYWNlcyBhcmUgcmUtY3JlYXRlZCBhdXRvbWF0aWNhbGx5LCBhbmQgdGhlaXIgY29udGVudAogICAgICAgICAqIGlzIGNvcGllZAogICAgICAgICAqLwogICAgICAgIEVSUigiICglcCkgSW1wbGVtZW50YXRpb24gd2FzIGNoYW5nZWQgZnJvbSAlZCB0byAlZFxuIiwgVGhpcywgVGhpcy0+SW1wbFR5cGUsIFRoaXMtPmRkcmF3LT5JbXBsVHlwZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUxPU1Q7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfSXNMb3N0KFRoaXMtPldpbmVEM0RTdXJmYWNlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgLyogRDNEOCBhbmQgOSBsb29zZSBmdWxsIGRldmljZXMsIHRodXMgdGhlcmUncyBvbmx5IGEgREVWSUNFTE9TVCBlcnJvci4KICAgICAgICAgKiBXaW5lRDNEIHVzZXMgdGhlIHNhbWUgZXJyb3IgZm9yIHN1cmZhY2VzCiAgICAgICAgICovCiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0RFVklDRUxPU1Q6ICAgICAgICAgcmV0dXJuIERERVJSX1NVUkZBQ0VMT1NUOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlJlc3RvcmUKICoKICogUmVzdG9yZXMgYSBsb3N0IHN1cmZhY2UuIFRoaXMgbWFrZXMgdGhlIHN1cmZhY2UgdXNhYmxlIGFnYWluLCBidXQKICogZG9lc24ndCByZWxvYWQgaXRzIG9sZCBjb250ZW50cwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6UmVzdG9yZSBmb3IgbW9yZSBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfUmVzdG9yZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoVGhpcy0+SW1wbFR5cGUgIT0gVGhpcy0+ZGRyYXctPkltcGxUeXBlKQogICAgewogICAgICAgIC8qIENhbGwgdGhlIHJlY3JlYXRpb24gY2FsbGJhY2suIE1ha2Ugc3VyZSB0byBBZGRSZWYgZmlyc3QgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfQWRkUmVmKGlmYWNlKTsKICAgICAgICBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRoaXMtPnN1cmZhY2VfZGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogTm90IG5lZWRlZCAqLyk7CiAgICB9CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9SZXN0b3JlKFRoaXMtPldpbmVEM0RTdXJmYWNlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRPdmVybGF5UG9zaXRpb24KICoKICogQ2hhbmdlcyB0aGUgZGlzcGxheSBjb29yZGluYXRlcyBvZiBhbiBvdmVybGF5IHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgWDoKICogIFk6CiAqCiAqIFJldHVybnM6CiAqICAgRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFLCBiZWNhdXNlIHdlIGRvbid0IHN1cHBvcnQgb3ZlcmxheXMgcmlnaHQgbm93CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIFgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgWSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQpOiBSZWxheVxuIiwgVGhpcywgWCwgWSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldE92ZXJsYXlQb3NpdGlvbihUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlVwZGF0ZU92ZXJsYXkKICoKICogTW9kaWZpZXMgdGhlIGF0dHJpYnV0ZXMgb2YgYW4gb3ZlcmxheSBzdXJmYWNlLgogKgogKiBQYXJhbXM6CiAqICBTcmNSZWN0OiBUaGUgc2VjdGlvbiBvZiB0aGUgc291cmNlIGJlaW5nIHVzZWQgZm9yIHRoZSBvdmVybGF5CiAqICBEc3RTdXJmYWNlOiBBZGRyZXNzIG9mIHRoZSBzdXJmYWNlIHRoYXQgaXMgb3ZlcmxhaWQKICogIERzdFJlY3Q6IFBsYWNlIG9mIHRoZSBvdmVybGF5CiAqICBGbGFnczogc29tZSBERE9WRVJfKiBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfVU5TVVBQT1JURUQsIGJlY2F1c2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXkoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJFQ1QgU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRzdFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJFQ1QgRHN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBERE9WRVJMQVlGWCBGWCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqRHN0ID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgRHN0U3VyZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBTcmNSZWN0LCBEc3QsIERzdFJlY3QsIEZsYWdzLCBGWCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1VwZGF0ZU92ZXJsYXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERzdCA/IERzdC0+V2luZUQzRFN1cmZhY2UgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERE9WRVJMQVlGWCAqKSBGWCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6VXBkYXRlT3ZlcmxheURpc3BsYXkKICoKICogVGhlIERYNyBzZGsgc2F5cyB0aGF0IGl0J3Mgbm90IGltcGxlbWVudGVkCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiA/CiAqCiAqIFJldHVybnM6IERERVJSX1VOU1VQUE9SVEVELCBiZWNhdXNlIHdlIGRvbid0IHN1cHBvcnQgb3ZlcmxheXMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5RGlzcGxheShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPigleClcbiIsIFRoaXMsIEZsYWdzKTsKICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlVwZGF0ZU92ZXJsYXlaT3JkZXIKICoKICogU2V0cyBhbiBvdmVybGF5J3MgWiBvcmRlcgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERPVkVSWl8qIGZsYWdzCiAqICBERFNSZWY6IERlZmluZXMgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIGluIHRoZSBvdmVybGF5IGNoYWluCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9OT1RPVkVSTEFZU1VSRkFDRSwgYmVjYXVzZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlcihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqRERTUmVmKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqUmVmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgRERTUmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwKTogUmVsYXlcbiIsIFRoaXMsIEZsYWdzLCBSZWYpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gIElXaW5lRDNEU3VyZmFjZV9VcGRhdGVPdmVybGF5Wk9yZGVyKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWYgPyBSZWYtPldpbmVEM0RTdXJmYWNlIDogTlVMTCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0RERJbnRlcmZhY2UKICoKICogUmV0dXJucyB0aGUgSURpcmVjdERyYXc3IGludGVyZmFjZSBwb2ludGVyIG9mIHRoZSBEaXJlY3REcmF3IG9iamVjdCB0aGlzCiAqIHN1cmZhY2UgYmVsb25ncyB0bwogKgogKiBQYXJhbXM6CiAqICBERDogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgREQgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldERESW50ZXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipERCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsREQpOwoKICAgIGlmKCFERCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBzd2l0Y2goVGhpcy0+dmVyc2lvbikKICAgIHsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgICooKElEaXJlY3REcmF3NyAqKikgREQpID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3Nyk7CiAgICAgICAgICAgIElEaXJlY3REcmF3N19BZGRSZWYoKihJRGlyZWN0RHJhdzcgKiopIEREKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgKigoSURpcmVjdERyYXc0ICoqKSBERCkgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXc0KTsKICAgICAgICAgICAgSURpcmVjdERyYXc0X0FkZFJlZigqKElEaXJlY3REcmF3NCAqKikgREQpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAqKChJRGlyZWN0RHJhdzIgKiopIEREKSA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdzIpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19BZGRSZWYoICooSURpcmVjdERyYXcyICoqKSBERCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICooKElEaXJlY3REcmF3ICoqKSBERCkgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXcpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19BZGRSZWYoICooSURpcmVjdERyYXcgKiopIEREKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyogVGhpcyBzZWVtcyBhbHNvIHdpbmRvd3MgaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgLSBJIGRvbid0IHRoaW5rIFdpbmVEM0QgbmVlZHMgdGhpcyAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9DaGFuZ2VVbmlxdWVuZXNzVmFsdWUoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIHZvbGF0aWxlIElEaXJlY3REcmF3U3VyZmFjZUltcGwqIHZUaGlzID0gVGhpczsKCiAgICBUUkFDRSgiKCVwKVxuIixUaGlzKTsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAvKiBBIHVuaXF1ZW5lc3MgdmFsdWUgb2YgMCBpcyBhcHBhcmVudGx5IHNwZWNpYWwuCiAgICAgKiBUaGlzIG5lZWRzIHRvIGJlIGNoZWNrZWQuCiAgICAgKiBUT0RPOiBXcml0ZSB0ZXN0cyBmb3IgdGhpcyBjb2RlIGFuZCBjaGVjayBpZiB0aGUgdm9sYXRpbGUsIGludGVybG9ja2VkIHN0dWZmIGlzIHJlYWxseSBuZWVkZWQKICAgICAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgICBEV09SRCBvbGRfdW5pcXVlbmVzc192YWx1ZSA9IHZUaGlzLT51bmlxdWVuZXNzX3ZhbHVlOwogICAgICAgIERXT1JEIG5ld191bmlxdWVuZXNzX3ZhbHVlID0gb2xkX3VuaXF1ZW5lc3NfdmFsdWUrMTsKCiAgICAgICAgaWYgKG9sZF91bmlxdWVuZXNzX3ZhbHVlID09IDApIGJyZWFrOwogICAgICAgIGlmIChuZXdfdW5pcXVlbmVzc192YWx1ZSA9PSAwKSBuZXdfdW5pcXVlbmVzc192YWx1ZSA9IDE7CgogICAgICAgIGlmIChJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSgoTE9ORyopJnZUaGlzLT51bmlxdWVuZXNzX3ZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZF91bmlxdWVuZXNzX3ZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld191bmlxdWVuZXNzX3ZhbHVlKQogICAgICAgICAgICA9PSBvbGRfdW5pcXVlbmVzc192YWx1ZSkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0VW5pcXVlbmVzc1ZhbHVlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLCBMUERXT1JEIHBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscFZhbHVlKTsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAqcFZhbHVlID0gVGhpcy0+dW5pcXVlbmVzc192YWx1ZTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRMT0QKICoKICogU2V0cyB0aGUgbGV2ZWwgb2YgZGV0YWlsIG9mIGEgdGV4dHVyZQogKgogKiBQYXJhbXM6CiAqICBNYXhMT0Q6IExPRCB0byBzZXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURPQkpFQ1QgaWYgdGhlIHN1cmZhY2UgaXMgaW52YWxpZCBmb3IgdGhpcyBtZXRob2QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRMT0QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE1heExPRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJWQpXG4iLCBUaGlzLCBNYXhMT0QpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfVEVYVFVSRU1BTkFHRSkpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRE9CSkVDVDsKICAgIH0KCiAgICBpZighVGhpcy0+d2luZUQzRFRleHR1cmUpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFRoZSBEaXJlY3REcmF3IHRleHR1cmUgaGFzIG5vIFdpbmVEM0RUZXh0dXJlIVxuIiwgVGhpcyk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRE9CSkVDVDsKICAgIH0KCiAgICBociA9IElXaW5lRDNEQmFzZVRleHR1cmVfU2V0TE9EKFRoaXMtPndpbmVEM0RUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXhMT0QpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldExPRAogKgogKiBSZXR1cm5zIHRoZSBsZXZlbCBvZiBkZXRhaWwgb2YgYSBEaXJlY3QzRCB0ZXh0dXJlCiAqCiAqIFBhcmFtczoKICogIE1heExPRDogQWRkcmVzcyB0byB3cml0ZSB0aGUgTE9EIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIE1heExPRCBpcyBOVUxMCiAqICBEREVSUl9JTlZBTElET0JKRUNUIGlmIHRoZSBzdXJmYWNlIGlzIGludmFsaWQgZm9yIHRoaXMgbWV0aG9kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0TE9EKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqTWF4TE9EKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgTWF4TE9EKTsKCiAgICBpZighTWF4TE9EKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfVEVYVFVSRU1BTkFHRSkpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRE9CSkVDVDsKICAgIH0KCiAgICAqTWF4TE9EID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRMT0QoVGhpcy0+d2luZUQzRFRleHR1cmUpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkJsdEZhc3QKICoKICogUGVyZm9ybXMgYSBmYXN0IEJsaXQuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6IFRoZSB4IGNvb3JkaW5hdGUgdG8gYmxpdCB0byBvbiB0aGUgZGVzdGluYXRpb24KICogIGRzdHk6IFRoZSB5IGNvb3JkaW5hdGUgdG8gYmxpdCB0byBvbiB0aGUgZGVzdGluYXRpb24KICogIFNvdXJjZTogVGhlIHNvdXJjZSBzdXJmYWNlCiAqICByc3JjOiBUaGUgc291cmNlIHJlY3RhbmdsZQogKiAgdHJhbnM6IFR5cGUgb2YgdHJhbnNmZXIuIFNvbWUgRERCTFRGQVNUXyogZmxhZ3MKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OkJsdEZhc3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHRGYXN0KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpyc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzcmMgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBTb3VyY2UpOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlcCwlcCwlZCk6IFJlbGF5XG4iLCBUaGlzLCBkc3R4LCBkc3R5LCBTb3VyY2UsIHJzcmMsIHRyYW5zKTsKCiAgICAvKiBTb3VyY2UgbXVzdCBiZSAhPSBOVUxMLCBUaGlzIGlzIG5vdCBjaGVja2VkIGJ5IHdpbmRvd3MuIFdpbmRvd3MgaGFwcGlseSB0aHJvd3MgYSAweGMwMDAwMDA1CiAgICAgKiBpbiB0aGF0IGNhc2UKICAgICAqLwogICAgaWYocnNyYykKICAgIHsKICAgICAgICBpZihyc3JjLT50b3AgPiByc3JjLT5ib3R0b20gfHwgcnNyYy0+bGVmdCA+IHJzcmMtPnJpZ2h0IHx8CiAgICAgICAgICAgcnNyYy0+cmlnaHQgPiBzcmMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoIHx8CiAgICAgICAgICAgcnNyYy0+Ym90dG9tID4gc3JjLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJTb3VyY2UgcmVjdGFuZ2xlIGlzIGludmFsaWQsIHJldHVybmluZyBEREVSUl9JTlZBTElEUkVDVFxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICB9CiAgICAgICAgaWYoZHN0eCArIHJzcmMtPnJpZ2h0IC0gcnNyYy0+bGVmdCA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoIHx8CiAgICAgICAgICAgZHN0eSArIHJzcmMtPmJvdHRvbSAtIHJzcmMtPnRvcCA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkRlc3RpbmF0aW9uIGFyZWEgb3V0IG9mIGJvdW5kcywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURSRUNUXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURSRUNUOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZihkc3R4ICsgc3JjLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aCA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoIHx8CiAgICAgICAgICAgZHN0eSArIHNyYy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0ID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiRGVzdGluYXRpb24gYXJlYSBvdXQgb2YgYm91bmRzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFJFQ1RcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgfQogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9CbHRGYXN0KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3R4LCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMgPyBzcmMtPldpbmVEM0RTdXJmYWNlIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOiAgICAgICAgICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOwogICAgICAgIGNhc2UgV0lORUQzREVSUl9XUk9OR1RFWFRVUkVGT1JNQVQ6ICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBJWEVMRk9STUFUOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRDbGlwcGVyCiAqCiAqIFJldHVybnMgdGhlIElEaXJlY3REcmF3Q2xpcHBlciBpbnRlcmZhY2Ugb2YgdGhlIGNsaXBwZXIgYXNzaWduZWQgdG8gdGhpcwogKiBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIENsaXBwZXI6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENsaXBwZXIgaXMgTlVMTAogKiAgRERFUlJfTk9DTElQUEVSQVRUQUNIRUQgaWYgdGhlcmUncyBubyBjbGlwcGVyIGF0dGFjaGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Q2xpcHBlcihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Q2xpcHBlciAqKkNsaXBwZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBDbGlwcGVyKTsKCiAgICBpZighQ2xpcHBlcikKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihUaGlzLT5jbGlwcGVyID09IE5VTEwpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfTk9DTElQUEVSQVRUQUNIRUQ7CiAgICB9CgogICAgKkNsaXBwZXIgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5jbGlwcGVyLCBJRGlyZWN0RHJhd0NsaXBwZXIpOwogICAgSURpcmVjdERyYXdDbGlwcGVyX0FkZFJlZigqQ2xpcHBlcik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0Q2xpcHBlcgogKgogKiBTZXRzIGEgY2xpcHBlciBmb3IgdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogSURpcmVjdERyYXdDbGlwcGVyIGludGVyZmFjZSBvZiB0aGUgY2xpcHBlciB0byBzZXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRDbGlwcGVyKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyICpDbGlwcGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXJJbXBsICpvbGRDbGlwcGVyID0gVGhpcy0+Y2xpcHBlcjsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLENsaXBwZXIpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdDbGlwcGVySW1wbCwgSURpcmVjdERyYXdDbGlwcGVyLCBDbGlwcGVyKSA9PSBUaGlzLT5jbGlwcGVyKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEREX09LOwogICAgfQoKICAgIFRoaXMtPmNsaXBwZXIgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd0NsaXBwZXJJbXBsLCBJRGlyZWN0RHJhd0NsaXBwZXIsIENsaXBwZXIpOwoKICAgIGlmIChDbGlwcGVyICE9IE5VTEwpCiAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyX0FkZFJlZihDbGlwcGVyKTsKICAgIGlmKG9sZENsaXBwZXIpCiAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyX1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0Uob2xkQ2xpcHBlciwgSURpcmVjdERyYXdDbGlwcGVyKSk7CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0Q2xpcHBlcihUaGlzLT5XaW5lRDNEU3VyZmFjZSwgVGhpcy0+Y2xpcHBlciA/IFRoaXMtPmNsaXBwZXItPndpbmVEM0RDbGlwcGVyIDogTlVMTCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0U3VyZmFjZURlc2MKICoKICogU2V0cyB0aGUgc3VyZmFjZSBkZXNjcmlwdGlvbi4gSXQgY2FuIG92ZXJyaWRlIHRoZSBwaXhlbCBmb3JtYXQsIHRoZSBzdXJmYWNlCiAqIG1lbW9yeSwgLi4uCiAqIEl0J3Mgbm90IHJlYWxseSB0ZXN0ZWQuCiAqCiAqIFBhcmFtczoKICogRERTRDogUG9pbnRlciB0byB0aGUgbmV3IHN1cmZhY2UgZGVzY3JpcHRpb24gdG8gc2V0CiAqIEZsYWdzOiBTb21lIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREU0QgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFN1cmZhY2VEZXNjKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBXSU5FRDNERk9STUFUIG5ld0Zvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCV4KVxuIiwgVGhpcywgRERTRCwgRmxhZ3MpOwoKICAgIGlmKCFERFNEKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoRERTRC0+ZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpCiAgICB7CiAgICAgICAgbmV3Rm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICAgICAgaWYobmV3Rm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiUmVxdWVzdGVkIHRvIHNldCBhbiB1bmtub3duIHBpeGVsZm9ybWF0XG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIGlmKG5ld0Zvcm1hdCAhPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZUaGlzLT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KSApCiAgICAgICAgewogICAgICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRGb3JtYXQoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtYXQpOwogICAgICAgICAgICBpZihociAhPSBERF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9DS0RFU1RPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX0RFU1RPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJkREU0QtPnUzLmRkY2tDS0Rlc3RPdmVybGF5KTsKICAgIH0KICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9DS0RFU1RCTFQpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVEJMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZERFNELT5kZGNrQ0tEZXN0Qmx0KTsKICAgIH0KICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ09WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfU1JDT1ZFUkxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZERFNELT5kZGNrQ0tTcmNPdmVybGF5KTsKICAgIH0KICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ0JMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNCTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmRERTRC0+ZGRja0NLU3JjQmx0KTsKICAgIH0KICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9MUFNVUkZBQ0UgJiYgRERTRC0+bHBTdXJmYWNlKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldE1lbShUaGlzLT5XaW5lRDNEU3VyZmFjZSwgRERTRC0+bHBTdXJmYWNlKTsKICAgICAgICBpZihociAhPSBXSU5FRDNEX09LKQogICAgICAgIHsKICAgICAgICAgICAgLyogTm8gbmVlZCBmb3IgYSB0cmFjZSBoZXJlLCB3aW5lZDNkIGRvZXMgdGhhdCBmb3IgdXMgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgc3dpdGNoKGhyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvKiBHbyBvbiAqLwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICBUaGlzLT5zdXJmYWNlX2Rlc2MgPSAqRERTRDsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0UGFsZXR0ZQogKgogKiBSZXR1cm5zIHRoZSBJRGlyZWN0RHJhd1BhbGV0dGUgaW50ZXJmYWNlIG9mIHRoZSBwYWxldHRlIGN1cnJlbnRseSBhc3NpZ25lZAogKiB0byB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBQYWw6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGludGVyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFBhbCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UGFsZXR0ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqKlBhbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSVdpbmVEM0RQYWxldHRlICp3UGFsOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZighUGFsKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRQYWxldHRlKFRoaXMtPldpbmVEM0RTdXJmYWNlLCAmd1BhbCk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZih3UGFsKQogICAgewogICAgICAgIGhyID0gSVdpbmVEM0RQYWxldHRlX0dldFBhcmVudCh3UGFsLCAoSVVua25vd24gKiopIFBhbCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgKlBhbCA9IE5VTEw7CiAgICAgICAgaHIgPSBEREVSUl9OT1BBTEVUVEVBVFRBQ0hFRDsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0Q29sb3JLZXlFbnVtCiAqCiAqIEVudW1BdHRhY2hlZFN1cmZhY2UgY2FsbGJhY2sgZm9yIFNldENvbG9yS2V5LiBVc2VkIHRvIHNldCBjb2xvciBrZXlzCiAqIHJlY3Vyc2l2ZWx5IGluIHRoZSBzdXJmYWNlIHRyZWUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdHJ1Y3QgU0NLQ29udGV4dAp7CiAgICBIUkVTVUxUIHJldDsKICAgIFdJTkVERENPTE9SS0VZICpDS2V5OwogICAgRFdPUkQgRmxhZ3M7Cn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKU2V0Q29sb3JLZXlFbnVtKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmZhY2UsCiAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqZGVzYywKICAgICAgICAgICAgICAgIHZvaWQgKmNvbnRleHQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHN1cmZhY2UpOwogICAgc3RydWN0IFNDS0NvbnRleHQgKmN0eCA9IGNvbnRleHQ7CiAgICBIUkVTVUxUIGhyOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LT5GbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+Q0tleSk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICBXQVJOKCJJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICBjdHgtPnJldCA9IGhyOwogICAgfQoKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfRW51bUF0dGFjaGVkU3VyZmFjZXMoc3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0Q29sb3JLZXlFbnVtKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmYWNlKTsKICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRDb2xvcktleQogKgogKiBTZXRzIHRoZSBjb2xvciBrZXlpbmcgb3B0aW9ucyBmb3IgdGhlIHN1cmZhY2UuIE9ic2VydmF0aW9ucyBzaG93ZWQgdGhhdAogKiBpbiBjYXNlIG9mIGNvbXBsZXggc3VyZmFjZXMgdGhlIGNvbG9yIGtleSBoYXMgdG8gYmUgYXNzaWduZWQgdG8gYWxsCiAqIHN1YmxldmVscy4KICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IEREQ0tFWV8qCiAqICBDS2V5OiBUaGUgbmV3IGNvbG9yIGtleQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6U2V0Q29sb3JLZXkgZm9yIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRDb2xvcktleShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENPTE9SS0VZICpDS2V5KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBzdHJ1Y3QgU0NLQ29udGV4dCBjdHggPSB7IEREX09LLCAoV0lORUREQ09MT1JLRVkgKikgQ0tleSwgRmxhZ3MgfTsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXApXG4iLCBUaGlzLCBGbGFncywgQ0tleSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmIChDS2V5KQogICAgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpCiAgICAgICAgewogICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tEZXN0Qmx0ID0gKkNLZXk7CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy51My5kZGNrQ0tEZXN0T3ZlcmxheSA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZGRja0NLU3JjT3ZlcmxheSA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY0JsdCA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLU1JDQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpCiAgICAgICAgewogICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICY9IH5ERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmPSB+RERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJj0gfkREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmPSB+RERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgIH0KICAgIGN0eC5yZXQgPSBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguQ0tleSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0VudW1BdHRhY2hlZFN1cmZhY2VzKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSAmY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRDb2xvcktleUVudW0pOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChjdHgucmV0KQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9JTlZBTElEQ0FMTDogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHgucmV0OwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0UGFsZXR0ZQogKgogKiBBc3NpZ25zIGEgRGlyZWN0RHJhd1BhbGV0dGUgb2JqZWN0IHRvIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFBhbDogSW50ZXJmYWNlIHRvIHRoZSBwYWxldHRlIHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFBhbGV0dGUoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGUgKlBhbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdQYWxldHRlICpvbGRQYWw7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgSURpcmVjdERyYXdQYWxldHRlSW1wbCAqUGFsSW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3UGFsZXR0ZUltcGwsIElEaXJlY3REcmF3UGFsZXR0ZSwgUGFsKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICAvKiBGaW5kIHRoZSBvbGQgcGFsZXR0ZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSURpcmVjdERyYXdTdXJmYWNlX0dldFBhbGV0dGUoaWZhY2UsICZvbGRQYWwpOwogICAgaWYoaHIgIT0gRERfT0sgJiYgaHIgIT0gRERFUlJfTk9QQUxFVFRFQVRUQUNIRUQpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICBpZihvbGRQYWwpIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKG9sZFBhbCk7ICAvKiBGb3IgdGhlIEdldFBhbGV0dGUgKi8KCiAgICAvKiBTZXQgdGhlIG5ldyBQYWxldHRlICovCiAgICBJV2luZUQzRFN1cmZhY2VfU2V0UGFsZXR0ZShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhbEltcGwgPyBQYWxJbXBsLT53aW5lRDNEUGFsZXR0ZSA6IE5VTEwpOwogICAgLyogQWRkUmVmIHRoZSBQYWxldHRlICovCiAgICBpZihQYWwpIElEaXJlY3REcmF3UGFsZXR0ZV9BZGRSZWYoUGFsKTsKCiAgICAvKiBSZWxlYXNlIHRoZSBvbGQgcGFsZXR0ZSAqLwogICAgaWYob2xkUGFsKSBJRGlyZWN0RHJhd1BhbGV0dGVfUmVsZWFzZShvbGRQYWwpOwoKICAgIC8qIElmIHRoaXMgaXMgYSBmcm9udCBidWZmZXIsIGFsc28gdXBkYXRlIHRoZSBiYWNrIGJ1ZmZlcnMKICAgICAqIFRPRE86IEhvdyBkbyB0aGluZ3Mgd29yayBmb3IgcGFsZXR0aXplZCBjdWJlIHRleHR1cmVzPwogICAgICovCiAgICBpZihUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0ZST05UQlVGRkVSKQogICAgewogICAgICAgIC8qIEZvciBwcmltYXJ5IHN1cmZhY2VzIHRoZSB0cmVlIGlzIGp1c3QgYSBsaXN0LCBzbyB0aGUgc2ltcGxlciBzY2hlbWUgZml0cyB0b28gKi8KICAgICAgICBERFNDQVBTMiBjYXBzMiA9IHsgRERTQ0FQU19QUklNQVJZU1VSRkFDRSwgMCwgMCwgMCB9OwoKICAgICAgICBzdXJmID0gVGhpczsKICAgICAgICB3aGlsZSgxKQogICAgICAgIHsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqYXR0YWNoOwogICAgICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgICAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYXBzMiwgJmF0dGFjaCk7CiAgICAgICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgcGFsZXR0ZSBvbiAlcFxuIiwgYXR0YWNoKTsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19TZXRQYWxldHRlKGF0dGFjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhbCk7CiAgICAgICAgICAgIHN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBhdHRhY2gpOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoYXR0YWNoKTsKICAgICAgICB9CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBWVGFibGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKY29uc3QgSURpcmVjdERyYXdTdXJmYWNlN1Z0YmwgSURpcmVjdERyYXdTdXJmYWNlN19WdGJsID0KewogICAgLyoqKiBJVW5rbm93biAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3REcmF3U3VyZmFjZSAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3SW1wbF9BZGRBdHRhY2hlZFN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZE92ZXJsYXlEaXJ0eVJlY3QsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0JsdCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQmx0QmF0Y2gsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0JsdEZhc3QsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0RlbGV0ZUF0dGFjaGVkU3VyZmFjZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRW51bUF0dGFjaGVkU3VyZmFjZXMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0VudW1PdmVybGF5Wk9yZGVycywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRmxpcCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0QXR0YWNoZWRTdXJmYWNlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldENhcHMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldENsaXBwZXIsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldENvbG9yS2V5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXREQywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQaXhlbEZvcm1hdCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0U3VyZmFjZURlc2MsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0luaXRpYWxpemUsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0lzTG9zdCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfTG9jaywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRDbGlwcGVyLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRDb2xvcktleSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VbmxvY2ssCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlEaXNwbGF5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyLAogICAgLyoqKiBJRGlyZWN0RHJhd1N1cmZhY2UyICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0RERJbnRlcmZhY2UsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1BhZ2VMb2NrLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9QYWdlVW5sb2NrLAogICAgLyoqKiBJRGlyZWN0RHJhd1N1cmZhY2UzICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0U3VyZmFjZURlc2MsCiAgICAvKioqIElEaXJlY3REcmF3U3VyZmFjZTQgKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0VW5pcXVlbmVzc1ZhbHVlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9DaGFuZ2VVbmlxdWVuZXNzVmFsdWUsCiAgICAvKioqIElEaXJlY3REcmF3U3VyZmFjZTcgKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldExPRCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0TE9ECn07Cg==