LyogRGlyZWN0RHJhdyBTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IChjKSAyMDA2IFN0ZWZhbiBE9nNpbmdlcgogKgogKiBUaGlzIGZpbGUgY29udGFpbnMgdGhlIChpbnRlcm5hbCkgZHJpdmVyIHJlZ2lzdHJhdGlvbiBmdW5jdGlvbnMsCiAqIGRyaXZlciBlbnVtZXJhdGlvbiBBUElzIGFuZCBEaXJlY3REcmF3IGNyZWF0aW9uIGZ1bmN0aW9ucy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIEEgbm9ybWFsIFF1ZXJ5SW50ZXJmYWNlIGltcGxlbWVudGF0aW9uLiBGb3IgUXVlcnlJbnRlcmZhY2UgcnVsZXMKICogc2VlIGRkcmF3LmMsIElEaXJlY3REcmF3Nzo6UXVlcnlJbnRlcmZhY2UuIFRoaXMgbWV0aG9kCiAqIGNhbiBRdWVyeSBJRGlyZWN0RHJhd1N1cmZhY2UgaW50ZXJmYWNlcyBpbiBhbGwgdmVyc2lvbiwgSURpcmVjdDNEVGV4dHVyZQogKiBpbiBhbGwgdmVyc2lvbnMsIHRoZSBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCBpbnRlcmZhY2UgYW5kIGl0IGNhbgogKiBjcmVhdGUgYW4gSURpcmVjdDNERGV2aWNlLiAoVXNlcyBJRGlyZWN0M0Q3OjpDcmVhdGVEZXZpY2UpCiAqCiAqIFBhcmFtczoKICogIHJpaWQ6IFRoZSBpbnRlcmZhY2UgaWQgcXVlcmllZCBmb3IKICogIG9iajogQWRkcmVzcyB0byB3cml0ZSB0aGUgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU19PSyBvbiBzdWNjZXNzCiAqICBFX05PSU5URVJGQUNFIGlmIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlIHdhc24ndCBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKCiAgICAvKiBBY2NvcmRpbmcgdG8gQ09NIGRvY3MsIGlmIHRoZSBRdWVyeUludGVyZmFjZSBmYWlscywgb2JqIHNob3VsZCBiZSBzZXQgdG8gTlVMTCAqLwogICAgKm9iaiA9IE5VTEw7CgogICAgaWYoIXJpaWQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lEaXJlY3REcmF3U3VyZmFjZTcpCiAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0RHJhd1N1cmZhY2U0KSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMykKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMikKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlKSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlMyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTMgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdHYW1tYUNvbnRyb2wpICkKICAgIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3R2FtbWFDb250cm9sIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICBlbHNlIGlmKCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0QzRERFVklDRV9XaW5lRDNEKSB8fAogICAgICAgICAgICAgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0M0RIQUxEZXZpY2UpfHwKICAgICAgICAgICAgIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdDNEUkdCRGV2aWNlKSApCiAgICB7CiAgICAgICAgSURpcmVjdDNERGV2aWNlNyAqZDNkOwoKICAgICAgICAvKiBDYWxsIGludG8gSURpcmVjdDNENyBmb3IgY3JlYXRpb24gKi8KICAgICAgICBJRGlyZWN0M0Q3X0NyZWF0ZURldmljZShJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdDNENyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZDNkKTsKCiAgICAgICAgKm9iaiA9IENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2U3LCBJRGlyZWN0M0REZXZpY2UsIGQzZCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3QzRERldmljZSBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwoKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYgKElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRFRleHR1cmUsIHJpaWQgKSB8fAogICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVGV4dHVyZTIsIHJpaWQgKSkKICAgIHsKICAgICAgICBpZiAoSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVGV4dHVyZSwgcmlpZCApKQogICAgICAgIHsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFRleHR1cmUpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRFRleHR1cmUgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RUZXh0dXJlMik7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEVGV4dHVyZTIgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIElVbmtub3duX0FkZFJlZiggKElVbmtub3duICopICpvYmopOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIEVSUigiTm8gaW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6QWRkUmVmCiAqCiAqIEEgbm9ybWFsIGFkZHJlZiBpbXBsZW1lbnRhdGlvbgogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRSZWYoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRSZWYgaW5jcmVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwogICAgcmV0dXJuIHJlZkNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95CiAqCiAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlCiAqCiAqIEZyZWVzIHRoZSBzdXJmYWNlLCByZWdhcmRsZXNzIG9mIGl0cyByZWZjb3VudC4KICogIFNlZSBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlIGZvciBtb3JlIGluZm9ybWF0aW9uCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IFN1cmZhY2UgdG8gZnJlZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95KElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlRoaXMpCnsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBDaGVjayB0aGUgcmVmY291bnQgYW5kIGdpdmUgYSB3YXJuaW5nICovCiAgICBpZihUaGlzLT5yZWYgPiAxKQogICAgewogICAgICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29tcGxleCBzdXJmYWNlIGlzIGRlc3Ryb3llZCwKICAgICAgICAgKiBiZWNhdXNlIHRoZSAybmQgc3VyZmFjZSB3YXMgYWRkcmVmKCllZCB3aGVuIHRoZSBhcHAKICAgICAgICAgKiBjYWxsZWQgR2V0QXR0YWNoZWRTdXJmYWNlCiAgICAgICAgICovCiAgICAgICAgV0FSTigiKCVwKTogRGVzdHJveWluZyBzdXJmYWNlIHdpdGggcmVmb3VudCAlZFxuIiwgVGhpcywgVGhpcy0+cmVmKTsKICAgIH0KCiAgICAvKiBDaGVjayBmb3IgYXR0YWNoZWQgc3VyZmFjZXMgYW5kIGRldGFjaCB0aGVtICovCiAgICBpZihUaGlzLT5maXJzdF9hdHRhY2hlZCAhPSBUaGlzKQogICAgewogICAgICAgIC8qIFdlbGwsIHRoaXMgc2hvdWxkbid0IGhhcHBlbjogVGhlIHN1cmZhY2UgYmVpbmcgYXR0YWNoZWQgaXMgYWRkcmVmKCllZAogICAgICAgICAgKiBpbiBBZGRBdHRhY2hlZFN1cmZhY2UsIHNvIGl0IHNob3VsZG4ndCBiZSByZWxlYXNlZCB1bnRpbCBEZWxldGVBdHRhY2hlZFN1cmZhY2UKICAgICAgICAgICogaXMgY2FsbGVkLCBiZWNhdXNlIHRoZSByZWZjb3VudCBpcyBoZWxkLiBJdCBsb29rcyBsaWtlIHRoZSBhcHAgcmVsZWFzZWQoKQogICAgICAgICAgKiBpdCBvZnRlbiBlbm91Z2ggdG8gZm9yY2UgdGhpcwogICAgICAgICAgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpyb290ID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+Zmlyc3RfYXR0YWNoZWQsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRldGFjaCA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpOwoKICAgICAgICBGSVhNRSgiKCVwKSBGcmVlaW5nIGEgc3VyZmFjZSB0aGF0IGlzIGF0dGFjaGVkIHRvIHN1cmZhY2UgJXBcbiIsIFRoaXMsIFRoaXMtPmZpcnN0X2F0dGFjaGVkKTsKCiAgICAgICAgLyogVGhlIHJlZmNvdW50IHdpbGwgZHJvcCB0byAtMSBoZXJlICovCiAgICAgICAgaWYoSURpcmVjdERyYXdTdXJmYWNlN19EZWxldGVBdHRhY2hlZFN1cmZhY2Uocm9vdCwgMCwgZGV0YWNoKSAhPSBERF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiKCVwKSBEZWxldGVBdHRhY2hlZFN1cmZhY2UgZmFpbGVkIVxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgfQoKICAgIHdoaWxlKFRoaXMtPm5leHRfYXR0YWNoZWQgIT0gTlVMTCkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpyb290ID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqZGV0YWNoID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+bmV4dF9hdHRhY2hlZCwgSURpcmVjdERyYXdTdXJmYWNlNyk7CgogICAgICAgIGlmKElEaXJlY3REcmF3U3VyZmFjZTdfRGVsZXRlQXR0YWNoZWRTdXJmYWNlKHJvb3QsIDAsIGRldGFjaCkgIT0gRERfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgRGVsZXRlQXR0YWNoZWRTdXJmYWNlIGZhaWxlZCFcbiIsIFRoaXMpOwogICAgICAgICAgICBhc3NlcnQoMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vdyBkZXN0cm95IHRoZSBzdXJmYWNlLiBXYWl0OiBJdCBjb3VsZCBoYXZlIGJlZW4gcmVsZWFzZWQgaWYgd2UgYXJlIGEgdGV4dHVyZSAqLwogICAgaWYoVGhpcy0+V2luZUQzRFN1cmZhY2UpCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwoKICAgIC8qIEhhdmluZyBhIHRleHR1cmUgaGFuZGxlIHNldCBpbXBsaWVzIHRoYXQgdGhlIGRldmljZSBzdGlsbCBleGlzdHMgKi8KICAgIGlmKFRoaXMtPkhhbmRsZSkKICAgIHsKICAgICAgICBUaGlzLT5kZHJhdy0+ZDNkZGV2aWNlLT5IYW5kbGVzW1RoaXMtPkhhbmRsZSAtIDFdLnB0ciA9IE5VTEw7CiAgICAgICAgVGhpcy0+ZGRyYXctPmQzZGRldmljZS0+SGFuZGxlc1tUaGlzLT5IYW5kbGUgLSAxXS50eXBlID0gRERyYXdIYW5kbGVfVW5rbm93bjsKICAgIH0KCiAgICAvKiBSZWR1Y2UgdGhlIGRkcmF3IHN1cmZhY2UgY291bnQgKi8KICAgIEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5kZHJhdy0+c3VyZmFjZXMpOwogICAgbGlzdF9yZW1vdmUoJlRoaXMtPnN1cmZhY2VfbGlzdF9lbnRyeSk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlCiAqCiAqIFJlZHVjZXMgdGhlIHN1cmZhY2UncyByZWZjb3VudCBieSAxLiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlCiAqIHN1cmZhY2UgaXMgZGVzdHJveWVkLgogKgogKiBEZXN0cm95aW5nIHRoZSBzdXJmYWNlIGlzIGEgYml0IHRyaWNreS4gRm9yIHRoZSBjb25uZWN0aW9uIGJldHdlZW4KICogV2luZUQzRFN1cmZhY2VzIGFuZCBEaXJlY3REcmF3U3VyZmFjZXMgc2VlIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKiBJdCBoYXMgYSBuaWNlIGdyYXBoIGV4cGxhaW5pbmcgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIFdoYXQgaGFwcGVucyBoZXJlIGlzIGJhc2ljYWxseSB0aGlzOgogKiBXaGVuIGEgc3VyZmFjZSBpcyBkZXN0cm95ZWQsIGl0cyBXaW5lRDNEU3VyZmFjZSBpcyByZWxlYXNlZCwKICogYW5kIHRoZSByZWZjb3VudCBvZiB0aGUgRGlyZWN0RHJhdyBpbnRlcmZhY2UgaXMgcmVkdWNlZCBieSAxLiBJZiBpdCBoYXMKICogY29tcGxleCBzdXJmYWNlcyBhdHRhY2hlZCB0byBpdCwgdGhlbiB0aGVzZSBzdXJmYWNlcyBhcmUgZGVzdHJveWVkIHRvbywKICogcmVnYXJkbGVzcyBvZiB0aGVpciByZWZjb3VudC4gSWYgYW55IHN1cmZhY2UgYmVpbmcgZGVzdHJveWVkIGhhcyBhbm90aGVyCiAqIHN1cmZhY2UgYXR0YWNoZWQgdG8gaXQgKHdpdGggYSAic29mdCIgYXR0YWNobWVudCwgbm90IGNvbXBsZXgpLCB0aGVuCiAqIHRoaXMgc3VyZmFjZSBpcyBkZXRhY2hlZCB3aXRoIERlbGV0ZUF0dGFjaGVkU3VyZmFjZS4KICoKICogV2hlbiB0aGUgc3VyZmFjZSBpcyBhIHRleHR1cmUsIHRoZSBXaW5lRDNEVGV4dHVyZSBpcyByZWxlYXNlZC4KICogSWYgdGhlIHN1cmZhY2UgaXMgdGhlIERpcmVjdDNEIHJlbmRlciB0YXJnZXQsIHRoZW4gdGhlIEQzRAogKiBjYXBhYmlsaXRpZXMgb2YgdGhlIFdpbmVEM0REZXZpY2UgYXJlIHVuaW5pdGlhbGl6ZWQsIHdoaWNoIGNhdXNlcyB0aGUKICogc3dhcGNoYWluIHRvIGJlIHJlbGVhc2VkLgogKgogKiBXaGVuIGEgY29tcGxleCBzdWJsZXZlbCBmYWxscyB0byByZWYgemVybywgdGhlbiB0aGlzIGlzIGlnbm9yZWQuCiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2UoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZjsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAocmVmID09IDApCiAgICB7CgogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICAgICAgSURpcmVjdERyYXdJbXBsICpkZHJhdzsKICAgICAgICBJVW5rbm93biAqaWZhY2VUb1JlbGVhc2UgPSBUaGlzLT5pZmFjZVRvUmVsZWFzZTsKICAgICAgICBpbnQgaTsKCiAgICAgICAgLyogQ29tcGxleCBhdHRhY2hlZCBzdXJmYWNlcyBhcmUgZGVzdHJveWVkIGltcGxpY2l0bHkgd2hlbiB0aGUgcm9vdCBpcyByZWxlYXNlZCAqLwogICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgaWYoIVRoaXMtPmlzX2NvbXBsZXhfcm9vdCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIiglcCkgQXR0ZW1wdCB0byBkZXN0cm95IGEgc3VyZmFjZSB0aGF0IGlzIG5vdCBhIGNvbXBsZXggcm9vdFxuIiwgVGhpcyk7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiByZWY7CiAgICAgICAgfQogICAgICAgIGRkcmF3ID0gVGhpcy0+ZGRyYXc7CgogICAgICAgIC8qIElmIGl0J3MgYSB0ZXh0dXJlLCBkZXN0cm95IHRoZSBXaW5lRDNEVGV4dHVyZS4KICAgICAgICAgKiBXaW5lRDNEIHdpbGwgZGVzdHJveSB0aGUgSVBhcmVudCBpbnRlcmZhY2VzCiAgICAgICAgICogb2YgdGhlIHN1YmxldmVscywgd2hpY2ggZGVzdHJveXMgdGhlIFdpbmVEM0RTdXJmYWNlcy4KICAgICAgICAgKiBTZXQgdGhlIHN1cmZhY2VzIHRvIE5VTEwgdG8gYXZvaWQgZGVzdHJveWluZyB0aGVtIGFnYWluIGxhdGVyCiAgICAgICAgICovCiAgICAgICAgaWYoVGhpcy0+d2luZUQzRFRleHR1cmUpCiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoVGhpcy0+d2luZUQzRFRleHR1cmUpOwogICAgICAgIH0KICAgICAgICAvKiBJZiBpdCdzIHRoZSBSZW5kZXJUYXJnZXQsIGRlc3Ryb3kgdGhlIGQzZGRldmljZSAqLwogICAgICAgIGVsc2UgaWYoVGhpcy0+d2luZUQzRFN3YXBDaGFpbikKICAgICAgICB7CiAgICAgICAgICAgIGlmKChkZHJhdy0+ZDNkX2luaXRpYWxpemVkKSAmJiAoVGhpcyA9PSBkZHJhdy0+ZDNkX3RhcmdldCkpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXApIERlc3Ryb3lpbmcgdGhlIHJlbmRlciB0YXJnZXQsIHVuaW5pdGlhbGl6aW5nIEQzRFxuIiwgVGhpcyk7CgogICAgICAgICAgICAgICAgLyogVW5zZXQgYW55IGluZGV4IGJ1ZmZlciwganVzdCB0byBiZSBzdXJlICovCiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRJbmRpY2VzKGRkcmF3LT53aW5lRDNERGV2aWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoZGRyYXctPndpbmVEM0REZXZpY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VmVydGV4RGVjbGFyYXRpb24oZGRyYXctPndpbmVEM0REZXZpY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgZGRyYXctPm51bUNvbnZlcnRlZERlY2xzOyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKGRkcmF3LT5kZWNsc1tpXS5kZWNsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRkcmF3LT5kZWNscyk7CiAgICAgICAgICAgICAgICBkZHJhdy0+bnVtQ29udmVydGVkRGVjbHMgPSAwOwoKICAgICAgICAgICAgICAgIGlmKElXaW5lRDNERGV2aWNlX1VuaW5pdDNEKGRkcmF3LT53aW5lRDNERGV2aWNlLCBEM0Q3Q0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UsIEQzRDdDQl9EZXN0cm95U3dhcENoYWluKSAhPSBEM0RfT0spCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogTm90IGdvb2QgKi8KICAgICAgICAgICAgICAgICAgICBFUlIoIiglcCkgRmFpbGVkIHRvIHVuaW5pdCAzRFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogRnJlZSB0aGUgZDNkIHdpbmRvdyBpZiBvbmUgd2FzIGNyZWF0ZWQgKi8KICAgICAgICAgICAgICAgICAgICBpZihkZHJhdy0+ZDNkX3dpbmRvdyAhPSAwICYmIGRkcmF3LT5kM2Rfd2luZG93ICE9IGRkcmF3LT5kZXN0X3dpbmRvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCIgKCVwKSBEZXN0cm95aW5nIHRoZSBoaWRkZW4gcmVuZGVyIHdpbmRvdyAlcFxuIiwgVGhpcywgZGRyYXctPmQzZF93aW5kb3cpOwogICAgICAgICAgICAgICAgICAgICAgICBEZXN0cm95V2luZG93KGRkcmF3LT5kM2Rfd2luZG93KTsKICAgICAgICAgICAgICAgICAgICAgICAgZGRyYXctPmQzZF93aW5kb3cgPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvKiBVbnNldCB0aGUgcG9pbnRlcnMgKi8KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUaGlzLT53aW5lRDNEU3dhcENoYWluID0gTlVMTDsgLyogVW5pbml0M0QgcmVsZWFzZXMgdGhlIHN3YXBjaGFpbiAqLwogICAgICAgICAgICAgICAgZGRyYXctPmQzZF9pbml0aWFsaXplZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgZGRyYXctPmQzZF90YXJnZXQgPSBOVUxMOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfVW5pbml0R0RJKGRkcmF3LT53aW5lRDNERGV2aWNlLCBEM0Q3Q0JfRGVzdHJveVN3YXBDaGFpbik7CiAgICAgICAgICAgICAgICBUaGlzLT53aW5lRDNEU3dhcENoYWluID0gTlVMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogUmVzZXQgdG8gdGhlIGRlZmF1bHQgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiB0eXBlLiBUaGlzIGlzIG5lZWRlZCBpZiBhcHBzIHVzZQogICAgICAgICAgICAgKiBub24gcmVuZGVyIHRhcmdldCBzdXJmYWNlcyBhbmQgZXhwZWN0IGJsaXRzIHRvIHdvcmsgYWZ0ZXIgZGVzdHJveWluZyB0aGUgcmVuZGVyCiAgICAgICAgICAgICAqIHRhcmdldC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVE9ETzogUmVjcmVhdGUgZXhpc3Rpbmcgb2Zmc2NyZWVuIHN1cmZhY2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkZHJhdy0+SW1wbFR5cGUgPSBEZWZhdWx0U3VyZmFjZVR5cGU7CgogICAgICAgICAgICAvKiBXcml0ZSBhIHRyYWNlIGJlY2F1c2UgRDNEIHVubG9hZGluZyB3YXMgdGhlIHJlYXNvbiBmb3IgbWFueQogICAgICAgICAgICAgKiBjcmFzaGVzIGR1cmluZyBkZXZlbG9wbWVudC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIEQzRCB1bmxvYWRlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfM0RERVZJQ0UgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVEVYVFVSRSAgICAgICAgKSApCiAgICAgICAgewogICAgICAgICAgICAvKiBJdCdzIGEgcmVuZGVyIHRhcmdldCwgYnV0IG5vIHN3YXBjaGFpbiB3YXMgY3JlYXRlZC4KICAgICAgICAgICAgICogVGhlIElQYXJlbnQgaW50ZXJmYWNlcyBoYXZlIHRvIGJlIHJlbGVhc2VkIG1hbnVhbGx5LgogICAgICAgICAgICAgKiBUaGUgc2FtZSBhcHBsaWVzIGZvciB0ZXh0dXJlcyB3aXRob3V0IGFuCiAgICAgICAgICAgICAqIElXaW5lRDNEVGV4dHVyZSBvYmplY3QgYXR0YWNoZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIElQYXJlbnQgKlBhcmVudDsKCiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPmNvbXBsZXhfYXJyYXlbaV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogT25seSB0aGUgdG9wbW9zdCBsZXZlbCBjYW4gaGF2ZSBtb3JlIHRoYW4gMSBzdXJmYWNlcyBpbiB0aGUgY29tcGxleAogICAgICAgICAgICAgICAgICAgICAqIGF0dGFjaG1lbnQgYXJyYXkoQ3ViZSB0ZXh0dXJlIHJvb3RzKSwgZm9yIGFsbCBvdGhlcnMgdGhlcmUgaXMgb25seQogICAgICAgICAgICAgICAgICAgICAqIG9uZQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlKHN1cmYpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHN1cmYtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJlBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIElQYXJlbnRfUmVsZWFzZShQYXJlbnQpOyAgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBUbyByZWxlYXNlIGl0ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHN1cmYgPSBzdXJmLT5jb21wbGV4X2FycmF5WzBdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogTm93IHRoZSB0b3AtbGV2ZWwgc3VyZmFjZSAqLwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKikgJlBhcmVudCk7CiAgICAgICAgICAgIElQYXJlbnRfUmVsZWFzZShQYXJlbnQpOyAgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBUbyByZWxlYXNlIGl0ICovCiAgICAgICAgfQoKICAgICAgICAvKiBUaGUgcmVmY291bnQgdGVzdCBzaG93cyB0aGF0IHRoZSBwYWxldHRlIGlzIGRldGFjaGVkIHdoZW4gdGhlIHN1cmZhY2UgaXMgZGVzdHJveWVkICovCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19TZXRQYWxldHRlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCiAgICAgICAgLyogTG9vcCB0aHJvdWdoIGFsbCBjb21wbGV4IGF0dGFjaGVkIHN1cmZhY2VzLAogICAgICAgICAqIGFuZCBkZXN0cm95IHRoZW0uCiAgICAgICAgICoKICAgICAgICAgKiBZZXQgYWdhaW4sIG9ubHkgdGhlIHJvb3QgY2FuIGhhdmUgbW9yZSB0aGFuIG9uZSBjb21wbGV4bHkgYXR0YWNoZWQgc3VyZmFjZSwgYWxsIHRoZSBvdGhlcnMKICAgICAgICAgKiBoYXZlIGEgdG90YWwgb2Ygb25lOwogICAgICAgICAqLwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZighVGhpcy0+Y29tcGxleF9hcnJheVtpXSkgYnJlYWs7CgogICAgICAgICAgICBzdXJmID0gVGhpcy0+Y29tcGxleF9hcnJheVtpXTsKICAgICAgICAgICAgVGhpcy0+Y29tcGxleF9hcnJheVtpXSA9IE5VTEw7CiAgICAgICAgICAgIHdoaWxlKHN1cmYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmRlc3Ryb3kgPSBzdXJmOwogICAgICAgICAgICAgICAgc3VyZiA9IHN1cmYtPmNvbXBsZXhfYXJyYXlbMF07ICAgICAgICAgICAgICAvKiBJdGVyYXRlIHRocm91Z2ggdGhlICJ0cmVlIiAqLwogICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95KGRlc3Ryb3kpOyAgICAvKiBEZXN0cm95IGl0ICovCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIERlc3Ryb3kgdGhlIHJvb3Qgc3VyZmFjZS4KICAgICAgICAgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0Rlc3Ryb3koVGhpcyk7CgogICAgICAgIC8qIFJlZHVjZSB0aGUgZGRyYXcgcmVmY291bnQgKi8KICAgICAgICBpZihpZmFjZVRvUmVsZWFzZSkgSVVua25vd25fUmVsZWFzZShpZmFjZVRvUmVsZWFzZSk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0QXR0YWNoZWRTdXJmYWNlCiAqCiAqIFJldHVybnMgYW4gYXR0YWNoZWQgc3VyZmFjZSB3aXRoIHRoZSByZXF1ZXN0ZWQgY2Fwcy4gU3VyZmFjZSBhdHRhY2htZW50CiAqIGFuZCBjb21wbGV4IHN1cmZhY2VzIGFyZSBub3QgY2xlYXJseSBkZXNjcmliZWQgYnkgdGhlIE1TRE4gb3Igc2RrLAogKiBzbyB0aGlzIG1ldGhvZCBpcyB0cmlja3kgYW5kIGxpa2VseSB0byBjb250YWluIHByb2JsZW1zLgogKiBUaGlzIGltcGxlbWVudGF0aW9uIHNlYXJjaGVzIHRoZSBjb21wbGV4IGxpc3QgZmlyc3QsIHRoZW4gdGhlCiAqIGF0dGFjaG1lbnQgY2hhaW4uCiAqCiAqIFRoZSBjaGFpbnMgYXJlIHNlYXJjaGVkIGZyb20gVGhpcyBkb3duIHRvIHRoZSBsYXN0IHN1cmZhY2UgaW4gdGhlIGNoYWluLAogKiBub3QgZnJvbSB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgY2hhaW4uIFRoZSBmaXJzdCBzdXJmYWNlIGZvdW5kIGlzCiAqIHJldHVybmVkLiBUaGUgTVNETiBzYXlzIHRoYXQgdGhpcyBtZXRob2QgZmFpbHMgaWYgbW9yZSB0aGFuIG9uZSBzdXJmYWNlCiAqIG1hdGNoZXMgdGhlIGNhcHMsIGJ1dCBpdCBpcyBub3Qgc3VyZSBpZiB0aGF0IGlzIHJpZ2h0LiBUaGUgYXR0YWNobWVudAogKiBzdHJ1Y3R1cmUgbWF5IG5vdCBldmVuIGFsbG93IHR3byBtYXRjaGluZyBzdXJmYWNlcy4KICoKICogVGhlIGZvdW5kIHN1cmZhY2UgaXMgQWRkUmVmLWVkIGJlZm9yZSBpdCBpcyByZXR1cm5lZC4KICoKICogUGFyYW1zOgogKiAgQ2FwczogUG9pbnRlciB0byBhIEREQ0FQUzIgc3RydWN0dXJlIGRlc2NyaWJpbmcgdGhlIGNhcHMgYXNrZWQgZm9yCiAqICBTdXJmYWNlOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBmb3VuZCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhcHMgb3IgU3VyZmFjZSBpcyBOVUxMCiAqICBEREVSUl9OT1RGT1VORCBpZiBubyBzdXJmYWNlIHdhcyBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQUzIgKkNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgRERTQ0FQUzIgb3VyX2NhcHM7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgQ2FwcywgU3VyZmFjZSk7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIG91cl9jYXBzID0gKkNhcHM7CgogICAgaWYoVGhpcy0+dmVyc2lvbiA8IDcpCiAgICB7CiAgICAgICAgLyogRWFybGllciBkeCBhcHBzIHB1dCBnYXJiYWdlIGludG8gdGhlc2UgbWVtYmVycywgY2xlYXIgdGhlbSAqLwogICAgICAgIG91cl9jYXBzLmR3Q2FwczIgPSAwOwogICAgICAgIG91cl9jYXBzLmR3Q2FwczMgPSAwOwogICAgICAgIG91cl9jYXBzLmR3Q2FwczQgPSAwOwogICAgfQoKICAgIFRSQUNFKCIoJXApOiBMb29raW5nIGZvciBjYXBzOiAleCwleCwleCwleFxuIiwgVGhpcywgb3VyX2NhcHMuZHdDYXBzLCBvdXJfY2Fwcy5kd0NhcHMyLCBvdXJfY2Fwcy5kd0NhcHMzLCBvdXJfY2Fwcy5kd0NhcHM0KTsgLyogRklYTUU6IEJldHRlciBkZWJ1Z2dpbmcgKi8KCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NUExFWF9BVFRBQ0hFRDsgaSsrKQogICAgewogICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgIGlmKCFzdXJmKSBicmVhazsKCiAgICAgICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlOiAoJXApIGNhcHM6ICV4LCV4LCV4LCV4XG4iLCBzdXJmLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMiwKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczMsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHM0KTsKICAgICAgICB9CgogICAgICAgIGlmICgoKHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIG91cl9jYXBzLmR3Q2FwcykgPT0gb3VyX2NhcHMuZHdDYXBzKSAmJgogICAgICAgICAgICAoKHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBvdXJfY2Fwcy5kd0NhcHMyKSA9PSBvdXJfY2Fwcy5kd0NhcHMyKSkgewoKICAgICAgICAgICAgLyogTVNETjogIlRoaXMgbWV0aG9kIGZhaWxzIGlmIG1vcmUgdGhhbiBvbmUgc3VyZmFjZSBpcyBhdHRhY2hlZAogICAgICAgICAgICAgKiB0aGF0IG1hdGNoZXMgdGhlIGNhcGFiaWxpdGllcyByZXF1ZXN0ZWQuIgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBOb3Qgc3VyZSBob3cgdG8gdGVzdCB0aGlzLgogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIFRSQUNFKCIoJXApOiBSZXR1cm5pbmcgc3VyZmFjZSAlcFxuIiwgVGhpcywgc3VyZik7CiAgICAgICAgICAgIFRSQUNFKCIoJXApOiBtaXBtYXBjb3VudD0lZFxuIiwgVGhpcywgc3VyZi0+bWlwbWFwX2xldmVsKTsKICAgICAgICAgICAgKlN1cmZhY2UgPSBJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoKlN1cmZhY2UpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5leHQsIGxvb2sgYXQgdGhlIGF0dGFjaG1lbnQgY2hhaW4gKi8KICAgIHN1cmYgPSBUaGlzOwoKICAgIHdoaWxlKCAoc3VyZiA9IHN1cmYtPm5leHRfYXR0YWNoZWQpICkKICAgIHsKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2U6ICglcCkgY2FwczogJXgsJXgsJXgsJXhcbiIsIHN1cmYsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMywKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgb3VyX2NhcHMuZHdDYXBzKSA9PSBvdXJfY2Fwcy5kd0NhcHMpICYmCiAgICAgICAgICAgICgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMiAmIG91cl9jYXBzLmR3Q2FwczIpID09IG91cl9jYXBzLmR3Q2FwczIpKSB7CgogICAgICAgICAgICBUUkFDRSgiKCVwKTogUmV0dXJuaW5nIHN1cmZhY2UgJXBcbiIsIFRoaXMsIHN1cmYpOwogICAgICAgICAgICAqU3VyZmFjZSA9IElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZigqU3VyZmFjZSk7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIiglcCkgRGlkbid0IGZpbmQgYSB2YWxpZCBzdXJmYWNlXG4iLCBUaGlzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgKlN1cmZhY2UgPSBOVUxMOwogICAgcmV0dXJuIERERVJSX05PVEZPVU5EOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6TG9jawogKgogKiBMb2NrcyB0aGUgc3VyZmFjZSBhbmQgcmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIHN1cmZhY2UncyBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgUmVjdDogUmVjdGFuZ2xlIHRvIGxvY2suIElmIE5VTEwsIHRoZSB3aG9sZSBzdXJmYWNlIGlzIGxvY2tlZAogKiAgRERTRDogUG9pbnRlciB0byBhIEREU1VSRkFDRURFU0MyIHdoaWNoIHNoYWxsIHJlY2VpdmUgdGhlIHN1cmZhY2UncyBkZXNjLgogKiAgRmxhZ3M6IExvY2tpbmcgZmxhZ3MsIGUuZyBSZWFkIG9ubHkgb3Igd3JpdGUgb25seQogKiAgaDogQW4gZXZlbnQgaGFuZGxlIHRoYXQncyBub3QgdXNlZCBhbmQgbXVzdCBiZSBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREU0QgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6TG9ja1JlY3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Mb2NrKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgaCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIExvY2tlZFJlY3Q7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwleCwlcClcbiIsIFRoaXMsIFJlY3QsIEREU0QsIEZsYWdzLCBoKTsKCiAgICBpZighRERTRCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aCBhbmQgZHdIZWlnaHQgYXJlIGNoYW5nZWFibGUsIHRodXMgbG9jayAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBTaG91bGQgSSBjaGVjayBmb3IgdGhlIGhhbmRsZSB0byBiZSBOVUxMPwogICAgICoKICAgICAqIFRoZSBERExPQ0sgZmxhZ3MgYW5kIHRoZSBEM0RMT0NLIGZsYWdzIGFyZSBlcXVhbAogICAgICogZm9yIHRoZSBzdXBwb3J0ZWQgdmFsdWVzLiBUaGUgb3RoZXJzIGFyZSBpZ25vcmVkIGJ5IFdpbmVEM0QKICAgICAqLwoKICAgIGlmKEREU0QtPmR3U2l6ZSAhPSBzaXplb2YoRERTVVJGQUNFREVTQykgJiYKICAgICAgIEREU0QtPmR3U2l6ZSAhPSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgewogICAgICAgIFdBUk4oIkludmFsaWQgc3RydWN0dXJlIHNpemUgJWQsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iLCBEREVSUl9JTlZBTElEUEFSQU1TKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFdpbmRvd3MgemVyb2VzIHRoaXMgaWYgdGhlIHJlY3QgaXMgaW52YWxpZCAqLwogICAgRERTRC0+bHBTdXJmYWNlID0gMDsKCiAgICBpZiAoUmVjdCkKICAgIHsKICAgICAgICBpZiAoKFJlY3QtPmxlZnQgPCAwKQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPnRvcCA8IDApCiAgICAgICAgICAgICAgICB8fCAoUmVjdC0+bGVmdCA+IFJlY3QtPnJpZ2h0KQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPnRvcCA+IFJlY3QtPmJvdHRvbSkKICAgICAgICAgICAgICAgIHx8IChSZWN0LT5yaWdodCA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoKQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPmJvdHRvbSA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUcnlpbmcgdG8gbG9jayBhbiBpbnZhbGlkIHJlY3RhbmdsZSwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTG9ja2VkUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICBzd2l0Y2goaHIpCiAgICAgICAgewogICAgICAgICAgICAvKiBEM0Q4IGFuZCBEM0Q5IHJldHVybiB0aGUgZ2VuZXJhbCBEM0RFUlJfSU5WQUxJRENBTEwgZXJyb3IsIGJ1dCBkZHJhdyBoYXMgYSBtb3JlCiAgICAgICAgICAgICAqIHNwZWNpZmljIGVycm9yLiBCdXQgc2luY2UgSVdpbmVEM0RTdXJmYWNlOjpMb2NrUmVjdCByZXR1cm5zIHRoYXQgZXJyb3IgaW4gdGhpcwogICAgICAgICAgICAgKiBvbmx5IG9jY2FzaW9uLCBrZWVwIGQzZDggYW5kIGQzZDkgZnJlZSBmcm9tIHRoZSByZXR1cm4gdmFsdWUgb3ZlcnJpZGUuIFRoZXJlIGFyZQogICAgICAgICAgICAgKiBtYW55IGRpZmZlcmVudCBwbGFjZXMgd2hlcmUgZDNkOC85IHdvdWxkIGhhdmUgdG8gY2F0Y2ggdGhlIERERVJSX1NVUkZBQ0VCVVNZLCBpdAogICAgICAgICAgICAgKiBpcyBtdWNoIGVhc2llciB0byBkbyBpdCBpbiBvbmUgcGxhY2UgaW4gZGRyYXcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNhc2UgV0lORUQzREVSUl9JTlZBTElEQ0FMTDogICAgcmV0dXJuIERERVJSX1NVUkZBQ0VCVVNZOwogICAgICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgLyogT3ZlcnJpZGUgdGhlIG1lbW9yeSBhcmVhLiBUaGUgcGl0Y2ggc2hvdWxkIGJlIHNldCBhbHJlYWR5LiBTdHJhbmdlbHkgd2luZG93cwogICAgICogZG9lcyBub3Qgc2V0IHRoZSBMUFNVUkZBQ0UgZmxhZyBvbiBsb2NrZWQgc3VyZmFjZXMgIT8hLgogICAgICogRERTRC0+ZHdGbGFncyB8PSBERFNEX0xQU1VSRkFDRTsKICAgICAqLwogICAgVGhpcy0+c3VyZmFjZV9kZXNjLmxwU3VyZmFjZSA9IExvY2tlZFJlY3QucEJpdHM7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoRERTRCwmKFRoaXMtPnN1cmZhY2VfZGVzYykpOwoKICAgIFRSQUNFKCJsb2NrZWQgc3VyZmFjZSByZXR1cm5pbmcgZGVzY3JpcHRpb24gOlxuIik7CiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKSBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6VW5sb2NrCiAqCiAqIFVubG9ja3MgYW4gbG9ja2VkIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgUmVjdDogTm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OlVubG9ja1JlY3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VbmxvY2soSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKnBSZWN0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHBSZWN0KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChUaGlzLT5XaW5lRDNEU3VyZmFjZSk7CiAgICBpZihTVUNDRUVERUQoaHIpKQogICAgewogICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5scFN1cmZhY2UgPSBOVUxMOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkZsaXAKICoKICogRmxpcHMgYSBzdXJmYWNlIHdpdGggdGhlIEREU0NBUFNfRkxJUCBmbGFnLiBUaGUgZmxpcCBpcyByZWxheWVkIHRvCiAqIElXaW5lRDNEU3VyZmFjZTo6RmxpcC4gQmVjYXVzZSBXaW5lRDNEIGRvZXNuJ3QgaGFuZGxlIGF0dGFjaGVkIHN1cmZhY2VzLAogKiB0aGUgZmxpcCB0YXJnZXQgaXMgcGFzc2VkIHRvIFdpbmVEM0QsIGV2ZW4gaWYgdGhlIGFwcCBkaWRuJ3Qgc3BlY2lmeSBvbmUKICoKICogUGFyYW1zOgogKiAgRGVzdE92ZXJyaWRlOiBTcGVjaWZpZXMgdGhlIHN1cmZhY2UgdGhhdCB3aWxsIGJlY29tZSB0aGUgbmV3IGZyb250CiAqICAgICAgICAgICAgICAgIGJ1ZmZlci4gSWYgTlVMTCwgdGhlIGN1cnJlbnQgYmFjayBidWZmZXIgaXMgdXNlZAogKiAgRmxhZ3M6IHNvbWUgRGlyZWN0RHJhdyBmbGFncywgc2VlIGluY2x1ZGUvZGRyYXcuaAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfTk9URkxJUFBBQkxFIGlmIG5vIGZsaXAgdGFyZ2V0IGNvdWxkIGJlIGZvdW5kCiAqICBEREVSUl9JTlZBTElET0JKRUNUIGlmIHRoZSBzdXJmYWNlIGlzbid0IGEgZnJvbnQgYnVmZmVyCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpGbGlwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRmxpcChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RPdmVycmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpPdmVycmlkZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIERlc3RPdmVycmlkZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpPdmVycmlkZTc7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIERlc3RPdmVycmlkZSwgRmxhZ3MpOwoKICAgIC8qIEZsaXAgaGFzIHRvIGJlIGNhbGxlZCBmcm9tIGEgZnJvbnQgYnVmZmVyCiAgICAgKiBXaGF0IGFib3V0IG92ZXJsYXkgc3VyZmFjZXMsIEFGQUlLIHRoZXkgY2FuIGZsaXAgdG9vPwogICAgICovCiAgICBpZiggIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GUk9OVEJVRkZFUiB8IEREU0NBUFNfT1ZFUkxBWSkpICkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRE9CSkVDVDsgLyogVW5jaGVja2VkICovCgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBXaW5lRDNEIGRvZXNuJ3Qga2VlcCB0cmFjayBvZiBhdHRhY2hlZCBzdXJmYWNlLCBzbyBmaW5kIHRoZSB0YXJnZXQgKi8KICAgIGlmKCFPdmVycmlkZSkKICAgIHsKICAgICAgICBERFNDQVBTMiBDYXBzOwoKICAgICAgICBtZW1zZXQoJkNhcHMsIDAsIHNpemVvZihDYXBzKSk7CiAgICAgICAgQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19CQUNLQlVGRkVSOwogICAgICAgIGhyID0gSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoaWZhY2UsICZDYXBzLCAmT3ZlcnJpZGU3KTsKICAgICAgICBpZihociAhPSBERF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiQ2FuJ3QgZmluZCBhIGZsaXAgdGFyZ2V0XG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX05PVEZMSVBQQUJMRTsgLyogVW5jaGVja2VkICovCiAgICAgICAgfQogICAgICAgIE92ZXJyaWRlID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgT3ZlcnJpZGU3KTsKCiAgICAgICAgLyogRm9yIHRoZSBHZXRBdHRhY2hlZFN1cmZhY2UgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoT3ZlcnJpZGU3KTsKICAgIH0KCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9GbGlwKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdmVycmlkZS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpCbHQKICoKICogUGVyZm9ybXMgYSBibGl0IG9uIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIERlc3RSZWN0OiBEZXN0aW5hdGlvbiByZWN0YW5nbGUsIGNhbiBiZSBOVUxMCiAqICBTcmNTdXJmYWNlOiBTb3VyY2Ugc3VyZmFjZSwgY2FuIGJlIE5VTEwKICogIFNyY1JlY3Q6IFNvdXJjZSByZWN0YW5nbGUsIGNhbiBiZSBOVUxMCiAqICBGbGFnczogQmx0IGZsYWdzCiAqICBEREJsdEZ4OiBTb21lIGV4dGVuZGVkIGJsdCBwYXJhbWV0ZXJzLCBjb25uZWN0ZWQgdG8gdGhlIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6Qmx0IGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHQoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKkRlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmNTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgRERCTFRGWCAqRERCbHRGeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyY1N1cmZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWRpdHkgb2YgdGhlIGZsYWdzIGhlcmUuIFdpbmVEM0QgSGFzIHRoZSBzb2Z0d2FyZS1vcGVuZ2wgc2VsZWN0aW9uIHBhdGggYW5kIHdvdWxkIGhhdmUKICAgICAqIHRvIGNoZWNrIGF0IDIgcGxhY2VzLCBhbmQgc29tZXRpbWVzIGRvIGRvdWJsZSBjaGVja3MuIFRoaXMgYWxzbyBzYXZlcyB0aGUgY2FsbCB0byB3aW5lZDNkIDotKQogICAgICovCiAgICBpZigoRmxhZ3MgJiBEREJMVF9LRVlTUkNPVkVSUklERSkgJiYgKCFEREJsdEZ4IHx8IEZsYWdzICYgRERCTFRfS0VZU1JDKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgc291cmNlIGNvbG9yIGtleSBwYXJhbWV0ZXJzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoKEZsYWdzICYgRERCTFRfS0VZREVTVE9WRVJSSURFKSAmJiAoIUREQmx0RnggfHwgRmxhZ3MgJiBEREJMVF9LRVlERVNUKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgZGVzdGluYXRpb24gY29sb3Iga2V5IHBhcmFtZXRlcnMsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBTaXplcyBjYW4gY2hhbmdlLCB0aGVyZWZvcmUgaG9sZCB0aGUgbG9jayB3aGVuIHRlc3RpbmcgdGhlIHJlY3RhbmdsZXMgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihEZXN0UmVjdCkKICAgIHsKICAgICAgICBpZihEZXN0UmVjdC0+dG9wID49IERlc3RSZWN0LT5ib3R0b20gfHwgRGVzdFJlY3QtPmxlZnQgPj0gRGVzdFJlY3QtPnJpZ2h0IHx8CiAgICAgICAgICAgRGVzdFJlY3QtPnJpZ2h0ID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICBEZXN0UmVjdC0+Ym90dG9tID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiRGVzdGluYXRpb24gcmVjdGFuZ2xlIGlzIGludmFsaWQsIHJldHVybmluZyBEREVSUl9JTlZBTElEUkVDVFxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICB9CiAgICB9CiAgICBpZihTcmMgJiYgU3JjUmVjdCkKICAgIHsKICAgICAgICBpZihTcmNSZWN0LT50b3AgPj0gU3JjUmVjdC0+Ym90dG9tIHx8IFNyY1JlY3QtPmxlZnQgPj1TcmNSZWN0LT5yaWdodCB8fAogICAgICAgICAgIFNyY1JlY3QtPnJpZ2h0ID4gU3JjLT5zdXJmYWNlX2Rlc2MuZHdXaWR0aCB8fAogICAgICAgICAgIFNyY1JlY3QtPmJvdHRvbSA+IFNyYy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiU291cmNlIHJlY3RhbmdsZSBpcyBpbnZhbGlkLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFJFQ1RcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgfQogICAgfQoKICAgIGlmKEZsYWdzICYgRERCTFRfS0VZU1JDICYmICghU3JjIHx8ICEoU3JjLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmIEREU0RfQ0tTUkNCTFQpKSkgewogICAgICAgIFdBUk4oIkREQkxUX0tFWURFU1QgYmxpdCB3aXRob3V0IGNvbG9yIGtleSBpbiBzdXJmYWNlLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBUT0RPOiBDaGVjayBpZiB0aGUgRERCbHRGeCBjb250YWlucyBhbnkgZGRyYXcgc3VyZmFjZSBwb2ludGVycy4gSWYgaXQgZG9lcywgY29weSB0aGUgc3RydWN0LAogICAgICogYW5kIHJlcGxhY2UgdGhlIGRkcmF3IHN1cmZhY2VzIHdpdGggdGhlIHdpbmVkM2Qgc3VyZmFjZXMKICAgICAqIFNvIGZhciBubyBibGl0dGluZyBvcGVyYXRpb25zIHVzaW5nIHN1cmZhY2VzIGluIHRoZSBibHRmeCBzdHJ1Y3QgYXJlIHN1cHBvcnRlZCBhbnl3YXkuCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0JsdChUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTcmMgPyBTcmMtPldpbmVEM0RTdXJmYWNlIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERCTFRGWCAqKSBEREJsdEZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RURVhGX1BPSU5UKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9OT1RBVkFJTEFCTEU6ICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfV1JPTkdURVhUVVJFRk9STUFUOiByZXR1cm4gRERFUlJfSU5WQUxJRFBJWEVMRk9STUFUOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkFkZEF0dGFjaGVkU3VyZmFjZQogKgogKiBBdHRhY2hlcyBhIHN1cmZhY2UgdG8gYW5vdGhlciBzdXJmYWNlLiBIb3cgdGhlIHN1cmZhY2UgYXR0YWNobWVudHMgd29yawogKiBpcyBub3QgdG90YWxseSB1bmRlcnN0b29kIHlldCwgYW5kIHRoaXMgbWV0aG9kIGlzIHByb25lIHRvIHByb2JsZW1zLgogKiBoZSBzdXJmYWNlIHRoYXQgaXMgYXR0YWNoZWQgaXMgQWRkUmVmLWVkLgogKgogKiBUZXN0cyB3aXRoIGNvbXBsZXggc3VyZmFjZXMgc3VnZ2VzdCB0aGF0IHRoZSBzdXJmYWNlIGF0dGFjaG1lbnRzIGZvcm0gYQogKiB0cmVlLCBidXQgbm8gbWV0aG9kIHRvIHRlc3QgdGhpcyBoYXMgYmVlbiBmb3VuZCB5ZXQuCiAqCiAqIFRoZSBhdHRhY2htZW50IGxpc3QgY29uc2lzdHMgb2YgYSBmaXJzdCBzdXJmYWNlIChmaXJzdF9hdHRhY2hlZCkgYW5kCiAqIGZvciBlYWNoIHN1cmZhY2UgYSBwb2ludGVyIHRvIHRoZSBuZXh0IGF0dGFjaGVkIHN1cmZhY2UgKG5leHRfYXR0YWNoZWQpLgogKiBGb3IgdGhlIGZpcnN0IHN1cmZhY2UsIGFuZCBhIHN1cmZhY2UgdGhhdCBoYXMgbm8gYXR0YWNobWVudHMKICogZmlyc3RfYXR0YWNoZWQgcG9pbnRzIHRvIHRoZSBzdXJmYWNlIGl0c2VsZi4gQSBzdXJmYWNlIHRoYXQgaGFzCiAqIG5vIHN1Y2Nlc3NvcnMgaW4gdGhlIGNoYWluIGhhcyBuZXh0X2F0dGFjaGVkIHNldCB0byBOVUxMLgogKgogKiBOZXdseSBhdHRhY2hlZCBzdXJmYWNlcyBhcmUgYXR0YWNoZWQgcmlnaHQgYWZ0ZXIgdGhlIHJvb3Qgc3VyZmFjZS4KICogSWYgYSBzdXJmYWNlIGlzIGF0dGFjaGVkIHRvIGEgY29tcGxleCBzdXJmYWNlIGNvbXBvdW5kLCBpdCdzIGF0dGFjaGVkIHRvCiAqIHRoZSBzdXJmYWNlIHRoYXQgdGhlIGFwcCByZXF1ZXN0ZWQsIG5vdCB0aGUgY29tcGxleCByb290LiBTZWUKICogR2V0QXR0YWNoZWRTdXJmYWNlIGZvciBhIGRlc2NyaXB0aW9uIGhvdyBzdXJmYWNlcyBhcmUgZm91bmQuCiAqCiAqIFRoaXMgaXMgaG93IHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHdvcmtzLCBhbmQgaXQgd2FzIGNvZGVkIGJ5IGxvb2tpbmcKICogYXQgdGhlIG5lZWRzIG9mIHRoZSBhcHBsaWNhdGlvbnMuCiAqCiAqIFNvIGZhciBvbmx5IFotQnVmZmVyIGF0dGFjaG1lbnRzIGFyZSB0ZXN0ZWQsIGFuZCB0aGV5IGFyZSBhY3RpdmF0ZWQgaW4KICogV2luZUQzRC4gTWlwbWFwcyBjb3VsZCBiZSB0cmlja3kgdG8gYWN0aXZhdGUgaW4gV2luZUQzRC4KICogQmFjayBidWZmZXJzIHNob3VsZCB3b3JrIGluIDJEIG1vZGUsIGJ1dCB0aGV5IGFyZSBub3QgdGVzdGVkKFRoZXkgY2FuIGJlCiAqIGF0dGFjaGVkIGluIG9sZGVyIGlmYWNlIHZlcnNpb25zKS4gUmVuZGVyaW5nIHRvIHRoZSBmcm9udCBidWZmZXIgYW5kCiAqIHN3aXRjaGluZyBiZXR3ZWVuIHRoYXQgYW5kIGRvdWJsZSBidWZmZXJpbmcgaXMgbm90IHlldCBpbXBsZW1lbnRlZCBpbgogKiBXaW5lRDNELCBzbyBmb3IgM0QgaXQgbWlnaHQgaGF2ZSB1bmV4cGVjdGVkIHJlc3VsdHMuCiAqCiAqIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQWRkQXR0YWNoZWRTdXJmYWNlIGlzIHRoZSByZWFsIHRoaW5nLAogKiBJRGlyZWN0RHJhd1N1cmZhY2U3SW1wbF9BZGRBdHRhY2hlZFN1cmZhY2UgaXMgYSB3cmFwcGVyIGFyb3VuZCBpdCB0aGF0CiAqIHBlcmZvcm1zIGFkZGl0aW9uYWwgY2hlY2tzLiBWZXJzaW9uIDcgb2YgdGhpcyBpbnRlcmZhY2UgaXMgbXVjaCBtb3JlIHJlc3RyaWN0aXZlCiAqIHRoYW4gaXRzIHByZWRlY2Vzc29ycy4KICoKICogUGFyYW1zOgogKiAgQXR0YWNoOiBTdXJmYWNlIHRvIGF0dGFjaCB0byBpZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfQ0FOTk9UQVRUQUNIU1VSRkFDRSBpZiB0aGUgc3VyZmFjZSBjYW4ndCBiZSBhdHRhY2hlZCBmb3Igc29tZSByZWFzb24KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmKQp7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgU3VyZik7CgogICAgaWYoU3VyZiA9PSBUaGlzKQogICAgICAgIHJldHVybiBEREVSUl9DQU5OT1RBVFRBQ0hTVVJGQUNFOyAvKiB1bmNoZWNrZWQgKi8KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIC8qIENoZWNrIGlmIHRoZSBzdXJmYWNlIGlzIGFscmVhZHkgYXR0YWNoZWQgc29tZXdoZXJlICovCiAgICBpZiggKFN1cmYtPm5leHRfYXR0YWNoZWQgIT0gTlVMTCkgfHwKICAgICAgICAoU3VyZi0+Zmlyc3RfYXR0YWNoZWQgIT0gU3VyZikgKQogICAgewogICAgICAgIC8qIFRPRE86IFRlc3QgZm9yIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIG1hbnVhbCBhdHRhY2htZW50LiBJcyBpdCBhIGNoYWluIG9yIGEgbGlzdD8KICAgICAgICAgKiBXaGF0IGhhcHBlbnMgaWYgb25lIHN1cmZhY2UgaXMgYXR0YWNoZWQgdG8gMiBkaWZmZXJlbnQgc3VyZmFjZXM/CiAgICAgICAgICovCiAgICAgICAgRklYTUUoIiglcCkgVGhlIFN1cmZhY2UgJXAgaXMgYWxyZWFkeSBhdHRhY2hlZCBzb21ld2hlcmUgZWxzZTogbmV4dF9hdHRhY2hlZCA9ICVwLCBmaXJzdF9hdHRhY2hlZCA9ICVwLCBjYW4ndCBoYW5kbGUgYnkgbm93XG4iLCBUaGlzLCBTdXJmLCBTdXJmLT5uZXh0X2F0dGFjaGVkLCBTdXJmLT5maXJzdF9hdHRhY2hlZCk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUFMUkVBRFlBVFRBQ0hFRDsKICAgIH0KCiAgICAvKiBUaGlzIGluc2VydHMgdGhlIG5ldyBzdXJmYWNlIGF0IHRoZSAybmQgcG9zaXRpb24gaW4gdGhlIGNoYWluLCByaWdodCBhZnRlciB0aGUgcm9vdCBzdXJmYWNlICovCiAgICBTdXJmLT5uZXh0X2F0dGFjaGVkID0gVGhpcy0+bmV4dF9hdHRhY2hlZDsKICAgIFN1cmYtPmZpcnN0X2F0dGFjaGVkID0gVGhpcy0+Zmlyc3RfYXR0YWNoZWQ7CiAgICBUaGlzLT5uZXh0X2F0dGFjaGVkID0gU3VyZjsKCiAgICAvKiBDaGVjayBpZiB0aGUgV2luZUQzRCBkZXB0aCBzdGVuY2lsIG5lZWRzIHVwZGF0aW5nICovCiAgICBpZihUaGlzLT5kZHJhdy0+ZDNkZGV2aWNlKQogICAgewogICAgICAgIElEaXJlY3QzRERldmljZUltcGxfVXBkYXRlRGVwdGhTdGVuY2lsKFRoaXMtPmRkcmF3LT5kM2RkZXZpY2UpOwogICAgfQoKICAgIC8qIE1TRE46IAogICAgICogIlRoaXMgbWV0aG9kIGluY3JlbWVudHMgdGhlIHJlZmVyZW5jZSBjb3VudCBvZiB0aGUgc3VyZmFjZSBiZWluZyBhdHRhY2hlZC4iCiAgICAgKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2U3SW1wbF9BZGRBdHRhY2hlZFN1cmZhY2UoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpBdHRhY2gpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBBdHRhY2gpOwoKICAgIC8qIFZlcnNpb24gNyBvZiB0aGlzIGludGVyZmFjZSBzZWVtcyB0byByZWZ1c2UgZXZlcnl0aGluZyBleGNlcHQgeiBidWZmZXJzLCBhcyBwZXIgbXNkbiAqLwogICAgaWYoIShTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1pCVUZGRVIpKQogICAgewoKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiB0cmllcyB0byBhdHRhY2ggYSBub24gWiBidWZmZXIgc3VyZmFjZS4gY2FwcyAlMDh4XG4iLAogICAgICAgICAgICAgIFN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2Fwcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0NBTk5PVEFUVEFDSFNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQWRkQXR0YWNoZWRTdXJmYWNlKFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3VyZik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkRlbGV0ZUF0dGFjaGVkU3VyZmFjZQogKgogKiBSZW1vdmVzIGEgc3VyZmFjZSBmcm9tIHRoZSBhdHRhY2htZW50IGNoYWluLiBUaGUgc3VyZmFjZSdzIHJlZmNvdW50CiAqIGlzIGRlY3JlYXNlZCBieSBvbmUgYWZ0ZXIgaXQgaGFzIGJlZW4gcmVtb3ZlZAogKgogKiBQYXJhbXM6CiAqICBGbGFnczogU29tZSBmbGFncywgbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbgogKiAgQXR0YWNoOiBTdXJmYWNlIHRvIGRldGFjaAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfU1VSRkFDRU5PVEFUVEFDSEVEIGlmIHRoZSBzdXJmYWNlIGlzbid0IGF0dGFjaGVkIHRvCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRGVsZXRlQXR0YWNoZWRTdXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqQXR0YWNoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgQXR0YWNoKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlByZXYgPSBUaGlzOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIFN1cmYpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiAoIVN1cmYgfHwgKFN1cmYtPmZpcnN0X2F0dGFjaGVkICE9IFRoaXMpIHx8IChTdXJmID09IFRoaXMpICkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9DQU5OT1RERVRBQ0hTVVJGQUNFOwogICAgfQoKICAgIC8qIFJlbW92ZSBNSVBNQVBTVUJMRVZFTCBpZiB0aGlzIHNlZW1lZCB0byBiZSBvbmUgKi8KICAgIGlmIChUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJgogICAgICAgIFN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKQogICAgewogICAgICAgIFN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgIC8qIEZJWE1FOiB3ZSBzaG91bGQgcHJvYmFibHkgYWxzbyBzdWJ0cmFjdCBmcm9tIGR3TWlwTWFwQ291bnQgb2YgdGhpcwogICAgICAgICAqIGFuZCBhbGwgcGFyZW50IHN1cmZhY2VzICovCiAgICB9CgogICAgLyogRmluZCB0aGUgcHJlZGVjZXNzb3Igb2YgdGhlIGRldGFjaGVkIHN1cmZhY2UgKi8KICAgIHdoaWxlKFByZXYpCiAgICB7CiAgICAgICAgaWYoUHJldi0+bmV4dF9hdHRhY2hlZCA9PSBTdXJmKSBicmVhazsKICAgICAgICBQcmV2ID0gUHJldi0+bmV4dF9hdHRhY2hlZDsKICAgIH0KCiAgICAvKiBUaGVyZSBtdXN0IGJlIGEgc3VyZmFjZSwgb3RoZXJ3aXNlIHRoZXJlJ3MgYSBidWcgKi8KICAgIGFzc2VydChQcmV2ICE9IE5VTEwpOwoKICAgIC8qIFVuY2hhaW4gdGhlIHN1cmZhY2UgKi8KICAgIFByZXYtPm5leHRfYXR0YWNoZWQgPSBTdXJmLT5uZXh0X2F0dGFjaGVkOwogICAgU3VyZi0+bmV4dF9hdHRhY2hlZCA9IE5VTEw7CiAgICBTdXJmLT5maXJzdF9hdHRhY2hlZCA9IFN1cmY7CgogICAgLyogQ2hlY2sgaWYgdGhlIFdpbmVEM0QgZGVwdGggc3RlbmNpbCBuZWVkcyB1cGRhdGluZyAqLwogICAgaWYoVGhpcy0+ZGRyYXctPmQzZGRldmljZSkKICAgIHsKICAgICAgICBJRGlyZWN0M0REZXZpY2VJbXBsX1VwZGF0ZURlcHRoU3RlbmNpbChUaGlzLT5kZHJhdy0+ZDNkZGV2aWNlKTsKICAgIH0KCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoQXR0YWNoKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpBZGRPdmVybGF5RGlydHlSZWN0CiAqCiAqICJUaGlzIG1ldGhvZCBpcyBub3QgY3VycmVudGx5IGltcGxlbWVudGVkIgogKgogKiBQYXJhbXM6CiAqICBSZWN0OiA/CiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9VTlNVUFBPUlRFRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZE92ZXJsYXlEaXJ0eVJlY3QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJFQ1QgUmVjdCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxSZWN0KTsKCiAgICAvKiBNU0ROIHNheXMgaXQncyBub3QgaW1wbGVtZW50ZWQuIEkgY291bGQgZm9yd2FyZCBpdCB0byBXaW5lRDNELCAKICAgICAqIHRoZW4gd2UnZCBpbXBsZW1lbnQgaXQsIGJ1dCBJIGRvbid0IHRoaW5rIHRoYXQncyBhIGdvb2QgaWRlYQogICAgICogKFN0ZWZhbiBE9nNpbmdlcikKICAgICAqLwojaWYgMAogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9BZGRPdmVybGF5RGlydHlSZWN0KFRoaXMtPldpbmVEM0RTdXJmYWNlLCBwUmVjdCk7CiNlbmRpZgogICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOyAvKiB1bmNoZWNrZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldERDCiAqCiAqIFJldHVybnMgYSBHREkgZGV2aWNlIGNvbnRleHQgZm9yIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIGhkYzogQWRkcmVzcyBvZiBhIEhEQyB2YXJpYWJsZSB0byBzdG9yZSB0aGUgZGMgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgaGRjIGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXREQwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldERDKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhEQyAqaGRjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBoZGMpOwoKICAgIGlmKCFoZGMpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERDKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGRjKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlREMKICoKICogUmVsZWFzZXMgdGhlIERDIHRoYXQgd2FzIGNvbnN0cnVjdGVkIHdpdGggR2V0REMKICoKICogUGFyYW1zOgogKiAgaGRjOiBIREMgdG8gcmVsZWFzZQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6UmVsZWFzZURDCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfUmVsZWFzZURDKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIREMgaGRjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBoZGMpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlREMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIGhkYyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0Q2FwcwogKgogKiBSZXR1cm5zIHRoZSBzdXJmYWNlJ3MgY2FwcwogKgogKiBQYXJhbXM6CiAqICBDYXBzOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBjYXBzIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhcHMgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldENhcHMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTMiAqQ2FwcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxDYXBzKTsKCiAgICBpZighQ2FwcykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAqQ2FwcyA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0UHJpb3JpdHkKICoKICogU2V0cyBhIHRleHR1cmUgcHJpb3JpdHkgZm9yIG1hbmFnZWQgdGV4dHVyZXMuCiAqCiAqIFBhcmFtczoKICogIFByaW9yaXR5OiBUaGUgbmV3IHByaW9yaXR5CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpTZXRQcmlvcml0eQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFByaW9yaXR5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLCBEV09SRCBQcmlvcml0eSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJWQpOiBSZWxheSFcbiIsVGhpcyxQcmlvcml0eSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldFByaW9yaXR5KFRoaXMtPldpbmVEM0RTdXJmYWNlLCBQcmlvcml0eSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0UHJpb3JpdHkKICoKICogUmV0dXJucyB0aGUgc3VyZmFjZSdzIHByaW9yaXR5CiAqCiAqIFBhcmFtczoKICogIFByaW9yaXR5OiBBZGRyZXNzIG9mIGEgdmFyaWFibGUgdG8gd3JpdGUgdGhlIHByaW9yaXR5IHRvCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQcmlvcml0eSA9PSBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXRQcmlvcml0eQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFByaW9yaXR5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpQcmlvcml0eSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLFRoaXMsUHJpb3JpdHkpOwoKICAgIGlmKCFQcmlvcml0eSkKICAgIHsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgKlByaW9yaXR5ID0gSVdpbmVEM0RTdXJmYWNlX0dldFByaW9yaXR5KFRoaXMtPldpbmVEM0RTdXJmYWNlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRQcml2YXRlRGF0YQogKgogKiBTdG9yZXMgc29tZSBkYXRhIGluIHRoZSBzdXJmYWNlIHRoYXQgaXMgaW50ZW5kZWQgZm9yIHRoZSBhcHBsaWNhdGlvbidzCiAqIHVzZS4KICoKICogUGFyYW1zOgogKiAgdGFnOiBHVUlEIHRoYXQgaWRlbnRpZmllcyB0aGUgZGF0YQogKiAgRGF0YTogUG9pbnRlciB0byB0aGUgcHJpdmF0ZSBkYXRhCiAqICBTaXplOiBTaXplIG9mIHRoZSBwcml2YXRlIGRhdGEKICogIEZsYWdzOiBTb21lIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6U2V0UHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwLCVkLCV4KTogUmVsYXlcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQodGFnKSwgRGF0YSwgU2l6ZSwgRmxhZ3MpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRQcml2YXRlRGF0YShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRQcml2YXRlRGF0YQogKgogKiBSZXR1cm5zIHRoZSBwcml2YXRlIGRhdGEgc2V0IHdpdGggSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0UHJpdmF0ZURhdGEKICoKICogUGFyYW1zOgogKiAgdGFnOiBHVUlEIG9mIHRoZSBkYXRhIHRvIHJldHVybgogKiAgRGF0YTogQWRkcmVzcyB3aGVyZSB0byB3cml0ZSB0aGUgZGF0YSB0bwogKiAgU2l6ZTogU2l6ZSBvZiB0aGUgYnVmZmVyIGF0IERhdGEKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRGF0YSBpcyBOVUxMCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXRQcml2YXRlRGF0YQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRkdVSUQgdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlNpemUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwLCVwKTogUmVsYXlcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQodGFnKSwgRGF0YSwgU2l6ZSk7CgogICAgaWYoIURhdGEpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldFByaXZhdGVEYXRhKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpemUpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkZyZWVQcml2YXRlRGF0YQogKgogKiBGcmVlcyBwcml2YXRlIGRhdGEgc3RvcmVkIGluIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHRhZzogVGFnIG9mIHRoZSBkYXRhIHRvIGZyZWUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpGcmVlUHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRkdVSUQgdGFnKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcyk6IFJlbGF5XG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHRhZykpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9GcmVlUHJpdmF0ZURhdGEoVGhpcy0+V2luZUQzRFN1cmZhY2UsIHRhZyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UGFnZUxvY2sKICoKICogUHJldmVudHMgYSBzeXNtZW0gc3VyZmFjZSBmcm9tIGJlaW5nIHBhZ2VkIG91dAogKgogKiBQYXJhbXM6CiAqICBGbGFnczogTm90IHVzZWQsIG11c3QgYmUgMCh1bmNoZWNrZWQpCiAqCiAqIFJldHVybnM6CiAqICBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1BhZ2VMb2NrKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgaWZhY2UsIEZsYWdzKTsKCiAgICAvKiBUaGlzIGlzIFdpbmRvd3MgbWVtb3J5IG1hbmFnZW1lbnQgcmVsYXRlZCAtIHdlIGRvbid0IG5lZWQgdGhpcyAqLwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UGFnZVVubG9jawogKgogKiBBbGxvd3MgYSBzeXNtZW0gc3VyZmFjZSB0byBiZSBwYWdlZCBvdXQKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IE5vdCB1c2VkLCBtdXN0IGJlIDAodW5jaGVja2VkKQogKgogKiBSZXR1cm5zOgogKiAgRERfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9QYWdlVW5sb2NrKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIFRSQUNFKCIoJXApLT4oJXgpXG4iLCBpZmFjZSwgRmxhZ3MpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkJsdEJhdGNoCiAqCiAqIEFuIHVuaW1wbGVtZW50ZWQgZnVuY3Rpb24KICoKICogUGFyYW1zOgogKiAgPwogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfVU5TVVBQT1JURUQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHRCYXRjaChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwgRERCTFRCQVRDSCAqQmF0Y2gsIERXT1JEIENvdW50LCBEV09SRCBGbGFncykKewogICAgVFJBQ0UoIiglcCktPiglcCwlZCwlMDh4KVxuIixpZmFjZSxCYXRjaCxDb3VudCxGbGFncyk7CgogICAgLyogTVNETjogIm5vdCBjdXJyZW50bHkgaW1wbGVtZW50ZWQiICovCiAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpFbnVtQXR0YWNoZWRTdXJmYWNlcwogKgogKiBFbnVtZXJhdGVzIGFsbCBzdXJmYWNlcyBhdHRhY2hlZCB0byB0aGlzIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgY29udGV4dDogUG9pbnRlciB0byBwYXNzIHVubW9kaWZpZWQgdG8gdGhlIGNhbGxiYWNrCiAqICBjYjogQ2FsbGJhY2sgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIGNiIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9FbnVtQXR0YWNoZWRTdXJmYWNlcyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNU1VSRkFDRVNDQUxMQkFDSzcgY2IpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICBERFNVUkZBQ0VERVNDMiBkZXNjOwogICAgaW50IGk7CgogICAgLyogQXR0YWNoZWQgc3VyZmFjZXMgYXJlbid0IGhhbmRsZWQgaW4gV2luZUQzRCAqLwogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsVGhpcyxjb250ZXh0LGNiKTsKCiAgICBpZighY2IpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICB7CiAgICAgICAgc3VyZiA9IFRoaXMtPmNvbXBsZXhfYXJyYXlbaV07CiAgICAgICAgaWYoIXN1cmYpIGJyZWFrOwoKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgZGVzYyA9IHN1cmYtPnN1cmZhY2VfZGVzYzsKICAgICAgICAvKiBjaGVjazogIT0gRERFTlVNUkVUX09LIG9yID09IERERU5VTVJFVF9DQU5DRUw/ICovCiAgICAgICAgaWYgKGNiKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGVzYywgY29udGV4dCkgPT0gRERFTlVNUkVUX0NBTkNFTCkKICAgICAgICB7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChzdXJmID0gVGhpcy0+bmV4dF9hdHRhY2hlZDsgc3VyZiAhPSBOVUxMOyBzdXJmID0gc3VyZi0+bmV4dF9hdHRhY2hlZCkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgZGVzYyA9IHN1cmYtPnN1cmZhY2VfZGVzYzsKICAgICAgICAvKiBjaGVjazogIT0gRERFTlVNUkVUX09LIG9yID09IERERU5VTVJFVF9DQU5DRUw/ICovCiAgICAgICAgaWYgKGNiKCBJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRlc2MsIGNvbnRleHQpID09IERERU5VTVJFVF9DQU5DRUwpCiAgICAgICAgewogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCIgZW5kIG9mIGVudW1lcmF0aW9uLlxuIik7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkVudW1PdmVybGF5Wk9yZGVycwogKgogKiAiRW51bWVyYXRlcyB0aGUgb3ZlcmxheSBzdXJmYWNlcyBvbiB0aGUgc3BlY2lmaWVkIGRlc3RpbmF0aW9uIgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERFTlVNT1ZFUkxBWVpfQkFDS1RPRlJPTlQgIG9yIERERU5VTU9WRVJMQVlaX0ZST05UVE9CQUNLCiAqICBjb250ZXh0OiBjb250ZXh0IHRvIHBhc3MgYmFjayB0byB0aGUgY2FsbGJhY2sKICogIGNiOiBjYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGVudW1lcmF0ZWQgc3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9FbnVtT3ZlcmxheVpPcmRlcnMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERERU5VTVNVUkZBQ0VTQ0FMTEJBQ0s3IGNiKQp7CiAgICAgRklYTUUoIiglcCktPigleCwlcCwlcCk6IFN0dWIhXG4iLCBpZmFjZSwgRmxhZ3MsIGNvbnRleHQsIGNiKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRCbHRTdGF0dXMKICoKICogUmV0dXJucyB0aGUgYmxpdHRpbmcgc3RhdHVzCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBEREdCU19DQU5CTFQgb3IgRERHQlNfSVNCTFRET05FCiAqCiAqIFJldHVybnM6CiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpCbHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPigleCk6IFJlbGF5XG4iLCBUaGlzLCBGbGFncyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldEJsdFN0YXR1cyhUaGlzLT5XaW5lRDNEU3VyZmFjZSwgRmxhZ3MpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRDb2xvcktleQogKgogKiBSZXR1cm5zIHRoZSBjb2xvciBrZXkgYXNzaWduZWQgdG8gdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICogIENLZXk6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGtleSB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDS2V5IGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDb2xvcktleShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENPTE9SS0VZICpDS2V5KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLCBGbGFncywgQ0tleSk7CgogICAgaWYoIUNLZXkpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICBzd2l0Y2ggKEZsYWdzKQogICAgewogICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICBpZiAoIShUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmIEREU0RfQ0tERVNUQkxUKSkKICAgICAgICB7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9OT0NPTE9SS0VZOwogICAgICAgIH0KICAgICAgICAqQ0tleSA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tEZXN0Qmx0OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICYgRERTRF9DS0RFU1RPVkVSTEFZKSkKICAgICAgICAgICAgewogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfTk9DT0xPUktFWTsKICAgICAgICAgICAgfQogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLnUzLmRkY2tDS0Rlc3RPdmVybGF5OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRERDS0VZX1NSQ0JMVDoKICAgICAgICBpZiAoIShUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmIEREU0RfQ0tTUkNCTFQpKQogICAgICAgIHsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX05PQ09MT1JLRVk7CiAgICAgICAgfQogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY0JsdDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICYgRERTRF9DS1NSQ09WRVJMQVkpKQogICAgICAgIHsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX05PQ09MT1JLRVk7CiAgICAgICAgfQogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY092ZXJsYXk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRGbGlwU3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIGZsaXBwaW5nIHN0YXR1cyBvZiB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERHRlNfQ0FORkxJUCBvZiBEREdGU19JU0ZMSVBET05FCiAqCiAqIFJldHVybnM6CiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXRGbGlwU3RhdHVzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPigleCk6IFJlbGF5XG4iLCBUaGlzLCBGbGFncyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldEZsaXBTdGF0dXMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIEZsYWdzKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0T3ZlcmxheVBvc2l0aW9uCiAqCiAqIFJldHVybnMgdGhlIGRpc3BsYXkgY29vcmRpbmF0ZXMgb2YgYSB2aXNpYmxlIGFuZCBhY3RpdmUgb3ZlcmxheSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFgKICogIFkKICoKICogUmV0dXJuczoKICogIERERVJSX05PVEFPVkVSTEFZU1VSRkFDRSwgYmVjYXVzZSBpdCdzIGEgc3R1YgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyAqWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyAqWSkgewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApOiBSZWxheVxuIiwgVGhpcywgWCwgWSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldE92ZXJsYXlQb3NpdGlvbihUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldFBpeGVsRm9ybWF0CiAqCiAqIFJldHVybnMgdGhlIHBpeGVsIGZvcm1hdCBvZiB0aGUgU3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBQaXhlbEZvcm1hdDogUG9pbnRlciB0byBhIEREUElYRUxGT1JNQVQgc3RydWN0dXJlIHRvIHdoaWNoIHRoZSBwaXhlbAogKiAgICAgICAgICAgICAgIGZvcm1hdCBzaG91bGQgYmUgd3JpdHRlbgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQaXhlbEZvcm1hdCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UGl4ZWxGb3JtYXQoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERQSVhFTEZPUk1BVCAqUGl4ZWxGb3JtYXQpCnsKICAgIC8qIFdoYXQgaXMgRERFUlJfSU5WQUxJRFNVUkZBQ0VUWVBFIGZvciBoZXJlPyAqLwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxQaXhlbEZvcm1hdCk7CgogICAgaWYoIVBpeGVsRm9ybWF0KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoUGl4ZWxGb3JtYXQsJlRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0U3VyZmFjZURlc2MKICoKICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhpcyBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IEFkZHJlc3Mgb2YgYSBERFNVUkZBQ0VERVNDMiBzdHJ1Y3R1cmUgdGhhdCBpcyB0byBiZSBmaWxsZWQgd2l0aCB0aGUKICogICAgICAgIHN1cmZhY2UgZGVzYwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBERFNEIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRTdXJmYWNlRGVzYyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsRERTRCk7CgogICAgaWYoIUREU0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgaWYgKEREU0QtPmR3U2l6ZSAhPSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgewogICAgICAgIFdBUk4oIkluY29ycmVjdCBzdHJ1Y3Qgc2l6ZSAlZCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIsRERTRC0+ZHdTaXplKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKEREU0QsJlRoaXMtPnN1cmZhY2VfZGVzYyk7CiAgICBUUkFDRSgiUmV0dXJuaW5nIHN1cmZhY2UgZGVzYzpcbiIpOwogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MoRERTRCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkluaXRpYWxpemUKICoKICogSW5pdGlhbGl6ZXMgdGhlIHN1cmZhY2UuIFRoaXMgaXMgYSBuby1vcCBpbiBXaW5lCiAqCiAqIFBhcmFtczoKICogIEREOiBQb2ludGVyIHRvIGFuIERpcmVjdERyYXcgaW50ZXJmYWNlCiAqICBERFNEOiBTdXJmYWNlIGRlc2NyaXB0aW9uIGZvciBpbml0aWFsaXphdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfSW5pdGlhbGl6ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICpERCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd0ltcGwgKmRkaW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXcsIEREKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLFRoaXMsZGRpbXBsLEREU0QpOwoKICAgIHJldHVybiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpJc0xvc3QKICoKICogQ2hlY2tzIGlmIHRoZSBzdXJmYWNlIGlzIGxvc3QKICoKICogUmV0dXJuczoKICogIEREX09LLCBpZiB0aGUgc3VyZmFjZSBpcyB1c2FibGUKICogIERERVJSX0lTTE9TVCBpZiB0aGUgc3VyZmFjZSBpcyBsb3N0CiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpJc0xvc3QgZm9yIG1vcmUgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0lzTG9zdChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogV2UgbG9zZSB0aGUgc3VyZmFjZSBpZiB0aGUgaW1wbGVtZW50YXRpb24gd2FzIGNoYW5nZWQgKi8KICAgIGlmKFRoaXMtPkltcGxUeXBlICE9IFRoaXMtPmRkcmF3LT5JbXBsVHlwZSkKICAgIHsKICAgICAgICAvKiBCdXQgdGhpcyBzaG91bGRuJ3QgaGFwcGVuLiBXaGVuIHdlIGNoYW5nZSB0aGUgaW1wbGVtZW50YXRpb24sCiAgICAgICAgICogYWxsIHN1cmZhY2VzIGFyZSByZS1jcmVhdGVkIGF1dG9tYXRpY2FsbHksIGFuZCB0aGVpciBjb250ZW50CiAgICAgICAgICogaXMgY29waWVkCiAgICAgICAgICovCiAgICAgICAgRVJSKCIgKCVwKSBJbXBsZW1lbnRhdGlvbiB3YXMgY2hhbmdlZCBmcm9tICVkIHRvICVkXG4iLCBUaGlzLCBUaGlzLT5JbXBsVHlwZSwgVGhpcy0+ZGRyYXctPkltcGxUeXBlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9TVVJGQUNFTE9TVDsKICAgIH0KCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9Jc0xvc3QoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICAvKiBEM0Q4IGFuZCA5IGxvb3NlIGZ1bGwgZGV2aWNlcywgdGh1cyB0aGVyZSdzIG9ubHkgYSBERVZJQ0VMT1NUIGVycm9yLgogICAgICAgICAqIFdpbmVEM0QgdXNlcyB0aGUgc2FtZSBlcnJvciBmb3Igc3VyZmFjZXMKICAgICAgICAgKi8KICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDogICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUxPU1Q7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UmVzdG9yZQogKgogKiBSZXN0b3JlcyBhIGxvc3Qgc3VyZmFjZS4gVGhpcyBtYWtlcyB0aGUgc3VyZmFjZSB1c2FibGUgYWdhaW4sIGJ1dAogKiBkb2Vzbid0IHJlbG9hZCBpdHMgb2xkIGNvbnRlbnRzCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpSZXN0b3JlIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZXN0b3JlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZihUaGlzLT5JbXBsVHlwZSAhPSBUaGlzLT5kZHJhdy0+SW1wbFR5cGUpCiAgICB7CiAgICAgICAgLyogQ2FsbCB0aGUgcmVjcmVhdGlvbiBjYWxsYmFjay4gTWFrZSBzdXJlIHRvIEFkZFJlZiBmaXJzdCAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9BZGRSZWYoaWZhY2UpOwogICAgICAgIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2soaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmVGhpcy0+c3VyZmFjZV9kZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBOb3QgbmVlZGVkICovKTsKICAgIH0KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1Jlc3RvcmUoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldE92ZXJsYXlQb3NpdGlvbgogKgogKiBDaGFuZ2VzIHRoZSBkaXNwbGF5IGNvb3JkaW5hdGVzIG9mIGFuIG92ZXJsYXkgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBYOgogKiAgWToKICoKICogUmV0dXJuczoKICogICBEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0UsIGJlY2F1c2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cyByaWdodCBub3cKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRPdmVybGF5UG9zaXRpb24oSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPTkcgWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBZKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCk6IFJlbGF5XG4iLCBUaGlzLCBYLCBZKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0T3ZlcmxheVBvc2l0aW9uKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6VXBkYXRlT3ZlcmxheQogKgogKiBNb2RpZmllcyB0aGUgYXR0cmlidXRlcyBvZiBhbiBvdmVybGF5IHN1cmZhY2UuCiAqCiAqIFBhcmFtczoKICogIFNyY1JlY3Q6IFRoZSBzZWN0aW9uIG9mIHRoZSBzb3VyY2UgYmVpbmcgdXNlZCBmb3IgdGhlIG92ZXJsYXkKICogIERzdFN1cmZhY2U6IEFkZHJlc3Mgb2YgdGhlIHN1cmZhY2UgdGhhdCBpcyBvdmVybGFpZAogKiAgRHN0UmVjdDogUGxhY2Ugb2YgdGhlIG92ZXJsYXkKICogIEZsYWdzOiBzb21lIERET1ZFUl8qIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9VTlNVUFBPUlRFRCwgYmVjYXVzZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUkVDVCBTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqRHN0U3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUkVDVCBEc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERET1ZFUkxBWUZYIEZYKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpEc3QgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBEc3RTdXJmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCV4LCVwKTogUmVsYXlcbiIsIFRoaXMsIFNyY1JlY3QsIERzdCwgRHN0UmVjdCwgRmxhZ3MsIEZYKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfVXBkYXRlT3ZlcmxheShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRHN0ID8gRHN0LT5XaW5lRDNEU3VyZmFjZSA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORURET1ZFUkxBWUZYICopIEZYKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBzd2l0Y2goaHIpIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICBjYXNlIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U6ICByZXR1cm4gRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFOwogICAgICAgIGNhc2UgV0lORURERVJSX09WRVJMQVlOT1RWSVNJQkxFOiAgIHJldHVybiBEREVSUl9PVkVSTEFZTk9UVklTSUJMRTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpVcGRhdGVPdmVybGF5RGlzcGxheQogKgogKiBUaGUgRFg3IHNkayBzYXlzIHRoYXQgaXQncyBub3QgaW1wbGVtZW50ZWQKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6ID8KICoKICogUmV0dXJuczogRERFUlJfVU5TVVBQT1JURUQsIGJlY2F1c2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlEaXNwbGF5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwogICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6VXBkYXRlT3ZlcmxheVpPcmRlcgogKgogKiBTZXRzIGFuIG92ZXJsYXkncyBaIG9yZGVyCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBERE9WRVJaXyogZmxhZ3MKICogIEREU1JlZjogRGVmaW5lcyB0aGUgcmVsYXRpdmUgcG9zaXRpb24gaW4gdGhlIG92ZXJsYXkgY2hhaW4KICoKICogUmV0dXJuczoKICogIERERVJSX05PVE9WRVJMQVlTVVJGQUNFLCBiZWNhdXNlIHdlIGRvbid0IHN1cHBvcnQgb3ZlcmxheXMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpERFNSZWYpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpSZWYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBERFNSZWYpOwoKICAgIFRSQUNFKCIoJXApLT4oJXgsJXApOiBSZWxheVxuIiwgVGhpcywgRmxhZ3MsIFJlZik7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSAgSVdpbmVEM0RTdXJmYWNlX1VwZGF0ZU92ZXJsYXlaT3JkZXIoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZiA/IFJlZi0+V2luZUQzRFN1cmZhY2UgOiBOVUxMKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXREREludGVyZmFjZQogKgogKiBSZXR1cm5zIHRoZSBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlIHBvaW50ZXIgb2YgdGhlIERpcmVjdERyYXcgb2JqZWN0IHRoaXMKICogc3VyZmFjZSBiZWxvbmdzIHRvCiAqCiAqIFBhcmFtczoKICogIEREOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBERCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0RERJbnRlcmZhY2UoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKkREKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxERCk7CgogICAgaWYoIUREKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIHN3aXRjaChUaGlzLT52ZXJzaW9uKQogICAgewogICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgKigoSURpcmVjdERyYXc3ICoqKSBERCkgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXc3KTsKICAgICAgICAgICAgSURpcmVjdERyYXc3X0FkZFJlZigqKElEaXJlY3REcmF3NyAqKikgREQpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAqKChJRGlyZWN0RHJhdzQgKiopIEREKSA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdzQpOwogICAgICAgICAgICBJRGlyZWN0RHJhdzRfQWRkUmVmKCooSURpcmVjdERyYXc0ICoqKSBERCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICooKElEaXJlY3REcmF3MiAqKikgREQpID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3Mik7CiAgICAgICAgICAgIElEaXJlY3REcmF3X0FkZFJlZiggKihJRGlyZWN0RHJhdzIgKiopIEREKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgKigoSURpcmVjdERyYXcgKiopIEREKSA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdyk7CiAgICAgICAgICAgIElEaXJlY3REcmF3X0FkZFJlZiggKihJRGlyZWN0RHJhdyAqKikgREQpOwogICAgICAgICAgICBicmVhazsKCiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKiBUaGlzIHNlZW1zIGFsc28gd2luZG93cyBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyAtIEkgZG9uJ3QgdGhpbmsgV2luZUQzRCBuZWVkcyB0aGlzICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0NoYW5nZVVuaXF1ZW5lc3NWYWx1ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgdm9sYXRpbGUgSURpcmVjdERyYXdTdXJmYWNlSW1wbCogdlRoaXMgPSBUaGlzOwoKICAgIFRSQUNFKCIoJXApXG4iLFRoaXMpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIEEgdW5pcXVlbmVzcyB2YWx1ZSBvZiAwIGlzIGFwcGFyZW50bHkgc3BlY2lhbC4KICAgICAqIFRoaXMgbmVlZHMgdG8gYmUgY2hlY2tlZC4KICAgICAqIFRPRE86IFdyaXRlIHRlc3RzIGZvciB0aGlzIGNvZGUgYW5kIGNoZWNrIGlmIHRoZSB2b2xhdGlsZSwgaW50ZXJsb2NrZWQgc3R1ZmYgaXMgcmVhbGx5IG5lZWRlZAogICAgICovCiAgICB3aGlsZSAoMSkgewogICAgICAgIERXT1JEIG9sZF91bmlxdWVuZXNzX3ZhbHVlID0gdlRoaXMtPnVuaXF1ZW5lc3NfdmFsdWU7CiAgICAgICAgRFdPUkQgbmV3X3VuaXF1ZW5lc3NfdmFsdWUgPSBvbGRfdW5pcXVlbmVzc192YWx1ZSsxOwoKICAgICAgICBpZiAob2xkX3VuaXF1ZW5lc3NfdmFsdWUgPT0gMCkgYnJlYWs7CiAgICAgICAgaWYgKG5ld191bmlxdWVuZXNzX3ZhbHVlID09IDApIG5ld191bmlxdWVuZXNzX3ZhbHVlID0gMTsKCiAgICAgICAgaWYgKEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlKChMT05HKikmdlRoaXMtPnVuaXF1ZW5lc3NfdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkX3VuaXF1ZW5lc3NfdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3X3VuaXF1ZW5lc3NfdmFsdWUpCiAgICAgICAgICAgID09IG9sZF91bmlxdWVuZXNzX3ZhbHVlKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRVbmlxdWVuZXNzVmFsdWUoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsIExQRFdPUkQgcFZhbHVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxwVmFsdWUpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICpwVmFsdWUgPSBUaGlzLT51bmlxdWVuZXNzX3ZhbHVlOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldExPRAogKgogKiBTZXRzIHRoZSBsZXZlbCBvZiBkZXRhaWwgb2YgYSB0ZXh0dXJlCiAqCiAqIFBhcmFtczoKICogIE1heExPRDogTE9EIHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRE9CSkVDVCBpZiB0aGUgc3VyZmFjZSBpcyBpbnZhbGlkIGZvciB0aGlzIG1ldGhvZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldExPRChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTWF4TE9EKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZClcbiIsIFRoaXMsIE1heExPRCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9URVhUVVJFTUFOQUdFKSkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElET0JKRUNUOwogICAgfQoKICAgIGlmKCFUaGlzLT53aW5lRDNEVGV4dHVyZSkKICAgIHsKICAgICAgICBFUlIoIiglcCkgVGhlIERpcmVjdERyYXcgdGV4dHVyZSBoYXMgbm8gV2luZUQzRFRleHR1cmUhXG4iLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElET0JKRUNUOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXRMT0QoVGhpcy0+d2luZUQzRFRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heExPRCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0TE9ECiAqCiAqIFJldHVybnMgdGhlIGxldmVsIG9mIGRldGFpbCBvZiBhIERpcmVjdDNEIHRleHR1cmUKICoKICogUGFyYW1zOgogKiAgTWF4TE9EOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBMT0QgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgTWF4TE9EIGlzIE5VTEwKICogIERERVJSX0lOVkFMSURPQkpFQ1QgaWYgdGhlIHN1cmZhY2UgaXMgaW52YWxpZCBmb3IgdGhpcyBtZXRob2QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRMT0QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpNYXhMT0QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBNYXhMT0QpOwoKICAgIGlmKCFNYXhMT0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9URVhUVVJFTUFOQUdFKSkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElET0JKRUNUOwogICAgfQoKICAgICpNYXhMT0QgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExPRChUaGlzLT53aW5lRDNEVGV4dHVyZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6Qmx0RmFzdAogKgogKiBQZXJmb3JtcyBhIGZhc3QgQmxpdC4KICoKICogUGFyYW1zOgogKiAgZHN0eDogVGhlIHggY29vcmRpbmF0ZSB0byBibGl0IHRvIG9uIHRoZSBkZXN0aW5hdGlvbgogKiAgZHN0eTogVGhlIHkgY29vcmRpbmF0ZSB0byBibGl0IHRvIG9uIHRoZSBkZXN0aW5hdGlvbgogKiAgU291cmNlOiBUaGUgc291cmNlIHN1cmZhY2UKICogIHJzcmM6IFRoZSBzb3VyY2UgcmVjdGFuZ2xlCiAqICB0cmFuczogVHlwZSBvZiB0cmFuc2Zlci4gU29tZSBEREJMVEZBU1RfKiBmbGFncwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6Qmx0RmFzdAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0JsdEZhc3QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKnJzcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCB0cmFucykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNvdXJjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVkLCVkLCVwLCVwLCVkKTogUmVsYXlcbiIsIFRoaXMsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwoKICAgIC8qIFNvdXJjZSBtdXN0IGJlICE9IE5VTEwsIFRoaXMgaXMgbm90IGNoZWNrZWQgYnkgd2luZG93cy4gV2luZG93cyBoYXBwaWx5IHRocm93cyBhIDB4YzAwMDAwMDUKICAgICAqIGluIHRoYXQgY2FzZQogICAgICovCiAgICBpZihyc3JjKQogICAgewogICAgICAgIGlmKHJzcmMtPnRvcCA+IHJzcmMtPmJvdHRvbSB8fCByc3JjLT5sZWZ0ID4gcnNyYy0+cmlnaHQgfHwKICAgICAgICAgICByc3JjLT5yaWdodCA+IHNyYy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICByc3JjLT5ib3R0b20gPiBzcmMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIlNvdXJjZSByZWN0YW5nbGUgaXMgaW52YWxpZCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURSRUNUXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURSRUNUOwogICAgICAgIH0KICAgICAgICBpZihkc3R4ICsgcnNyYy0+cmlnaHQgLSByc3JjLT5sZWZ0ID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICBkc3R5ICsgcnNyYy0+Ym90dG9tIC0gcnNyYy0+dG9wID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiRGVzdGluYXRpb24gYXJlYSBvdXQgb2YgYm91bmRzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFJFQ1RcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmKGRzdHggKyBzcmMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoID4gVGhpcy0+c3VyZmFjZV9kZXNjLmR3V2lkdGggfHwKICAgICAgICAgICBkc3R5ICsgc3JjLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQgPiBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJEZXN0aW5hdGlvbiBhcmVhIG91dCBvZiBib3VuZHMsIHJldHVybmluZyBEREVSUl9JTlZBTElEUkVDVFxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICB9CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0JsdEZhc3QoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdHgsIGRzdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYyA/IHNyYy0+V2luZUQzRFN1cmZhY2UgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFucyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9OT1RBVkFJTEFCTEU6ICAgICAgICAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX1dST05HVEVYVFVSRUZPUk1BVDogICAgIHJldHVybiBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldENsaXBwZXIKICoKICogUmV0dXJucyB0aGUgSURpcmVjdERyYXdDbGlwcGVyIGludGVyZmFjZSBvZiB0aGUgY2xpcHBlciBhc3NpZ25lZCB0byB0aGlzCiAqIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgQ2xpcHBlciBpcyBOVUxMCiAqICBEREVSUl9OT0NMSVBQRVJBVFRBQ0hFRCBpZiB0aGVyZSdzIG5vIGNsaXBwZXIgYXR0YWNoZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDbGlwcGVyKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyICoqQ2xpcHBlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIENsaXBwZXIpOwoKICAgIGlmKCFDbGlwcGVyKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKFRoaXMtPmNsaXBwZXIgPT0gTlVMTCkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9OT0NMSVBQRVJBVFRBQ0hFRDsKICAgIH0KCiAgICAqQ2xpcHBlciA9IElDT01fSU5URVJGQUNFKFRoaXMtPmNsaXBwZXIsIElEaXJlY3REcmF3Q2xpcHBlcik7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXJfQWRkUmVmKCpDbGlwcGVyKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRDbGlwcGVyCiAqCiAqIFNldHMgYSBjbGlwcGVyIGZvciB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBDbGlwcGVyOiBJRGlyZWN0RHJhd0NsaXBwZXIgaW50ZXJmYWNlIG9mIHRoZSBjbGlwcGVyIHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldENsaXBwZXIoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKkNsaXBwZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlckltcGwgKm9sZENsaXBwZXIgPSBUaGlzLT5jbGlwcGVyOwogICAgSFdORCBjbGlwV2luZG93OwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsQ2xpcHBlcik7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmIChJQ09NX09CSkVDVChJRGlyZWN0RHJhd0NsaXBwZXJJbXBsLCBJRGlyZWN0RHJhd0NsaXBwZXIsIENsaXBwZXIpID09IFRoaXMtPmNsaXBwZXIpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERfT0s7CiAgICB9CgogICAgVGhpcy0+Y2xpcHBlciA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3Q2xpcHBlckltcGwsIElEaXJlY3REcmF3Q2xpcHBlciwgQ2xpcHBlcik7CgogICAgaWYgKENsaXBwZXIgIT0gTlVMTCkKICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXJfQWRkUmVmKENsaXBwZXIpOwogICAgaWYob2xkQ2xpcHBlcikKICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXJfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShvbGRDbGlwcGVyLCBJRGlyZWN0RHJhd0NsaXBwZXIpKTsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRDbGlwcGVyKFRoaXMtPldpbmVEM0RTdXJmYWNlLCBUaGlzLT5jbGlwcGVyID8gVGhpcy0+Y2xpcHBlci0+d2luZUQzRENsaXBwZXIgOiBOVUxMKTsKCiAgICBpZihUaGlzLT53aW5lRDNEU3dhcENoYWluKSB7CiAgICAgICAgY2xpcFdpbmRvdyA9IE5VTEw7CiAgICAgICAgaWYoQ2xpcHBlcikgewogICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXJfR2V0SFduZChDbGlwcGVyLCAmY2xpcFdpbmRvdyk7CiAgICAgICAgfQoKICAgICAgICBpZihjbGlwV2luZG93KSB7CiAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1NldERlc3RXaW5kb3dPdmVycmlkZShUaGlzLT53aW5lRDNEU3dhcENoYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcFdpbmRvdyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fU2V0RGVzdFdpbmRvd092ZXJyaWRlKFRoaXMtPndpbmVEM0RTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5kZHJhdy0+ZDNkX3dpbmRvdyk7CiAgICAgICAgfQogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRTdXJmYWNlRGVzYwogKgogKiBTZXRzIHRoZSBzdXJmYWNlIGRlc2NyaXB0aW9uLiBJdCBjYW4gb3ZlcnJpZGUgdGhlIHBpeGVsIGZvcm1hdCwgdGhlIHN1cmZhY2UKICogbWVtb3J5LCAuLi4KICogSXQncyBub3QgcmVhbGx5IHRlc3RlZC4KICoKICogUGFyYW1zOgogKiBERFNEOiBQb2ludGVyIHRvIHRoZSBuZXcgc3VyZmFjZSBkZXNjcmlwdGlvbiB0byBzZXQKICogRmxhZ3M6IFNvbWUgZmxhZ3MKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRERTRCBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0U3VyZmFjZURlc2MoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFdJTkVEM0RGT1JNQVQgbmV3Rm9ybWF0ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXgpXG4iLCBUaGlzLCBERFNELCBGbGFncyk7CgogICAgaWYoIUREU0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkKICAgIHsKICAgICAgICBuZXdGb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwoKICAgICAgICBpZihuZXdGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJSZXF1ZXN0ZWQgdG8gc2V0IGFuIHVua25vd24gcGl4ZWxmb3JtYXRcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgaWYobmV3Rm9ybWF0ICE9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJlRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQpICkKICAgICAgICB7CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldEZvcm1hdChUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm1hdCk7CiAgICAgICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVE9WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVE9WRVJMQVksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmRERTRC0+dTMuZGRja0NLRGVzdE92ZXJsYXkpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVEJMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9ERVNUQkxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJkREU0QtPmRkY2tDS0Rlc3RCbHQpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLU1JDT1ZFUkxBWSkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJkREU0QtPmRkY2tDS1NyY092ZXJsYXkpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLU1JDQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX1NSQ0JMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZERFNELT5kZGNrQ0tTcmNCbHQpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSAmJiBERFNELT5scFN1cmZhY2UpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKFRoaXMtPldpbmVEM0RTdXJmYWNlLCBERFNELT5scFN1cmZhY2UpOwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBuZWVkIGZvciBhIHRyYWNlIGhlcmUsIHdpbmVkM2QgZG9lcyB0aGF0IGZvciB1cyAqLwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICBzd2l0Y2goaHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzREVSUl9JTlZBTElEQ0FMTDogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgICAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8qIEdvIG9uICovCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQoKICAgIFRoaXMtPnN1cmZhY2VfZGVzYyA9ICpERFNEOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRQYWxldHRlCiAqCiAqIFJldHVybnMgdGhlIElEaXJlY3REcmF3UGFsZXR0ZSBpbnRlcmZhY2Ugb2YgdGhlIHBhbGV0dGUgY3VycmVudGx5IGFzc2lnbmVkCiAqIHRvIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFBhbDogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgUGFsIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQYWxldHRlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdQYWxldHRlICoqUGFsKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJV2luZUQzRFBhbGV0dGUgKndQYWw7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBQYWwpOwoKICAgIGlmKCFQYWwpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldFBhbGV0dGUoVGhpcy0+V2luZUQzRFN1cmZhY2UsICZ3UGFsKTsKICAgIGlmKGhyICE9IEREX09LKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmKHdQYWwpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFBhbGV0dGVfR2V0UGFyZW50KHdQYWwsIChJVW5rbm93biAqKikgUGFsKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAqUGFsID0gTlVMTDsKICAgICAgICBociA9IERERVJSX05PUEFMRVRURUFUVEFDSEVEOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXRDb2xvcktleUVudW0KICoKICogRW51bUF0dGFjaGVkU3VyZmFjZSBjYWxsYmFjayBmb3IgU2V0Q29sb3JLZXkuIFVzZWQgdG8gc2V0IGNvbG9yIGtleXMKICogcmVjdXJzaXZlbHkgaW4gdGhlIHN1cmZhY2UgdHJlZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0cnVjdCBTQ0tDb250ZXh0CnsKICAgIEhSRVNVTFQgcmV0OwogICAgV0lORUREQ09MT1JLRVkgKkNLZXk7CiAgICBEV09SRCBGbGFnczsKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpTZXRDb2xvcktleUVudW0oSURpcmVjdERyYXdTdXJmYWNlNyAqc3VyZmFjZSwKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpkZXNjLAogICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgc3VyZmFjZSk7CiAgICBzdHJ1Y3QgU0NLQ29udGV4dCAqY3R4ID0gY29udGV4dDsKICAgIEhSRVNVTFQgaHI7CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgtPkZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LT5DS2V5KTsKICAgIGlmKGhyICE9IEREX09LKQogICAgewogICAgICAgIFdBUk4oIklXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIGN0eC0+cmV0ID0gaHI7CiAgICB9CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19FbnVtQXR0YWNoZWRTdXJmYWNlcyhzdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRDb2xvcktleUVudW0pOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmZhY2UpOwogICAgcmV0dXJuIERERU5VTVJFVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldENvbG9yS2V5CiAqCiAqIFNldHMgdGhlIGNvbG9yIGtleWluZyBvcHRpb25zIGZvciB0aGUgc3VyZmFjZS4gT2JzZXJ2YXRpb25zIHNob3dlZCB0aGF0CiAqIGluIGNhc2Ugb2YgY29tcGxleCBzdXJmYWNlcyB0aGUgY29sb3Iga2V5IGhhcyB0byBiZSBhc3NpZ25lZCB0byBhbGwKICogc3VibGV2ZWxzLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERDS0VZXyoKICogIENLZXk6IFRoZSBuZXcgY29sb3Iga2V5CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpTZXRDb2xvcktleSBmb3IgZGV0YWlscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldENvbG9yS2V5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ09MT1JLRVkgKkNLZXkpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIHN0cnVjdCBTQ0tDb250ZXh0IGN0eCA9IHsgRERfT0ssIChXSU5FRERDT0xPUktFWSAqKSBDS2V5LCBGbGFncyB9OwogICAgVFJBQ0UoIiglcCktPigleCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDS2V5KTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKENLZXkpCiAgICB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5ERENLRVlfQ09MT1JTUEFDRSkKICAgICAgICB7CiAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS0Rlc3RCbHQgPSAqQ0tleTsKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLnUzLmRkY2tDS0Rlc3RPdmVybGF5ID0gKkNLZXk7CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tTcmNPdmVybGF5ID0gKkNLZXk7CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZGRja0NLU3JjQmx0ID0gKkNLZXk7CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5ERENLRVlfQ09MT1JTUEFDRSkKICAgICAgICB7CiAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJj0gfkREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICY9IH5ERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmPSB+RERTRF9DS1NSQ09WRVJMQVk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEREQ0tFWV9TUkNCTFQ6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICY9IH5ERFNEX0NLU1JDQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQogICAgY3R4LnJldCA9IElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5DS2V5KTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfRW51bUF0dGFjaGVkU3VyZmFjZXMoaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopICZjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldENvbG9yS2V5RW51bSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKGN0eC5yZXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5yZXQ7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRQYWxldHRlCiAqCiAqIEFzc2lnbnMgYSBEaXJlY3REcmF3UGFsZXR0ZSBvYmplY3QgdG8gdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgUGFsOiBJbnRlcmZhY2UgdG8gdGhlIHBhbGV0dGUgdG8gc2V0CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UGFsZXR0ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqUGFsKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGUgKm9sZFBhbDsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsICpQYWxJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdQYWxldHRlSW1wbCwgSURpcmVjdERyYXdQYWxldHRlLCBQYWwpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBQYWwpOwoKICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQuZHdGbGFncyAmIChERFBGX1BBTEVUVEVJTkRFWEVEMSB8IEREUEZfUEFMRVRURUlOREVYRUQyIHwKICAgICAgICAgICAgRERQRl9QQUxFVFRFSU5ERVhFRDQgfCBERFBGX1BBTEVUVEVJTkRFWEVEOCB8IEREUEZfUEFMRVRURUlOREVYRURUTzgpKSkgewogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICB9CgogICAgLyogRmluZCB0aGUgb2xkIHBhbGV0dGUgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZV9HZXRQYWxldHRlKGlmYWNlLCAmb2xkUGFsKTsKICAgIGlmKGhyICE9IEREX09LICYmIGhyICE9IERERVJSX05PUEFMRVRURUFUVEFDSEVEKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgaWYob2xkUGFsKSBJRGlyZWN0RHJhd1BhbGV0dGVfUmVsZWFzZShvbGRQYWwpOyAgLyogRm9yIHRoZSBHZXRQYWxldHRlICovCgogICAgLyogU2V0IHRoZSBuZXcgUGFsZXR0ZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1NldFBhbGV0dGUoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYWxJbXBsID8gUGFsSW1wbC0+d2luZUQzRFBhbGV0dGUgOiBOVUxMKTsKICAgIC8qIEFkZFJlZiB0aGUgUGFsZXR0ZSAqLwogICAgaWYoUGFsKSBJRGlyZWN0RHJhd1BhbGV0dGVfQWRkUmVmKFBhbCk7CgogICAgLyogUmVsZWFzZSB0aGUgb2xkIHBhbGV0dGUgKi8KICAgIGlmKG9sZFBhbCkgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2Uob2xkUGFsKTsKCiAgICAvKiBJZiB0aGlzIGlzIGEgZnJvbnQgYnVmZmVyLCBhbHNvIHVwZGF0ZSB0aGUgYmFjayBidWZmZXJzCiAgICAgKiBUT0RPOiBIb3cgZG8gdGhpbmdzIHdvcmsgZm9yIHBhbGV0dGl6ZWQgY3ViZSB0ZXh0dXJlcz8KICAgICAqLwogICAgaWYoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19GUk9OVEJVRkZFUikKICAgIHsKICAgICAgICAvKiBGb3IgcHJpbWFyeSBzdXJmYWNlcyB0aGUgdHJlZSBpcyBqdXN0IGEgbGlzdCwgc28gdGhlIHNpbXBsZXIgc2NoZW1lIGZpdHMgdG9vICovCiAgICAgICAgRERTQ0FQUzIgY2FwczIgPSB7IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UsIDAsIDAsIDAgfTsKCiAgICAgICAgc3VyZiA9IFRoaXM7CiAgICAgICAgd2hpbGUoMSkKICAgICAgICB7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmF0dGFjaDsKICAgICAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAgICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2FwczIsICZhdHRhY2gpOwogICAgICAgICAgICBpZihociAhPSBERF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRSQUNFKCJTZXR0aW5nIHBhbGV0dGUgb24gJXBcbiIsIGF0dGFjaCk7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfU2V0UGFsZXR0ZShhdHRhY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYWwpOwogICAgICAgICAgICBzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgYXR0YWNoKTsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGF0dGFjaCk7CiAgICAgICAgfQogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCmNvbnN0IElEaXJlY3REcmF3U3VyZmFjZTdWdGJsIElEaXJlY3REcmF3U3VyZmFjZTdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQWRkUmVmLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0RHJhd1N1cmZhY2UgKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlN0ltcGxfQWRkQXR0YWNoZWRTdXJmYWNlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9BZGRPdmVybGF5RGlydHlSZWN0LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHQsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0JsdEJhdGNoLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHRGYXN0LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZWxldGVBdHRhY2hlZFN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0VudW1BdHRhY2hlZFN1cmZhY2VzLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9FbnVtT3ZlcmxheVpPcmRlcnMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0ZsaXAsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEF0dGFjaGVkU3VyZmFjZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Qmx0U3RhdHVzLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDYXBzLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDbGlwcGVyLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDb2xvcktleSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0REMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbiwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UGFsZXR0ZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UGl4ZWxGb3JtYXQsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFN1cmZhY2VEZXNjLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Jbml0aWFsaXplLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Jc0xvc3QsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0xvY2ssCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0Q2xpcHBlciwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UGFsZXR0ZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfVW5sb2NrLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5RGlzcGxheSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlciwKICAgIC8qKiogSURpcmVjdERyYXdTdXJmYWNlMiAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldERESW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9QYWdlTG9jaywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUGFnZVVubG9jaywKICAgIC8qKiogSURpcmVjdERyYXdTdXJmYWNlMyAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFN1cmZhY2VEZXNjLAogICAgLyoqKiBJRGlyZWN0RHJhd1N1cmZhY2U0ICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFVuaXF1ZW5lc3NWYWx1ZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQ2hhbmdlVW5pcXVlbmVzc1ZhbHVlLAogICAgLyoqKiBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UHJpb3JpdHksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRMT0QsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldExPRAp9Owo=