LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVDTEFSRV9ERUJVR19DSEFOTkVMKGRlbGF5aGxwKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZml4dXApCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSkKREVDTEFSRV9ERUJVR19DSEFOTkVMKHNlZ21lbnQpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3aW4zMikKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0VfKHdpbjMyKSgiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0VfKHdpbjMyKSgiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCgkgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRV8od2luMzIpKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSl7CglkYmdfZGVjbF9zdHIod2luMzIsIDEwMjQpOwoKCWRzcHJpbnRmKHdpbjMyLCIlNGxkICUwOGx4ICUwOHgiLAoJCSBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCglmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKCSAgICBkc3ByaW50Zih3aW4zMiwgIiAgJXMiLCAoY2hhciopUlZBKG5hbWVbal0pICk7CglpZiAoKCpmdW5jdGlvbiA+PSBydmFfc3RhcnQpICYmICgqZnVuY3Rpb24gPD0gcnZhX2VuZCkpCgkgIGRzcHJpbnRmKHdpbjMyLCAiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilSVkEoKmZ1bmN0aW9uKSk7CglUUkFDRV8od2luMzIpKCIlc1xuIiwgZGJnX3N0cih3aW4zMikpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCAKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBCT09MIHNub29wICkKewoJdV9zaG9ydAkJCQkqIG9yZGluYWw7Cgl1X2xvbmcJCQkJKiBmdW5jdGlvbjsKCXVfY2hhcgkJCQkqKiBuYW1lLCAqZW5hbWU7CglpbnQJCQkJaTsKCVBFX01PRFJFRgkJCSpwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzID0gcGVtLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBpbnQJCQlsb2FkX2FkZHIgPSB3bS0+bW9kdWxlOwoJdV9sb25nCQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFXyh3aW4zMikoIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFXyh3aW4zMikoIiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQkvKiBOb3QgYSBmYXRhbCBwcm9ibGVtLCBzb21lIGFwcHMgZG8KCQkgKiBHZXRQcm9jQWRkcmVzcygwLCJSZWdpc3RlclBlbkFwcCIpIHdoaWNoIHRyaWdnZXJzIHRoaXMKCQkgKiBjYXNlLgoJCSAqLwoJCVdBUk5fKHdpbjMyKSgiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFsCT0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKSB7CgkJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspIHsKCQkJZW5hbWU9KGNoYXIqKVJWQSgqbmFtZSk7CgkJCWlmKCFzdHJjbXAoZW5hbWUsZnVuY05hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyID0gZnVuY3Rpb25bKm9yZGluYWxdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCgkJCQlyZXR1cm4gc25vb3A/IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsKm9yZGluYWwsKEZBUlBST0MpUlZBKGFkZHIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKEZBUlBST0MpUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCX0KCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIAl7CgkJaW50IGk7CgkJaWYgKExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSA+IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKSB7CgkJCVRSQUNFXyh3aW4zMikoIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlhZGRyID0gZnVuY3Rpb25bKGludClmdW5jTmFtZS1leHBvcnRzLT5CYXNlXTsKICAgICAgICAgICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CgkJZW5hbWUgPSAiIjsKCQlpZiAobmFtZSkgewoJCSAgICBmb3IgKGk9MDtpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7aSsrKSB7CgkJCSAgICBlbmFtZSA9IChjaGFyKilSVkEoKm5hbWUpOwoJCQkgICAgaWYgKCpvcmRpbmFsID09IExPV09SRChmdW5jTmFtZSktZXhwb3J0cy0+QmFzZSkKCQkJICAgIAlicmVhazsKCQkJICAgIG9yZGluYWwrKzsKCQkJICAgIG5hbWUrKzsKCQkgICAgfQoJCSAgICBpZiAoaT09ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcykKCQkgICAgCWVuYW1lID0gIiI7CgkJfQoJCWlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCgkJCXJldHVybiBzbm9vcD8gU05PT1BfR2V0UHJvY0FkZHJlc3Mod20tPm1vZHVsZSxlbmFtZSwoRFdPUkQpZnVuY05hbWUtZXhwb3J0cy0+QmFzZSwoRkFSUFJPQylSVkEoYWRkcikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKEZBUlBST0MpUlZBKGFkZHIpOwoJCWZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKCX0KCWlmIChmb3J3YXJkKQogICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfTU9EUkVGICp3bTsKCQljaGFyIG1vZHVsZVsyNTZdOwoJCWNoYXIgKmVuZCA9IHN0cmNocihmb3J3YXJkLCAnLicpOwoKCQlpZiAoIWVuZCkgcmV0dXJuIE5VTEw7CgkJYXNzZXJ0KGVuZC1mb3J3YXJkPDI1Nik7CgkJc3RybmNweShtb2R1bGUsIGZvcndhcmQsIChlbmQgLSBmb3J3YXJkKSk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSXyh3aW4zMikoIm1vZHVsZSBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJ1xuIiwgZm9yd2FyZCApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoJCXJldHVybiBNT0RVTEVfR2V0UHJvY0FkZHJlc3MoIHdtLT5tb2R1bGUsIGVuZCArIDEsIHNub29wICk7Cgl9CglyZXR1cm4gTlVMTDsKfQoKRFdPUkQgZml4dXBfaW1wb3J0cyggV0lORV9NT0RSRUYgKndtICkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIFBFX01PRFJFRgkJCSpwZW07CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gd20tPm1vZHVsZTsKICAgIGludAkJCQlpLGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb249MTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIAogICAgYXNzZXJ0KHdtLT50eXBlPT1NT0RVTEUzMl9QRSk7CiAgICBwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwogICAgaWYgKHBlbS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIFRSQUNFXyh3aW4zMikoIkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICBpZiAoIXBlX2ltcCkgcmV0dXJuIDA7CgogICAgLyogV2UgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgaW1wb3J0IHdpdGggITAgY2hhcmFjdGVyaXN0aWNzIGFuZAogICAgICogZGV0ZWN0IGJyb2tlbiBpbXBvcnRzIHdpdGggYWxsIGNoYXJhY3RlcmlzdHNpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CiAgICAJV0lORV9NT0RSRUYJCSp3bUltcDsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKIAljaGFyCQkJKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCgkvKiBkb24ndCB1c2UgTU9EVUxFX0xvYWQsIFdpbjMyIGNyZWF0ZXMgbmV3IHRhc2sgZGlmZmVyZW50bHkgKi8KCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CgkgICAgY2hhciAqcCxidWZmZXJbMjAwMF07CgkgICAgCgkgICAgLyogR2V0TW9kdWxlRmlsZU5hbWUgd291bGQgdXNlIHRoZSB3cm9uZyBwcm9jZXNzLCBzbyBkb24ndCB1c2UgaXQgKi8KCSAgICBzdHJjcHkoYnVmZmVyLHdtLT5zaG9ydG5hbWUpOwoJICAgIGlmICghKHAgPSBzdHJyY2hyIChidWZmZXIsICdcXCcpKSkKCQlwID0gYnVmZmVyOwoJICAgIHN0cmNweSAocCArIDEsIG5hbWUpOwoJICAgIHdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBidWZmZXIsIDAsIDAgKTsKCX0KCWlmICghd21JbXApIHsKCSAgICBFUlJfKG1vZHVsZSkoIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIHJldHVybiAxOwoJfQogICAgICAgIHdtLT5kZXBzW2krK10gPSB3bUltcDsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIFRSQUNFXyh3aW4zMikoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFXyh3aW4zMikoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlJfKHdpbjMyKSgiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFXyh3aW4zMikoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUl8od2luMzIpKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0VfKHdpbjMyKSgiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0VfKHdpbjMyKSgiLS0tIE9yZGluYWwgJXMuJWRcbiIsbmFtZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSXyh3aW4zMikoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFXyh3aW4zMikoIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxuYW1lLHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJRVJSXyh3aW4zMikoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgcGVfbmFtZS0+SGludCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZSggSE1PRFVMRSBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIFRSQUNFXyh3aW4zMikoIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRV8od2luMzIpKCIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICAgIGZvciAoaSA9IDA7IGk8IFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCiAgICB7CiAgICAgICAgVFJBQ0VfKHdpbjMyKSgiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZT1NQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKICAgICAgICB2bWFfc2l6ZT1NQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplKTsKICAgICAgICBwZV9zZWcrKzsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoIHVuc2lnbmVkIGludCBsb2FkX2FkZHIsIElNQUdFX0JBU0VfUkVMT0NBVElPTiAqciApCnsKICAgIGludCBkZWx0YSA9IGxvYWRfYWRkciAtIFBFX0hFQURFUihsb2FkX2FkZHIpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICBpbnQJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKICAgIGludAlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJVFJBQ0VfKGZpeHVwKSgiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRV8oZml4dXApKCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgojaWYgMQoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiNlbHNlCgkJCQl7IGludCBoPSoodW5zaWduZWQgc2hvcnQqKShwYWdlK29mZnNldCk7CgkJCQkgIGludCBsPXItPlR5cGVPZmZzZXRbKytpXTsKCQkJCSAgKih1bnNpZ25lZCBpbnQqKShwYWdlICsgb2Zmc2V0KSA9IChoPDwxNikgKyBsICsgZGVsdGE7CgkJCQl9CiNlbmRpZgoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hBREo6CgkJCQlGSVhNRV8od2luMzIpKCJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJRklYTUVfKHdpbjMyKSgiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlGSVhNRV8od2luMzIpKCJVbmtub3duIGZpeHVwIHR5cGVcbiIpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJciA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopciArIHItPlNpemVPZkJsb2NrKTsKCX0KfQoJCQoKCQoJCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKiAKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IgCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0cyB3aGljaCBhcmUgcGFnZS1hbGlnbmVkLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRTMyIHBvaW50IHRvIHRoZSBzdGFydCBvZiBpdCkKICovCkhNT0RVTEUgUEVfTG9hZEltYWdlKCBIRklMRSBoRmlsZSwgT0ZTVFJVQ1QgKm9mcywgTFBDU1RSICptb2ROYW1lICkKewogICAgSE1PRFVMRQloTW9kdWxlOwogICAgSEFORExFCW1hcHBpbmc7CgogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VjOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBpbnQJaSwgcmF3c2l6ZSwgbG93ZXN0X3ZhLCBsb3dlc3RfZmEsIHZtYV9zaXplLCBmaWxlX3NpemUgPSAwOwogICAgRFdPUkQgbG9hZF9hZGRyLCBhb2VwLCByZWxvYyA9IDA7CgogICAgLyogUmV0cmlldmUgZmlsZSBzaXplICovCiAgICBpZiAoIEdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKCBoRmlsZSwgJmJoZmkgKSApIAogICAgCWZpbGVfc2l6ZSA9IGJoZmkubkZpbGVTaXplTG93OyAvKiBGSVhNRTogNjQgYml0ICovCgogICAgLyogTWFwIHRoZSBQRSBmaWxlIHNvbWV3aGVyZSAqLwogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nQSggaEZpbGUsIE5VTEwsIFBBR0VfUkVBRE9OTFkgfCBTRUNfQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCBOVUxMICk7CiAgICBpZiAoIW1hcHBpbmcpCiAgICB7CiAgICAgICAgV0FSTl8od2luMzIpKCJDcmVhdGVGaWxlTWFwcGluZyBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBXQVJOXyh3aW4zMikoIk1hcFZpZXdPZkZpbGUgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgbnQgPSBQRV9IRUFERVIoIGhNb2R1bGUgKTsKCiAgICAvKiBDaGVjayBzaWduYXR1cmUgKi8KICAgIGlmICggbnQtPlNpZ25hdHVyZSAhPSBJTUFHRV9OVF9TSUdOQVRVUkUgKQogICAgewogICAgICAgIFdBUk5fKHdpbjMyKSgiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgYXJjaGl0ZWN0dXJlICovCiAgICBpZiAoIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYgKQogICAgewogICAgICAgIE1FU1NBR0UoIlRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAobnQtPkZpbGVIZWFkZXIuTWFjaGluZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjogTUVTU0FHRSgiVW5rbm93biIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOiAgICBNRVNTQUdFKCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIE1FU1NBR0UoIlIzMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOiAgIE1FU1NBR0UoIlI0MDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDogIE1FU1NBR0UoIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBNRVNTQUdFKCJBbHBoYSIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOiBNRVNTQUdFKCJQb3dlclBDIik7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IE1FU1NBR0UoIlVua25vd24tJTA0eCIsIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgTUVTU0FHRSgiKVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBGaW5kIG91dCBob3cgbGFyZ2UgdGhpcyBleGVjdXRlYWJsZSBzaG91bGQgYmUgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICByYXdzaXplID0gMDsgbG93ZXN0X3ZhID0gMHgxMDAwMDsgbG93ZXN0X2ZhID0gMHgxMDAwMDsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspIAogICAgewogICAgICAgIGlmIChsb3dlc3RfdmEgPiBwZV9zZWNbaV0uVmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgbG93ZXN0X3ZhID0gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzOwogICAgCWlmIChwZV9zZWNbaV0uQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkgICAgY29udGludWU7CiAgICAJaWYgKHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhIDwgbG93ZXN0X2ZhKQogICAgICAgICAgICBsb3dlc3RfZmEgPSBwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YTsKCWlmIChwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YStwZV9zZWNbaV0uU2l6ZU9mUmF3RGF0YSA+IHJhd3NpemUpCgkgICAgcmF3c2l6ZSA9IHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhK3BlX3NlY1tpXS5TaXplT2ZSYXdEYXRhOwogICAgfQogCiAgICAvKiBDaGVjayBmaWxlIHNpemUgKi8KICAgIGlmICggZmlsZV9zaXplICYmIGZpbGVfc2l6ZSA8IHJhd3NpemUgKQogICAgewogICAgICAgIEVSUl8od2luMzIpKCJQRSBtb2R1bGUgaXMgdG9vIHNtYWxsIChoZWFkZXI6ICVkLCBmaWxlc2l6ZTogJWQpLCAiCiAgICAgICAgICAgICAgICAgICAgInByb2JhYmx5IHRydW5jYXRlZCBkb3dubG9hZD9cbiIsIAogICAgICAgICAgICAgICAgICAgIHJhd3NpemUsIGZpbGVfc2l6ZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgZW50cnlwb2ludCBhZGRyZXNzICovCiAgICBhb2VwID0gbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQ7CiAgICBpZiAoYW9lcCAmJiAoYW9lcCA8IGxvd2VzdF92YSkpCiAgICAgICAgRklYTUVfKHdpbjMyKSgiV0FSTklORzogJyVzJyBoYXMgYW4gaW52YWxpZCBlbnRyeXBvaW50ICgweCUwOGx4KSAiCiAgICAgICAgICAgICAgICAgICAgICAiYmVsb3cgdGhlIGZpcnN0IHZpcnR1YWwgYWRkcmVzcyAoMHglMDh4KSAiCiAgICAgICAgICAgICAgICAgICAgICAiKHBvc3NpYmxlIFZpcnVzIEluZmVjdGlvbiBvciBicm9rZW4gYmluYXJ5KSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgb2ZzLT5zelBhdGhOYW1lLCBhb2VwLCBsb3dlc3RfdmEgKTsKCgogICAgLyogQWxsb2NhdGUgbWVtb3J5IGZvciBtb2R1bGUgKi8KICAgIGxvYWRfYWRkciA9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCiAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCAodm9pZCopbG9hZF9hZGRyLCB2bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIGlmIChsb2FkX2FkZHIgPT0gMCkgCiAgICB7CiAgICAgICAgLyogV2UgbmVlZCB0byBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbnMgKi8KCWRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0M7CiAgICAgICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICAgICAgcmVsb2MgPSBkaXItPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICBGSVhNRV8od2luMzIpKAogICAgICAgICAgICAgICAgICAgIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgICAgICAgIG9mcy0+c3pQYXRoTmFtZSwKICAgICAgICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIGxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCSBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCgkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIH0KCiAgICBUUkFDRV8od2luMzIpKCJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgICAgICBsb2FkX2FkZHIsIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UsIHZtYV9zaXplICk7CiAgICBUUkFDRV8oc2VnbWVudCkoIkxvYWRpbmcgJXMgYXQgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICBvZnMtPnN6UGF0aE5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIgKi8KICAgICooUElNQUdFX0RPU19IRUFERVIpbG9hZF9hZGRyID0gKihQSU1BR0VfRE9TX0hFQURFUiloTW9kdWxlOwogICAgKlBFX0hFQURFUiggbG9hZF9hZGRyICkgPSAqbnQ7CiAgICBtZW1jcHkoIFBFX1NFQ1RJT05TKGxvYWRfYWRkciksIFBFX1NFQ1RJT05TKGhNb2R1bGUpLAogICAgICAgICAgICBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyApOwojaWYgMAogICAgLyogQ29waWVzIGFsbCBzdHVmZiB1cCB0byB0aGUgZmlyc3Qgc2VjdGlvbi4gSW5jbHVkaW5nIHdpbjMyIHZpcnVzZXMuICovCiAgICBtZW1jcHkoIGxvYWRfYWRkciwgaE1vZHVsZSwgbG93ZXN0X2ZhICk7CiNlbmRpZgoKICAgIC8qIENvcHkgc2VjdGlvbnMgaW50byBtb2R1bGUgaW1hZ2UgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWMrKykKICAgIHsKICAgICAgICAvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCiAgICAgICAgLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQogICAgICAgICAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKICAgICAgICAgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCiAgICAgICAgICovCiAgICAgICAgaWYoIShwZV9zZWMtPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKICAgICAgICAgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgICAgICAoY2hhciopKGhNb2R1bGUgKyBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEpLAogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2lmIDAKICAgICAgICAvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwogICAgICAgIGlmKHN0cmNtcChwZV9zZWMtPk5hbWUsICIuYnNzIikgPT0gMCkKICAgICAgICAgICAgbWVtc2V0KCh2b2lkICopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLCAwLCAKICAgICAgICAgICAgICAgICAgIHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSA/CiAgICAgICAgICAgICAgICAgICBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemUgOgogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCiAgICB9CgogICAgLyogUGVyZm9ybSBiYXNlIHJlbG9jYXRpb24sIGlmIG5lY2Vzc2FyeSAqLwogICAgaWYgKCByZWxvYyApCiAgICAgICAgZG9fcmVsb2NhdGlvbnMoIGxvYWRfYWRkciwgKElNQUdFX0JBU0VfUkVMT0NBVElPTiAqKVJWQShyZWxvYykgKTsKCiAgICAvKiBHZXQgbW9kdWxlIG5hbWUgKi8KICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgICptb2ROYW1lID0gKExQQ1NUUilSVkEoKChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcykpLT5OYW1lKTsKCiAgICAvKiBXZSBkb24ndCBuZWVkIHRoZSBvcmlnbmFsIG1hcHBpbmcgYW55IG1vcmUgKi8KICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gKEhNT0RVTEUpbG9hZF9hZGRyOwoKZXJyb3I6CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0ZTVFJVQ1QgKm9mcywgRFdPUkQgZmxhZ3MsIEJPT0wgYnVpbHRpbiApCnsKICAgIERXT1JEIGxvYWRfYWRkciA9IChEV09SRCloTW9kdWxlOyAgLyogZm9yIFJWQSAqLwogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQgPSBQRV9IRUFERVIoaE1vZHVsZSk7CiAgICBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKnBlX2ltcG9ydCA9IE5VTEw7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZICpwZV9yZXNvdXJjZSA9IE5VTEw7CiAgICBXSU5FX01PRFJFRiAqd207CiAgICBpbnQJcmVzdWx0OwogICAgY2hhciAqbW9kbmFtZTsKCgogICAgLyogUmV0cmlldmUgRGF0YURpcmVjdG9yeSBlbnRyaWVzICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfZXhwb3J0ID0gKFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9pbXBvcnQgPSAoUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0U7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX3Jlc291cmNlID0gKFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFk7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0VfKHdpbjMyKSgiRGVidWcgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUVfKHdpbjMyKSgiQ29weXJpZ2h0IHN0cmluZyBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FXyh3aW4zMikoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0VfKHdpbjMyKSgiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFXyh3aW4zMikoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0VfKHdpbjMyKSgiRGVsYXllZCBpbXBvcnQsIHN0dWIgY2FsbHMgTG9hZExpYnJhcnlcbiIgKTsKCQkvKgoJCSAqIE5vdGhpbmcgdG8gZG8gaGVyZS4KCQkgKi8KCiNpZmRlZiBJbWdEZWxheURlc2NyCgkJLyoKCQkgKiBUaGlzIGNvZGUgaXMgdXNlZnVsIHRvIG9ic2VydmUgd2hhdCB0aGUgaGVjayBpcyBnb2luZyBvbi4KCQkgKi8KCQl7CgkJSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgIHBlX2RlbGF5ID0gKFBJbWdEZWxheURlc2NyKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+c3pOYW1lID0gJXNcbiIsIHBlX2RlbGF5LT5zek5hbWUpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5waG1vZCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5waG1vZCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJTlQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElOVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBCb3VuZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wQm91bmRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5kd1RpbWVTdGFtcCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5kd1RpbWVTdGFtcCk7CiAgICAgICAgfQojZW5kaWYgLyogSW1nRGVsYXlEZXNjciAqLwoJfQoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT01fREVTQ1JJUFRPUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FXyh3aW4zMikoIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FXyh3aW4zMikoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICB3bSA9IChXSU5FX01PRFJFRiAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCp3bSkgKTsKICAgIHdtLT5tb2R1bGUgPSBoTW9kdWxlOwoKICAgIGlmICggYnVpbHRpbiApIAogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIGlmICggZmxhZ3MgJiBET05UX1JFU09MVkVfRExMX1JFRkVSRU5DRVMgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUzsKICAgIGlmICggZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFOwoKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICB3bS0+YmluZm10LnBlLnBlX2V4cG9ydCA9IHBlX2V4cG9ydDsKICAgIHdtLT5iaW5mbXQucGUucGVfaW1wb3J0ID0gcGVfaW1wb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9yZXNvdXJjZSA9IHBlX3Jlc291cmNlOwogICAgd20tPmJpbmZtdC5wZS50bHNpbmRleCA9IC0xOwoKICAgIGlmICggcGVfZXhwb3J0ICkgCiAgICAgICAgbW9kbmFtZSA9IChjaGFyICopUlZBKCBwZV9leHBvcnQtPk5hbWUgKTsKICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogdHJ5IHRvIGZpbmQgb3V0IHRoZSBuYW1lIGZyb20gdGhlIE9GU1RSVUNUICovCiAgICAgICAgY2hhciAqczsKICAgICAgICBtb2RuYW1lID0gb2ZzLT5zelBhdGhOYW1lOwogICAgICAgIGlmICgocz1zdHJyY2hyKG1vZG5hbWUsJ1xcJykpKSBtb2RuYW1lID0gcysxOwogICAgfQogICAgd20tPm1vZG5hbWUgPSBIRUFQX3N0cmR1cEEoIEdldFByb2Nlc3NIZWFwKCksIDAsIG1vZG5hbWUgKTsKCiAgICByZXN1bHQgPSBHZXRMb25nUGF0aE5hbWVBKCBvZnMtPnN6UGF0aE5hbWUsIE5VTEwsIDAgKTsKICAgIHdtLT5sb25nbmFtZSA9IChjaGFyICopSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCByZXN1bHQrMSApOwogICAgR2V0TG9uZ1BhdGhOYW1lQSggb2ZzLT5zelBhdGhOYW1lLCB3bS0+bG9uZ25hbWUsIHJlc3VsdCsxICk7CgogICAgd20tPnNob3J0bmFtZSA9IEhFQVBfc3RyZHVwQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2ZzLT5zelBhdGhOYW1lICk7CgogICAgLyogTGluayBNT0RSRUYgaW50byBwcm9jZXNzIGxpc3QgKi8KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCiAgICB3bS0+bmV4dCA9IFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDsKICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdCA9IHdtOwogICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd207CgogICAgaWYgKCAhKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSApCiAgICB7CiAgICAgICAgaWYgKCBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiApCiAgICAgICAgICAgIEZJWE1FXyh3aW4zMikoIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iICk7CiAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPmV4ZV9tb2RyZWYgPSB3bTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKCBwZV9leHBvcnQgKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIEZpeHVwIEltcG9ydHMgKi8KCiAgICBpZiAoICAgIHBlX2ltcG9ydCAmJiBmaXh1cF9pbXBvcnRzKCB3bSApIAogICAgICAgICAmJiAhKCB3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFICkKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlMgKSApIAogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwogICAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKICAgICAgICBpZiAoICF3bS0+cHJldiApCiAgICAgICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPnByZXYtPm5leHQgPSB3bS0+bmV4dDsKCiAgICAgICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd20tPnByZXY7CiAgICAgICAgd20tPm5leHQgPSB3bS0+cHJldiA9IE5VTEw7CgogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKICAgICAgICAvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCiAgICAgICAgICogbGVmdC4gSW5jbHVkaW5nIGRsbHMgbG9hZGVkIGJ5IHRoaXMgZGxsIGJlZm9yZSB0aGUKICAgICAgICAgKiBmYWlsZWQgb25lLiBVbnJvbGxpbmcgaXMgcmF0aGVyIGRpZmZpY3VsdCB3aXRoIHRoZQogICAgICAgICAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwogICAgICAgICAqIGFyb3VuZCB3aXRoIG5vIHByb2JsZW1zLCBzbyB3ZSBkb24ndCBjYXJlLgogICAgICAgICAqIEFzIHRoZXNlIG1pZ2h0IHJlZmVyZW5jZSBvdXIgd20sIHdlIGRvbid0IGZyZWUgaXQuCiAgICAgICAgICovCiAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCldJTkVfTU9EUkVGICpQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzLCBEV09SRCAqZXJyKQp7CglMUENTVFIJCW1vZE5hbWUgPSBOVUxMOwoJT0ZTVFJVQ1QJb2ZzOwoJSE1PRFVMRQkJaE1vZHVsZTMyOwoJSE1PRFVMRTE2CWhNb2R1bGUxNjsKCU5FX01PRFVMRQkqcE1vZHVsZTsKCVdJTkVfTU9EUkVGCSp3bTsKCWNoYXIgICAgICAgIAlkbGxuYW1lWzI1Nl0sICpwOwoJSEZJTEUJCWhGaWxlOwoKCS8qIEFwcGVuZCAuRExMIHRvIG5hbWUgaWYgbm8gZXh0ZW5zaW9uIHByZXNlbnQgKi8KCXN0cmNweSggZGxsbmFtZSwgbmFtZSApOwoJaWYgKCEocCA9IHN0cnJjaHIoIGRsbG5hbWUsICcuJykpIHx8IHN0cmNociggcCwgJy8nICkgfHwgc3RyY2hyKCBwLCAnXFwnKSkKCQlzdHJjYXQoIGRsbG5hbWUsICIuRExMIiApOwoKCS8qIExvYWQgUEUgbW9kdWxlICovCgloRmlsZSA9IE9wZW5GaWxlKCBkbGxuYW1lLCAmb2ZzLCBPRl9SRUFEIHwgT0ZfU0hBUkVfREVOWV9XUklURSApOwoJaWYgKCBoRmlsZSAhPSBIRklMRV9FUlJPUiApCgl7CgkJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgJm9mcywgJm1vZE5hbWUgKTsKCQlDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlpZighaE1vZHVsZTMyKQoJCXsKCQkJKmVyciA9IEVSUk9SX09VVE9GTUVNT1JZOwkvKiBOb3QgZW50aXJlbHkgcmlnaHQsIGJ1dCBnb29kIGVub3VnaCAqLwoJCQlyZXR1cm4gTlVMTDsKCQl9Cgl9CgllbHNlCgl7CgkJKmVyciA9IEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCglpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcywgbW9kTmFtZSApKSA8IDMyKQoJewoJCSplcnIgPSAoRFdPUkQpaE1vZHVsZTE2OwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCgkJcmV0dXJuIE5VTEw7Cgl9CglwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CglwTW9kdWxlLT5mbGFncyAgICA9IE5FX0ZGTEFHU19MSUJNT0RVTEUgfCBORV9GRkxBR1NfU0lOR0xFREFUQSB8IE5FX0ZGTEFHU19XSU4zMjsKCXBNb2R1bGUtPm1vZHVsZTMyID0gaE1vZHVsZTMyOwoKCS8qIENyZWF0ZSAzMi1iaXQgTU9EUkVGICovCglpZiAoICEod20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgJm9mcywgZmxhZ3MsIEZBTFNFICkpICkKCXsKCQlFUlJfKHdpbjMyKSgiY2FuJ3QgbG9hZCAlc1xuIixvZnMuc3pQYXRoTmFtZSk7CgkJRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CgkJKmVyciA9IEVSUk9SX09VVE9GTUVNT1JZOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmICh3bS0+YmluZm10LnBlLnBlX2V4cG9ydCkKCQlTTk9PUF9SZWdpc3RlckRMTCh3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtLT5iaW5mbXQucGUucGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyk7CgoJKmVyciA9IDA7CglyZXR1cm4gd207Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfVW5sb2FkTGlicmFyeQogKgogKiBVbmxvYWQgdGhlIGxpYnJhcnkgdW5tYXBwaW5nIHRoZSBpbWFnZSBhbmQgZnJlZWluZyB0aGUgbW9kcmVmIHN0cnVjdHVyZS4KICovCnZvaWQgUEVfVW5sb2FkTGlicmFyeShXSU5FX01PRFJFRiAqd20pCnsKCS8qIEZJWE1FLCBkbyBzb21ldGhpbmcgaGVyZSAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTG9hZCB0aGUgUEUgbWFpbiAuRVhFLiBBbGwgb3RoZXIgbG9hZGluZyBpcyBkb25lIGJ5IFBFX0xvYWRMaWJyYXJ5RXhBCiAqIEZJWE1FOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCB1c2UgUEVfTG9hZExpYnJhcnlFeEEsIGJ1dCBjdXJyZW50bHkgY2FuJ3QKICogZHVlIHRvIHRoZSBQUk9DRVNTX0NyZWF0ZSBzdHVmZi4KICovCkJPT0wgUEVfQ3JlYXRlUHJvY2VzcyggSEZJTEUgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExQQ1NUUiBjbWRfbGluZSwgTFBDU1RSIGVudiwgCiAgICAgICAgICAgICAgICAgICAgICAgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHBzYSwgTFBTRUNVUklUWV9BVFRSSUJVVEVTIHRzYSwKICAgICAgICAgICAgICAgICAgICAgICBCT09MIGluaGVyaXQsIERXT1JEIGZsYWdzLCBMUFNUQVJUVVBJTkZPQSBzdGFydHVwLAogICAgICAgICAgICAgICAgICAgICAgIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogICAgTFBDU1RSIG1vZE5hbWUgPSBOVUxMOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUgaE1vZHVsZTMyOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIC8qIExvYWQgZmlsZSAqLwogICAgaWYgKCAoaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgb2ZzLCAmbW9kTmFtZSApKSA8IDMyICkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIGhNb2R1bGUzMiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KI2lmIDAKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZTMyKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIDIwICk7ICAvKiBGSVhNRTogbm90IHRoZSByaWdodCBlcnJvciBjb2RlICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQojZW5kaWYKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwogICAgaWYgKCAoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBvZnMsIG1vZE5hbWUgKSkgPCAzMiApIAogICAgewogICAgICAgIFNldExhc3RFcnJvciggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgcE1vZHVsZS0+ZmxhZ3MgICAgPSBORV9GRkxBR1NfV0lOMzI7CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCiAgICAvKiBDcmVhdGUgbmV3IHByb2Nlc3MgKi8KICAgIGlmICggIVBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIHBzYSwgdHNhLCBpbmhlcml0LCBmbGFncywgc3RhcnR1cCwgaW5mbyApICkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogTm90ZTogUEVfQ3JlYXRlTW9kdWxlIGFuZCB0aGUgcmVtYWluaW5nIHByb2Nlc3MgaW5pdGlhbGl6YXRpb24gd2lsbAogICAgICAgICAgICAgYmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgbmV3IHByb2Nlc3MsIGluIFRBU0tfQ2FsbFRvU3RhcnQgKi8KCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQRV9VbmxvYWRJbWFnZSBbaW50ZXJuYWxdCiAqLwppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUgaE1vZHVsZSApCnsKCUZJWE1FXyh3aW4zMikoInN0dWIuXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KQk9PTCBQRV9Jbml0RExMKCBXSU5FX01PRFJFRiAqd20sIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkICkKewogICAgQk9PTCByZXR2ID0gVFJVRTsKICAgIGFzc2VydCggd20tPnR5cGUgPT0gTU9EVUxFMzJfUEUgKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopUlZBX1BUUiggd20tPm1vZHVsZSxPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCiAgICAgICAgcmV0diA9IGVudHJ5KCB3bS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9CgogICAgcmV0dXJuIHJldHY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfSW5pdFRscwkJCShpbnRlcm5hbCkKICoKICogSWYgaW5jbHVkZWQsIGluaXRpYWxpc2VzIHRoZSB0aHJlYWQgbG9jYWwgc3RvcmFnZXMgb2YgbW9kdWxlcy4KICogUG9pbnRlcnMgaW4gdGhvc2Ugc3RydWN0cyBhcmUgbm90IFJWQXMgYnV0IHJlYWwgcG9pbnRlcnMgd2hpY2ggaGF2ZSBiZWVuCiAqIHJlbG9jYXRlZCBieSBkb19yZWxvY2F0aW9ucygpIGFscmVhZHkuCiAqLwp2b2lkIFBFX0luaXRUbHMoIHZvaWQgKQp7CglXSU5FX01PRFJFRgkJKndtOwoJUEVfTU9EUkVGCQkqcGVtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlpZiAod20tPnR5cGUhPU1PRFVMRTMyX1BFKQoJCQljb250aW51ZTsKCQlwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIHBlbS0+dGxzaW5kZXggPT0gLTEgKSB7CgkJCXBlbS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQkqcGRpci0+QWRkcmVzc09mSW5kZXg9cGVtLT50bHNpbmRleDsgICAKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEsZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNicyA9IAoJCSAgICAgICAoUElNQUdFX1RMU19DQUxMQkFDSyAqKXBkaXItPkFkZHJlc3NPZkNhbGxCYWNrczsKCgkJICAgICBpZiAoKmNicykKCQkgICAgICAgRklYTUVfKHdpbjMyKSgiVExTIENhbGxiYWNrcyBhcmVuJ3QgZ29pbmcgdG8gYmUgY2FsbGVkXG4iKTsKCQl9CgoJCVRsc1NldFZhbHVlKCBwZW0tPnRsc2luZGV4LCBtZW0gKTsKCX0KfQoK