LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIE5vdGU6IFRoaXMgY29kZSBoYXNuJ3QgYmVlbiBjb21wbGV0ZWx5IGNsZWFuZWQgdXAgeWV0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid293bnQzMi5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIndpbmNvbi5oIgoKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJkb3N2bS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZXhjcHQuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGludCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KTsKCldPUkQgRE9TVk1fcHNwID0gMDsKV09SRCBET1NWTV9yZXR2YWwgPSAwOwoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKCnR5cGVkZWYgc3RydWN0IF9ET1NFVkVOVCB7CiAgaW50IGlycSxwcmlvcml0eTsKICBET1NSRUxBWSByZWxheTsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBfRE9TRVZFTlQgKm5leHQ7Cn0gRE9TRVZFTlQsICpMUERPU0VWRU5UOwoKc3RhdGljIHN0cnVjdCBfRE9TRVZFTlQgKnBlbmRpbmdfZXZlbnQsICpjdXJyZW50X2V2ZW50OwpzdGF0aWMgSEFORExFIGV2ZW50X25vdGlmaWVyOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gcWNyaXQ7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJnFjcml0LAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAwLCAoRFdPUkQpKF9fRklMRV9fICI6IHFjcml0IikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBxY3JpdCA9IHsgJmNyaXRzZWN0X2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgRE9TVk1fSGFzUGVuZGluZ0V2ZW50cwogKgogKiBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgcGVuZGluZyBldmVudHMgdGhhdCBhcmUgbm90CiAqIGJsb2NrZWQgYnkgY3VycmVudGx5IGFjdGl2ZSBldmVudC4KICovCnN0YXRpYyBCT09MIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoIHZvaWQgKQp7ICAgCiAgICBpZiAoIXBlbmRpbmdfZXZlbnQpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICghY3VycmVudF9ldmVudCkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBpZiAocGVuZGluZ19ldmVudC0+cHJpb3JpdHkgPCBjdXJyZW50X2V2ZW50LT5wcmlvcml0eSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICByZXR1cm4gRkFMU0U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIERPU1ZNX1NlbmRPbmVFdmVudAogKgogKiBQcm9jZXNzIHNpbmdsZSBwZW5kaW5nIGV2ZW50LgogKgogKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgd2l0aCBxdWV1ZSBjcml0aWNhbCBzZWN0aW9uIGxvY2tlZC4gCiAqIFRoZSBmdW5jdGlvbiB0ZW1wb3JhcmlseSByZWxlYXNlcyB0aGUgY3JpdGljYWwgc2VjdGlvbiBpZiBpdCBpcyAKICogcG9zc2libGUgdGhhdCBpbnRlcm5hbCBpbnRlcnJ1cHQgaGFuZGxlciBvciB1c2VyIHByb2NlZHVyZSB3aWxsIAogKiBiZSBjYWxsZWQuIFRoaXMgaXMgYmVjYXVzZSB3ZSBtYXkgb3RoZXJ3aXNlIGdldCBhIGRlYWRsb2NrIGlmCiAqIGFub3RoZXIgdGhyZWFkIGlzIHdhaXRpbmcgZm9yIHRoZSBzYW1lIGNyaXRpY2FsIHNlY3Rpb24uCiAqLwpzdGF0aWMgdm9pZCBET1NWTV9TZW5kT25lRXZlbnQoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKICAgIExQRE9TRVZFTlQgZXZlbnQgPSBwZW5kaW5nX2V2ZW50OwoKICAgIC8qIFJlbW92ZSBmcm9tIHBlbmRpbmcgZXZlbnRzIGxpc3QuICovCiAgICBwZW5kaW5nX2V2ZW50ID0gZXZlbnQtPm5leHQ7CgogICAgLyogUHJvY2VzcyBhY3RpdmUgZXZlbnQuICovCiAgICBpZiAoZXZlbnQtPmlycSA+PSAwKSAKICAgIHsKICAgICAgICBCWVRFIGludG51bSA9IChldmVudC0+aXJxIDwgOCkgPwogICAgICAgICAgICAoZXZlbnQtPmlycSArIDgpIDogKGV2ZW50LT5pcnEgLSA4ICsgMHg3MCk7CiAgICAgICAgICAgIAogICAgICAgIC8qIEV2ZW50IGlzIGFuIElSUSwgbW92ZSBpdCB0byBjdXJyZW50IGV2ZW50cyBsaXN0LiAqLwogICAgICAgIGV2ZW50LT5uZXh0ID0gY3VycmVudF9ldmVudDsKICAgICAgICBjdXJyZW50X2V2ZW50ID0gZXZlbnQ7CgogICAgICAgIFRSQUNFKCAiRGlzcGF0Y2hpbmcgSVJRICVkLlxuIiwgZXZlbnQtPmlycSApOwoKICAgICAgICBpZiAoSVNWODYoY29udGV4dCkpCiAgICAgICAgewogICAgICAgICAgICAvKiAKICAgICAgICAgICAgICogTm90ZSB0aGF0IGlmIERPU1ZNX0hhcmR3YXJlSW50ZXJydXB0Uk0gY2FsbHMgYW4gaW50ZXJuYWwgCiAgICAgICAgICAgICAqIGludGVycnVwdCBkaXJlY3RseSwgY3VycmVudF9ldmVudCBtaWdodCBiZSBjbGVhcmVkIAogICAgICAgICAgICAgKiAoYW5kIGV2ZW50IGZyZWVkKSBpbiB0aGlzIGNhbGwuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgICAgICBET1NWTV9IYXJkd2FyZUludGVycnVwdFJNKCBjb250ZXh0LCBpbnRudW0gKTsKICAgICAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyByb3V0aW5lIG9ubHkgbW9kaWZpZXMgY3VycmVudCBjb250ZXh0IHNvIGl0IGlzCiAgICAgICAgICAgICAqIG5vdCBuZWNlc3NhcnkgdG8gcmVsZWFzZSBjcml0aWNhbCBzZWN0aW9uLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRE9TVk1fSGFyZHdhcmVJbnRlcnJ1cHRQTSggY29udGV4dCwgaW50bnVtICk7CiAgICAgICAgfQogICAgfSAKICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogQ2FsbGJhY2sgZXZlbnQuICovCiAgICAgICAgVFJBQ0UoICJEaXNwYXRjaGluZyBjYWxsYmFjayBldmVudC5cbiIgKTsKCiAgICAgICAgaWYgKElTVjg2KGNvbnRleHQpKQogICAgICAgIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQ2FsbCByZWxheSBpbW1lZGlhdGVseSBpbiByZWFsIG1vZGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgICAgICAgICAoKmV2ZW50LT5yZWxheSkoIGNvbnRleHQsIGV2ZW50LT5kYXRhICk7CiAgICAgICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEZvcmNlIHJldHVybiB0byByZWxheSBjb2RlLiBXZSBkbyBub3Qgd2FudCB0bwogICAgICAgICAgICAgKiBjYWxsIHJlbGF5IGRpcmVjdGx5IGJlY2F1c2Ugd2UgbWF5IGJlIGluc2lkZSBhIHNpZ25hbCBoYW5kbGVyLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRE9TVk1fQnVpbGRDYWxsRnJhbWUoIGNvbnRleHQsIGV2ZW50LT5yZWxheSwgZXZlbnQtPmRhdGEgKTsKICAgICAgICB9CgogICAgICAgIGZyZWUoZXZlbnQpOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzCiAqCiAqIEFzIGxvbmcgYXMgY29udGV4dCBpbnN0cnVjdGlvbiBwb2ludGVyIHN0YXlzIHVubW9kaWZpZWQsCiAqIHByb2Nlc3MgYWxsIHBlbmRpbmcgZXZlbnRzIHRoYXQgYXJlIG5vdCBibG9ja2VkIGJ5IGN1cnJlbnRseQogKiBhY3RpdmUgZXZlbnQuCiAqCiAqIFRoaXMgcm91dGluZSBhc3N1bWVzIHRoYXQgY2FsbGVyIGhhcyBhbHJlYWR5IGNsZWFyZWQgVEVCLnZtODZfcGVuZGluZyAKICogYW5kIGNoZWNrZWQgdGhhdCBpbnRlcnJ1cHRzIGFyZSBlbmFibGVkLgogKi8Kdm9pZCBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCBDT05URVhUODYgKmNvbnRleHQgKQp7ICAgCiAgICBEV09SRCBvbGRfY3MgPSBjb250ZXh0LT5TZWdDczsKICAgIERXT1JEIG9sZF9pcCA9IGNvbnRleHQtPkVpcDsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwoKICAgIFRSQUNFKCAiQ2FsbGVkIGluICVzIG1vZGUgJXMgZXZlbnRzIHBlbmRpbmcgKHRpbWU9JWxkKVxuIiwKICAgICAgICAgICBJU1Y4Nihjb250ZXh0KSA/ICJyZWFsIiA6ICJwcm90ZWN0ZWQiLAogICAgICAgICAgIERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSA/ICJ3aXRoIiA6ICJ3aXRob3V0IiwKICAgICAgICAgICBHZXRUaWNrQ291bnQoKSApOwogICAgVFJBQ0UoICJjczppcD0lMDRseDolMDhseCwgc3M6c3A9JTA0bHg6JTA4bHhcbiIsCiAgICAgICAgICAgY29udGV4dC0+U2VnQ3MsIGNvbnRleHQtPkVpcCwgY29udGV4dC0+U2VnU3MsIGNvbnRleHQtPkVzcCk7CgogICAgd2hpbGUgKGNvbnRleHQtPlNlZ0NzID09IG9sZF9jcyAmJgogICAgICAgICAgIGNvbnRleHQtPkVpcCA9PSBvbGRfaXAgJiYKICAgICAgICAgICBET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpCiAgICB7CiAgICAgICAgRE9TVk1fU2VuZE9uZUV2ZW50KGNvbnRleHQpOwoKICAgICAgICAvKgogICAgICAgICAqIEV2ZW50IGhhbmRsaW5nIG1heSBoYXZlIHR1cm5lZCBwZW5kaW5nIGV2ZW50cyBmbGFnIG9uLgogICAgICAgICAqIFdlIGRpc2FibGUgaXQgaGVyZSBiZWNhdXNlIHRoaXMgcHJldmVudHMgc29tZQogICAgICAgICAqIHVubmVjZXNzYXJ5IGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24uCiAgICAgICAgICovCiAgICAgICAgTnRDdXJyZW50VGViKCktPnZtODZfcGVuZGluZyA9IDA7CiAgICB9CgojaWZkZWYgTVpfU1VQUE9SVEVECgogICAgaWYgKERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKSkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIEludGVycnVwdHMgZGlzYWJsZWQsIGJ1dCB0aGVyZSBhcmUgc3RpbGwKICAgICAgICAgKiBwZW5kaW5nIGV2ZW50cywgbWFrZSBzdXJlIHRoYXQgcGVuZGluZyBmbGFnIGlzIHR1cm5lZCBvbi4KICAgICAgICAgKi8KICAgICAgICBUUkFDRSggIkFub3RoZXIgZXZlbnQgaXMgcGVuZGluZywgc2V0dGluZyBWSVAgZmxhZy5cbiIgKTsKICAgICAgICBOdEN1cnJlbnRUZWIoKS0+dm04Nl9wZW5kaW5nIHw9IFZJUF9NQVNLOwogICAgfQoKI2Vsc2UKCiAgICBGSVhNRSgiTm8gRE9TIC5leGUgZmlsZSBzdXBwb3J0IG9uIHRoaXMgcGxhdGZvcm0gKHlldClcbiIpOwoKI2VuZGlmIC8qIE1aX1NVUFBPUlRFRCAqLwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7Cn0KCgojaWZkZWYgTVpfU1VQUE9SVEVECi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBMUERPU0VWRU5UIGV2ZW50LCBjdXIsIHByZXY7CiAgQk9PTCAgICAgICBvbGRfcGVuZGluZzsKCiAgaWYgKE1aX0N1cnJlbnQoKSkgewogICAgZXZlbnQgPSBtYWxsb2Moc2l6ZW9mKERPU0VWRU5UKSk7CiAgICBpZiAoIWV2ZW50KSB7CiAgICAgIEVSUigib3V0IG9mIG1lbW9yeSBhbGxvY2F0aW5nIGV2ZW50IGVudHJ5XG4iKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgZXZlbnQtPmlycSA9IGlycTsgZXZlbnQtPnByaW9yaXR5ID0gcHJpb3JpdHk7CiAgICBldmVudC0+cmVsYXkgPSByZWxheTsgZXZlbnQtPmRhdGEgPSBkYXRhOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZxY3JpdCk7CiAgICBvbGRfcGVuZGluZyA9IERPU1ZNX0hhc1BlbmRpbmdFdmVudHMoKTsKCiAgICAvKiBpbnNlcnQgZXZlbnQgaW50byBsaW5rZWQgbGlzdCwgaW4gb3JkZXIgKmFmdGVyKgogICAgICogYWxsIGVhcmxpZXIgZXZlbnRzIG9mIGhpZ2hlciBvciBlcXVhbCBwcmlvcml0eSAqLwogICAgY3VyID0gcGVuZGluZ19ldmVudDsgcHJldiA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICYmIGN1ci0+cHJpb3JpdHk8PXByaW9yaXR5KSB7CiAgICAgIHByZXYgPSBjdXI7CiAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIGV2ZW50LT5uZXh0ID0gY3VyOwogICAgaWYgKHByZXYpIHByZXYtPm5leHQgPSBldmVudDsKICAgIGVsc2UgcGVuZGluZ19ldmVudCA9IGV2ZW50OwoKICAgIGlmICghb2xkX3BlbmRpbmcgJiYgRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKSB7CiAgICAgIFRSQUNFKCJuZXcgZXZlbnQgcXVldWVkLCBzaWduYWxsaW5nICh0aW1lPSVsZClcbiIsIEdldFRpY2tDb3VudCgpKTsKICAgICAgCiAgICAgIC8qIEFsZXJ0IFZNODYgdGhyZWFkIGFib3V0IHRoZSBuZXcgZXZlbnQuICovCiAgICAgIGtpbGwoZG9zdm1fcGlkLFNJR1VTUjIpOwoKICAgICAgLyogV2FrZSB1cCBET1NWTV9XYWl0IHNvIHRoYXQgaXQgY2FuIHNlcnZlIHBlbmRpbmcgZXZlbnRzLiAqLwogICAgICBTZXRFdmVudChldmVudF9ub3RpZmllcik7CiAgICB9IGVsc2UgewogICAgICBUUkFDRSgibmV3IGV2ZW50IHF1ZXVlZCAodGltZT0lbGQpXG4iLCBHZXRUaWNrQ291bnQoKSk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnFjcml0KTsKICB9IGVsc2UgewogICAgLyogRE9TIHN1YnN5c3RlbSBub3QgcnVubmluZyAqLwogICAgLyogKHRoaXMgcHJvYmFibHkgbWVhbnMgdGhhdCB3ZSdyZSBydW5uaW5nIGEgd2luMTYgYXBwCiAgICAgKiAgd2hpY2ggdXNlcyBEUE1JIHRvIHRodW5rIGRvd24gdG8gRE9TIHNlcnZpY2VzKSAqLwogICAgaWYgKGlycTwwKSB7CiAgICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgICBDT05URVhUODYgY29udGV4dDsKICAgICAgbWVtc2V0KCZjb250ZXh0LDAsc2l6ZW9mKGNvbnRleHQpKTsKICAgICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgICB9IGVsc2UgewogICAgICBFUlIoIklSUSB3aXRob3V0IERPUyB0YXNrOiBzaG91bGQgbm90IGhhcHBlblxuIik7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzQ29uc29sZSh2b2lkKQp7CiAgSU5QVVRfUkVDT1JEIG1zZzsKICBEV09SRCByZXM7CiAgQllURSBzY2FuLCBhc2NpaTsKCiAgaWYgKFJlYWRDb25zb2xlSW5wdXRBKEdldFN0ZEhhbmRsZShTVERfSU5QVVRfSEFORExFKSwmbXNnLDEsJnJlcykpIHsKICAgIHN3aXRjaCAobXNnLkV2ZW50VHlwZSkgewogICAgY2FzZSBLRVlfRVZFTlQ6CiAgICAgIHNjYW4gPSBtc2cuRXZlbnQuS2V5RXZlbnQud1ZpcnR1YWxTY2FuQ29kZTsKICAgICAgYXNjaWkgPSBtc2cuRXZlbnQuS2V5RXZlbnQudUNoYXIuQXNjaWlDaGFyOwogICAgICBUUkFDRSgic2NhbiAlMDJ4LCBhc2NpaSAlMDJ4XG4iLCBzY2FuLCBhc2NpaSk7CgogICAgICAvKiBzZXQgdGhlICJicmVhayIgKHJlbGVhc2UpIGZsYWcgaWYga2V5IHJlbGVhc2VkICovCiAgICAgIGlmICghbXNnLkV2ZW50LktleUV2ZW50LmJLZXlEb3duKSBzY2FuIHw9IDB4ODA7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy5FdmVudC5LZXlFdmVudC5kd0NvbnRyb2xLZXlTdGF0ZSAmIEVOSEFOQ0VEX0tFWSkgewogICAgICAgIERPU1ZNX0ludDA5U2VuZFNjYW4oMHhFMCwwKTsKICAgICAgfQogICAgICBET1NWTV9JbnQwOVNlbmRTY2FuKHNjYW4sIGFzY2lpKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1PVVNFX0VWRU5UOgogICAgICBET1NWTV9JbnQzM0NvbnNvbGUoJm1zZy5FdmVudC5Nb3VzZUV2ZW50KTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkRPV19CVUZGRVJfU0laRV9FVkVOVDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBXSU5ET1dfQlVGRkVSX1NJWkVfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIE1FTlVfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgTUVOVV9FVkVOVC5cbiIpOwogICAgICBicmVhazsKICAgIGNhc2UgRk9DVVNfRVZFTlQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgRk9DVVNfRVZFTlQuXG4iKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5rbm93biBjb25zb2xlIGV2ZW50OiAlZFxuIiwgbXNnLkV2ZW50VHlwZSk7CiAgICB9CiAgfQp9CgpzdGF0aWMgdm9pZCBET1NWTV9Qcm9jZXNzTWVzc2FnZShNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIFRSQUNFKCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4eCwgbHBhcmFtPSUwOGx4XG4iLG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgaWYgKChtc2ctPm1lc3NhZ2U+PVdNX01PVVNFRklSU1QpJiYKICAgICAgKG1zZy0+bWVzc2FnZTw9V01fTU9VU0VMQVNUKSkgewogICAgRE9TVk1fSW50MzNNZXNzYWdlKG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgfSBlbHNlIHsKICAgIHN3aXRjaCAobXNnLT5tZXNzYWdlKSB7CiAgICBjYXNlIFdNX0tFWVVQOgogICAgICBzY2FuID0gMHg4MDsKICAgIGNhc2UgV01fS0VZRE9XTjoKICAgICAgc2NhbiB8PSAobXNnLT5sUGFyYW0gPj4gMTYpICYgMHg3ZjsKCiAgICAgIC8qIGNoZWNrIHdoZXRoZXIgZXh0ZW5kZWQgYml0IGlzIHNldCwKICAgICAgICogYW5kIGlmIHNvLCBxdWV1ZSB0aGUgZXh0ZW5zaW9uIHByZWZpeCAqLwogICAgICBpZiAobXNnLT5sUGFyYW0gJiAweDEwMDAwMDApIHsKCS8qIEZJWE1FOiBzb21lIGtleXMgKGZ1bmN0aW9uIGtleXMpIGhhdmUKCSAqIGV4dGVuZGVkIGJpdCBzZXQgZXZlbiB3aGVuIHRoZXkgc2hvdWxkbid0LAoJICogc2hvdWxkIGNoZWNrIGZvciB0aGVtICovCglET1NWTV9JbnQwOVNlbmRTY2FuKDB4RTAsMCk7CiAgICAgIH0KICAgICAgRE9TVk1fSW50MDlTZW5kU2NhbihzY2FuLDApOwogICAgICBicmVhazsKICAgIH0KICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURPU1ZNX1dhaXQKICoKICogV2FpdCBmb3IgYXN5bmNocm9ub3VzIGV2ZW50cy4gVGhpcyByb3V0aW5lIHRlbXBvcmFyaWx5IGVuYWJsZXMKICogaW50ZXJydXB0cyBhbmQgd2FpdHMgdW50aWwgc29tZSBhc3luY2hyb25vdXMgZXZlbnQgaGFzIGJlZW4gCiAqIHByb2Nlc3NlZC4KICovCnZvaWQgV0lOQVBJIERPU1ZNX1dhaXQoIENPTlRFWFQ4NiAqd2FpdGN0eCApCnsKICAgIGlmIChET1NWTV9IYXNQZW5kaW5nRXZlbnRzKCkpCiAgICB7CiAgICAgICAgQ09OVEVYVDg2IGNvbnRleHQgPSAqd2FpdGN0eDsKICAgICAgICAKICAgICAgICAvKgogICAgICAgICAqIElmIERPU1ZNX1dhaXQgaXMgY2FsbGVkIGZyb20gcHJvdGVjdGVkIG1vZGUgd2UgZW11bGF0ZQogICAgICAgICAqIGludGVycnVwdCByZWZsZWN0aW9uIGFuZCBjb252ZXJ0IGNvbnRleHQgaW50byByZWFsIG1vZGUgY29udGV4dC4KICAgICAgICAgKiBUaGlzIGlzIGFjdHVhbGx5IHRoZSBjb3JyZWN0IHRoaW5nIHRvIGRvIGFzIGxvbmcgYXMgRE9TVk1fV2FpdAogICAgICAgICAqIGlzIG9ubHkgY2FsbGVkIGZyb20gdGhvc2UgaW50ZXJydXB0IGZ1bmN0aW9ucyB0aGF0IERQTUkgcmVmbGVjdHMKICAgICAgICAgKiB0byByZWFsIG1vZGUuCiAgICAgICAgICoKICAgICAgICAgKiBGSVhNRTogTmVlZCB0byB0aGluayBhYm91dCB3aGVyZSB0byBwbGFjZSByZWFsIG1vZGUgc3RhY2suCiAgICAgICAgICogRklYTUU6IElmIERPU1ZNX1dhaXQgY2FsbHMgYXJlIG5lc3RlZCBzdGFjayBnZXRzIGNvcnJ1cHRlZC4KICAgICAgICAgKiAgICAgICAgQ2FuIHRoaXMgcmVhbGx5IGhhcHBlbj8KICAgICAgICAgKi8KICAgICAgICBpZiAoIUlTVjg2KCZjb250ZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnRleHQuRUZsYWdzIHw9IFY4Nl9GTEFHOwogICAgICAgICAgICBjb250ZXh0LlNlZ1NzID0gMHhmZmZmOwogICAgICAgICAgICBjb250ZXh0LkVzcCA9IDA7CiAgICAgICAgfQoKICAgICAgICBjb250ZXh0LkVGbGFncyB8PSBWSUZfTUFTSzsKICAgICAgICBjb250ZXh0LlNlZ0NzID0gMDsKICAgICAgICBjb250ZXh0LkVpcCA9IDA7CgogICAgICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQpOwoKICAgICAgICBpZihjb250ZXh0LlNlZ0NzIHx8IGNvbnRleHQuRWlwKQogICAgICAgICAgICBEUE1JX0NhbGxSTVByb2MoICZjb250ZXh0LCBOVUxMLCAwLCBUUlVFICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgSEFORExFIG9ianNbMl07CiAgICAgICAgaW50ICAgIG9iamMgPSBET1NWTV9Jc1dpbjE2KCkgPyAyIDogMTsKICAgICAgICBEV09SRCAgd2FpdHJldDsKCiAgICAgICAgb2Jqc1swXSA9IGV2ZW50X25vdGlmaWVyOwogICAgICAgIG9ianNbMV0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CgogICAgICAgIHdhaXRyZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKCBvYmpjLCBvYmpzLCBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElORklOSVRFLCBRU19BTExJTlBVVCApOwogICAgICAgIAogICAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOZXcgcGVuZGluZyBldmVudCBoYXMgYmVlbiBxdWV1ZWQsIHdlIGlnbm9yZSBpdAogICAgICAgICAgICAgKiBoZXJlIGJlY2F1c2UgaXQgd2lsbCBiZSBwcm9jZXNzZWQgb24gbmV4dCBjYWxsIHRvCiAgICAgICAgICAgICAqIERPU1ZNX1dhaXQuCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChvYmpjID09IDIgJiYgd2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkKICAgICAgICB7CiAgICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIG9iamMpCiAgICAgICAgewogICAgICAgICAgICBNU0cgbXNnOwogICAgICAgICAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogZ290IGEgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoJm1zZyk7CiAgICAgICAgICAgICAgICAvKiB3ZSBkb24ndCBuZWVkIGEgVHJhbnNsYXRlTWVzc2FnZSBoZXJlICovCiAgICAgICAgICAgICAgICBEaXNwYXRjaE1lc3NhZ2VBKCZtc2cpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIEVSUl8obW9kdWxlKSggImRvc3ZtIHdhaXQgZXJyb3I9JWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIH0KICAgIH0KfQoKCkRXT1JEIFdJTkFQSSBET1NWTV9Mb29wKCBIQU5ETEUgaFRocmVhZCApCnsKICBIQU5ETEUgb2Jqc1syXTsKICBNU0cgbXNnOwogIERXT1JEIHdhaXRyZXQ7CgogIG9ianNbMF0gPSBHZXRTdGRIYW5kbGUoU1REX0lOUFVUX0hBTkRMRSk7CiAgb2Jqc1sxXSA9IGhUaHJlYWQ7CgogIGZvcig7OykgewogICAgICBUUkFDRV8oaW50KSgid2FpdGluZyBmb3IgYWN0aW9uXG4iKTsKICAgICAgd2FpdHJldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMoMiwgb2JqcywgRkFMU0UsIElORklOSVRFLCBRU19BTExJTlBVVCk7CiAgICAgIGlmICh3YWl0cmV0ID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgICAgIERPU1ZNX1Byb2Nlc3NDb25zb2xlKCk7CiAgICAgIH0KICAgICAgZWxzZSBpZiAod2FpdHJldCA9PSBXQUlUX09CSkVDVF8wICsgMSkgewogICAgICAgICBEV09SRCBydjsKICAgICAgICAgaWYoIUdldEV4aXRDb2RlVGhyZWFkKGhUaHJlYWQsICZydikpIHsKICAgICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGdldCB0aHJlYWQgZXhpdCBjb2RlIVxuIik7CiAgICAgICAgICAgICBydiA9IDA7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHJ2OwogICAgICB9CiAgICAgIGVsc2UgaWYgKHdhaXRyZXQgPT0gV0FJVF9PQkpFQ1RfMCArIDIpIHsKICAgICAgICAgIHdoaWxlIChQZWVrTWVzc2FnZUEoJm1zZywwLDAsMCxQTV9SRU1PVkUpKSB7CiAgICAgICAgICAgICAgaWYgKG1zZy5od25kKSB7CiAgICAgICAgICAgICAgICAgIC8qIGl0J3MgYSB3aW5kb3cgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgICBET1NWTV9Qcm9jZXNzTWVzc2FnZSgmbXNnKTsKICAgICAgICAgICAgICAgICAgRGlzcGF0Y2hNZXNzYWdlQSgmbXNnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvKiBpdCdzIGEgdGhyZWFkIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgICAgc3dpdGNoIChtc2cubWVzc2FnZSkgewogICAgICAgICAgICAgICAgICBjYXNlIFdNX1FVSVQ6CiAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9wIHRoaXMgbWFkbmVzcyEhICovCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgICAgY2FzZSBXTV9VU0VSOgogICAgICAgICAgICAgICAgICAgICAgLyogcnVuIHBhc3NlZCBwcm9jZWR1cmUgaW4gdGhpcyB0aHJlYWQgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIChzb3J0IG9mIGxpa2UgQVBDLCBidXQgd2Ugc2lnbmFsIHRoZSBjb21wbGV0aW9uKSAqLwogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIERPU19TUEMgKnNwYyA9IChET1NfU1BDICopbXNnLmxQYXJhbTsKICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRV8oaW50KSgiY2FsbGluZyAlcCB3aXRoIGFyZyAlMDhseFxuIiwgc3BjLT5wcm9jLCBzcGMtPmFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgKHNwYy0+cHJvYykoc3BjLT5hcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFXyhpbnQpKCJkb25lLCBzaWduYWxsaW5nIGV2ZW50ICV4XG4iLCBtc2cud1BhcmFtKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRFdmVudCggKEhBTkRMRSltc2cud1BhcmFtICk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgICBFUlJfKGludCkoIk1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHMgcmV0dXJuZWQgdW5leHBlY3RlZCB2YWx1ZS5cbiIpOwogICAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICB9Cn0KCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIoZXhjZXB0aW9uX2hhbmRsZXIpCnsKICBFWENFUFRJT05fUkVDT1JEICpyZWMgPSBHZXRFeGNlcHRpb25JbmZvcm1hdGlvbigpLT5FeGNlcHRpb25SZWNvcmQ7CiAgQ09OVEVYVCAqY29udGV4dCA9IEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkNvbnRleHRSZWNvcmQ7CiAgaW50IGFyZyA9IHJlYy0+RXhjZXB0aW9uSW5mb3JtYXRpb25bMF07CiAgQk9PTCByZXQ7CgogIHN3aXRjaChyZWMtPkV4Y2VwdGlvbkNvZGUpIHsKICBjYXNlIEVYQ0VQVElPTl9WTTg2X0lOVHg6CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIkNhbGwgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICAgIH0KICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgYXJnICk7CiAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKSB7CiAgICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggcmV0PSUwNGx4OiUwNGx4XG4iLAoJICAgICAgYXJnLCBjb250ZXh0LT5TZWdDcywgY29udGV4dC0+RWlwICk7CiAgICAgIERQUklOVEYoIiBlYXg9JTA4bHggZWJ4PSUwOGx4IGVjeD0lMDhseCBlZHg9JTA4bHggZXNpPSUwOGx4IGVkaT0lMDhseFxuIiwKCSAgICAgIGNvbnRleHQtPkVheCwgY29udGV4dC0+RWJ4LCBjb250ZXh0LT5FY3gsIGNvbnRleHQtPkVkeCwKCSAgICAgIGNvbnRleHQtPkVzaSwgY29udGV4dC0+RWRpICk7CiAgICAgIERQUklOVEYoIiBlYnA9JTA4bHggZXNwPSUwOGx4IGRzPSUwNGx4IGVzPSUwNGx4IGZzPSUwNGx4IGdzPSUwNGx4IGZsYWdzPSUwOGx4XG4iLAoJICAgICAgY29udGV4dC0+RWJwLCBjb250ZXh0LT5Fc3AsIGNvbnRleHQtPlNlZ0RzLCBjb250ZXh0LT5TZWdFcywKCSAgICAgIGNvbnRleHQtPlNlZ0ZzLCBjb250ZXh0LT5TZWdHcywgY29udGV4dC0+RUZsYWdzICk7CiAgICB9CiAgICByZXR1cm4gcmV0ID8gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTiA6IEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7CgogIGNhc2UgRVhDRVBUSU9OX1ZNODZfU1RJOgogIC8qIGNhc2UgRVhDRVBUSU9OX1ZNODZfUElDUkVUVVJOOiAqLwogICAgaWYgKCFJU1Y4Nihjb250ZXh0KSkKICAgICAgRVJSKCAiUHJvdGVjdGVkIG1vZGUgU1RJIGNhdWdodCBieSByZWFsIG1vZGUgaGFuZGxlciFcbiIgKTsKICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoY29udGV4dCk7CiAgICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX0VYRUNVVElPTjsKICAKICBjYXNlIEVYQ0VQVElPTl9TSU5HTEVfU1RFUDoKICAgIHJldCA9IERPU1ZNX0VtdWxhdGVJbnRlcnJ1cHRSTSggY29udGV4dCwgMSApOwogICAgcmV0dXJuIHJldCA/IEVYQ0VQVElPTl9DT05USU5VRV9FWEVDVVRJT04gOiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwogIAogIGNhc2UgRVhDRVBUSU9OX0JSRUFLUE9JTlQ6CiAgICByZXQgPSBET1NWTV9FbXVsYXRlSW50ZXJydXB0Uk0oIGNvbnRleHQsIDMgKTsKICAgIHJldHVybiByZXQgPyBFWENFUFRJT05fQ09OVElOVUVfRVhFQ1VUSU9OIDogRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKICAKICB9CiAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9TRUFSQ0g7Cn0KCmludCBXSU5BUEkgRE9TVk1fRW50ZXIoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKICBpZiAoIUlTVjg2KGNvbnRleHQpKQogICAgICBFUlIoICJDYWxsZWQgd2l0aCBwcm90ZWN0ZWQgbW9kZSBjb250ZXh0IVxuIiApOwoKICBfX1RSWQogIHsKICAgICAgV09XQ2FsbGJhY2sxNkV4KCAwLCBXQ0IxNl9SRUdTLCAwLCBOVUxMLCAoRFdPUkQgKiljb250ZXh0ICk7CiAgICAgIFRSQUNFXyhtb2R1bGUpKCAidm04NiByZXR1cm5lZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSApOwogIH0KICBfX0VYQ0VQVChleGNlcHRpb25faGFuZGxlcikKICB7CiAgICBUUkFDRV8obW9kdWxlKSggImxlYXZpbmcgdm04NiBtb2RlXG4iICk7CiAgfQogIF9fRU5EVFJZCgogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU91dFBJQyAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICAgIGlmIChwb3J0ICE9IDB4MjApCiAgICB7CiAgICAgICAgRklYTUUoICJVbnN1cHBvcnRlZCBQSUMgcG9ydCAlMDR4XG4iLCBwb3J0ICk7CiAgICB9CiAgICBlbHNlIGlmICh2YWwgPT0gMHgyMCB8fCAodmFsID49IDB4NjAgJiYgdmFsIDw9IDB4NjcpKSAKICAgIHsKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwoKICAgICAgICBpZiAoIWN1cnJlbnRfZXZlbnQpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCAiJXMgd2l0aG91dCBhY3RpdmUgSVJRXG4iLAogICAgICAgICAgICAgICAgICB2YWwgPT0gMHgyMCA/ICJFT0kiIDogIlNwZWNpZmljIEVPSSIgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodmFsICE9IDB4MjAgJiYgdmFsIC0gMHg2MCAhPSBjdXJyZW50X2V2ZW50LT5pcnEpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCAiU3BlY2lmaWMgRU9JIGJ1dCBjdXJyZW50IElSUSAlZCBpcyBub3QgJWRcbiIsIAogICAgICAgICAgICAgICAgICBjdXJyZW50X2V2ZW50LT5pcnEsIHZhbCAtIDB4NjAgKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTFBET1NFVkVOVCBldmVudCA9IGN1cnJlbnRfZXZlbnQ7CgogICAgICAgICAgICBUUkFDRSggIlJlY2VpdmVkICVzIGZvciBjdXJyZW50IElSUSAlZCwgY2xlYXJpbmcgZXZlbnRcbiIsCiAgICAgICAgICAgICAgICAgICB2YWwgPT0gMHgyMCA/ICJFT0kiIDogIlNwZWNpZmljIEVPSSIsIGV2ZW50LT5pcnEgKTsKCiAgICAgICAgICAgIGN1cnJlbnRfZXZlbnQgPSBldmVudC0+bmV4dDsKICAgICAgICAgICAgaWYgKGV2ZW50LT5yZWxheSkKICAgICAgICAgICAgICAgICgqZXZlbnQtPnJlbGF5KShOVUxMLGV2ZW50LT5kYXRhKTsKICAgICAgICAgICAgZnJlZShldmVudCk7CgogICAgICAgICAgICBpZiAoRE9TVk1fSGFzUGVuZGluZ0V2ZW50cygpKSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoICJBbm90aGVyIGV2ZW50IHBlbmRpbmcsIHNldHRpbmcgcGVuZGluZyBmbGFnXG4iICk7CiAgICAgICAgICAgICAgICBOdEN1cnJlbnRUZWIoKS0+dm04Nl9wZW5kaW5nIHw9IFZJUF9NQVNLOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcWNyaXQpOwogICAgfSAKICAgIGVsc2UgCiAgICB7CiAgICAgICAgRklYTUUoICJVbnJlY29nbml6ZWQgUElDIGNvbW1hbmQgJTAyeFxuIiwgdmFsICk7CiAgICB9Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRW50ZXIgKFdJTkVET1MuQCkKICovCklOVCBXSU5BUEkgRE9TVk1fRW50ZXIoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKIEVSUl8obW9kdWxlKSgiRE9TIHJlYWxtb2RlIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBhcmNoaXRlY3R1cmUhXG4iKTsKIHJldHVybiAtMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlXYWl0IChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9XYWl0KCBDT05URVhUODYgKndhaXRjdHggKSB7IH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJT3V0UElDIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9QSUNfaW9wb3J0X291dCggV09SRCBwb3J0LCBCWVRFIHZhbCkge30KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJUXVldWVFdmVudCAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgRE9TVk1fUXVldWVFdmVudCggSU5UIGlycSwgSU5UIHByaW9yaXR5LCBET1NSRUxBWSByZWxheSwgTFBWT0lEIGRhdGEpCnsKICBpZiAoaXJxPDApIHsKICAgIC8qIGNhbGxiYWNrIGV2ZW50LCBwZXJmb3JtIGl0IHdpdGggZHVtbXkgY29udGV4dCAqLwogICAgQ09OVEVYVDg2IGNvbnRleHQ7CiAgICBtZW1zZXQoJmNvbnRleHQsMCxzaXplb2YoY29udGV4dCkpOwogICAgKCpyZWxheSkoJmNvbnRleHQsZGF0YSk7CiAgfSBlbHNlIHsKICAgIEVSUigiSVJRIHdpdGhvdXQgRE9TIHRhc2s6IHNob3VsZCBub3QgaGFwcGVuXG4iKTsKICB9Cn0KCiNlbmRpZiAvKiBNWl9TVVBQT1JURUQgKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgIERPU1ZNX0Fja25vd2xlZGdlSVJRCiAqCiAqIFRoaXMgcm91dGluZSBzaG91bGQgYmUgY2FsbGVkIGJ5IGFsbCBpbnRlcm5hbCBJUlEgaGFuZGxlcnMuCiAqLwp2b2lkIFdJTkFQSSBET1NWTV9BY2tub3dsZWRnZUlSUSggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogICAgLyoKICAgICAqIFNlbmQgRU9JIHRvIFBJQy4KICAgICAqLwogICAgRE9TVk1fUElDX2lvcG9ydF9vdXQoIDB4MjAsIDB4MjAgKTsKCiAgICAvKgogICAgICogUHJvdGVjdGVkIG1vZGUgSVJRIGhhbmRsZXJzIGFyZSBzdXBwb3NlZAogICAgICogdG8gdHVybiBWSUYgZmxhZyBvbiBiZWZvcmUgdGhleSByZXR1cm4uCiAgICAgKi8KICAgIGlmICghSVNWODYoY29udGV4dCkpCiAgICAgICAgTnRDdXJyZW50VGViKCktPmRwbWlfdmlmID0gMTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgRE9TVk1fQmlvc0RhdGEKICoKICogR2V0IHBvaW50ZXIgdG8gQklPUyBkYXRhIGFyZWEuIFRoaXMgaXMgbm90IGF0IGZpeGVkIGxvY2F0aW9uCiAqIGJlY2F1c2UgdGhvc2UgV2luMTYgcHJvZ3JhbXMgdGhhdCBkbyBub3QgdXNlIGFueSByZWFsIG1vZGUgY29kZSBoYXZlCiAqIHByb3RlY3RlZCBOVUxMIHBvaW50ZXIgY2F0Y2hpbmcgYmxvY2sgYXQgbG93IGxpbmVhciBtZW1vcnkgYW5kCiAqIEJJT1MgZGF0YSBoYXMgYmVlbiBtb3ZlZCB0byBhbm90aGVyIGxvY2F0aW9uLgogKi8KQklPU0RBVEEgKkRPU1ZNX0Jpb3NEYXRhKCB2b2lkICkKewogICAgTERUX0VOVFJZIGVudHJ5OwogICAgRkFSUFJPQzE2IHByb2M7CgogICAgcHJvYyA9IEdldFByb2NBZGRyZXNzMTYoIEdldE1vZHVsZUhhbmRsZTE2KCAiS0VSTkVMIiApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBDU1RSKShVTE9OR19QVFIpMTkzICk7CiAgICB3aW5lX2xkdF9nZXRfZW50cnkoIExPV09SRChwcm9jKSwgJmVudHJ5ICk7CiAgICByZXR1cm4gKEJJT1NEQVRBICopd2luZV9sZHRfZ2V0X2Jhc2UoICZlbnRyeSApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERsbE1haW4gIChET1NWTS4wKQogKi8KQk9PTCBXSU5BUEkgRGxsTWFpbiggSElOU1RBTkNFIGhpbnN0RExMLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCApCnsKICAgIFRSQUNFXyhtb2R1bGUpKCIoJXAsJWxkLCVwKVxuIiwgaGluc3RETEwsIGZkd1JlYXNvbiwgbHB2UmVzZXJ2ZWQpOwoKICAgIGlmIChmZHdSZWFzb24gPT0gRExMX1BST0NFU1NfQVRUQUNIKQogICAgewogICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaGluc3RETEwpOwogICAgICAgIERPU1ZNX0luaXRTZWdtZW50cygpOwoKICAgICAgICBldmVudF9ub3RpZmllciA9IENyZWF0ZUV2ZW50QShOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmKCFldmVudF9ub3RpZmllcikKICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBldmVudCBvYmplY3QhXG4iKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cg==