LyogRGlyZWN0RHJhdyBTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IChjKSAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IChjKSAyMDA2IFN0ZWZhbiBE9nNpbmdlcgogKgogKiBUaGlzIGZpbGUgY29udGFpbnMgdGhlIChpbnRlcm5hbCkgZHJpdmVyIHJlZ2lzdHJhdGlvbiBmdW5jdGlvbnMsCiAqIGRyaXZlciBlbnVtZXJhdGlvbiBBUElzIGFuZCBEaXJlY3REcmF3IGNyZWF0aW9uIGZ1bmN0aW9ucy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIEEgbm9ybWFsIFF1ZXJ5SW50ZXJmYWNlIGltcGxlbWVudGF0aW9uLiBGb3IgUXVlcnlJbnRlcmZhY2UgcnVsZXMKICogc2VlIGRkcmF3LmMsIElEaXJlY3REcmF3Nzo6UXVlcnlJbnRlcmZhY2UuIFRoaXMgbWV0aG9kCiAqIGNhbiBRdWVyeSBJRGlyZWN0RHJhd1N1cmZhY2UgaW50ZXJmYWNlcyBpbiBhbGwgdmVyc2lvbiwgSURpcmVjdDNEVGV4dHVyZQogKiBpbiBhbGwgdmVyc2lvbnMsIHRoZSBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCBpbnRlcmZhY2UgYW5kIGl0IGNhbgogKiBjcmVhdGUgYW4gSURpcmVjdDNERGV2aWNlLiAoVXNlcyBJRGlyZWN0M0Q3OjpDcmVhdGVEZXZpY2UpCiAqCiAqIFBhcmFtczoKICogIHJpaWQ6IFRoZSBpbnRlcmZhY2UgaWQgcXVlcmllZCBmb3IKICogIG9iajogQWRkcmVzcyB0byB3cml0ZSB0aGUgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU19PSyBvbiBzdWNjZXNzCiAqICBFX05PSU5URVJGQUNFIGlmIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlIHdhc24ndCBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKCiAgICAvKiBBY2NvcmRpbmcgdG8gQ09NIGRvY3MsIGlmIHRoZSBRdWVyeUludGVyZmFjZSBmYWlscywgb2JqIHNob3VsZCBiZSBzZXQgdG8gTlVMTCAqLwogICAgKm9iaiA9IE5VTEw7CgogICAgaWYoIXJpaWQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lEaXJlY3REcmF3U3VyZmFjZTcpCiAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0RHJhd1N1cmZhY2U0KSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMykKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlMikKICAgICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdTdXJmYWNlKSApCiAgICB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlMyk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3U3VyZmFjZTMgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UgaWYoIElzRXF1YWxHVUlEKHJpaWQsICZJSURfSURpcmVjdERyYXdHYW1tYUNvbnRyb2wpICkKICAgIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCk7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIElEaXJlY3REcmF3R2FtbWFDb250cm9sIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICBlbHNlIGlmKCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0QzRERFVklDRV9XaW5lRDNEKSB8fAogICAgICAgICAgICAgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JRGlyZWN0M0RIQUxEZXZpY2UpICkKICAgIHsKICAgICAgICBJRGlyZWN0M0REZXZpY2U3ICpkM2Q7CgogICAgICAgIC8qIENhbGwgaW50byBJRGlyZWN0M0Q3IGZvciBjcmVhdGlvbiAqLwogICAgICAgIElEaXJlY3QzRDdfQ3JlYXRlRGV2aWNlKElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0M0Q3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkM2QpOwoKICAgICAgICAqb2JqID0gQ09NX0lOVEVSRkFDRV9DQVNUKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZTcsIElEaXJlY3QzRERldmljZSwgZDNkKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdDNERGV2aWNlIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CgogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgZWxzZSBpZiAoSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEVGV4dHVyZSwgcmlpZCApIHx8CiAgICAgICAgICAgICBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0RUZXh0dXJlMiwgcmlpZCApKQogICAgewogICAgICAgIGlmIChJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0RUZXh0dXJlLCByaWlkICkpCiAgICAgICAgewogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEVGV4dHVyZSk7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEVGV4dHVyZSBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRFRleHR1cmUyKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0RUZXh0dXJlMiBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgSVVua25vd25fQWRkUmVmKCAoSVVua25vd24gKikgKm9iaik7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgRVJSKCJObyBpbnRlcmZhY2VcbiIpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpBZGRSZWYKICoKICogQSBub3JtYWwgYWRkcmVmIGltcGxlbWVudGF0aW9uCiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZFJlZihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50IC0gMSk7CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0Rlc3Ryb3kKICoKICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIElEaXJlY3REcmF3U3VyZmFjZTc6OlJlbGVhc2UKICoKICogRnJlZXMgdGhlIHN1cmZhY2UsIHJlZ2FyZGxlc3Mgb2YgaXRzIHJlZmNvdW50LgogKiAgU2VlIElEaXJlY3REcmF3U3VyZmFjZTc6OlJlbGVhc2UgZm9yIG1vcmUgaW5mb3JtYXRpb24KICoKICogUGFyYW1zOgogKiAgVGhpczogU3VyZmFjZSB0byBmcmVlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9EZXN0cm95KElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlRoaXMpCnsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBDaGVjayB0aGUgcmVmY291bnQgYW5kIGdpdmUgYSB3YXJuaW5nICovCiAgICBpZihUaGlzLT5yZWYgPiAxKQogICAgewogICAgICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29tcGxleCBzdXJmYWNlIGlzIGRlc3Ryb3llZCwKICAgICAgICAgKiBiZWNhdXNlIHRoZSAybmQgc3VyZmFjZSB3YXMgYWRkcmVmKCllZCB3aGVuIHRoZSBhcHAKICAgICAgICAgKiBjYWxsZWQgR2V0QXR0YWNoZWRTdXJmYWNlCiAgICAgICAgICovCiAgICAgICAgV0FSTigiKCVwKTogRGVzdHJveWluZyBzdXJmYWNlIHdpdGggcmVmb3VudCAlZFxuIiwgVGhpcywgVGhpcy0+cmVmKTsKICAgIH0KCiAgICAvKiBDaGVjayBmb3IgYXR0YWNoZWQgc3VyZmFjZXMgYW5kIGRldGFjaCB0aGVtICovCiAgICBpZihUaGlzLT5maXJzdF9hdHRhY2hlZCAhPSBUaGlzKQogICAgewogICAgICAgIC8qIFdlbGwsIHRoaXMgc2hvdWxkbid0IGhhcHBlbjogVGhlIHN1cmZhY2UgYmVpbmcgYXR0YWNoZWQgaXMgYWRkcmVmKCllZAogICAgICAgICAgKiBpbiBBZGRBdHRhY2hlZFN1cmZhY2UsIHNvIGl0IHNob3VsZG4ndCBiZSByZWxlYXNlZCB1bnRpbCBEZWxldGVBdHRhY2hlZFN1cmZhY2UKICAgICAgICAgICogaXMgY2FsbGVkLCBiZWNhdXNlIHRoZSByZWZjb3VudCBpcyBoZWxkLiBJdCBsb29rcyBsaWtlIHRoZSBhcHAgcmVsZWFzZWQoKQogICAgICAgICAgKiBpdCBvZnRlbiBlbm91Z2ggdG8gZm9yY2UgdGhpcwogICAgICAgICAgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpyb290ID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+Zmlyc3RfYXR0YWNoZWQsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRldGFjaCA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpOwoKICAgICAgICBGSVhNRSgiKCVwKSBGcmVlaW5nIGEgc3VyZmFjZSB0aGF0IGlzIGF0dGFjaGVkIHRvIHN1cmZhY2UgJXBcbiIsIFRoaXMsIFRoaXMtPmZpcnN0X2F0dGFjaGVkKTsKCiAgICAgICAgLyogVGhlIHJlZmNvdW50IHdpbGwgZHJvcCB0byAtMSBoZXJlICovCiAgICAgICAgaWYoSURpcmVjdERyYXdTdXJmYWNlN19EZWxldGVBdHRhY2hlZFN1cmZhY2Uocm9vdCwgMCwgZGV0YWNoKSAhPSBERF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiKCVwKSBEZWxldGVBdHRhY2hlZFN1cmZhY2UgZmFpbGVkIVxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgfQoKICAgIHdoaWxlKFRoaXMtPm5leHRfYXR0YWNoZWQgIT0gTlVMTCkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpyb290ID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqZGV0YWNoID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+bmV4dF9hdHRhY2hlZCwgSURpcmVjdERyYXdTdXJmYWNlNyk7CgogICAgICAgIGlmKElEaXJlY3REcmF3U3VyZmFjZTdfRGVsZXRlQXR0YWNoZWRTdXJmYWNlKHJvb3QsIDAsIGRldGFjaCkgIT0gRERfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgRGVsZXRlQXR0YWNoZWRTdXJmYWNlIGZhaWxlZCFcbiIsIFRoaXMpOwogICAgICAgICAgICBhc3NlcnQoMCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vdyBkZXN0cm95IHRoZSBzdXJmYWNlLiBXYWl0OiBJdCBjb3VsZCBoYXZlIGJlZW4gcmVsZWFzZWQgaWYgd2UgYXJlIGEgdGV4dHVyZSAqLwogICAgaWYoVGhpcy0+V2luZUQzRFN1cmZhY2UpCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwoKICAgIC8qIEhhdmluZyBhIHRleHR1cmUgaGFuZGxlIHNldCBpbXBsaWVzIHRoYXQgdGhlIGRldmljZSBzdGlsbCBleGlzdHMgKi8KICAgIGlmKFRoaXMtPkhhbmRsZSkKICAgIHsKICAgICAgICBUaGlzLT5kZHJhdy0+ZDNkZGV2aWNlLT5IYW5kbGVzW1RoaXMtPkhhbmRsZSAtIDFdLnB0ciA9IE5VTEw7CiAgICAgICAgVGhpcy0+ZGRyYXctPmQzZGRldmljZS0+SGFuZGxlc1tUaGlzLT5IYW5kbGUgLSAxXS50eXBlID0gRERyYXdIYW5kbGVfVW5rbm93bjsKICAgIH0KCiAgICAvKiBSZWR1Y2UgdGhlIGRkcmF3IHN1cmZhY2UgY291bnQgKi8KICAgIEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5kZHJhdy0+c3VyZmFjZXMpOwogICAgbGlzdF9yZW1vdmUoJlRoaXMtPnN1cmZhY2VfbGlzdF9lbnRyeSk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZWxlYXNlCiAqCiAqIFJlZHVjZXMgdGhlIHN1cmZhY2UncyByZWZjb3VudCBieSAxLiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlCiAqIHN1cmZhY2UgaXMgZGVzdHJveWVkLgogKgogKiBEZXN0cm95aW5nIHRoZSBzdXJmYWNlIGlzIGEgYml0IHRyaWNreS4gRm9yIHRoZSBjb25uZWN0aW9uIGJldHdlZW4KICogV2luZUQzRFN1cmZhY2VzIGFuZCBEaXJlY3REcmF3U3VyZmFjZXMgc2VlIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKiBJdCBoYXMgYSBuaWNlIGdyYXBoIGV4cGxhaW5pbmcgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIFdoYXQgaGFwcGVucyBoZXJlIGlzIGJhc2ljYWxseSB0aGlzOgogKiBXaGVuIGEgc3VyZmFjZSBpcyBkZXN0cm95ZWQsIGl0cyBXaW5lRDNEU3VyZmFjZSBpcyByZWxlYXNlZCwKICogYW5kIHRoZSByZWZjb3VudCBvZiB0aGUgRGlyZWN0RHJhdyBpbnRlcmZhY2UgaXMgcmVkdWNlZCBieSAxLiBJZiBpdCBoYXMKICogY29tcGxleCBzdXJmYWNlcyBhdHRhY2hlZCB0byBpdCwgdGhlbiB0aGVzZSBzdXJmYWNlcyBhcmUgZGVzdHJveWVkIHRvbywKICogcmVnYXJkbGVzcyBvZiB0aGVpciByZWZjb3VudC4gSWYgYW55IHN1cmZhY2UgYmVpbmcgZGVzdHJveWVkIGhhcyBhbm90aGVyCiAqIHN1cmZhY2UgYXR0YWNoZWQgdG8gaXQgKHdpdGggYSAic29mdCIgYXR0YWNobWVudCwgbm90IGNvbXBsZXgpLCB0aGVuCiAqIHRoaXMgc3VyZmFjZSBpcyBkZXRhY2hlZCB3aXRoIERlbGV0ZUF0dGFjaGVkU3VyZmFjZS4KICoKICogV2hlbiB0aGUgc3VyZmFjZSBpcyBhIHRleHR1cmUsIHRoZSBXaW5lRDNEVGV4dHVyZSBpcyByZWxlYXNlZC4KICogSWYgdGhlIHN1cmZhY2UgaXMgdGhlIERpcmVjdDNEIHJlbmRlciB0YXJnZXQsIHRoZW4gdGhlIEQzRAogKiBjYXBhYmlsaXRpZXMgb2YgdGhlIFdpbmVEM0REZXZpY2UgYXJlIHVuaW5pdGlhbGl6ZWQsIHdoaWNoIGNhdXNlcyB0aGUKICogc3dhcGNoYWluIHRvIGJlIHJlbGVhc2VkLgogKgogKiBXaGVuIGEgY29tcGxleCBzdWJsZXZlbCBmYWxscyB0byByZWYgemVybywgdGhlbiB0aGlzIGlzIGlnbm9yZWQuCiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2UoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFVMT05HIHJlZjsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBpZiAocmVmID09IDApCiAgICB7CgogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICAgICAgSURpcmVjdERyYXdJbXBsICpkZHJhdzsKICAgICAgICBJVW5rbm93biAqaWZhY2VUb1JlbGVhc2UgPSBUaGlzLT5pZmFjZVRvUmVsZWFzZTsKICAgICAgICBpbnQgaTsKCiAgICAgICAgLyogQ29tcGxleCBhdHRhY2hlZCBzdXJmYWNlcyBhcmUgZGVzdHJveWVkIGltcGxpY2l0ZWx5IHdoZW4gdGhlIHJvb3QgaXMgcmVsZWFzZWQgKi8KICAgICAgICBpZighVGhpcy0+aXNfY29tcGxleF9yb290KQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiKCVwKSBBdHRlbXB0IHRvIGRlc3Ryb3kgYSBzdXJmYWNlIHRoYXQgaXMgbm90IGEgY29tcGxleCByb290XG4iLCBUaGlzKTsKICAgICAgICAgICAgcmV0dXJuIHJlZjsKICAgICAgICB9CiAgICAgICAgZGRyYXcgPSBUaGlzLT5kZHJhdzsKCiAgICAgICAgLyogSWYgaXQncyBhIHRleHR1cmUsIGRlc3Ryb3kgdGhlIFdpbmVEM0RUZXh0dXJlLgogICAgICAgICAqIFdpbmVEM0Qgd2lsbCBkZXN0cm95IHRoZSBJUGFyZW50IGludGVyZmFjZXMKICAgICAgICAgKiBvZiB0aGUgc3VibGV2ZWxzLCB3aGljaCBkZXN0cm95cyB0aGUgV2luZUQzRFN1cmZhY2VzLgogICAgICAgICAqIFNldCB0aGUgc3VyZmFjZXMgdG8gTlVMTCB0byBhdm9pZCBkZXN0cm95aW5nIHRoZW0gYWdhaW4gbGF0ZXIKICAgICAgICAgKi8KICAgICAgICBpZihUaGlzLT53aW5lRDNEVGV4dHVyZSkKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShUaGlzLT53aW5lRDNEVGV4dHVyZSk7CiAgICAgICAgfQogICAgICAgIC8qIElmIGl0J3MgdGhlIFJlbmRlclRhcmdldCwgZGVzdHJveSB0aGUgZDNkZGV2aWNlICovCiAgICAgICAgZWxzZSBpZiggKGRkcmF3LT5kM2RfaW5pdGlhbGl6ZWQpICYmIChUaGlzID09IGRkcmF3LT5kM2RfdGFyZ2V0KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIERlc3Ryb3lpbmcgdGhlIHJlbmRlciB0YXJnZXQsIHVuaW5pdGlhbGl6aW5nIEQzRFxuIiwgVGhpcyk7CgogICAgICAgICAgICAvKiBVbnNldCBhbnkgaW5kZXggYnVmZmVyLCBqdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SW5kaWNlcyhkZHJhdy0+d2luZUQzRERldmljZSwgTlVMTCwgMCk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoZGRyYXctPndpbmVEM0REZXZpY2UsIE5VTEwpOwoKICAgICAgICAgICAgaWYoSVdpbmVEM0REZXZpY2VfVW5pbml0M0QoZGRyYXctPndpbmVEM0REZXZpY2UsIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZSwgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pICE9IEQzRF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTm90IGdvb2QgKi8KICAgICAgICAgICAgICAgIEVSUigiKCVwKSBGYWlsZWQgdG8gdW5pbml0IDNEXG4iLCBUaGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEZyZWUgdGhlIGQzZCB3aW5kb3cgaWYgb25lIHdhcyBjcmVhdGVkICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+ZDNkX3dpbmRvdyAhPSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCIgKCVwKSBEZXN0cm95aW5nIHRoZSBoaWRkZW4gcmVuZGVyIHdpbmRvdyAlcFxuIiwgVGhpcywgZGRyYXctPmQzZF93aW5kb3cpOwogICAgICAgICAgICAgICAgICAgIERlc3Ryb3lXaW5kb3coZGRyYXctPmQzZF93aW5kb3cpOwogICAgICAgICAgICAgICAgICAgIGRkcmF3LT5kM2Rfd2luZG93ID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIFVuc2V0IHRoZSBwb2ludGVycyAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBkZHJhdy0+ZDNkX2luaXRpYWxpemVkID0gRkFMU0U7CiAgICAgICAgICAgIGRkcmF3LT5kM2RfdGFyZ2V0ID0gTlVMTDsKCiAgICAgICAgICAgIC8qIFdyaXRlIGEgdHJhY2UgYmVjYXVzZSBEM0QgdW5sb2FkaW5nIHdhcyB0aGUgcmVhc29uIGZvciBtYW55CiAgICAgICAgICAgICAqIGNyYXNoZXMgZHVyaW5nIGRldmVsb3BtZW50LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgRDNEIHVubG9hZGVkXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU18zRERFVklDRSAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19URVhUVVJFICAgICAgICApICkKICAgICAgICB7CiAgICAgICAgICAgIC8qIEl0J3MgYSByZW5kZXIgdGFyZ2V0LCBidXQgbm8gc3dhcGNoYWluIHdhcyBjcmVhdGVkLgogICAgICAgICAgICAgKiBUaGUgSVBhcmVudCBpbnRlcmZhY2VzIGhhdmUgdG8gYmUgcmVsZWFzZWQgbWFudWFsbHkuCiAgICAgICAgICAgICAqIFRoZSBzYW1lIGFwcGxpZXMgZm9yIHRleHR1cmVzIHdpdGhvdXQgYW4KICAgICAgICAgICAgICogSVdpbmVEM0RUZXh0dXJlIG9iamVjdCBhdHRhY2hlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSVBhcmVudCAqUGFyZW50OwoKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTVBMRVhfQVRUQUNIRUQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoVGhpcy0+Y29tcGxleF9hcnJheVtpXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBPbmx5IHRoZSB0b3Btb3N0IGxldmVsIGNhbiBoYXZlIG1vcmUgdGhhbiAxIHN1cmZhY2VzIGluIHRoZSBjb21wbGV4CiAgICAgICAgICAgICAgICAgICAgICogYXR0YWNobWVudCBhcnJheShDdWJlIHRleHR1cmUgcm9vdHMpLCBmb3IgYWxsIG90aGVycyB0aGVyZSBpcyBvbmx5CiAgICAgICAgICAgICAgICAgICAgICogb25lCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgc3VyZiA9IFRoaXMtPmNvbXBsZXhfYXJyYXlbaV07CiAgICAgICAgICAgICAgICAgICAgd2hpbGUoc3VyZikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQoc3VyZi0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICoqKSAmUGFyZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBGb3IgdGhlIGdldFBhcmVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICBJUGFyZW50X1JlbGVhc2UoUGFyZW50KTsgIC8qIFRvIHJlbGVhc2UgaXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgc3VyZiA9IHN1cmYtPmNvbXBsZXhfYXJyYXlbMF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBOb3cgdGhlIHRvcC1sZXZlbCBzdXJmYWNlICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICoqKSAmUGFyZW50KTsKICAgICAgICAgICAgSVBhcmVudF9SZWxlYXNlKFBhcmVudCk7ICAvKiBGb3IgdGhlIGdldFBhcmVudCAqLwogICAgICAgICAgICBJUGFyZW50X1JlbGVhc2UoUGFyZW50KTsgIC8qIFRvIHJlbGVhc2UgaXQgKi8KICAgICAgICB9CgogICAgICAgIC8qIFRoZSByZWZjb3VudCB0ZXN0IHNob3dzIHRoYXQgdGhlIHBhbGV0dGUgaXMgZGV0YWNoZWQgd2hlbiB0aGUgc3VyZmFjZSBpcyBkZXN0cm95ZWQgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1NldFBhbGV0dGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwoKICAgICAgICAvKiBMb29wIHRocm91Z2ggYWxsIGNvbXBsZXggYXR0YWNoZWQgc3VyZmFjZXMsCiAgICAgICAgICogYW5kIGRlc3Ryb3kgdGhlbS4KICAgICAgICAgKgogICAgICAgICAqIFlldCBhZ2Fpbiwgb25seSB0aGUgcm9vdCBjYW4gaGF2ZSBtb3JlIHRoYW4gb25lIGNvbXBsZXhseSBhdHRhY2hlZCBzdXJmYWNlLCBhbGwgdGhlIG90aGVycwogICAgICAgICAqIGhhdmUgYSB0b3RhbCBvZiBvbmU7CiAgICAgICAgICovCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTVBMRVhfQVRUQUNIRUQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFUaGlzLT5jb21wbGV4X2FycmF5W2ldKSBicmVhazsKCiAgICAgICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgICAgICBUaGlzLT5jb21wbGV4X2FycmF5W2ldID0gTlVMTDsKICAgICAgICAgICAgd2hpbGUoc3VyZikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqZGVzdHJveSA9IHN1cmY7CiAgICAgICAgICAgICAgICBzdXJmID0gc3VyZi0+Y29tcGxleF9hcnJheVswXTsgICAgICAgICAgICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCB0aGUgInRyZWUiICovCiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0Rlc3Ryb3koZGVzdHJveSk7ICAgIC8qIERlc3Ryb3kgaXQgKi8KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogRGVzdHJveSB0aGUgcm9vdCBzdXJmYWNlLgogICAgICAgICAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRGVzdHJveShUaGlzKTsKCiAgICAgICAgLyogUmVkdWNlIHRoZSBkZHJhdyByZWZjb3VudCAqLwogICAgICAgIGlmKGlmYWNlVG9SZWxlYXNlKSBJVW5rbm93bl9SZWxlYXNlKGlmYWNlVG9SZWxlYXNlKTsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0QXR0YWNoZWRTdXJmYWNlCiAqCiAqIFJldHVybnMgYW4gYXR0YWNoZWQgc3VyZmFjZSB3aXRoIHRoZSByZXF1ZXN0ZWQgY2Fwcy4gU3VyZmFjZSBhdHRhY2htZW50CiAqIGFuZCBjb21wbGV4IHN1cmZhY2VzIGFyZSBub3QgY2xlYXJseSBkZXNjcmliZWQgYnkgdGhlIE1TRE4gb3Igc2RrLAogKiBzbyB0aGlzIG1ldGhvZCBpcyB0cmlja3kgYW5kIGxpa2VseSB0byBjb250YWluIHByb2JsZW1zLgogKiBUaGlzIGltcGxlbWVudGF0aW9uIHNlYXJjaGVzIHRoZSBjb21wbGV4IGxpc3QgZmlyc3QsIHRoZW4gdGhlCiAqIGF0dGFjaG1lbnQgY2hhaW4uCiAqCiAqIFRoZSBjaGFpbnMgYXJlIHNlYXJjaGVkIGZyb20gVGhpcyBkb3duIHRvIHRoZSBsYXN0IHN1cmZhY2UgaW4gdGhlIGNoYWluLAogKiBub3QgZnJvbSB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgY2hhaW4uIFRoZSBmaXJzdCBzdXJmYWNlIGZvdW5kIGlzCiAqIHJldHVybmVkLiBUaGUgTVNETiBzYXlzIHRoYXQgdGhpcyBtZXRob2QgZmFpbHMgaWYgbW9yZSB0aGFuIG9uZSBzdXJmYWNlCiAqIG1hdGNoZXMgdGhlIGNhcHMsIGJ1dCBpdCBpcyBub3Qgc3VyZSBpZiB0aGF0IGlzIHJpZ2h0LiBUaGUgYXR0YWNobWVudAogKiBzdHJ1Y3R1cmUgbWF5IG5vdCBldmVuIGFsbG93IHR3byBtYXRjaGluZyBzdXJmYWNlcy4KICoKICogVGhlIGZvdW5kIHN1cmZhY2UgaXMgQWRkUmVmLWVkIGJlZm9yZSBpdCBpcyByZXR1cm5lZC4KICoKICogUGFyYW1zOgogKiAgQ2FwczogUG9pbnRlciB0byBhIEREQ0FQUzIgc3RydWN0dXJlIGRlc2NyaWJpbmcgdGhlIGNhcHMgYXNrZWQgZm9yCiAqICBTdXJmYWNlOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBmb3VuZCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhcHMgb3IgU3VyZmFjZSBpcyBOVUxMCiAqICBEREVSUl9OT1RGT1VORCBpZiBubyBzdXJmYWNlIHdhcyBmb3VuZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQUzIgKkNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgRERTQ0FQUzIgb3VyX2NhcHM7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgQ2FwcywgU3VyZmFjZSk7CgogICAgb3VyX2NhcHMgPSAqQ2FwczsKCiAgICBpZihUaGlzLT52ZXJzaW9uIDwgNykKICAgIHsKICAgICAgICAvKiBFYXJsaWVyIGR4IGFwcHMgcHV0IGdhcmJhZ2UgaW50byB0aGVzZSBtZW1iZXJzLCBjbGVhciB0aGVtICovCiAgICAgICAgb3VyX2NhcHMuZHdDYXBzMiA9IDA7CiAgICAgICAgb3VyX2NhcHMuZHdDYXBzMyA9IDA7CiAgICAgICAgb3VyX2NhcHMuZHdDYXBzNCA9IDA7CiAgICB9CgogICAgVFJBQ0UoIiglcCk6IExvb2tpbmcgZm9yIGNhcHM6ICV4LCV4LCV4LCV4XG4iLCBUaGlzLCBvdXJfY2Fwcy5kd0NhcHMsIG91cl9jYXBzLmR3Q2FwczIsIG91cl9jYXBzLmR3Q2FwczMsIG91cl9jYXBzLmR3Q2FwczQpOyAvKiBGSVhNRTogQmV0dGVyIGRlYnVnZ2luZyAqLwoKICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBpKyspCiAgICB7CiAgICAgICAgc3VyZiA9IFRoaXMtPmNvbXBsZXhfYXJyYXlbaV07CiAgICAgICAgaWYoIXN1cmYpIGJyZWFrOwoKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2U6ICglcCkgY2FwczogJXgsJXgsJXgsJXhcbiIsIHN1cmYsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMywKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgb3VyX2NhcHMuZHdDYXBzKSA9PSBvdXJfY2Fwcy5kd0NhcHMpICYmCiAgICAgICAgICAgICgoc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzMiAmIG91cl9jYXBzLmR3Q2FwczIpID09IG91cl9jYXBzLmR3Q2FwczIpKSB7CgogICAgICAgICAgICAvKiBNU0ROOiAiVGhpcyBtZXRob2QgZmFpbHMgaWYgbW9yZSB0aGFuIG9uZSBzdXJmYWNlIGlzIGF0dGFjaGVkCiAgICAgICAgICAgICAqIHRoYXQgbWF0Y2hlcyB0aGUgY2FwYWJpbGl0aWVzIHJlcXVlc3RlZC4iCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIE5vdCBzdXJlIGhvdyB0byB0ZXN0IHRoaXMuCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgVFJBQ0UoIiglcCk6IFJldHVybmluZyBzdXJmYWNlICVwXG4iLCBUaGlzLCBzdXJmKTsKICAgICAgICAgICAgVFJBQ0UoIiglcCk6IG1pcG1hcGNvdW50PSVkXG4iLCBUaGlzLCBzdXJmLT5taXBtYXBfbGV2ZWwpOwogICAgICAgICAgICAqU3VyZmFjZSA9IElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZigqU3VyZmFjZSk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgICAgICB9CiAgICB9CgogICAgLyogTmV4dCwgbG9vayBhdCB0aGUgYXR0YWNobWVudCBjaGFpbiAqLwogICAgc3VyZiA9IFRoaXM7CgogICAgd2hpbGUoIChzdXJmID0gc3VyZi0+bmV4dF9hdHRhY2hlZCkgKQogICAgewogICAgICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZTogKCVwKSBjYXBzOiAleCwleCwleCwleFxuIiwgc3VyZiwKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcywKICAgICAgICAgICAgICAgICAgIHN1cmYtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIsCiAgICAgICAgICAgICAgICAgICBzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMzLAogICAgICAgICAgICAgICAgICAgc3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzNCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoKChzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBvdXJfY2Fwcy5kd0NhcHMpID09IG91cl9jYXBzLmR3Q2FwcykgJiYKICAgICAgICAgICAgKChzdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgb3VyX2NhcHMuZHdDYXBzMikgPT0gb3VyX2NhcHMuZHdDYXBzMikpIHsKCiAgICAgICAgICAgIFRSQUNFKCIoJXApOiBSZXR1cm5pbmcgc3VyZmFjZSAlcFxuIiwgVGhpcywgc3VyZik7CiAgICAgICAgICAgICpTdXJmYWNlID0gSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKCpTdXJmYWNlKTsKICAgICAgICAgICAgcmV0dXJuIEREX09LOwogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgiKCVwKSBEaWRuJ3QgZmluZCBhIHZhbGlkIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgcmV0dXJuIERERVJSX05PVEZPVU5EOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6TG9jawogKgogKiBMb2NrcyB0aGUgc3VyZmFjZSBhbmQgcmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIHN1cmZhY2UncyBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgUmVjdDogUmVjdGFuZ2xlIHRvIGxvY2suIElmIE5VTEwsIHRoZSB3aG9sZSBzdXJmYWNlIGlzIGxvY2tlZAogKiAgRERTRDogUG9pbnRlciB0byBhIEREU1VSRkFDRURFU0MyIHdoaWNoIHNoYWxsIHJlY2VpdmUgdGhlIHN1cmZhY2UncyBkZXNjLgogKiAgRmxhZ3M6IExvY2tpbmcgZmxhZ3MsIGUuZyBSZWFkIG9ubHkgb3Igd3JpdGUgb25seQogKiAgaDogQW4gZXZlbnQgaGFuZGxlIHRoYXQncyBub3QgdXNlZCBhbmQgbXVzdCBiZSBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREU0QgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6TG9ja1JlY3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Mb2NrKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgaCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIExvY2tlZFJlY3Q7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwleCwlcClcbiIsIFRoaXMsIFJlY3QsIEREU0QsIEZsYWdzLCBoKTsKCiAgICBpZiAoUmVjdCkKICAgIHsKICAgICAgICBpZiAoKFJlY3QtPmxlZnQgPCAwKQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPnRvcCA8IDApCiAgICAgICAgICAgICAgICB8fCAoUmVjdC0+bGVmdCA+IFJlY3QtPnJpZ2h0KQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPnRvcCA+IFJlY3QtPmJvdHRvbSkKICAgICAgICAgICAgICAgIHx8IChSZWN0LT5yaWdodCA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd1dpZHRoKQogICAgICAgICAgICAgICAgfHwgKFJlY3QtPmJvdHRvbSA+IFRoaXMtPnN1cmZhY2VfZGVzYy5kd0hlaWdodCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUcnlpbmcgdG8gbG9jayBhbiBpbnZhbGlkIHJlY3RhbmdsZSwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICB9CgogICAgaWYoIUREU0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogU2hvdWxkIEkgY2hlY2sgZm9yIHRoZSBoYW5kbGUgdG8gYmUgTlVMTD8KICAgICAqCiAgICAgKiBUaGUgRERMT0NLIGZsYWdzIGFuZCB0aGUgRDNETE9DSyBmbGFncyBhcmUgZXF1YWwKICAgICAqIGZvciB0aGUgc3VwcG9ydGVkIHZhbHVlcy4gVGhlIG90aGVycyBhcmUgaWdub3JlZCBieSBXaW5lRDNECiAgICAgKi8KCiAgICAvKiBIbW0uIEFuYXJjaHkgb25saW5lIHBhc3NlcyBhbiB1bmluaXRpYWxpemVkIHN1cmZhY2UgZGVzY3JpcHRvciwKICAgICAqIHRoYXQgbWVhbnMgaXQgZG9lc24ndCBoYXZlIGR3U2l6ZSBzZXQuIEluaXQgaXQgdG8gc29tZSBzYW5lCiAgICAgKiB2YWx1ZQogICAgICovCiAgICBpZihERFNELT5kd1NpemUgPD0gc2l6ZW9mKEREU1VSRkFDRURFU0MpKQogICAgewogICAgICAgIEREU0QtPmR3U2l6ZSA9IHNpemVvZihERFNVUkZBQ0VERVNDKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBERFNELT5kd1NpemUgPSBzaXplb2YoRERTVVJGQUNFREVTQzIpOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkxvY2tlZFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwogICAgaWYoaHIgIT0gRDNEX09LKSByZXR1cm4gaHI7CgogICAgLyogT3ZlcnJpZGUgdGhlIG1lbW9yeSBhcmVhLiBUaGUgcGl0Y2ggc2hvdWxkIGJlIHNldCBhbHJlYWR5LiBTdHJhbmdlbHkgd2luZG93cwogICAgICogZG9lcyBub3Qgc2V0IHRoZSBMUFNVUkZBQ0UgZmxhZyBvbiBsb2NrZWQgc3VyZmFjZXMgIT8hLgogICAgICogRERTRC0+ZHdGbGFncyB8PSBERFNEX0xQU1VSRkFDRTsKICAgICAqLwogICAgVGhpcy0+c3VyZmFjZV9kZXNjLmxwU3VyZmFjZSA9IExvY2tlZFJlY3QucEJpdHM7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoRERTRCwmKFRoaXMtPnN1cmZhY2VfZGVzYykpOwoKICAgIFRSQUNFKCJsb2NrZWQgc3VyZmFjZSByZXR1cm5pbmcgZGVzY3JpcHRpb24gOlxuIik7CiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKSBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpVbmxvY2sKICoKICogVW5sb2NrcyBhbiBsb2NrZWQgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBSZWN0OiBOb3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6VW5sb2NrUmVjdAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VubG9jayhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqcFJlY3QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgcFJlY3QpOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwogICAgaWYoU1VDQ0VFREVEKGhyKSkKICAgIHsKICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MubHBTdXJmYWNlID0gTlVMTDsKICAgIH0KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkZsaXAKICoKICogRmxpcHMgYSBzdXJmYWNlIHdpdGggdGhlIEREU0NBUFNfRkxJUCBmbGFnLiBUaGUgZmxpcCBpcyByZWxheWVkIHRvCiAqIElXaW5lRDNEU3VyZmFjZTo6RmxpcC4gQmVjYXVzZSBXaW5lRDNEIGRvZXNuJ3QgaGFuZGxlIGF0dGFjaGVkIHN1cmZhY2VzLAogKiB0aGUgZmxpcCB0YXJnZXQgaXMgcGFzc2VkIHRvIFdpbmVEM0QsIGV2ZW4gaWYgdGhlIGFwcCBkaWRuJ3Qgc3BlY2lmeSBvbmUKICoKICogUGFyYW1zOgogKiAgRGVzdE92ZXJyaWRlOiBTcGVjaWZpZXMgdGhlIHN1cmZhY2UgdGhhdCB3aWxsIGJlY29tZSB0aGUgbmV3IGZyb250CiAqICAgICAgICAgICAgICAgIGJ1ZmZlci4gSWYgTlVMTCwgdGhlIGN1cnJlbnQgYmFjayBidWZmZXIgaXMgdXNlZAogKiAgRmxhZ3M6IHNvbWUgRGlyZWN0RHJhdyBmbGFncywgc2VlIGluY2x1ZGUvZGRyYXcuaAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfTk9URkxJUFBBQkxFIGlmIG5vIGZsaXAgdGFyZ2V0IGNvdWxkIGJlIGZvdW5kCiAqICBEREVSUl9JTlZBTElET0JKRUNUIGlmIHRoZSBzdXJmYWNlIGlzbid0IGEgZnJvbnQgYnVmZmVyCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpGbGlwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfRmxpcChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkRlc3RPdmVycmlkZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpPdmVycmlkZSA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIERlc3RPdmVycmlkZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpPdmVycmlkZTc7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIERlc3RPdmVycmlkZSwgRmxhZ3MpOwoKICAgIC8qIEZsaXAgaGFzIHRvIGJlIGNhbGxlZCBmcm9tIGEgZnJvbnQgYnVmZmVyCiAgICAgKiBXaGF0IGFib3V0IG92ZXJsYXkgc3VyZmFjZXMsIEFGQUlLIHRoZXkgY2FuIGZsaXAgdG9vPwogICAgICovCiAgICBpZiggIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0ZST05UQlVGRkVSKSApCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURPQkpFQ1Q7IC8qIFVuY2tlY2tlZCAqLwoKICAgIC8qIFdpbmVEM0QgZG9lc24ndCBrZWVwIHRyYWNrIG9mIGF0dGFjaGVkIHN1cmZhY2UsIHNvIGZpbmQgdGhlIHRhcmdldCAqLwogICAgaWYoIU92ZXJyaWRlKQogICAgewogICAgICAgIEREU0NBUFMyIENhcHM7CgogICAgICAgIG1lbXNldCgmQ2FwcywgMCwgc2l6ZW9mKENhcHMpKTsKICAgICAgICBDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0JBQ0tCVUZGRVI7CiAgICAgICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShpZmFjZSwgJkNhcHMsICZPdmVycmlkZTcpOwogICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJDYW4ndCBmaW5kIGEgZmxpcCB0YXJnZXRcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfTk9URkxJUFBBQkxFOyAvKiBVbmNoZWNrZWQgKi8KICAgICAgICB9CiAgICAgICAgT3ZlcnJpZGUgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBPdmVycmlkZTcpOwoKICAgICAgICAvKiBGb3IgdGhlIEdldEF0dGFjaGVkU3VyZmFjZSAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShPdmVycmlkZTcpOwogICAgfQoKICAgIHJldHVybiAgSVdpbmVEM0RTdXJmYWNlX0ZsaXAoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE92ZXJyaWRlLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6Qmx0CiAqCiAqIFBlcmZvcm1zIGEgYmxpdCBvbiB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBEZXN0UmVjdDogRGVzdGluYXRpb24gcmVjdGFuZ2xlLCBjYW4gYmUgTlVMTAogKiAgU3JjU3VyZmFjZTogU291cmNlIHN1cmZhY2UsIGNhbiBiZSBOVUxMCiAqICBTcmNSZWN0OiBTb3VyY2UgcmVjdGFuZ2UsIGNhbiBiZSBOVUxMCiAqICBGbGFnczogQmx0IGZsYWdzCiAqICBEREJsdEZ4OiBTb21lIGV4dGVuZGVkIGJsdCBwYXJhbWV0ZXJzLCBjb25uZWN0ZWQgdG8gdGhlIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6Qmx0IGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHQoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKkRlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmNTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgRERCTFRGWCAqRERCbHRGeCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKlNyYyA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyY1N1cmZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWRpdHkgb2YgdGhlIGZsYWdzIGhlcmUuIFdpbmVEM0QgSGFzIHRoZSBzb2Z0d2FyZS1vcGVuZ2wgc2VsZWN0aW9uIHBhdGggYW5kIHdvdWxkIGhhdmUKICAgICAqIHRvIGNoZWNrIGF0IDIgcGxhY2VzLCBhbmQgc29tZXRpbWVzIGRvIGRvdWJsZSBjaGVja3MuIFRoaXMgYWxzbyBzYXZlcyB0aGUgY2FsbCB0byB3aW5lZDNkIDotKQogICAgICovCiAgICBpZigoRmxhZ3MgJiBEREJMVF9LRVlTUkNPVkVSUklERSkgJiYgKCFEREJsdEZ4IHx8IEZsYWdzICYgRERCTFRfS0VZU1JDKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgc291cmNlIGNvbG9yIGtleSBwYXJhbWV0ZXJzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoKEZsYWdzICYgRERCTFRfS0VZREVTVE9WRVJSSURFKSAmJiAoIUREQmx0RnggfHwgRmxhZ3MgJiBEREJMVF9LRVlERVNUKSkgewogICAgICAgIFdBUk4oIkludmFsaWQgZGVzdGluYXRpb24gY29sb3Iga2V5IHBhcmFtZXRlcnMsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZihGbGFncyAmIEREQkxUX0tFWVNSQyAmJiAoIVNyYyB8fCAhKFNyYy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkpIHsKICAgICAgICBXQVJOKCJEREJMVF9LRVlERVNUIGJsaXQgd2l0aG91dCBjb2xvciBrZXkgaW4gc3VyZmFjZSwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFRPRE86IENoZWNrIGlmIHRoZSBEREJsdEZ4IGNvbnRhaW5zIGFueSBkZHJhdyBzdXJmYWNlIHBvaW50ZXJzLiBJZiBpdCBkb2VzLCBjb3B5IHRoZSBzdHJ1Y3QsCiAgICAgKiBhbmQgcmVwbGFjZSB0aGUgZGRyYXcgc3VyZmFjZXMgd2l0aCB0aGUgd2luZWQzZCBzdXJmYWNlcwogICAgICogU28gZmFyIG5vIGJsaXR0aW5nIG9wZXJhdGlvbnMgdXNpbmcgc3VyZmFjZXMgaW4gdGhlIGJsdGZ4IHN0cnVjdCBhcmUgc3VwcG9ydGVkIGFueXdheS4KICAgICAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfQmx0KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNyYyA/IFNyYy0+V2luZUQzRFN1cmZhY2UgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEREJMVEZYICopIEREQmx0RngsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRFWEZfUE9JTlQpOwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9OT1RBVkFJTEFCTEU6ICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfV1JPTkdURVhUVVJFRk9STUFUOiByZXR1cm4gRERFUlJfSU5WQUxJRFBJWEVMRk9STUFUOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkFkZEF0dGFjaGVkU3VyZmFjZQogKgogKiBBdHRhY2hlcyBhIHN1cmZhY2UgdG8gYW5vdGhlciBzdXJmYWNlLiBIb3cgdGhlIHN1cmZhY2UgYXR0YWNobWVudHMgd29yawogKiBpcyBub3QgdG90YWxseSB1bmRlcnN0b29kIHlldCwgYW5kIHRoaXMgbWV0aG9kIGlzIHByb25lIHRvIHByb2JsZW1zLgogKiBoZSBzdXJmYWNlIHRoYXQgaXMgYXR0YWNoZWQgaXMgQWRkUmVmLWVkLgogKgogKiBUZXN0cyB3aXRoIGNvbXBsZXggc3VyZmFjZXMgc3VnZ2VzdCB0aGF0IHRoZSBzdXJmYWNlIGF0dGFjaG1lbnRzIGZvcm0gYQogKiB0cmVlLCBidXQgbm8gbWV0aG9kIHRvIHRlc3QgdGhpcyBoYXMgYmVlbiBmb3VuZCB5ZXQuCiAqCiAqIFRoZSBhdHRhY2htZW50IGxpc3QgY29uc2lzdHMgb2YgYSBmaXJzdCBzdXJmYWNlIChmaXJzdF9hdHRhY2hlZCkgYW5kCiAqIGZvciBlYWNoIHN1cmZhY2UgYSBwb2ludGVyIHRvIHRoZSBuZXh0IGF0dGFjaGVkIHN1cmZhY2UgKG5leHRfYXR0YWNoZWQpLgogKiBGb3IgdGhlIGZpcnN0IHN1cmZhY2UsIGFuZCBhIHN1cmZhY2UgdGhhdCBoYXMgbm8gYXR0YWNobWVudHMKICogZmlyc3RfYXR0YWNoZWQgcG9pbnRzIHRvIHRoZSBzdXJmYWNlIGl0c2VsZi4gQSBzdXJmYWNlIHRoYXQgaGFzCiAqIG5vIHN1Y2Nlc3NvcnMgaW4gdGhlIGNoYWluIGhhcyBuZXh0X2F0dGFjaGVkIHNldCB0byBOVUxMLgogKgogKiBOZXdseSBhdHRhY2hlZCBzdXJmYWNlcyBhcmUgYXR0YWNoZWQgcmlnaHQgYWZ0ZXIgdGhlIHJvb3Qgc3VyZmFjZS4KICogSWYgYSBzdXJmYWNlIGlzIGF0dGFjaGVkIHRvIGEgY29tcGxleCBzdXJmYWNlIGNvbXBvdW5kLCBpdCdzIGF0dGFjaGVkIHRvCiAqIHRoZSBzdXJmYWNlIHRoYXQgdGhlIGFwcCByZXF1ZXN0ZWQsIG5vdCB0aGUgY29tcGxleCByb290LiBTZWUKICogR2V0QXR0YWNoZWRTdXJmYWNlIGZvciBhIGRlc2NyaXB0aW9uIGhvdyBzdXJmYWNlcyBhcmUgZm91bmQuCiAqCiAqIFRoaXMgaXMgaG93IHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIHdvcmtzLCBhbmQgaXQgd2FzIGNvZGVkIGJ5IGxvb2tpbmcKICogYXQgdGhlIG5lZWRzIG9mIHRoZSBhcHBsaWNhdGlvbnMuCiAqCiAqIFNvIGZhciBvbmx5IFotQnVmZmVyIGF0dGFjaG1lbnRzIGFyZSB0ZXN0ZWQsIGFuZCB0aGV5IGFyZSBhY3RpdmF0ZWQgaW4KICogV2luZUQzRC4gTWlwbWFwcyBjb3VsZCBiZSB0cmlja3kgdG8gYWN0aXZhdGUgaW4gV2luZUQzRC4KICogQmFjayBidWZmZXJzIHNob3VsZCB3b3JrIGluIDJEIG1vZGUsIGJ1dCB0aGV5IGFyZSBub3QgdGVzdGVkKFRoZXkgY2FuIGJlCiAqIGF0dGFjaGVkIGluIG9sZGVyIGlmYWNlIHZlcnNpb25zKS4gUmVuZGVyaW5nIHRvIHRoZSBmcm9udCBidWZmZXIgYW5kCiAqIHN3aXRjaGluZyBiZXR3ZWVuIHRoYXQgYW5kIGRvdWJsZSBidWZmZXJpbmcgaXMgbm90IHlldCBpbXBsZW1lbnRlZCBpbgogKiBXaW5lRDNELCBzbyBmb3IgM0QgaXQgbWlnaHQgaGF2ZSB1bmV4cGVjdGVkIHJlc3VsdHMuCiAqCiAqIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQWRkQXR0YWNoZWRTdXJmYWNlIGlzIHRoZSByZWFsIHRoaW5nLAogKiBJRGlyZWN0RHJhd1N1cmZhY2U3SW1wbF9BZGRBdHRhY2hlZFN1cmZhY2UgaXMgYSB3cmFwcGVyIGFyb3VuZCBpdCB0aGF0CiAqIHBlcmZvcm1zIGFkZGl0aW9uYWwgY2hlY2tzLiBWZXJzaW9uIDcgb2YgdGhpcyBpbnRlcmZhY2UgaXMgbXVjaCBtb3JlIHJlc3RyaWN0aXZlCiAqIHRoYW4gaXRzIHByZWRlY2Vzc29ycy4KICoKICogUGFyYW1zOgogKiAgQXR0YWNoOiBTdXJmYWNlIHRvIGF0dGFjaCB0byBpZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfQ0FOTk9UQVRUQUNIU1VSRkFDRSBpZiB0aGUgc3VyZmFjZSBjYW4ndCBiZSBhdHRhY2hlZCBmb3Igc29tZSByZWFzb24KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmKQp7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgU3VyZik7CgogICAgaWYoU3VyZiA9PSBUaGlzKQogICAgICAgIHJldHVybiBEREVSUl9DQU5OT1RBVFRBQ0hTVVJGQUNFOyAvKiB1bmNoZWNrZWQgKi8KCiAgICAvKiBDaGVjayBpZiB0aGUgc3VyZmFjZSBpcyBhbHJlYWR5IGF0dGFjaGVkIHNvbWV3aGVyZSAqLwogICAgaWYoIChTdXJmLT5uZXh0X2F0dGFjaGVkICE9IE5VTEwpIHx8CiAgICAgICAgKFN1cmYtPmZpcnN0X2F0dGFjaGVkICE9IFN1cmYpICkKICAgIHsKICAgICAgICAvKiBUT0RPOiBUZXN0IGZvciB0aGUgc3RydWN0dXJlIG9mIHRoZSBtYW51YWwgYXR0YWNobWVudC4gSXMgaXQgYSBjaGFpbiBvciBhIGxpc3Q/CiAgICAgICAgICogV2hhdCBoYXBwZW5zIGlmIG9uZSBzdXJmYWNlIGlzIGF0dGFjaGVkIHRvIDIgZGlmZmVyZW50IHN1cmZhY2VzPwogICAgICAgICAqLwogICAgICAgIEZJWE1FKCIoJXApIFRoZSBTdXJmYWNlICVwIGlzIGFscmVhZHkgYXR0YWNoZWQgc29tZXdoZXJlIGVsc2U6IG5leHRfYXR0YWNoZWQgPSAlcCwgZmlyc3RfYXR0YWNoZWQgPSAlcCwgY2FuJ3QgaGFuZGxlIGJ5IG5vd1xuIiwgVGhpcywgU3VyZiwgU3VyZi0+bmV4dF9hdHRhY2hlZCwgU3VyZi0+Zmlyc3RfYXR0YWNoZWQpOwogICAgICAgIHJldHVybiBEREVSUl9TVVJGQUNFQUxSRUFEWUFUVEFDSEVEOwogICAgfQoKICAgIC8qIFRoaXMgaW5zZXJ0cyB0aGUgbmV3IHN1cmZhY2UgYXQgdGhlIDJuZCBwb3NpdGlvbiBpbiB0aGUgY2hhaW4sIHJpZ2h0IGFmdGVyIHRoZSByb290IHN1cmZhY2UgKi8KICAgIFN1cmYtPm5leHRfYXR0YWNoZWQgPSBUaGlzLT5uZXh0X2F0dGFjaGVkOwogICAgU3VyZi0+Zmlyc3RfYXR0YWNoZWQgPSBUaGlzLT5maXJzdF9hdHRhY2hlZDsKICAgIFRoaXMtPm5leHRfYXR0YWNoZWQgPSBTdXJmOwoKICAgIC8qIENoZWNrIGlmIHRoZSBXaW5lRDNEIGRlcHRoIHN0ZW5jaWwgbmVlZHMgdXBkYXRpbmcgKi8KICAgIGlmKFRoaXMtPmRkcmF3LT5kM2RkZXZpY2UpCiAgICB7CiAgICAgICAgSURpcmVjdDNERGV2aWNlSW1wbF9VcGRhdGVEZXB0aFN0ZW5jaWwoVGhpcy0+ZGRyYXctPmQzZGRldmljZSk7CiAgICB9CgogICAgLyogTVNETjogCiAgICAgKiAiVGhpcyBtZXRob2QgaW5jcmVtZW50cyB0aGUgcmVmZXJlbmNlIGNvdW50IG9mIHRoZSBzdXJmYWNlIGJlaW5nIGF0dGFjaGVkLiIKICAgICAqLwogICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoU3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgcmV0dXJuIEREX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlN0ltcGxfQWRkQXR0YWNoZWRTdXJmYWNlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqQXR0YWNoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgQXR0YWNoKTsKCiAgICAvKiBWZXJzaW9uIDcgb2YgdGhpcyBpbnRlcmZhY2Ugc2VlbXMgdG8gcmVmdXNlIGV2ZXJ5dGhpbmcgZXhjZXB0IHogYnVmZmVycywgYXMgcGVyIG1zZG4gKi8KICAgIGlmKCEoU3VyZi0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19aQlVGRkVSKSkKICAgIHsKCiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gdHJpZXMgdG8gYXR0YWNoIGEgbm9uIFogYnVmZmVyIHN1cmZhY2UuIGNhcHMgJTA4eFxuIiwKICAgICAgICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMpOwogICAgICAgIHJldHVybiBEREVSUl9DQU5OT1RBVFRBQ0hTVVJGQUNFOwogICAgfQoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZShUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1cmYpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpEZWxldGVBdHRhY2hlZFN1cmZhY2UKICoKICogUmVtb3ZlcyBhIHN1cmZhY2UgZnJvbSB0aGUgYXR0YWNobWVudCBjaGFpbi4gVGhlIHN1cmZhY2UncyByZWZjb3VudAogKiBpcyBkZWNyZWFzZWQgYnkgb25lIGFmdGVyIGl0IGhhcyBiZWVuIHJlbW92ZWQKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MsIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb24KICogIEF0dGFjaDogU3VyZmFjZSB0byBkZXRhY2gKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX1NVUkZBQ0VOT1RBVFRBQ0hFRCBpZiB0aGUgc3VyZmFjZSBpc24ndCBhdHRhY2hlZCB0bwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0RlbGV0ZUF0dGFjaGVkU3VyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkF0dGFjaCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIEF0dGFjaCk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpQcmV2ID0gVGhpczsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEZsYWdzLCBTdXJmKTsKCiAgICBpZiAoIVN1cmYgfHwgKFN1cmYtPmZpcnN0X2F0dGFjaGVkICE9IFRoaXMpIHx8IChTdXJmID09IFRoaXMpICkKICAgICAgICByZXR1cm4gRERFUlJfQ0FOTk9UREVUQUNIU1VSRkFDRTsKCiAgICAvKiBSZW1vdmUgTUlQTUFQU1VCTEVWRUwgaWYgdGhpcyBzZWVtZWQgdG8gYmUgb25lICovCiAgICBpZiAoVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICYKICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgIHsKICAgICAgICBTdXJmLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9NSVBNQVBTVUJMRVZFTDsKICAgICAgICAvKiBGSVhNRTogd2Ugc2hvdWxkIHByb2JhYmx5IGFsc28gc3VidHJhY3QgZnJvbSBkd01pcE1hcENvdW50IG9mIHRoaXMKICAgICAgICAgKiBhbmQgYWxsIHBhcmVudCBzdXJmYWNlcyAqLwogICAgfQoKICAgIC8qIEZpbmQgdGhlIHByZWRlY2Vzc29yIG9mIHRoZSBkZXRhY2hlZCBzdXJmYWNlICovCiAgICB3aGlsZShQcmV2KQogICAgewogICAgICAgIGlmKFByZXYtPm5leHRfYXR0YWNoZWQgPT0gU3VyZikgYnJlYWs7CiAgICAgICAgUHJldiA9IFByZXYtPm5leHRfYXR0YWNoZWQ7CiAgICB9CgogICAgLyogVGhlcmUgbXVzdCBiZSBhIHN1cmZhY2UsIG90aGVyd2lzZSB0aGVyZSdzIGEgYnVnICovCiAgICBhc3NlcnQoUHJldiAhPSBOVUxMKTsKCiAgICAvKiBVbmNoYWluIHRoZSBzdXJmYWNlICovCiAgICBQcmV2LT5uZXh0X2F0dGFjaGVkID0gU3VyZi0+bmV4dF9hdHRhY2hlZDsKICAgIFN1cmYtPm5leHRfYXR0YWNoZWQgPSBOVUxMOwogICAgU3VyZi0+Zmlyc3RfYXR0YWNoZWQgPSBTdXJmOwoKICAgIC8qIENoZWNrIGlmIHRoZSBXaW5lRDNEIGRlcHRoIHN0ZW5jaWwgbmVlZHMgdXBkYXRpbmcgKi8KICAgIGlmKFRoaXMtPmRkcmF3LT5kM2RkZXZpY2UpCiAgICB7CiAgICAgICAgSURpcmVjdDNERGV2aWNlSW1wbF9VcGRhdGVEZXB0aFN0ZW5jaWwoVGhpcy0+ZGRyYXctPmQzZGRldmljZSk7CiAgICB9CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKEF0dGFjaCk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpBZGRPdmVybGF5RGlydHlSZWN0CiAqCiAqICJUaGlzIG1ldGhvZCBpcyBub3QgY3VycmVudGx5IGltcGxlbWVudGVkIgogKgogKiBQYXJhbXM6CiAqICBSZWN0OiA/CiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9VTlNVUFBPUlRFRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZE92ZXJsYXlEaXJ0eVJlY3QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJFQ1QgUmVjdCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxSZWN0KTsKCiAgICAvKiBNU0ROIHNheXMgaXQncyBub3QgaW1wbGVtZW50ZWQuIEkgY291bGQgZm9yd2FyZCBpdCB0byBXaW5lRDNELCAKICAgICAqIHRoZW4gd2UnZCBpbXBsZW1lbnQgaXQsIGJ1dCBJIGRvbid0IHRoaW5rIHRoYXQncyBhIGdvb2QgaWRlYQogICAgICogKFN0ZWZhbiBE9nNpbmdlcikKICAgICAqLwojaWYgMAogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9BZGRPdmVybGF5RGlydHlSZWN0KFRoaXMtPldpbmVEM0RTdXJmYWNlLCBwUmVjdCk7CiNlbmRpZgogICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOyAvKiB1bmNoZWNrZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldERDCiAqCiAqIFJldHVybnMgYSBHREkgZGV2aWNlIGNvbnRleHQgZm9yIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIGhkYzogQWRkcmVzcyBvZiBhIEhEQyB2YXJpYWJsZSB0byBzdG9yZSB0aGUgZGMgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgaGRjIGlzIE5VTEwKICogIEZvciBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpHZXREQwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldERDKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhEQyAqaGRjKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIGhkYyk7CgogICAgaWYoIWhkYykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX0dldERDKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UmVsZWFzZURDCiAqCiAqIFJlbGVhc2VzIHRoZSBEQyB0aGF0IHdhcyBjb25zdHJ1Y3RlZCB3aXRoIEdldERDCiAqCiAqIFBhcmFtczoKICogIGhkYzogSERDIHRvIHJlbGVhc2UKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OlJlbGVhc2VEQwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1JlbGVhc2VEQyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSERDIGhkYykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCk6IFJlbGF5XG4iLCBUaGlzLCBoZGMpOwoKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZURDKFRoaXMtPldpbmVEM0RTdXJmYWNlLCBoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0Q2FwcwogKgogKiBSZXR1cm5zIHRoZSBzdXJmYWNlJ3MgY2FwcwogKgogKiBQYXJhbXM6CiAqICBDYXBzOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBjYXBzIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIENhcHMgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldENhcHMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTMiAqQ2FwcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxDYXBzKTsKCiAgICBpZighQ2FwcykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAqQ2FwcyA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0UHJpb3JpdHkKICoKICogU2V0cyBhIHRleHR1cmUgcHJpb3JpdHkgZm9yIG1hbmFnZWQgdGV4dHVyZXMuCiAqCiAqIFBhcmFtczoKICogIFByaW9yaXR5OiBUaGUgbmV3IHByaW9yaXR5CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpTZXRQcmlvcml0eQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFByaW9yaXR5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLCBEV09SRCBQcmlvcml0eSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglZCk6IFJlbGF5IVxuIixUaGlzLFByaW9yaXR5KTsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1NldFByaW9yaXR5KFRoaXMtPldpbmVEM0RTdXJmYWNlLCBQcmlvcml0eSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRQcmlvcml0eQogKgogKiBSZXR1cm5zIHRoZSBzdXJmYWNlJ3MgcHJpb3JpdHkKICoKICogUGFyYW1zOgogKiAgUHJpb3JpdHk6IEFkZHJlc3Mgb2YgYSB2YXJpYWJsZSB0byB3cml0ZSB0aGUgcHJpb3JpdHkgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFByaW9yaXR5ID09IE5VTEwKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OkdldFByaW9yaXR5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0UHJpb3JpdHkoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlByaW9yaXR5KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsVGhpcyxQcmlvcml0eSk7CgogICAgaWYoIVByaW9yaXR5KQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgICpQcmlvcml0eSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQcmlvcml0eShUaGlzLT5XaW5lRDNEU3VyZmFjZSk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRQcml2YXRlRGF0YQogKgogKiBTdG9yZXMgc29tZSBkYXRhIGluIHRoZSBzdXJmYWNlIHRoYXQgaXMgaW50ZW5kZWQgZm9yIHRoZSBhcHBsaWNhdGlvbidzCiAqIHVzZS4KICoKICogUGFyYW1zOgogKiAgdGFnOiBHVUlEIHRoYXQgaWRlbnRpZmllcyB0aGUgZGF0YQogKiAgRGF0YTogUG9pbnRlciB0byB0aGUgcHJpdmF0ZSBkYXRhCiAqICBTaXplOiBTaXplIG9mIHRoZSBwcml2YXRlIGRhdGEKICogIEZsYWdzOiBTb21lIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6U2V0UHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwLCVkLCV4KTogUmVsYXlcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQodGFnKSwgRGF0YSwgU2l6ZSwgRmxhZ3MpOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldFByaXZhdGVEYXRhKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncyk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0UHJpdmF0ZURhdGEKICoKICogUmV0dXJucyB0aGUgcHJpdmF0ZSBkYXRhIHNldCB3aXRoIElEaXJlY3REcmF3U3VyZmFjZTc6OlNldFByaXZhdGVEYXRhCiAqCiAqIFBhcmFtczoKICogIHRhZzogR1VJRCBvZiB0aGUgZGF0YSB0byByZXR1cm4KICogIERhdGE6IEFkZHJlc3Mgd2hlcmUgdG8gd3JpdGUgdGhlIGRhdGEgdG8KICogIFNpemU6IFNpemUgb2YgdGhlIGJ1ZmZlciBhdCBEYXRhCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIERhdGEgaXMgTlVMTAogKiAgRm9yIG1vcmUgZGV0YWlscywgc2VlIElXaW5lRDNEU3VyZmFjZTo6R2V0UHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZHVUlEIHRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpTaXplKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwLCVwKTogUmVsYXlcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQodGFnKSwgRGF0YSwgU2l6ZSk7CgogICAgaWYoIURhdGEpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9HZXRQcml2YXRlRGF0YShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkZyZWVQcml2YXRlRGF0YQogKgogKiBGcmVlcyBwcml2YXRlIGRhdGEgc3RvcmVkIGluIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHRhZzogVGFnIG9mIHRoZSBkYXRhIHRvIGZyZWUKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBGb3IgbW9yZSBkZXRhaWxzLCBzZWUgSVdpbmVEM0RTdXJmYWNlOjpGcmVlUHJpdmF0ZURhdGEKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRkdVSUQgdGFnKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVzKTogUmVsYXlcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQodGFnKSk7CgogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9GcmVlUHJpdmF0ZURhdGEoVGhpcy0+V2luZUQzRFN1cmZhY2UsIHRhZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpQYWdlTG9jawogKgogKiBQcmV2ZW50cyBhIHN5c21lbSBzdXJmYWNlIGZyb20gYmVpbmcgcGFnZWQgb3V0CiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBOb3QgdXNlZCwgbXVzdCBiZSAwKHVuY2hlY2tlZCkKICoKICogUmV0dXJuczoKICogIEREX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfUGFnZUxvY2soSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIFRSQUNFKCIoJXApLT4oJXgpXG4iLCBpZmFjZSwgRmxhZ3MpOwoKICAgIC8qIFRoaXMgaXMgV2luZG93cyBtZW1vcnkgbWFuYWdlbWVudCByZWxhdGVkIC0gd2UgZG9uJ3QgbmVlZCB0aGlzICovCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpQYWdlVW5sb2NrCiAqCiAqIEFsbG93cyBhIHN5c21lbSBzdXJmYWNlIHRvIGJlIHBhZ2VkIG91dAogKgogKiBQYXJhbXM6CiAqICBGbGFnczogTm90IHVzZWQsIG11c3QgYmUgMCh1bmNrZWNoZWQpCiAqCiAqIFJldHVybnM6CiAqICBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1BhZ2VVbmxvY2soSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgVFJBQ0UoIiglcCktPigleClcbiIsIGlmYWNlLCBGbGFncyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6Qmx0QmF0Y2gKICoKICogQW4gdW5pbXBsZW1lbnRlZCBmdW5jdGlvbgogKgogKiBQYXJhbXM6CiAqICA/CiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9VTlNVUFBPUlRFRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0JsdEJhdGNoKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLCBEREJMVEJBVENIICpCYXRjaCwgRFdPUkQgQ291bnQsIERXT1JEIEZsYWdzKQp7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVkLCUwOHgpXG4iLGlmYWNlLEJhdGNoLENvdW50LEZsYWdzKTsKCiAgICAvKiBNU0ROOiAibm90IGN1cnJlbnRseSBpbXBsZW1lbnRlZCIgKi8KICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkVudW1BdHRhY2hlZFN1cmZhY2VzCiAqCiAqIEVudW1lcmF0ZXMgYWxsIHN1cmZhY2VzIGF0dGFjaGVkIHRvIHRoaXMgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBjb250ZXh0OiBQb2ludGVyIHRvIHBhc3MgdW5tb2RpZmllZCB0byB0aGUgY2FsbGJhY2sKICogIGNiOiBDYWxsYmFjayBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIHN1cmZhY2UKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgY2IgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0VudW1BdHRhY2hlZFN1cmZhY2VzKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEREVOVU1TVVJGQUNFU0NBTExCQUNLNyBjYikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBpbnQgaTsKCiAgICAvKiBBdHRhY2hlZCBzdXJmYWNlcyBhcmVuJ3QgaGFuZGxlZCBpbiBXaW5lRDNEICovCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIixUaGlzLGNvbnRleHQsY2IpOwoKICAgIGlmKCFjYikKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NUExFWF9BVFRBQ0hFRDsgaSsrKQogICAgewogICAgICAgIHN1cmYgPSBUaGlzLT5jb21wbGV4X2FycmF5W2ldOwogICAgICAgIGlmKCFzdXJmKSBicmVhazsKCiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgIGRlc2MgPSBzdXJmLT5zdXJmYWNlX2Rlc2M7CiAgICAgICAgLyogY2hlY2s6ICE9IERERU5VTVJFVF9PSyBvciA9PSBEREVOVU1SRVRfQ0FOQ0VMPyAqLwogICAgICAgIGlmIChjYihJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRlc2MsIGNvbnRleHQpID09IERERU5VTVJFVF9DQU5DRUwpCiAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KCiAgICBmb3IgKHN1cmYgPSBUaGlzLT5uZXh0X2F0dGFjaGVkOyBzdXJmICE9IE5VTEw7IHN1cmYgPSBzdXJmLT5uZXh0X2F0dGFjaGVkKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICBkZXNjID0gc3VyZi0+c3VyZmFjZV9kZXNjOwogICAgICAgIC8qIGNoZWNrOiAhPSBEREVOVU1SRVRfT0sgb3IgPT0gRERFTlVNUkVUX0NBTkNFTD8gKi8KICAgICAgICBpZiAoY2IoIElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGVzYywgY29udGV4dCkgPT0gRERFTlVNUkVUX0NBTkNFTCkKICAgICAgICAgICAgcmV0dXJuIEREX09LOwogICAgfQoKICAgIFRSQUNFKCIgZW5kIG9mIGVudW1lcmF0aW9uLlxuIik7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6RW51bU92ZXJsYXlaT3JkZXJzCiAqCiAqICJFbnVtZXJhdGVzIHRoZSBvdmVybGF5IHN1cmZhY2VzIG9uIHRoZSBzcGVjaWZpZWQgZGVzdGluYXRpb24iCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBEREVOVU1PVkVSTEFZWl9CQUNLVE9GUk9OVCAgb3IgRERFTlVNT1ZFUkxBWVpfRlJPTlRUT0JBQ0sKICogIGNvbnRleHQ6IGNvbnRleHQgdG8gcGFzcyBiYWNrIHRvIHRoZSBjYWxsYmFjawogKiAgY2I6IGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggZW51bWVyYXRlZCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0VudW1PdmVybGF5Wk9yZGVycyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNU1VSRkFDRVNDQUxMQkFDSzcgY2IpCnsKICAgICBGSVhNRSgiKCVwKS0+KCV4LCVwLCVwKTogU3R1YiFcbiIsIGlmYWNlLCBGbGFncywgY29udGV4dCwgY2IpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldEJsdFN0YXR1cwogKgogKiBSZXR1cm5zIHRoZSBibGl0dGluZyBzdGF0dXMKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IERER0JTX0NBTkJMVCBvciBEREdCU19JU0JMVERPTkUKICoKICogUmV0dXJuczoKICogIFNlZSBJV2luZUQzRFN1cmZhY2U6OkJsdAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCV4KTogUmVsYXlcbiIsIFRoaXMsIEZsYWdzKTsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRCbHRTdGF0dXMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIEZsYWdzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRDb2xvcktleQogKgogKiBSZXR1cm5zIHRoZSBjb2xvciBrZXkgYXNzaWduZWQgdG8gdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MKICogIENLZXk6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGtleSB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDS2V5IGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDb2xvcktleShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENPTE9SS0VZICpDS2V5KQp7CiAgICAvKiBUaGVyZSBpcyBhIERERVJSX05PQ09MT1JLRVkgZXJyb3IsIGJ1dCBob3cgZG8gd2Uga25vdyBpZiBhIGNvbG9yIGtleQogICAgICogaXNuJ3QgdGhlcmU/IFRoYXQncyBsaWtlIHNheWluZyB0aGF0IGFuIGludCBpc24ndCB0aGVyZS4gKFdoaWNoIE1TCiAgICAgKiBoYXMgZG9uZSBpbiBvdGhlciBkb2NzLikgKi8KICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDS2V5KTsKCiAgICBpZighQ0tleSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBzd2l0Y2ggKEZsYWdzKQogICAgewogICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAqQ0tleSA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tEZXN0Qmx0OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICpDS2V5ID0gVGhpcy0+c3VyZmFjZV9kZXNjLnUzLmRkY2tDS0Rlc3RPdmVybGF5OwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRERDS0VZX1NSQ0JMVDoKICAgICAgICAqQ0tleSA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tTcmNCbHQ7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAqQ0tleSA9IFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tTcmNPdmVybGF5OwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0RmxpcFN0YXR1cwogKgogKiBSZXR1cm5zIHRoZSBmbGlwcGluZyBzdGF0dXMgb2YgdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IERER0ZTX0NBTkZMSVAgb2YgRERHRlNfSVNGTElQRE9ORQogKgogKiBSZXR1cm5zOgogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6R2V0RmxpcFN0YXR1cwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXgpOiBSZWxheVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldEZsaXBTdGF0dXMoVGhpcy0+V2luZUQzRFN1cmZhY2UsIEZsYWdzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw6ICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRPdmVybGF5UG9zaXRpb24KICoKICogUmV0dXJucyB0aGUgZGlzcGxheSBjb29yZGluYXRlcyBvZiBhIHZpc2libGUgYW5kIGFjdGl2ZSBvdmVybGF5IHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgWAogKiAgWQogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HICpYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HICpZKSB7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKTogUmVsYXlcbiIsIFRoaXMsIFgsIFkpOwoKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfR2V0T3ZlcmxheVBvc2l0aW9uKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0UGl4ZWxGb3JtYXQKICoKICogUmV0dXJucyB0aGUgcGl4ZWwgZm9ybWF0IG9mIHRoZSBTdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFBpeGVsRm9ybWF0OiBQb2ludGVyIHRvIGEgRERQSVhFTEZPUk1BVCBzdHJ1Y3R1cmUgdG8gd2hpY2ggdGhlIHBpeGVsCiAqICAgICAgICAgICAgICAgZm9ybWF0IHNob3VsZCBiZSB3cml0dGVuCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFBpeGVsRm9ybWF0IGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQaXhlbEZvcm1hdChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFBJWEVMRk9STUFUICpQaXhlbEZvcm1hdCkKewogICAgLyogV2hhdCBpcyBEREVSUl9JTlZBTElEU1VSRkFDRVRZUEUgZm9yIGhlcmU/ICovCiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLFBpeGVsRm9ybWF0KTsKCiAgICBpZighUGl4ZWxGb3JtYXQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKFBpeGVsRm9ybWF0LCZUaGlzLT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0U3VyZmFjZURlc2MKICoKICogUmV0dXJucyB0aGUgZGVzY3JpcHRpb24gb2YgdGhpcyBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IEFkZHJlc3Mgb2YgYSBERFNVUkZBQ0VERVNDMiBzdHJ1Y3R1cmUgdGhhdCBpcyB0byBiZSBmaWxsZWQgd2l0aCB0aGUKICogICAgICAgIHN1cmZhY2UgZGVzYwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBERFNEIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRTdXJmYWNlRGVzYyhJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsRERTRCk7CgogICAgaWYoIUREU0QpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgaWYgKChERFNELT5kd1NpemUgPCBzaXplb2YoRERTVVJGQUNFREVTQykpIHx8CiAgICAgICAgKEREU0QtPmR3U2l6ZSA+IHNpemVvZihERFNVUkZBQ0VERVNDMikpKQogICAgewogICAgICAgIEVSUigiSW1wb3NzaWJsZS9TdHJhbmdlIHN0cnVjdCBzaXplICVkLlxuIixERFNELT5kd1NpemUpOwogICAgICAgIHJldHVybiBEREVSUl9HRU5FUklDOwogICAgfQoKICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRShERFNELCZUaGlzLT5zdXJmYWNlX2Rlc2MpOwogICAgVFJBQ0UoIlJldHVybmluZyBzdXJmYWNlIGRlc2M6XG4iKTsKICAgIGlmIChUUkFDRV9PTihkZHJhdykpIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKEREU0QpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkluaXRpYWxpemUKICoKICogSW5pdGlhbGl6ZXMgdGhlIHN1cmZhY2UuIFRoaXMgaXMgYSBuby1vcCBpbiBXaW5lCiAqCiAqIFBhcmFtczoKICogIEREOiBQb2ludGVyIHRvIGFuIERpcmVjdERyYXcgaW50ZXJmYWNlCiAqICBERFNEOiBTdXJmYWNlIGRlc2NyaXB0aW9uIGZvciBpbml0aWFsaXphdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfSW5pdGlhbGl6ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICpERCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd0ltcGwgKmRkaW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXcsIEREKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLFRoaXMsZGRpbXBsLEREU0QpOwoKICAgIHJldHVybiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpJc0xvc3QKICoKICogQ2hlY2tzIGlmIHRoZSBzdXJmYWNlIGlzIGxvc3QKICoKICogUmV0dXJuczoKICogIEREX09LLCBpZiB0aGUgc3VyZmFjZSBpcyB1c2VhYmxlCiAqICBEREVSUl9JU0xPU1QgaWYgdGhlIHN1cmZhY2UgaXMgbG9zdAogKiAgU2VlIElXaW5lRDNEU3VyZmFjZTo6SXNMb3N0IGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Jc0xvc3QoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogV2UgbG9zZSB0aGUgc3VyZmFjZSBpZiB0aGUgaW1wbGVtZW50YXRpb24gd2FzIGNoYW5nZWQgKi8KICAgIGlmKFRoaXMtPkltcGxUeXBlICE9IFRoaXMtPmRkcmF3LT5JbXBsVHlwZSkKICAgIHsKICAgICAgICAvKiBCdXQgdGhpcyBzaG91bGRuJ3QgaGFwcGVuLiBXaGVuIHdlIGNoYW5nZSB0aGUgaW1wbGVtZW50YXRpb24sCiAgICAgICAgICogYWxsIHN1cmZhY2VzIGFyZSByZS1jcmVhdGVkIGF1dG9tYXRpY2FsbHksIGFuZCB0aGVpciBjb250ZW50CiAgICAgICAgICogaXMgY29waWVkCiAgICAgICAgICovCiAgICAgICAgRVJSKCIgKCVwKSBJbXBsZW1lbnRhdGlvbiB3YXMgY2hhbmdlZCBmcm9tICVkIHRvICVkXG4iLCBUaGlzLCBUaGlzLT5JbXBsVHlwZSwgVGhpcy0+ZGRyYXctPkltcGxUeXBlKTsKICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUxPU1Q7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfSXNMb3N0KFRoaXMtPldpbmVEM0RTdXJmYWNlKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICAvKiBEM0Q4IGFuZCA5IGxvb3NlIGZ1bGwgZGV2aWNlcywgdGh1cyB0aGVyZSdzIG9ubHkgYSBERVZJQ0VMT1NUIGVycm9yLgogICAgICAgICAqIFdpbmVEM0QgdXNlcyB0aGUgc2FtZSBlcnJvciBmb3Igc3VyZmFjZXMKICAgICAgICAgKi8KICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDogICAgICAgICByZXR1cm4gRERFUlJfU1VSRkFDRUxPU1Q7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6UmVzdG9yZQogKgogKiBSZXN0b3JlcyBhIGxvc3Qgc3VyZmFjZS4gVGhpcyBtYWtlcyB0aGUgc3VyZmFjZSB1c2FibGUgYWdhaW4sIGJ1dAogKiBkb2Vzbid0IHJlbG9hZCBpdHMgb2xkIGNvbnRlbnRzCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBTZWUgSVdpbmVEM0RTdXJmYWNlOjpSZXN0b3JlIGZvciBtb3JlIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZXN0b3JlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoVGhpcy0+SW1wbFR5cGUgIT0gVGhpcy0+ZGRyYXctPkltcGxUeXBlKQogICAgewogICAgICAgIC8qIENhbGwgdGhlIHJlY3JlYXRpb24gY2FsbGJhY2suIE1ha2Ugc3VyZSB0byBBZGRSZWYgZmlyc3QgKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfQWRkUmVmKGlmYWNlKTsKICAgICAgICBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRoaXMtPnN1cmZhY2VfZGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogTm90IG5lZWRlZCAqLyk7CiAgICB9CiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1Jlc3RvcmUoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0T3ZlcmxheVBvc2l0aW9uCiAqCiAqIENoYW5nZXMgdGhlIGRpc3BsYXkgY29vcmRpbmF0ZXMgb2YgYW4gb3ZlcmxheSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIFg6CiAqICBZOgogKgogKiBSZXR1cm5zOgogKiAgIERERVJSX05PVEFPVkVSTEFZU1VSRkFDRSwgYmVjYXVzZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzIHJpZ2h0IG5vdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbihJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9ORyBYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT05HIFkpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQpOiBSZWxheVxuIiwgVGhpcywgWCwgWSk7CgogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9TZXRPdmVybGF5UG9zaXRpb24oVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpVcGRhdGVPdmVybGF5CiAqCiAqIE1vZGlmaWVzIHRoZSBhdHRyaWJ1dGVzIG9mIGFuIG92ZXJsYXkgc3VyZmFjZS4KICoKICogUGFyYW1zOgogKiAgU3JjUmVjdDogVGhlIHNlY3Rpb24gb2YgdGhlIHNvdXJjZSBiZWluZyB1c2VkIGZvciB0aGUgb3ZlcmxheQogKiAgRHN0U3VyZmFjZTogQWRkcmVzcyBvZiB0aGUgc3VyZmFjZSB0aGF0IGlzIG92ZXJsYWlkCiAqICBEc3RSZWN0OiBQbGFjZSBvZiB0aGUgb3ZlcmxheQogKiAgRmxhZ3M6IHNvbWUgRERPVkVSXyogZmxhZ3MKICoKICogUmV0dXJuczoKICogIERERVJSX1VOU1VQUE9SVEVELCBiZWNhdXNlIHdlIGRvbid0IHN1cHBvcnQgb3ZlcmxheXMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSRUNUIFNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpEc3RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSRUNUIERzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERPVkVSTEFZRlggRlgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKkRzdCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIERzdFN1cmZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBTcmNSZWN0LCBEc3QsIERzdFJlY3QsIEZsYWdzLCBGWCk7CgogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9VcGRhdGVPdmVybGF5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRHN0ID8gRHN0LT5XaW5lRDNEU3VyZmFjZSA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRHN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORURET1ZFUkxBWUZYICopIEZYKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OlVwZGF0ZU92ZXJsYXlEaXNwbGF5CiAqCiAqIFRoZSBEWDcgc2RrIHNheXMgdGhhdCBpdCdzIG5vdCBpbXBsZW1lbnRlZAogKgogKiBQYXJhbXM6CiAqICBGbGFnczogPwogKgogKiBSZXR1cm5zOiBEREVSUl9VTlNVUFBPUlRFRCwgYmVjYXVzZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheURpc3BsYXkoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXgpXG4iLCBUaGlzLCBGbGFncyk7CiAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpVcGRhdGVPdmVybGF5Wk9yZGVyCiAqCiAqIFNldHMgYW4gb3ZlcmxheSdzIFogb3JkZXIKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IERET1ZFUlpfKiBmbGFncwogKiAgRERTUmVmOiBEZWZpbmVzIHRoZSByZWxhdGl2ZSBwb3NpdGlvbiBpbiB0aGUgb3ZlcmxheSBjaGFpbgogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfTk9UT1ZFUkxBWVNVUkZBQ0UsIGJlY2F1c2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKkREU1JlZikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqUmVmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgRERTUmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwKTogUmVsYXlcbiIsIFRoaXMsIEZsYWdzLCBSZWYpOwogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9VcGRhdGVPdmVybGF5Wk9yZGVyKFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZiA/IFJlZi0+V2luZUQzRFN1cmZhY2UgOiBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldERESW50ZXJmYWNlCiAqCiAqIFJldHVybnMgdGhlIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgcG9pbnRlciBvZiB0aGUgRGlyZWN0RHJhdyBvYmplY3QgdGhpcwogKiBzdXJmYWNlIGJlbG9uZ3MgdG8KICoKICogUGFyYW1zOgogKiAgREQ6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGludGVyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXREREludGVyZmFjZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqREQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLEREKTsKCiAgICBpZighREQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgc3dpdGNoKFRoaXMtPnZlcnNpb24pCiAgICB7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgICAqKChJRGlyZWN0RHJhdzcgKiopIEREKSA9IElDT01fSU5URVJGQUNFKFRoaXMtPmRkcmF3LCBJRGlyZWN0RHJhdzcpOwogICAgICAgICAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKCooSURpcmVjdERyYXc3ICoqKSBERCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICooKElEaXJlY3REcmF3NCAqKikgREQpID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3NCk7CiAgICAgICAgICAgIElEaXJlY3REcmF3NF9BZGRSZWYoKihJRGlyZWN0RHJhdzQgKiopIEREKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgKigoSURpcmVjdERyYXcyICoqKSBERCkgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5kZHJhdywgSURpcmVjdERyYXcyKTsKICAgICAgICAgICAgSURpcmVjdERyYXdfQWRkUmVmKCAqKElEaXJlY3REcmF3MiAqKikgREQpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAqKChJRGlyZWN0RHJhdyAqKikgREQpID0gSUNPTV9JTlRFUkZBQ0UoVGhpcy0+ZGRyYXcsIElEaXJlY3REcmF3KTsKICAgICAgICAgICAgSURpcmVjdERyYXdfQWRkUmVmKCAqKElEaXJlY3REcmF3ICoqKSBERCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qIFRoaXMgc2VlbXMgYWxzbyB3aW5kb3dzIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIC0gSSBkb24ndCB0aGluayBXaW5lRDNEIG5lZWRzIHRoaXMgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQ2hhbmdlVW5pcXVlbmVzc1ZhbHVlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICB2b2xhdGlsZSBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsKiB2VGhpcyA9IFRoaXM7CgogICAgVFJBQ0UoIiglcClcbiIsVGhpcyk7CiAgICAvKiBBIHVuaXF1ZW5lc3MgdmFsdWUgb2YgMCBpcyBhcHBhcmVudGx5IHNwZWNpYWwuCiAgICAqIFRoaXMgbmVlZHMgdG8gYmUgY2hlY2tlZC4gKi8KICAgIHdoaWxlICgxKSB7CiAgICAgICAgRFdPUkQgb2xkX3VuaXF1ZW5lc3NfdmFsdWUgPSB2VGhpcy0+dW5pcXVlbmVzc192YWx1ZTsKICAgICAgICBEV09SRCBuZXdfdW5pcXVlbmVzc192YWx1ZSA9IG9sZF91bmlxdWVuZXNzX3ZhbHVlKzE7CgogICAgICAgIGlmIChvbGRfdW5pcXVlbmVzc192YWx1ZSA9PSAwKSBicmVhazsKICAgICAgICBpZiAobmV3X3VuaXF1ZW5lc3NfdmFsdWUgPT0gMCkgbmV3X3VuaXF1ZW5lc3NfdmFsdWUgPSAxOwoKICAgICAgICBpZiAoSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoKExPTkcqKSZ2VGhpcy0+dW5pcXVlbmVzc192YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRfdW5pcXVlbmVzc192YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdfdW5pcXVlbmVzc192YWx1ZSkKICAgICAgICAgICAgPT0gb2xkX3VuaXF1ZW5lc3NfdmFsdWUpCiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0VW5pcXVlbmVzc1ZhbHVlKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLCBMUERXT1JEIHBWYWx1ZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscFZhbHVlKTsKICAgICpwVmFsdWUgPSBUaGlzLT51bmlxdWVuZXNzX3ZhbHVlOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0TE9ECiAqCiAqIFNldHMgdGhlIGxldmVsIG9mIGRldGFpbCBvZiBhIHRleHR1cmUKICoKICogUGFyYW1zOgogKiAgTWF4TE9EOiBMT0QgdG8gc2V0CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElET0JKRUNUIGlmIHRoZSBzdXJmYWNlIGlzIGludmFsaWQgZm9yIHRoaXMgbWV0aG9kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0TE9EKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBNYXhMT0QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJWQpXG4iLCBUaGlzLCBNYXhMT0QpOwoKICAgIGlmICghKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9URVhUVVJFTUFOQUdFKSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRE9CSkVDVDsKCiAgICBpZighVGhpcy0+d2luZUQzRFRleHR1cmUpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFRoZSBEaXJlY3REcmF3IHRleHR1cmUgaGFzIG5vIFdpbmVEM0RUZXh0dXJlIVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURPQkpFQ1Q7CiAgICB9CgogICAgcmV0dXJuIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0TE9EKFRoaXMtPndpbmVEM0RUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heExPRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpHZXRMT0QKICoKICogUmV0dXJucyB0aGUgbGV2ZWwgb2YgZGV0YWlsIG9mIGEgRGlyZWN0M0QgdGV4dHVyZQogKgogKiBQYXJhbXM6CiAqICBNYXhMT0Q6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIExPRCB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBNYXhMT0QgaXMgTlVMTAogKiAgRERFUlJfSU5WQUxJRE9CSkVDVCBpZiB0aGUgc3VyZmFjZSBpcyBpbnZhbGlkIGZvciB0aGlzIG1ldGhvZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldExPRChJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKk1heExPRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIE1heExPRCk7CgogICAgaWYoIU1heExPRCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBpZiAoIShUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfVEVYVFVSRU1BTkFHRSkpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURPQkpFQ1Q7CgogICAgKk1heExPRCA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0TE9EKFRoaXMtPndpbmVEM0RUZXh0dXJlKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkJsdEZhc3QKICoKICogUGVyZm9ybXMgYSBmYXN0IEJsaXQuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6IFRoZSB4IGNvb3JkaW5hdGUgdG8gYmxpdCB0byBvbiB0aGUgZGVzdGluYXRpb24KICogIGRzdHk6IFRoZSB5IGNvb3JkaW5hdGUgdG8gYmxpdCB0byBvbiB0aGUgZGVzdGluYXRpb24KICogIFNvdXJjZTogVGhlIHNvdXJjZSBzdXJmYWNlCiAqICByc3JjOiBUaGUgc291cmNlIHJlY3RhbmdsZQogKiAgdHJhbnM6IFR5cGUgb2YgdHJhbnNmZXIuIFNvbWUgRERCTFRGQVNUXyogZmxhZ3MKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFN1cmZhY2U6OkJsdEZhc3QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHRGYXN0KElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpyc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzcmMgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBTb3VyY2UpOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlcCwlcCwlZCk6IFJlbGF5XG4iLCBUaGlzLCBkc3R4LCBkc3R5LCBTb3VyY2UsIHJzcmMsIHRyYW5zKTsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9CbHRGYXN0KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3R4LCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMgPyBzcmMtPldpbmVEM0RTdXJmYWNlIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMpOwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9OT1RBVkFJTEFCTEU6ICAgICAgICAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX1dST05HVEVYVFVSRUZPUk1BVDogICAgIHJldHVybiBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldENsaXBwZXIKICoKICogUmV0dXJucyB0aGUgSURpcmVjdERyYXdDbGlwcGVyIGludGVyZmFjZSBvZiB0aGUgY2xpcHBlciBhc3NpZ25lZCB0byB0aGlzCiAqIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgQ2xpcHBlciBpcyBOVUxMCiAqICBEREVSUl9OT0NMSVBQRVJBVFRBQ0hFRCBpZiB0aGVyZSdzIG5vIGNsaXBwZXIgYXR0YWNoZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRDbGlwcGVyKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdDbGlwcGVyICoqQ2xpcHBlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIENsaXBwZXIpOwoKICAgIGlmKCFDbGlwcGVyKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIGlmKFRoaXMtPmNsaXBwZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gRERFUlJfTk9DTElQUEVSQVRUQUNIRUQ7CgogICAgKkNsaXBwZXIgPSBJQ09NX0lOVEVSRkFDRShUaGlzLT5jbGlwcGVyLCBJRGlyZWN0RHJhd0NsaXBwZXIpOwogICAgSURpcmVjdERyYXdDbGlwcGVyX0FkZFJlZigqQ2xpcHBlcik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRDbGlwcGVyCiAqCiAqIFNldHMgYSBjbGlwcGVyIGZvciB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBDbGlwcGVyOiBJRGlyZWN0RHJhd0NsaXBwZXIgaW50ZXJmYWNlIG9mIHRoZSBjbGlwcGVyIHRvIHNldAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldENsaXBwZXIoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKkNsaXBwZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlckltcGwgKm9sZENsaXBwZXIgPSBUaGlzLT5jbGlwcGVyOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsQ2xpcHBlcik7CiAgICBpZiAoSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdDbGlwcGVySW1wbCwgSURpcmVjdERyYXdDbGlwcGVyLCBDbGlwcGVyKSA9PSBUaGlzLT5jbGlwcGVyKQogICAgICAgIHJldHVybiBERF9PSzsKCiAgICBUaGlzLT5jbGlwcGVyID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdDbGlwcGVySW1wbCwgSURpcmVjdERyYXdDbGlwcGVyLCBDbGlwcGVyKTsKCiAgICBpZiAoQ2xpcHBlciAhPSBOVUxMKQogICAgICAgIElEaXJlY3REcmF3Q2xpcHBlcl9BZGRSZWYoQ2xpcHBlcik7CiAgICBpZihvbGRDbGlwcGVyKQogICAgICAgIElEaXJlY3REcmF3Q2xpcHBlcl9SZWxlYXNlKElDT01fSU5URVJGQUNFKG9sZENsaXBwZXIsIElEaXJlY3REcmF3Q2xpcHBlcikpOwoKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfU2V0Q2xpcHBlcihUaGlzLT5XaW5lRDNEU3VyZmFjZSwgVGhpcy0+Y2xpcHBlci0+d2luZUQzRENsaXBwZXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0U3VyZmFjZURlc2MKICoKICogU2V0cyB0aGUgc3VyZmFjZSBkZXNjcmlwdGlvbi4gSXQgY2FuIG92ZXJyaWRlIHRoZSBwaXhlbCBmb3JtYXQsIHRoZSBzdXJmYWNlCiAqIG1lbW9yeSwgLi4uCiAqIEl0J3Mgbm90IHJlYWxseSB0ZXN0ZWQuCiAqCiAqIFBhcmFtczoKICogRERTRDogUG9pbnRlciB0byB0aGUgbmV3IHN1cmZhY2UgZGVzY3JpcHRpb24gdG8gc2V0CiAqIEZsYWdzOiBTb21lIGZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREU0QgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFN1cmZhY2VEZXNjKElEaXJlY3REcmF3U3VyZmFjZTcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBXSU5FRDNERk9STUFUIG5ld0Zvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCV4KVxuIiwgVGhpcywgRERTRCwgRmxhZ3MpOwoKICAgIGlmKCFERFNEKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkKICAgIHsKICAgICAgICBuZXdGb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwoKICAgICAgICBpZihuZXdGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJSZXF1ZXN0ZWQgdG8gc2V0IGFuIHVua25vd24gcGl4ZWxmb3JtYXRcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgaWYobmV3Rm9ybWF0ICE9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJlRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQpICkKICAgICAgICB7CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX1NldEZvcm1hdChUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm1hdCk7CiAgICAgICAgICAgIGlmKGhyICE9IEREX09LKSByZXR1cm4gaHI7CiAgICAgICAgfQogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVE9WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KFRoaXMtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVE9WRVJMQVksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmRERTRC0+dTMuZGRja0NLRGVzdE92ZXJsYXkpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVEJMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9ERVNUQkxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJkREU0QtPmRkY2tDS0Rlc3RCbHQpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLU1JDT1ZFUkxBWSkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJkREU0QtPmRkY2tDS1NyY092ZXJsYXkpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLU1JDQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX1NSQ0JMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZERFNELT5kZGNrQ0tTcmNCbHQpOwogICAgfQogICAgaWYgKEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSAmJiBERFNELT5scFN1cmZhY2UpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKFRoaXMtPldpbmVEM0RTdXJmYWNlLCBERFNELT5scFN1cmZhY2UpOwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBuZWVkIGZvciBhIHRyYWNlIGhlcmUsIHdpbmVkM2QgZG9lcyB0aGF0IGZvciB1cyAqLwogICAgICAgICAgICBzd2l0Y2goaHIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzREVSUl9JTlZBTElEQ0FMTDogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgICAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8qIEdvIG9uICovCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQoKICAgIFRoaXMtPnN1cmZhY2VfZGVzYyA9ICpERFNEOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3U3VyZmFjZTc6OkdldFBhbGV0dGUKICoKICogUmV0dXJucyB0aGUgSURpcmVjdERyYXdQYWxldHRlIGludGVyZmFjZSBvZiB0aGUgcGFsZXR0ZSBjdXJyZW50bHkgYXNzaWduZWQKICogdG8gdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgUGFsOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBQYWwgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFBhbGV0dGUoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGUgKipQYWwpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIGlmYWNlKTsKICAgIElXaW5lRDNEUGFsZXR0ZSAqd1BhbDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIFBhbCk7CgogICAgaWYoIVBhbCkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRQYWxldHRlKFRoaXMtPldpbmVEM0RTdXJmYWNlLCAmd1BhbCk7CiAgICBpZihociAhPSBERF9PSykgcmV0dXJuIGhyOwoKICAgIGlmKHdQYWwpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFBhbGV0dGVfR2V0UGFyZW50KHdQYWwsIChJVW5rbm93biAqKikgUGFsKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAqUGFsID0gTlVMTDsKICAgICAgICBociA9IERERVJSX05PUEFMRVRURUFUVEFDSEVEOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldENvbG9yS2V5RW51bQogKgogKiBFbnVtQXR0YWNoZWRTdXJmYWNlIGNhbGxiYWNrIGZvciBTZXRDb2xvcktleS4gVXNlZCB0byBzZXQgY29sb3Iga2V5cwogKiByZWN1cnNpdmVseSBpbiB0aGUgc3VyZmFjZSB0cmVlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RydWN0IFNDS0NvbnRleHQKewogICAgSFJFU1VMVCByZXQ7CiAgICBXSU5FRERDT0xPUktFWSAqQ0tleTsKICAgIERXT1JEIEZsYWdzOwp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClNldENvbG9yS2V5RW51bShJRGlyZWN0RHJhd1N1cmZhY2U3ICpzdXJmYWNlLAogICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBzdXJmYWNlKTsKICAgIHN0cnVjdCBTQ0tDb250ZXh0ICpjdHggPSBjb250ZXh0OwogICAgSFJFU1VMVCBocjsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC0+RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgtPkNLZXkpOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgV0FSTigiSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5IGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgY3R4LT5yZXQgPSBocjsKICAgIH0KCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0VudW1BdHRhY2hlZFN1cmZhY2VzKHN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldENvbG9yS2V5RW51bSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZmFjZSk7CiAgICByZXR1cm4gRERFTlVNUkVUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdTdXJmYWNlNzo6U2V0Q29sb3JLZXkKICoKICogU2V0cyB0aGUgY29sb3Iga2V5aW5nIG9wdGlvbnMgZm9yIHRoZSBzdXJmYWNlLiBPYnNlcnZhdGlvbnMgc2hvd2VkIHRoYXQKICogaW4gY2FzZSBvZiBjb21wbGV4IHN1cmZhY2VzIHRoZSBjb2xvciBrZXkgaGFzIHRvIGJlIGFzc2lnbmVkIHRvIGFsbAogKiBzdWJsZXZlbHMuCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBERENLRVlfKgogKiAgQ0tleTogVGhlIG5ldyBjb2xvciBrZXkKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIFNlZSBJV2luZUQzRFN1cmZhY2U6OlNldENvbG9yS2V5IGZvciBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0Q29sb3JLZXkoSURpcmVjdERyYXdTdXJmYWNlNyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDT0xPUktFWSAqQ0tleSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpOwogICAgc3RydWN0IFNDS0NvbnRleHQgY3R4ID0geyBERF9PSywgKFdJTkVERENPTE9SS0VZICopIENLZXksIEZsYWdzIH07CiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIENLZXkpOwoKICAgIGlmIChDS2V5KQogICAgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpCiAgICAgICAgewogICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kZGNrQ0tEZXN0Qmx0ID0gKkNLZXk7CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy51My5kZGNrQ0tEZXN0T3ZlcmxheSA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZGRja0NLU3JjT3ZlcmxheSA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmRkY2tDS1NyY0JsdCA9ICpDS2V5OwogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0NLU1JDQkxUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpCiAgICAgICAgewogICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgIFRoaXMtPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICY9IH5ERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmPSB+RERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJj0gfkREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICBUaGlzLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmPSB+RERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgIH0KICAgIGN0eC5yZXQgPSBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguQ0tleSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0VudW1BdHRhY2hlZFN1cmZhY2VzKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSAmY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRDb2xvcktleUVudW0pOwogICAgc3dpdGNoKGN0eC5yZXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN0eC5yZXQ7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1N1cmZhY2U3OjpTZXRQYWxldHRlCiAqCiAqIEFzc2lnbnMgYSBEaXJlY3REcmF3UGFsZXR0ZSBvYmplY3QgdG8gdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgUGFsOiBJbnRlcmZhY2UgdG8gdGhlIHBhbGV0dGUgdG8gc2V0CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0UGFsZXR0ZShJRGlyZWN0RHJhd1N1cmZhY2U3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqUGFsKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGUgKm9sZFBhbDsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsICpQYWxJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdQYWxldHRlSW1wbCwgSURpcmVjdERyYXdQYWxldHRlLCBQYWwpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBQYWwpOwoKICAgIC8qIEZpbmQgdGhlIG9sZCBwYWxldHRlICovCiAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZV9HZXRQYWxldHRlKGlmYWNlLCAmb2xkUGFsKTsKICAgIGlmKGhyICE9IEREX09LICYmIGhyICE9IERERVJSX05PUEFMRVRURUFUVEFDSEVEKSByZXR1cm4gaHI7CiAgICBpZihvbGRQYWwpIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKG9sZFBhbCk7ICAvKiBGb3IgdGhlIEdldFBhbGV0dGUgKi8KCiAgICAvKiBTZXQgdGhlIG5ldyBQYWxldHRlICovCiAgICBJV2luZUQzRFN1cmZhY2VfU2V0UGFsZXR0ZShUaGlzLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhbEltcGwgPyBQYWxJbXBsLT53aW5lRDNEUGFsZXR0ZSA6IE5VTEwpOwogICAgLyogQWRkUmVmIHRoZSBQYWxldHRlICovCiAgICBpZihQYWwpIElEaXJlY3REcmF3UGFsZXR0ZV9BZGRSZWYoUGFsKTsKCiAgICAvKiBSZWxlYXNlIHRoZSBvbGQgcGFsZXR0ZSAqLwogICAgaWYob2xkUGFsKSBJRGlyZWN0RHJhd1BhbGV0dGVfUmVsZWFzZShvbGRQYWwpOwoKICAgIC8qIElmIHRoaXMgaXMgYSBmcm9udCBidWZmZXIsIGFsc28gdXBkYXRlIHRoZSBiYWNrIGJ1ZmZlcnMKICAgICAqIFRPRE86IEhvdyBkbyB0aGluZ3Mgd29yayBmb3IgcGFsZXR0aXplZCBjdWJlIHRleHR1cmVzPwogICAgICovCiAgICBpZihUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0ZST05UQlVGRkVSKQogICAgewogICAgICAgIC8qIEZvciBwcmltYXJ5IHN1cmZhY2VzIHRoZSB0cmVlIGlzIGp1c3QgYSBsaXN0LCBzbyB0aGUgc2ltcGxlciBzY2hlbWUgZml0cyB0b28gKi8KICAgICAgICBERFNDQVBTMiBjYXBzMiA9IHsgRERTQ0FQU19QUklNQVJZU1VSRkFDRSwgMCwgMCwgMCB9OwoKICAgICAgICBzdXJmID0gVGhpczsKICAgICAgICB3aGlsZSgxKQogICAgICAgIHsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqYXR0YWNoOwogICAgICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgICAgICBociA9IElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYXBzMiwgJmF0dGFjaCk7CiAgICAgICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgcGFsZXR0ZSBvbiAlcFxuIiwgYXR0YWNoKTsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19TZXRQYWxldHRlKGF0dGFjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhbCk7CiAgICAgICAgICAgIHN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBhdHRhY2gpOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoYXR0YWNoKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFZUYWJsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpjb25zdCBJRGlyZWN0RHJhd1N1cmZhY2U3VnRibCBJRGlyZWN0RHJhd1N1cmZhY2U3X1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qKiogSURpcmVjdERyYXdTdXJmYWNlICoqKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZTdJbXBsX0FkZEF0dGFjaGVkU3VyZmFjZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQWRkT3ZlcmxheURpcnR5UmVjdCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQmx0LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9CbHRCYXRjaCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRGVsZXRlQXR0YWNoZWRTdXJmYWNlLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9FbnVtQXR0YWNoZWRTdXJmYWNlcywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRW51bU92ZXJsYXlaT3JkZXJzLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9GbGlwLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRBdHRhY2hlZFN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Q2FwcywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Q2xpcHBlciwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfR2V0Q29sb3JLZXksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldERDLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRPdmVybGF5UG9zaXRpb24sCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0dldFBpeGVsRm9ybWF0LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRTdXJmYWNlRGVzYywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfSW5pdGlhbGl6ZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfSXNMb3N0LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9Mb2NrLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9SZWxlYXNlREMsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1Jlc3RvcmUsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldENsaXBwZXIsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldENvbG9yS2V5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRPdmVybGF5UG9zaXRpb24sCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFBhbGV0dGUsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VubG9jaywKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheURpc3BsYXksCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIsCiAgICAvKioqIElEaXJlY3REcmF3U3VyZmFjZTIgKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXREREludGVyZmFjZSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfUGFnZUxvY2ssCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1BhZ2VVbmxvY2ssCiAgICAvKioqIElEaXJlY3REcmF3U3VyZmFjZTMgKioqLwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9TZXRTdXJmYWNlRGVzYywKICAgIC8qKiogSURpcmVjdERyYXdTdXJmYWNlNCAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhLAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRVbmlxdWVuZXNzVmFsdWUsCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX0NoYW5nZVVuaXF1ZW5lc3NWYWx1ZSwKICAgIC8qKiogSURpcmVjdERyYXdTdXJmYWNlNyAqKiovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRQcmlvcml0eSwKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfU2V0TE9ELAogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbF9HZXRMT0QKfTsK