LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5udC5oIgojaW5jbHVkZSAid2luY29uLmgiCgojaW5jbHVkZSAibXNkb3MuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zdm0uaCIKI2luY2x1ZGUgInN0YWNrZnJhbWUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChpbnQpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSk7CgpXT1JEIERPU1ZNX3BzcCA9IDA7CldPUkQgRE9TVk1fcmV0dmFsID0gMDsKCiNpZmRlZiBIQVZFX1NZU19WTTg2X0gKIyBpbmNsdWRlIDxzeXMvdm04Ni5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKCnR5cGVkZWYgc3RydWN0IF9ET1NFVkVOVCB7CiAgaW50IGlycSxwcmlvcml0eTsKICBET1NSRUxBWSByZWxheTsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBfRE9TRVZFTlQgKm5leHQ7Cn0gRE9TRVZFTlQsICpMUERPU0VWRU5UOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQgPSBDUklUSUNBTF9TRUNUSU9OX0lOSVQoIkRPU1ZNIik7CnN0YXRpYyBzdHJ1Y3QgX0RPU0VWRU5UICpwZW5kaW5nX2V2ZW50LCAqY3VycmVudF9ldmVudDsKc3RhdGljIEhBTkRMRSBldmVudF9ub3RpZmllcjsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMKICoKICogUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIHBlbmRpbmcgZXZlbnRzIHRoYXQgYXJlIG5vdAogKiBibG9ja2VkIGJ5IGN1cnJlbnRseSBhY3RpdmUgZXZlbnQuCiAqLwpzdGF0aWMgQk9PTCBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCB2b2lkICkKeyAgIAogICAgaWYgKCFwZW5kaW5nX2V2ZW50KQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIWN1cnJlbnRfZXZlbnQpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaWYgKHBlbmRpbmdfZXZlbnQtPnByaW9yaXR5IDwgY3VycmVudF9ldmVudC0+cHJpb3JpdHkpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBET1NWTV9TZW5kT25lRXZlbnQKICoKICogUHJvY2VzcyBzaW5nbGUgcGVuZGluZyBldmVudC4KICoKICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIHdpdGggcXVldWUgY3JpdGljYWwgc2VjdGlvbiBsb2NrZWQuIAogKiBUaGUgZnVuY3Rpb24gdGVtcG9yYXJpbHkgcmVsZWFzZXMgdGhlIGNyaXRpY2FsIHNlY3Rpb24gaWYgaXQgaXMgCiAqIHBvc3NpYmxlIHRoYXQgaW50ZXJuYWwgaW50ZXJydXB0IGhhbmRsZXIgb3IgdXNlciBwcm9jZWR1cmUgd2lsbCAKICogYmUgY2FsbGVkLiBUaGlzIGlzIGJlY2F1c2Ugd2UgbWF5IG90aGVyd2lzZSBnZXQgYSBkZWFkbG9jayBpZgogKiBhbm90aGVyIHRocmVhZCBpcyB3YWl0aW5nIGZvciB0aGUgc2FtZSBjcml0aWNhbCBzZWN0aW9uLgogKi8Kc3RhdGljIHZvaWQgRE9TVk1fU2VuZE9uZUV2ZW50KCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBMUERPU0VWRU5UIGV2ZW50ID0gcGVuZGluZ19ldmVudDsKCiAgICAvKiBSZW1vdmUgZnJvbSBwZW5kaW5nIGV2ZW50cyBsaXN0LiAqLwogICAgcGVuZGluZ19ldmVudCA9IGV2ZW50LT5uZXh0OwoKICAgIC8qIFByb2Nlc3MgYWN0aXZlIGV2ZW50LiAqLwogICAgaWYgKGV2ZW50LT5pcnEgPj0gMCkgCiAgICB7CiAgICAgICAgQllURSBpbnRudW0gPSAoZXZlbnQtPmlycSA8IDgpID8KICAgICAgICAgICAgKGV2ZW50LT5pcnEgKyA4KSA6IChldmVudC0+aXJxIC0gOCArIDB4NzApOwogICAgICAgICAgICAKICAgICAgICAvKiBFdmVudCBpcyBhbiBJUlEsIG1vdmUgaXQgdG8gY3VycmVudCBldmVudHMgbGlzdC4gKi8KICAgICAgICBldmVudC0+bmV4dCA9IGN1cnJlbnRfZXZlbnQ7CiAgICAgICAgY3VycmVudF9ldmVudCA9IGV2ZW50OwoKICAgICAgICBUUkFDRSggIkRpc3BhdGNoaW5nIElSUSAlZC5cbiIsIGV2ZW50LT5pcnEgKTsKCiAgICAgICAgaWYgKElTVjg2KGNvbnRleHQpKQogICAgICAgIHsKICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCBpZiBET1NWTV9IYXJkd2FyZUludGVycnVwdFJNIGNhbGxzIGFuIGludGVybmFsIAogICAgICAgICAgICAgKiBpbnRlcnJ1cHQgZGlyZWN0bHksIGN1cnJlbnRfZXZlbnQgbWlnaHQgYmUgY2xlYXJlZCAKICAgICAgICAgICAgICogKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyBjYWxsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgRE9TVk1fSGFyZHdhcmVJbnRlcnJ1cHRSTSggY29udGV4dCwgaW50bnVtICk7CiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgcm91dGluZSBvbmx5IG1vZGlmaWVzIGN1cnJlbnQgY29udGV4dCBzbyBpdCBpcwogICAgICAgICAgICAgKiBub3QgbmVjZXNzYXJ5IHRvIHJlbGVhc2UgY3JpdGljYWwgc2VjdGlvbi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0hhcmR3YXJlSW50ZXJydXB0UE0oIGNvbnRleHQsIGludG51bSApOwogICAgICAgIH0KICAgIH0gCiAgICBlbHNlIAogICAgewogICAgICAgIC8qIENhbGxiYWNrIGV2ZW50LiAqLwogICAgICAgIFRSQUNFKCAiRGlzcGF0Y2hpbmcgY2FsbGJhY2sgZXZlbnQuXG4iICk7CgogICAgICAgIGlmIChJU1Y4Nihjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIENhbGwgcmVsYXkgaW1tZWRpYXRlbHkgaW4gcmVhbCBtb2RlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICAgICAgKCpldmVudC0+cmVsYXkpKCBjb250ZXh0LCBldmVudC0+ZGF0YSApOwogICAgICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3JjZSByZXR1cm4gdG8gcmVsYXkgY29kZS4gV2UgZG8gbm90IHdhbnQgdG8KICAgICAgICAgICAgICogY2FsbCByZWxheSBkaXJlY3RseSBiZWNhdXNlIHdlIG1heSBiZSBpbnNpZGUgYSBzaWduYWwgaGFuZGxlci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERPU1ZNX0J1aWxkQ2FsbEZyYW1lKCBjb250ZXh0LCBldmVudC0+cmVsYXksIGV2ZW50LT5kYXRhICk7CiAgICAgICAgfQoKICAgICAgICBmcmVlKGV2ZW50KTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cwogKgogKiBBcyBsb25nIGFzIGNvbnRleHQgaW5zdHJ1Y3Rpb24gcG9pbnRlciBzdGF5cyB1bm1vZGlmaWVkLAogKiBwcm9jZXNzIGFsbCBwZW5kaW5nIGV2ZW50cyB0aGF0IGFyZSBub3QgYmxvY2tlZCBieSBjdXJyZW50bHkKICogYWN0aXZlIGV2ZW50LgogKgogKiBUaGlzIHJvdXRpbmUgYXNzdW1lcyB0aGF0IGNhbGxlciBoYXMgYWxyZWFkeSBjbGVhcmVkIFRFQi52bTg2X3BlbmRpbmcgCiAqIGFuZCBjaGVja2VkIHRoYXQgaW50ZXJydXB0cyBhcmUgZW5hYmxlZC4KICovCnZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyggQ09OVEVYVDg2ICpjb250ZXh0ICkKeyAgIAogICAgRFdPUkQgb2xkX2NzID0gY29udGV4dC0+U2VnQ3M7CiAgICBEV09SRCBvbGRfaXAgPSBjb250ZXh0LT5FaXA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKCiAgICBUUkFDRSggIkNhbGxlZCBpbiAlcyBtb2RlICVzIGV2ZW50cyBwZW5kaW5nICh0aW1lPSVsZClcbiIsCiAgICAgICAgICAgSVNWODYoY29udGV4dCkgPyAicmVhbCIgOiAicHJvdGVjdGVkIiwKICAgICAgICAgICBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkgPyAid2l0aCIgOiAid2l0aG91dCIsCiAgICAgICAgICAgR2V0VGlja0NvdW50KCkgKTsKICAgIFRSQUNFKCAiY3M6aXA9JTA0bHg6JTA4bHgsIHNzOnNwPSUwNGx4OiUwOGx4XG4iLAogICAgICAgICAgIGNvbnRleHQtPlNlZ0NzLCBjb250ZXh0LT5FaXAsIGNvbnRleHQtPlNlZ1NzLCBjb250ZXh0LT5Fc3ApOwoKICAgIHdoaWxlIChjb250ZXh0LT5TZWdDcyA9PSBvbGRfY3MgJiYKICAgICAgICAgICBjb250ZXh0LT5FaXAgPT0gb2xkX2lwICYmCiAgICAgICAgICAgRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIERPU1ZNX1NlbmRPbmVFdmVudChjb250ZXh0KTsKCiAgICAgICAgLyoKICAgICAgICAgKiBFdmVudCBoYW5kbGluZyBtYXkgaGF2ZSB0dXJuZWQgcGVuZGluZyBldmVudHMgZmxhZyBvbi4KICAgICAgICAgKiBXZSBkaXNhYmxlIGl0IGhlcmUgYmVjYXVzZSB0aGlzIHByZXZlbnRzIHNvbWUKICAgICAgICAgKiB1bm5lY2Vzc2FyeSBjYWxscyB0byB0aGlzIGZ1bmN0aW9uLgogICAgICAgICAqLwogICAgICAgIE50Q3VycmVudFRlYigpLT52bTg2X3BlbmRpbmcgPSAwOwogICAgfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKICAgIGlmICghSVNWODYoY29udGV4dCkgJiYgY29udGV4dC0+U2VnQ3MgPT0gb2xkX2NzICYmIGNvbnRleHQtPkVpcCA9PSBvbGRfaXApCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBSb3V0aW5lIHdhcyBjYWxsZWQgZnJvbSBEUE1JIGJ1dCB0aGVyZSB3YXMgbm90aGluZyB0byBkby4KICAgICAgICAgKiBXZSBmb3JjZSBhIGR1bW15IHJlbGF5IGNhbGwgaGVyZSBzbyB0aGF0IHdlIGRvbid0IGdldCBhIHJhY2UKICAgICAgICAgKiBpZiBzaWduYWxzIGFyZSB1bmJsb2NrZWQgd2hlbiB3ZSByZXR1cm4gdG8gRFBNSSBhcHBsaWNhdGlvbi4KICAgICAgICAgKi8KICAgICAgICBUUkFDRSggIkNhbGxlZCBidXQgdGhlcmUgd2FzIG5vdGhpbmcgdG8gZG8sIGNhbGxpbmcgTlVMTCByZWxheS5cbiIgKTsKICAgICAgICBET1NWTV9CdWlsZENhbGxGcmFtZSggY29udGV4dCwgTlVMTCwgTlVMTCApOwogICAgfQoKICAgIGlmIChET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJbnRlcnJ1cHRzIGRpc2FibGVkLCBidXQgdGhlcmUgYXJlIHN0aWxsCiAgICAgICAgICogcGVuZGluZyBldmVudHMsIG1ha2Ugc3VyZSB0aGF0IHBlbmRpbmcgZmxhZyBpcyB0dXJuZWQgb24uCiAgICAgICAgICovCiAgICAgICAgVFJBQ0UoICJBbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHNldHRpbmcgVklQIGZsYWcuXG4iICk7CiAgICAgICAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyB8PSBWSVBfTUFTSzsKICAgIH0KCiNlbHNlCgogICAgRklYTUUoIk5vIERPUyAuZXhlIGZpbGUgc3VwcG9ydCBvbiB0aGlzIHBsYXRmb3JtICh5ZXQpXG4iKTsKCiNlbmRpZiAvKiBNWl9TVVBQT1JURUQgKi8KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwp9CgoKI2lmZGVmIE1aX1NVUFBPUlRFRAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVF1ZXVlRXZlbnQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1F1ZXVlRXZlbnQoIElOVCBpcnEsIElOVCBwcmlvcml0eSwgRE9TUkVMQVkgcmVsYXksIExQVk9JRCBkYXRhKQp7CiAgTFBET1NFVkVOVCBldmVudCwgY3VyLCBwcmV2OwogIEJPT0wgICAgICAgb2xkX3BlbmRpbmc7CgogIGlmIChNWl9DdXJyZW50KCkpIHsKICAgIGV2ZW50ID0gbWFsbG9jKHNpemVvZihET1NFVkVOVCkpOwogICAgaWYgKCFldmVudCkgewogICAgICBFUlIoIm91dCBvZiBtZW1vcnkgYWxsb2NhdGluZyBldmVudCBlbnRyeVxuIik7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGV2ZW50LT5pcnEgPSBpcnE7IGV2ZW50LT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgZXZlbnQtPnJlbGF5ID0gcmVsYXk7IGV2ZW50LT5kYXRhID0gZGF0YTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgb2xkX3BlbmRpbmcgPSBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCk7CgogICAgLyogaW5zZXJ0IGV2ZW50IGludG8gbGlua2VkIGxpc3QsIGluIG9yZGVyICphZnRlcioKICAgICAqIGFsbCBlYXJsaWVyIGV2ZW50cyBvZiBoaWdoZXIgb3IgZXF1YWwgcHJpb3JpdHkgKi8KICAgIGN1ciA9IHBlbmRpbmdfZXZlbnQ7IHByZXYgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAmJiBjdXItPnByaW9yaXR5PD1wcmlvcml0eSkgewogICAgICBwcmV2ID0gY3VyOwogICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBldmVudC0+bmV4dCA9IGN1cjsKICAgIGlmIChwcmV2KSBwcmV2LT5uZXh0ID0gZXZlbnQ7CiAgICBlbHNlIHBlbmRpbmdfZXZlbnQgPSBldmVudDsKCiAgICBpZiAoIW9sZF9wZW5kaW5nICYmIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkgewogICAgICBUUkFDRSgibmV3IGV2ZW50IHF1ZXVlZCwgc2lnbmFsbGluZyAodGltZT0lbGQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICAgIAogICAgICAvKiBBbGVydCBWTTg2IHRocmVhZCBhYm91dCB0aGUgbmV3IGV2ZW50LiAqLwogICAgICBraWxsKGRvc3ZtX3BpZCxTSUdVU1IyKTsKCiAgICAgIC8qIFdha2UgdXAgRE9TVk1fV2FpdCBzbyB0aGF0IGl0IGNhbiBzZXJ2ZSBwZW5kaW5nIGV2ZW50cy4gKi8KICAgICAgU2V0RXZlbnQoZXZlbnRfbm90aWZpZXIpOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0UoIm5ldyBldmVudCBxdWV1ZWQgKHRpbWU9JWxkKVxuIiwgR2V0VGlja0NvdW50KCkpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgfSBlbHNlIHsKICAgIC8qIERPUyBzdWJzeXN0ZW0gbm90IHJ1bm5pbmcgKi8KICAgIC8qICh0aGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgd2UncmUgcnVubmluZyBhIHdpbjE2IGFwcAogICAgICogIHdoaWNoIHVzZXMgRFBNSSB0byB0aHVuayBkb3duIHRvIERPUyBzZXJ2aWNlcykgKi8KICAgIGlmIChpcnE8MCkgewogICAgICAvKiBjYWxsYmFjayBldmVudCwgcGVyZm9ybSBpdCB3aXRoIGR1bW15IGNvbnRleHQgKi8KICAgICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICAgIG1lbXNldCgmY29udGV4dCwwLHNpemVvZihjb250ZXh0KSk7CiAgICAgICgqcmVsYXkpKCZjb250ZXh0LGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgRVJSKCJJUlEgd2l0aG91dCBET1MgdGFzazogc2hvdWxkIG5vdCBoYXBwZW5cbiIpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc0NvbnNvbGUodm9pZCkKewogIElOUFVUX1JFQ09SRCBtc2c7CiAgRFdPUkQgcmVzOwogIEJZVEUgc2NhbiwgYXNjaWk7CgogIGlmIChSZWFkQ29uc29sZUlucHV0QShHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSksJm1zZywxLCZyZXMpKSB7CiAgICBzd2l0Y2ggKG1zZy5FdmVudFR5cGUpIHsKICAgIGNhc2UgS0VZX0VWRU5UOgogICAgICBzY2FuID0gbXNnLkV2ZW50LktleUV2ZW50LndWaXJ0dWFsU2NhbkNvZGU7CiAgICAgIGFzY2lpID0gbXNnLkV2ZW50LktleUV2ZW50LnVDaGFyLkFzY2lpQ2hhcjsKICAgICAgVFJBQ0UoInNjYW4gJTAyeCwgYXNjaWkgJTAyeFxuIiwgc2NhbiwgYXNjaWkpOwoKICAgICAgLyogc2V0IHRoZSAiYnJlYWsiIChyZWxlYXNlKSBmbGFnIGlmIGtleSByZWxlYXNlZCAqLwogICAgICBpZiAoIW1zZy5FdmVudC5LZXlFdmVudC5iS2V5RG93bikgc2NhbiB8PSAweDgwOwoKICAgICAgLyogY2hlY2sgd2hldGhlciBleHRlbmRlZCBiaXQgaXMgc2V0LAogICAgICAgKiBhbmQgaWYgc28sIHF1ZXVlIHRoZSBleHRlbnNpb24gcHJlZml4ICovCiAgICAgIGlmIChtc2cuRXZlbnQuS2V5RXZlbnQuZHdDb250cm9sS2V5U3RhdGUgJiBFTkhBTkNFRF9LRVkpIHsKICAgICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLCBhc2NpaSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBNT1VTRV9FVkVOVDoKICAgICAgRE9TVk1fSW50MzNDb25zb2xlKCZtc2cuRXZlbnQuTW91c2VFdmVudCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgV0lORE9XX0JVRkZFUl9TSVpFX0VWRU5ULlxuIik7CiAgICAgIGJyZWFrOwogICAgY2FzZSBNRU5VX0VWRU5UOgogICAgICBGSVhNRSgidW5oYW5kbGVkIE1FTlVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIEZPQ1VTX0VWRU5UOgogICAgICBGSVhNRSgidW5oYW5kbGVkIEZPQ1VTX0VWRU5ULlxuIik7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgRklYTUUoInVua25vd24gY29uc29sZSBldmVudDogJWRcbiIsIG1zZy5FdmVudFR5cGUpOwogICAgfQogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoTVNHICptc2cpCnsKICBCWVRFIHNjYW4gPSAwOwoKICBUUkFDRSgiZ290IG1lc3NhZ2UgJTA0eCwgd3BhcmFtPSUwOHgsIGxwYXJhbT0lMDhseFxuIixtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIGlmICgobXNnLT5tZXNzYWdlPj1XTV9NT1VTRUZJUlNUKSYmCiAgICAgIChtc2ctPm1lc3NhZ2U8PVdNX01PVVNFTEFTVCkpIHsKICAgIERPU1ZNX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJRE9TVk1fSW50MDlTZW5kU2NhbigweEUwLDApOwogICAgICB9CiAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oc2NhbiwwKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlET1NWTV9XYWl0CiAqCiAqIFdhaXQgZm9yIGFzeW5jaHJvbm91cyBldmVudHMuIFRoaXMgcm91dGluZSB0ZW1wb3JhcmlseSBlbmFibGVzCiAqIGludGVycnVwdHMgYW5kIHdhaXRzIHVudGlsIHNvbWUgYXN5bmNocm9ub3VzIGV2ZW50IGhhcyBiZWVuIAogKiBwcm9jZXNzZWQuCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9XYWl0KCBDT05URVhUODYgKndhaXRjdHggKQp7CiAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKQogICAgewogICAgICAgIENPTlRFWFQ4NiBjb250ZXh0ID0gKndhaXRjdHg7CiAgICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBET1NWTV9XYWl0IGlzIGNhbGxlZCBmcm9tIHByb3RlY3RlZCBtb2RlIHdlIGVtdWxhdGUKICAgICAgICAgKiBpbnRlcnJ1cHQgcmVmbGVjdGlvbiBhbmQgY29udmVydCBjb250ZXh0IGludG8gcmVhbCBtb2RlIGNvbnRleHQuCiAgICAgICAgICogVGhpcyBpcyBhY3R1YWxseSB0aGUgY29ycmVjdCB0aGluZyB0byBkbyBhcyBsb25nIGFzIERPU1ZNX1dhaXQKICAgICAgICAgKiBpcyBvbmx5IGNhbGxlZCBmcm9tIHRob3NlIGludGVycnVwdCBmdW5jdGlvbnMgdGhhdCBEUE1JIHJlZmxlY3RzCiAgICAgICAgICogdG8gcmVhbCBtb2RlLgogICAgICAgICAqCiAgICAgICAgICogRklYTUU6IE5lZWQgdG8gdGhpbmsgYWJvdXQgd2hlcmUgdG8gcGxhY2UgcmVhbCBtb2RlIHN0YWNrLgogICAgICAgICAqIEZJWE1FOiBJZiBET1NWTV9XYWl0IGNhbGxzIGFyZSBuZXN0ZWQgc3RhY2sgZ2V0cyBjb3JydXB0ZWQuCiAgICAgICAgICogICAgICAgIENhbiB0aGlzIHJlYWxseSBoYXBwZW4/CiAgICAgICAgICovCiAgICAgICAgaWYgKCFJU1Y4NigmY29udGV4dCkpCiAgICAgICAgewogICAgICAgICAgICBjb250ZXh0LkVGbGFncyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICBjb250ZXh0LlNlZ1NzID0gMHhmZmZmOwogICAgICAgICAgICBjb250ZXh0LkVzcCA9IDA7CiAgICAgICAgfQoKICAgICAgICBjb250ZXh0LkVGbGFncyB8PSBWSUZfTUFTSzsKICAgICAgICBjb250ZXh0LlNlZ0NzID0gMDsKICAgICAgICBjb250ZXh0LkVpcCA9IDA7CgogICAgICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQpOwoKICAgICAgICBpZihjb250ZXh0LlNlZ0NzIHx8IGNvbnRleHQuRWlwKQogICAgICAgICAgICBEUE1JX0NhbGxSTVByb2MoICZjb250ZXh0LCBOVUxMLCAwLCBUUlVFICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgSEFORExFIG9ianNbMl07CiAgICAgICAgaW50ICAgIG9iamMgPSBET1NWTV9Jc1dpbjE2KCkgPyAyIDogMTsKICAgICAgICBEV09SRCAgd2FpdHJldDsKCiAgICAgICAgb2Jqc1swXSA9IGV2ZW50X25vdGlmaWVyOwogICAgICAgIG9ianNbMV0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CgogICAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKCBvYmpjLCBvYmpzLCBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElORklOSVRFLCBRU19BTExJTlBVVCApOwogICAgICAgIAogICAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOZXcgcGVuZGluZyBldmVudCBoYXMgYmVlbiBxdWV1ZWQsIHdlIGlnbm9yZSBpdAogICAgICAgICAgICAgKiBoZXJlIGJlY2F1c2UgaXQgd2lsbCBiZSBwcm9jZXNzZWQgb24gbmV4dCBjYWxsIHRvCiAgICAgICAgICAgICAqIERPU1ZNX1dhaXQuCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChvYmpjID09IDIgJiYgd2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkKICAgICAgICB7CiAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIG9iamMpCiAgICAgICAgewogICAgICAgICAgICBNU0cgbXNnOwogICAgICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogZ290IGEgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgICAgICAvKiB3ZSBkb24ndCBuZWVkIGEgVHJhbnNsYXRlTWVzc2FnZSBoZXJlICovCiAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIEVSUl8obW9kdWxlKSggImRvc3ZtIHdhaXQgZXJyb3I9JWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIH0KICAgIH0KfQoKCkRXT1JEIFdJTkFQSSBET1NWTV9Mb29wKCBIQU5ETEUgaFRocmVhZCApCnsKICBIQU5ETEUgb2Jqc1syXTsKICBNU0cgbXNnOwogIERXT1JEIHdhaXRyZXQ7CgogIG9ianNbMF0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgb2Jqc1sxXSA9IGhUaHJlYWQ7CgogIGZvcig7OykgewogICAgICBUUkFDRV8oaW50KSgid2FpdGluZyBmb3IgYWN0aW9uXG4iKTsKICAgICAgd2FpdHJldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMiwgb2JqcywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCk7CiAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgIH0KICAgICAgZWxzZSBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkgewogICAgICAgICBEV09SRCBydjsKICAgICAgICAgaWYoIUdldEV4aXRDb2RlVGhyZWFkKGhUaHJlYWQsICZydikpIHsKICAgICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGdldCB0aHJlYWQgZXhpdCBjb2RlIVxuIik7CiAgICAgICAgICAgICBydiA9IDA7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHJ2OwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDIpIHsKICAgICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkUpKSB7CiAgICAgICAgICAgICAgaWYgKG1zZy5od25kKSB7CiAgICAgICAgICAgICAgICAgIC8qIGl0J3MgYSB3aW5kb3cgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgdGhyZWFkIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgc3dpdGNoIChtc2cubWVzc2FnZSkgewogICAgICAgICAgICAgICAgICBjYXNlIFdNX1FVSVQ6CiAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9wIHRoaXMgbWFkbmVzcyEhICovCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9VU0VSOgogICAgICAgICAgICAgICAgICAgICAgLyogcnVuIHBhc3NlZCBwcm9jZWR1cmUgaW4gdGhpcyB0aHJlYWQgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIChzb3J0IG9mIGxpa2UgQVBDLCBidXQgd2Ugc2lnbmFsIHRoZSBjb21wbGV0aW9uKSAqLwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIERPU19TUEMgKnNwYyA9IChET1NfU1BDICopbXNnLmxQYXJhbTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiY2FsbGluZyAlcCB3aXRoIGFyZyAlMDhseFxuIiwgc3BjLT5wcm9jLCBzcGMtPmFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgKHNwYy0+cHJvYykoc3BjLT5hcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFXyhpbnQpKCJkb25lLCBzaWduYWxsaW5nIGV2ZW50ICV4XG4iLCBtc2cud1BhcmFtKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRFdmVudCggKEhBTkRMRSltc2cud1BhcmFtICk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgICBFUlJfKGludCkoIk1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMgcmV0dXJuZWQgdW5leHBlY3RlZCB2YWx1ZS5cbiIpOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICB9Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIoZXhjZXB0aW9uX2hhbmRsZXIpCnsKICBFWENFUFRJT05fUkVDT1JEICpyZWMgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5FeGNlcHRpb25SZWNvcmQ7CiAgQ09OVEVYVCAqY29udGV4dCA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkNvbnRleHRSZWNvcmQ7CiAgaW50IGFyZyA9IHJlYy0+RXhjZXB0aW9uSW5mb3JtYXRpb25bMF07CiAgQk9PTCByZXQ7CgogIHN3aXRjaChyZWMtPkV4Y2VwdGlvbkNvZGUpIHsKICBjYXNlIEVYQ0VQVElPTl9WTTg2X0lOVHg6CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIkNhbGwgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICAgIH0KICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgYXJnICk7CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICB9CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTiA6IEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7CgogIGNhc2UgRVhDRVBUSU9OX1ZNODZfU1RJOgogIC8qIGNhc2UgRVhDRVBUSU9OX1ZNODZfUElDUkVUVVJOOiAqLwogICAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgRVJSKCAiUHJvdGVjdGVkIG1vZGUgU1RJIGNhdWdodCBieSByZWFsIG1vZGUgaGFuZGxlciFcbiIgKTsKCiAgICBjb250ZXh0LT5FRmxhZ3MgfD0gVklGX01BU0s7CiAgICBjb250ZXh0LT5FRmxhZ3MgJj0gflZJUF9NQVNLOwogICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhjb250ZXh0KTsKICAgIHJldHVybiBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OOwogIH0KICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX1NFQVJDSDsKfQoKaW50IFdJTkFQSSBET1NWTV9FbnRlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogIC8qIFNvbWUgY2FsbGVycyBmb3JnZXQgdG8gdHVybiBWODZfRkxBRyBvbi4gKi8KICBjb250ZXh0LT5FRmxhZ3MgfD0gVjg2X0ZMQUc7CgogIF9fVFJZCiAgewogICAgX193aW5lX2VudGVyX3ZtODYoIGNvbnRleHQgKTsKICAgIFRSQUNFXyhtb2R1bGUpKCAidm04NiByZXR1cm5lZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSApOwogIH0KICBfX0VYQ0VQVChleGNlcHRpb25faGFuZGxlcikKICB7CiAgICBUUkFDRV8obW9kdWxlKSggImxlYXZpbmcgdm04NiBtb2RlXG4iICk7CiAgfQogIF9fRU5EVFJZCgogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICAgIExQRE9TRVZFTlQgZXZlbnQ7CgogICAgaWYgKChwb3J0PT0weDIwKSAmJiAodmFsPT0weDIwKSkgewogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICBpZiAoY3VycmVudF9ldmVudCkgewoJLyogRU9JIChFbmQgT2YgSW50ZXJydXB0KSAqLwoJVFJBQ0UoInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gY3VycmVudF9ldmVudDsKCWN1cnJlbnRfZXZlbnQgPSBldmVudC0+bmV4dDsKCWlmIChldmVudC0+cmVsYXkpCgkoKmV2ZW50LT5yZWxheSkoTlVMTCxldmVudC0+ZGF0YSk7CglmcmVlKGV2ZW50KTsKCglpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKSB7CgkgIC8qIGFub3RoZXIgZXZlbnQgaXMgcGVuZGluZywgd2hpY2ggd2Ugc2hvdWxkIHByb2JhYmx5CgkgICAqIGJlIGFibGUgdG8gcHJvY2VzcyBub3cgKi8KCSAgVFJBQ0UoImFub3RoZXIgZXZlbnQgcGVuZGluZywgc2V0dGluZyBmbGFnXG4iKTsKCSAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyB8PSBWSVBfTUFTSzsKCX0KICAgICAgfSBlbHNlIHsKCVdBUk4oIkVPSSB3aXRob3V0IGFjdGl2ZSBJUlFcbiIpOwogICAgICB9CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICB9IGVsc2UgewogICAgICBGSVhNRSgidW5yZWNvZ25pemVkIFBJQyBjb21tYW5kICUwMnhcbiIsdmFsKTsKICAgIH0KfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlFbnRlciAoV0lORURPUy5AKQogKi8KSU5UIFdJTkFQSSBET1NWTV9FbnRlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogRVJSXyhtb2R1bGUpKCJET1MgcmVhbG1vZGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZSFcbiIpOwogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVdhaXQgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1dhaXQoIENPTlRFWFQ4NiAqd2FpdGN0eCApIHsgfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlPdXRQSUMgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKSB7fQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlRdWV1ZUV2ZW50IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9RdWV1ZUV2ZW50KCBJTlQgaXJxLCBJTlQgcHJpb3JpdHksIERPU1JFTEFZIHJlbGF5LCBMUFZPSUQgZGF0YSkKewogIGlmIChpcnE8MCkgewogICAgLyogY2FsbGJhY2sgZXZlbnQsIHBlcmZvcm0gaXQgd2l0aCBkdW1teSBjb250ZXh0ICovCiAgICBDT05URVhUODYgY29udGV4dDsKICAgIG1lbXNldCgmY29udGV4dCwwLHNpemVvZihjb250ZXh0KSk7CiAgICAoKnJlbGF5KSgmY29udGV4dCxkYXRhKTsKICB9IGVsc2UgewogICAgRVJSKCJJUlEgd2l0aG91dCBET1MgdGFzazogc2hvdWxkIG5vdCBoYXBwZW5cbiIpOwogIH0KfQoKI2VuZGlmIC8qIE1aX1NVUFBPUlRFRCAqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgRE9TVk1fQWNrbm93bGVkZ2VJUlEKICoKICogVGhpcyByb3V0aW5lIHNob3VsZCBiZSBjYWxsZWQgYnkgYWxsIGludGVybmFsIElSUSBoYW5kbGVycy4KICovCnZvaWQgV0lOQVBJIERPU1ZNX0Fja25vd2xlZGdlSVJRKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICAvKgogICAgICogU2VuZCBFT0kgdG8gUElDLgogICAgICovCiAgICBET1NWTV9QSUNfaW9wb3J0X291dCggMHgyMCwgMHgyMCApOwoKICAgIC8qCiAgICAgKiBQcm90ZWN0ZWQgbW9kZSBJUlEgaGFuZGxlcnMgYXJlIHN1cHBvc2VkCiAgICAgKiB0byB0dXJuIFZJRiBmbGFnIG9uIGJlZm9yZSB0aGV5IHJldHVybi4KICAgICAqLwogICAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+ZHBtaV92aWYgPSAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERsbE1haW4gIChET1NWTS5Jbml0KQogKi8KQk9PTCBXSU5BUEkgRGxsTWFpbiggSElOU1RBTkNFIGhpbnN0RExMLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCApCnsKICAgIFRSQUNFXyhtb2R1bGUpKCIoJXAsJWxkLCVwKVxuIiwgaGluc3RETEwsIGZkd1JlYXNvbiwgbHB2UmVzZXJ2ZWQpOwoKICAgIGlmIChmZHdSZWFzb24gPT0gRExMX1BST0NFU1NfQVRUQUNIKQogICAgewogICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaGluc3RETEwpOwogICAgICAgIERPU1ZNX0luaXRTZWdtZW50cygpOwoKICAgICAgICBldmVudF9ub3RpZmllciA9IENyZWF0ZUV2ZW50QShOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmKCFldmVudF9ub3RpZmllcikKICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBldmVudCBvYmplY3QhXG4iKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cg==