LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVDTEFSRV9ERUJVR19DSEFOTkVMKGRlbGF5aGxwKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZml4dXApCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSkKREVDTEFSRV9ERUJVR19DSEFOTkVMKHNlZ21lbnQpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTCh3aW4zMikKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0VfKHdpbjMyKSgiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0VfKHdpbjMyKSgiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCgkgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRV8od2luMzIpKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJTA4eCIsIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCURQUklOVEYoIlxuIik7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIAoJV0lORV9NT0RSRUYgKndtLAkvKiBbaW5dIFdJTkUgbW9kcmVmZXJlbmNlICovCglMUENTVFIgZnVuY05hbWUsCS8qIFtpbl0gZnVuY3Rpb24gbmFtZSAqLwogICAgICAgIEJPT0wgc25vb3AgKQp7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUEVfTU9EUkVGCQkJKnBlbSA9ICYod20tPmJpbmZtdC5wZSk7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHMgPSBwZW0tPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0VfKHdpbjMyKSgiKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJVFJBQ0VfKHdpbjMyKSgiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTl8od2luMzIpKCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWwJPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHIgPSBmdW5jdGlvblsqb3JkaW5hbF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJCXJldHVybiBzbm9vcD8gU05PT1BfR2V0UHJvY0FkZHJlc3Mod20tPm1vZHVsZSxlbmFtZSwqb3JkaW5hbCwoRkFSUFJPQylSVkEoYWRkcikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRkFSUFJPQylSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfQoJCQlvcmRpbmFsKys7CgkJCW5hbWUrKzsKCQl9Cgl9IGVsc2UgCXsKCQlpbnQgaTsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJVFJBQ0VfKHdpbjMyKSgiCW9yZGluYWwgJWQgb3V0IG9mIHJhbmdlIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dPUkQoZnVuY05hbWUpKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJCWFkZHIgPSBmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdOwogICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKCQllbmFtZSA9ICIiOwoJCWlmIChuYW1lKSB7CgkJICAgIGZvciAoaT0wO2k8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcztpKyspIHsKCQkJICAgIGVuYW1lID0gKGNoYXIqKVJWQSgqbmFtZSk7CgkJCSAgICBpZiAoKm9yZGluYWwgPT0gTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlKQoJCQkgICAgCWJyZWFrOwoJCQkgICAgb3JkaW5hbCsrOwoJCQkgICAgbmFtZSsrOwoJCSAgICB9CgkJICAgIGlmIChpPT1leHBvcnRzLT5OdW1iZXJPZk5hbWVzKQoJCSAgICAJZW5hbWUgPSAiIjsKCQl9CgkJaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJcmV0dXJuIHNub29wPyBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLChEV09SRClmdW5jTmFtZS1leHBvcnRzLT5CYXNlLChGQVJQUk9DKVJWQShhZGRyKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRkFSUFJPQylSVkEoYWRkcik7CgkJZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwoJfQoJaWYgKGZvcndhcmQpCiAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9NT0RSRUYgKndtOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKCQlhc3NlcnQoZW5kLWZvcndhcmQ8MjU2KTsKCQlzdHJuY3B5KG1vZHVsZSwgZm9yd2FyZCwgKGVuZCAtIGZvcndhcmQpKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGlmICghKHdtID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG1vZHVsZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlJfKHdpbjMyKSgibW9kdWxlIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJcmV0dXJuIE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd20tPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKTsKCX0KCXJldHVybiBOVUxMOwp9CgpEV09SRCBmaXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgUEVfTU9EUkVGCQkJKnBlbTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBhc3NlcnQod20tPnR5cGU9PU1PRFVMRTMyX1BFKTsKICAgIHBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0VfKHdpbjMyKSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0c2ljcyAwIChub3RhYmx5IEJvcmxhbmQpIGFuZAogICAgICogc3dpdGNoIHRoZSBkZXRlY3Rpb24gb2ZmIGZvciB0aGVtLgogICAgICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewoJaWYgKCFpICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gPSAwOwoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CglpKys7CiAgICB9CiAgICBpZiAoIWkpIHJldHVybiAwOyAgLyogbm8gaW1wb3J0cyAqLwoKICAgIC8qIEFsbG9jYXRlIG1vZHVsZSBkZXBlbmRlbmN5IGxpc3QgKi8KICAgIHdtLT5uRGVwcyA9IGk7CiAgICB3bS0+ZGVwcyAgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGkqc2l6ZW9mKFdJTkVfTU9EUkVGICopICk7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlXSU5FX01PRFJFRgkJKndtSW1wOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwogCWNoYXIJCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCS8qIGRvbid0IHVzZSBNT0RVTEVfTG9hZCwgV2luMzIgY3JlYXRlcyBuZXcgdGFzayBkaWZmZXJlbnRseSAqLwoJd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIG5hbWUsIDAsIDAgKTsKCWlmICghd21JbXApIHsKCSAgICBjaGFyICpwLGJ1ZmZlclsyMDAwXTsKCSAgICAKCSAgICAvKiBHZXRNb2R1bGVGaWxlTmFtZSB3b3VsZCB1c2UgdGhlIHdyb25nIHByb2Nlc3MsIHNvIGRvbid0IHVzZSBpdCAqLwoJICAgIHN0cmNweShidWZmZXIsd20tPnNob3J0bmFtZSk7CgkgICAgaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCXAgPSBidWZmZXI7CgkgICAgc3RyY3B5IChwICsgMSwgbmFtZSk7CgkgICAgd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIGJ1ZmZlciwgMCwgMCApOwoJfQoJaWYgKCF3bUltcCkgewoJICAgIEVSUl8obW9kdWxlKSgiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0VfKHdpbjMyKSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0VfKHdpbjMyKSgiLS0tIE9yZGluYWwgJXMsJWRcbiIsIG5hbWUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpb3JkaW5hbCwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUl8od2luMzIpKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0VfKHdpbjMyKSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSXyh3aW4zMikoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRV8od2luMzIpKCJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRV8od2luMzIpKCItLS0gT3JkaW5hbCAlcy4lZFxuIixuYW1lLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlJfKHdpbjMyKSgiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPShQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0VfKHdpbjMyKSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlFUlJfKHdpbjMyKSgiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgVFJBQ0VfKHdpbjMyKSgiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICAgIFRSQUNFXyh3aW4zMikoIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBUUkFDRV8od2luMzIpKCIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplPU1BWCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHZtYV9zaXplPU1BWCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPk1pc2MuVmlydHVhbFNpemUpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyggdW5zaWduZWQgaW50IGxvYWRfYWRkciwgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyICkKewogICAgaW50IGRlbHRhID0gbG9hZF9hZGRyIC0gUEVfSEVBREVSKGxvYWRfYWRkciktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIGludAloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwogICAgaW50CWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRV8oZml4dXApKCIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCVRSQUNFXyhmaXh1cCkoInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKCQkJCS8qIEZJWE1FOiBpZiB0aGlzIGlzIGFuIGV4cG9ydGVkIGFkZHJlc3MsIGZpcmUgdXAgZW5oYW5jZWQgbG9naWMgKi8KCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJRklYTUVfKHdpbjMyKSgiRG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggSU1BR0VfUkVMX0JBU0VEX0hJR0hBREpcbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX01JUFNfSk1QQUREUjoKCQkJCUZJWE1FXyh3aW4zMikoIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJRklYTUVfKHdpbjMyKSgiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpITU9EVUxFIFBFX0xvYWRJbWFnZSggSEZJTEUgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExQQ1NUUiAqbW9kTmFtZSwgV09SRCAqdmVyc2lvbiApCnsKICAgIEhNT0RVTEUJaE1vZHVsZTsKICAgIEhBTkRMRQltYXBwaW5nOwoKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlYzsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwogICAgaW50CWksIHJhd3NpemUsIGxvd2VzdF92YSwgbG93ZXN0X2ZhLCB2bWFfc2l6ZSwgZmlsZV9zaXplID0gMDsKICAgIERXT1JEIGxvYWRfYWRkciwgYW9lcCwgcmVsb2MgPSAwOwoKICAgIC8qIFJldHJpZXZlIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSggaEZpbGUsICZiaGZpICkgKSAKICAgIAlmaWxlX3NpemUgPSBiaGZpLm5GaWxlU2l6ZUxvdzsgLyogRklYTUU6IDY0IGJpdCAqLwoKICAgIC8qIE1hcCB0aGUgUEUgZmlsZSBzb21ld2hlcmUgKi8KICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIFdBUk5fKHdpbjMyKSgiQ3JlYXRlRmlsZU1hcHBpbmcgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaE1vZHVsZSA9IChITU9EVUxFKU1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWhNb2R1bGUpCiAgICB7CiAgICAgICAgV0FSTl8od2luMzIpKCJNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CgogICAgLyogQ2hlY2sgc2lnbmF0dXJlICovCiAgICBpZiAoIG50LT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFICkKICAgIHsKICAgICAgICBXQVJOXyh3aW4zMikoImltYWdlIGRvZXNuJ3QgaGF2ZSBQRSBzaWduYXR1cmUsIGJ1dCAweCUwOGx4XG4iLAogICAgICAgICAgICAgICAgICAgIG50LT5TaWduYXR1cmUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENoZWNrIGFyY2hpdGVjdHVyZSAqLwogICAgaWYgKCBudC0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2ICkKICAgIHsKICAgICAgICBNRVNTQUdFKCJUcnlpbmcgdG8gbG9hZCBQRSBpbWFnZSBmb3IgdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0dXJlICgiKTsKICAgICAgICBzd2l0Y2ggKG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpCiAgICAgICAgewogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046IE1FU1NBR0UoIlVua25vd24iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDogICAgTUVTU0FHRSgiSTg2MCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMzAwMDogICBNRVNTQUdFKCJSMzAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDogICBNRVNTQUdFKCJSNDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6ICBNRVNTQUdFKCJSMTAwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfQUxQSEE6ICAgTUVTU0FHRSgiQWxwaGEiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzogTUVTU0FHRSgiUG93ZXJQQyIpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBNRVNTQUdFKCJVbmtub3duLSUwNHgiLCBudC0+RmlsZUhlYWRlci5NYWNoaW5lKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIE1FU1NBR0UoIilcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogRmluZCBvdXQgaG93IGxhcmdlIHRoaXMgZXhlY3V0ZWFibGUgc2hvdWxkIGJlICovCiAgICBwZV9zZWMgPSBQRV9TRUNUSU9OUyggaE1vZHVsZSApOwogICAgcmF3c2l6ZSA9IDA7IGxvd2VzdF92YSA9IDB4MTAwMDA7IGxvd2VzdF9mYSA9IDB4MTAwMDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKSAKICAgIHsKICAgICAgICBpZiAobG93ZXN0X3ZhID4gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzKQogICAgICAgICAgIGxvd2VzdF92YSA9IHBlX3NlY1tpXS5WaXJ0dWFsQWRkcmVzczsKICAgIAlpZiAocGVfc2VjW2ldLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJICAgIGNvbnRpbnVlOwogICAgCWlmIChwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YSA8IGxvd2VzdF9mYSkKICAgICAgICAgICAgbG93ZXN0X2ZhID0gcGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGE7CglpZiAocGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGEgPiByYXdzaXplKQoJICAgIHJhd3NpemUgPSBwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YStwZV9zZWNbaV0uU2l6ZU9mUmF3RGF0YTsKICAgIH0KIAogICAgLyogQ2hlY2sgZmlsZSBzaXplICovCiAgICBpZiAoIGZpbGVfc2l6ZSAmJiBmaWxlX3NpemUgPCByYXdzaXplICkKICAgIHsKICAgICAgICBFUlJfKHdpbjMyKSgiUEUgbW9kdWxlIGlzIHRvbyBzbWFsbCAoaGVhZGVyOiAlZCwgZmlsZXNpemU6ICVkKSwgIgogICAgICAgICAgICAgICAgICAgICJwcm9iYWJseSB0cnVuY2F0ZWQgZG93bmxvYWQ/XG4iLCAKICAgICAgICAgICAgICAgICAgICByYXdzaXplLCBmaWxlX3NpemUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENoZWNrIGVudHJ5cG9pbnQgYWRkcmVzcyAqLwogICAgYW9lcCA9IG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50OwogICAgaWYgKGFvZXAgJiYgKGFvZXAgPCBsb3dlc3RfdmEpKQogICAgICAgIEZJWE1FXyh3aW4zMikoIldBUk5JTkc6ICclcycgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICAgImJlbG93IHRoZSBmaXJzdCB2aXJ0dWFsIGFkZHJlc3MgKDB4JTA4eCkgIgogICAgICAgICAgICAgICAgICAgICAgIihwb3NzaWJsZSBWaXJ1cyBJbmZlY3Rpb24gb3IgYnJva2VuIGJpbmFyeSkhXG4iLAogICAgICAgICAgICAgICAgICAgICAgIG9mcy0+c3pQYXRoTmFtZSwgYW9lcCwgbG93ZXN0X3ZhICk7CgoKICAgIC8qIEZJWE1FOiAgSGFjayEgIFdoaWxlIHdlIGRvbid0IHJlYWxseSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyB5ZXQsCiAgICAgKiAgICAgICAgIHRoaXMgY2hlY2tzIGZvciB0aG9zZSBzcGVjaWFsIGNhc2VzIHdoZXJlIHRoZSB3aG9sZSBETEwKICAgICAqICAgICAgICAgY29uc2lzdHMgb25seSBvZiBzaGFyZWQgc2VjdGlvbnMgYW5kIGlzIG1hcHBlZCBpbnRvIHRoZQogICAgICogICAgICAgICBzaGFyZWQgYWRkcmVzcyBzcGFjZSA+IDJHQi4gIEluIHRoaXMgY2FzZSwgd2UgYXNzdW1lIHRoYXQKICAgICAqICAgICAgICAgdGhlIG1vZHVsZSBnb3QgbWFwcGVkIGF0IGl0cyBiYXNlIGFkZHJlc3MuIFRodXMgd2Ugc2ltcGx5CiAgICAgKiAgICAgICAgIGNoZWNrIHdoZXRoZXIgdGhlIG1vZHVsZSBoYXMgYWN0dWFsbHkgYmVlbiBtYXBwZWQgdGhlcmUKICAgICAqICAgICAgICAgYW5kIHVzZSBpdCwgaWYgc28uICBUaGlzIGlzIG5lZWRlZCB0byBnZXQgV2luOTUgVVNFUjMyLkRMTAogICAgICogICAgICAgICB0byB3b3JrICh1bnRpbCB3ZSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyBwcm9wZXJseSkuCiAgICAgKi8KCiAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgIHsKICAgICAgICBITU9EVUxFIHNoYXJlZE1vZCA9IChITU9EVUxFKW50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7IAogICAgICAgIElNQUdFX05UX0hFQURFUlMgKnNoYXJlZE50ID0gKFBJTUFHRV9OVF9IRUFERVJTKQogICAgICAgICAgICAgICAoIChMUEJZVEUpc2hhcmVkTW9kICsgKChMUEJZVEUpbnQgLSAoTFBCWVRFKWhNb2R1bGUpICk7CgogICAgICAgIC8qIFdlbGwsIHRoaXMgY2hlY2sgaXMgbm90IHJlYWxseSBjb21wcmVoZW5zaXZlLCAKICAgICAgICAgICBidXQgc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBub3cgLi4uICovCiAgICAgICAgaWYgKCAgICAhSXNCYWRSZWFkUHRyKCAoTFBCWVRFKXNoYXJlZE1vZCwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkKICAgICAgICAgICAgICYmIG1lbWNtcCggKExQQllURSlzaGFyZWRNb2QsIChMUEJZVEUpaE1vZHVsZSwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkgPT0gMAogICAgICAgICAgICAgJiYgIUlzQmFkUmVhZFB0ciggc2hhcmVkTnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIHNoYXJlZE50LCBudCwgc2l6ZW9mKElNQUdFX05UX0hFQURFUlMpICkgPT0gMCApCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgICAgICByZXR1cm4gc2hhcmVkTW9kOwogICAgICAgIH0KICAgIH0KCgogICAgLyogQWxsb2NhdGUgbWVtb3J5IGZvciBtb2R1bGUgKi8KICAgIGxvYWRfYWRkciA9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCiAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCAodm9pZCopbG9hZF9hZGRyLCB2bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIGlmIChsb2FkX2FkZHIgPT0gMCkgCiAgICB7CiAgICAgICAgLyogV2UgbmVlZCB0byBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbnMgKi8KCWRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0M7CiAgICAgICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICAgICAgcmVsb2MgPSBkaXItPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICBGSVhNRV8od2luMzIpKAogICAgICAgICAgICAgICAgICAgIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgICAgICAgIG9mcy0+c3pQYXRoTmFtZSwKICAgICAgICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIC8qIEZJWE1FOiBJZiB3ZSBuZWVkIHRvIHJlbG9jYXRlIGEgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikgd2Ugc2hvdWxkCiAgICAgICAgICogICAgICAgIHJlYWxseSBtYWtlIHN1cmUgdGhhdCB0aGUgKm5ldyogYmFzZSBhZGRyZXNzIGlzIGFsc28gPiAyR0IuCiAgICAgICAgICogICAgICAgIFNvbWUgRExMcyByZWFsbHkgY2hlY2sgdGhlIE1TQiBvZiB0aGUgbW9kdWxlIGhhbmRsZSA6LS8KICAgICAgICAgKi8KICAgICAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgICAgICAgICAgRVJSXyh3aW4zMikoICJGb3JjZWQgdG8gcmVsb2NhdGUgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikuIFRoaXMgaXMgbm90IGdvb2QuXG4iICk7CgogICAgICAgIGxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCSBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCgkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIH0KCiAgICBUUkFDRV8od2luMzIpKCJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgICAgICBsb2FkX2FkZHIsIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UsIHZtYV9zaXplICk7CiAgICBUUkFDRV8oc2VnbWVudCkoIkxvYWRpbmcgJXMgYXQgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICBvZnMtPnN6UGF0aE5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIgKi8KICAgICooUElNQUdFX0RPU19IRUFERVIpbG9hZF9hZGRyID0gKihQSU1BR0VfRE9TX0hFQURFUiloTW9kdWxlOwogICAgKlBFX0hFQURFUiggbG9hZF9hZGRyICkgPSAqbnQ7CiAgICBtZW1jcHkoIFBFX1NFQ1RJT05TKGxvYWRfYWRkciksIFBFX1NFQ1RJT05TKGhNb2R1bGUpLAogICAgICAgICAgICBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyApOwojaWYgMAogICAgLyogQ29waWVzIGFsbCBzdHVmZiB1cCB0byB0aGUgZmlyc3Qgc2VjdGlvbi4gSW5jbHVkaW5nIHdpbjMyIHZpcnVzZXMuICovCiAgICBtZW1jcHkoIGxvYWRfYWRkciwgaE1vZHVsZSwgbG93ZXN0X2ZhICk7CiNlbmRpZgoKICAgIC8qIENvcHkgc2VjdGlvbnMgaW50byBtb2R1bGUgaW1hZ2UgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWMrKykKICAgIHsKICAgICAgICAvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCiAgICAgICAgLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQogICAgICAgICAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKICAgICAgICAgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCiAgICAgICAgICovCiAgICAgICAgaWYoIShwZV9zZWMtPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKICAgICAgICAgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgICAgICAoY2hhciopKGhNb2R1bGUgKyBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEpLAogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2lmIDAKICAgICAgICAvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwogICAgICAgIGlmKHN0cmNtcChwZV9zZWMtPk5hbWUsICIuYnNzIikgPT0gMCkKICAgICAgICAgICAgbWVtc2V0KCh2b2lkICopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLCAwLCAKICAgICAgICAgICAgICAgICAgIHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSA/CiAgICAgICAgICAgICAgICAgICBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemUgOgogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCiAgICB9CgogICAgLyogUGVyZm9ybSBiYXNlIHJlbG9jYXRpb24sIGlmIG5lY2Vzc2FyeSAqLwogICAgaWYgKCByZWxvYyApCiAgICAgICAgZG9fcmVsb2NhdGlvbnMoIGxvYWRfYWRkciwgKElNQUdFX0JBU0VfUkVMT0NBVElPTiAqKVJWQShyZWxvYykgKTsKCiAgICAvKiBHZXQgbW9kdWxlIG5hbWUgKi8KICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgICptb2ROYW1lID0gKExQQ1NUUilSVkEoKChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcykpLT5OYW1lKTsKCiAgICAvKiBHZXQgZXhwZWN0ZWQgT1MgLyBTdWJzeXN0ZW0gdmVyc2lvbiAqLwogICAgKnZlcnNpb24gPSAgICggKG50LT5PcHRpb25hbEhlYWRlci5NYWpvclN1YnN5c3RlbVZlcnNpb24gJiAweGZmKSA8PCA4ICkKICAgICAgICAgICAgICAgfCAgIChudC0+T3B0aW9uYWxIZWFkZXIuTWlub3JTdWJzeXN0ZW1WZXJzaW9uICYgMHhmZik7CgogICAgLyogV2UgZG9uJ3QgbmVlZCB0aGUgb3JpZ25hbCBtYXBwaW5nIGFueSBtb3JlICovCiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIChITU9EVUxFKWxvYWRfYWRkcjsKCmVycm9yOgogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAgUEVfQ3JlYXRlTW9kdWxlCiAqCiAqIENyZWF0ZSBXSU5FX01PRFJFRiBzdHJ1Y3R1cmUgZm9yIGxvYWRlZCBITU9EVUxFMzIsIGxpbmsgaXQgaW50bwogKiBwcm9jZXNzIG1vZHJlZl9saXN0LCBhbmQgZml4dXAgYWxsIGltcG9ydHMuCiAqCiAqIE5vdGU6IGhNb2R1bGUgbXVzdCBwb2ludCB0byBhIGNvcnJlY3RseSBhbGxvY2F0ZWQgUEUgaW1hZ2UsCiAqICAgICAgIHdpdGggYmFzZSByZWxvY2F0aW9ucyBhcHBsaWVkOyB0aGUgMTYtYml0IGR1bW15IG1vZHVsZQogKiAgICAgICBhc3NvY2lhdGVkIHRvIGhNb2R1bGUgbXVzdCBhbHJlYWR5IGV4aXN0LgogKgogKiBOb3RlOiBUaGlzIHJvdXRpbmUgbXVzdCBhbHdheXMgYmUgY2FsbGVkIGluIHRoZSBjb250ZXh0IG9mIHRoZQogKiAgICAgICBwcm9jZXNzIHRoYXQgaXMgdG8gb3duIHRoZSBtb2R1bGUgdG8gYmUgY3JlYXRlZC4KICovCldJTkVfTU9EUkVGICpQRV9DcmVhdGVNb2R1bGUoIEhNT0RVTEUgaE1vZHVsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9GU1RSVUNUICpvZnMsIERXT1JEIGZsYWdzLCBCT09MIGJ1aWx0aW4gKQp7CiAgICBEV09SRCBsb2FkX2FkZHIgPSAoRFdPUkQpaE1vZHVsZTsgIC8qIGZvciBSVkEgKi8KICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUEVfSEVBREVSKGhNb2R1bGUpOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpwZV9pbXBvcnQgPSBOVUxMOwogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0ID0gTlVMTDsKICAgIElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSAqcGVfcmVzb3VyY2UgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgaW50CXJlc3VsdDsKICAgIGNoYXIgKm1vZG5hbWU7CgoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfaW1wb3J0ID0gKFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9yZXNvdXJjZSA9IChQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUVfKHdpbjMyKSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUVfKHdpbjMyKSgiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DIGhhbmRsZWQgaW4gUEVfTG9hZEltYWdlICovCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUcgaGFuZGxlZCBieSBkZWJ1Z2dlciAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRzsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFXyh3aW4zMikoIkRlYnVnIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVDsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FXyh3aW4zMikoIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFI7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMgaGFuZGxlZCBpbiBQRV9UbHNJbml0ICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUVfKHdpbjMyKSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFXyh3aW4zMikoIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRV8od2luMzIpKCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUxBWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgewoJCVRSQUNFXyh3aW4zMikoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrMTU7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRV8od2luMzIpKCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iICk7CgoKICAgIC8qIEFsbG9jYXRlIGFuZCBmaWxsIFdJTkVfTU9EUkVGICovCgogICAgd20gPSAoV0lORV9NT0RSRUYgKilIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqd20pICk7CiAgICB3bS0+bW9kdWxlID0gaE1vZHVsZTsKCiAgICBpZiAoIGJ1aWx0aW4gKSAKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfSU5URVJOQUw7CiAgICBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CiAgICBpZiAoIGZsYWdzICYgTE9BRF9MSUJSQVJZX0FTX0RBVEFGSUxFICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRTsKCiAgICB3bS0+dHlwZSA9IE1PRFVMRTMyX1BFOwogICAgd20tPmJpbmZtdC5wZS5wZV9leHBvcnQgPSBwZV9leHBvcnQ7CiAgICB3bS0+YmluZm10LnBlLnBlX2ltcG9ydCA9IHBlX2ltcG9ydDsKICAgIHdtLT5iaW5mbXQucGUucGVfcmVzb3VyY2UgPSBwZV9yZXNvdXJjZTsKICAgIHdtLT5iaW5mbXQucGUudGxzaW5kZXggPSAtMTsKCiAgICBpZiAoIHBlX2V4cG9ydCApIAogICAgICAgIG1vZG5hbWUgPSAoY2hhciAqKVJWQSggcGVfZXhwb3J0LT5OYW1lICk7CiAgICBlbHNlIAogICAgewogICAgICAgIC8qIHRyeSB0byBmaW5kIG91dCB0aGUgbmFtZSBmcm9tIHRoZSBPRlNUUlVDVCAqLwogICAgICAgIGNoYXIgKnM7CiAgICAgICAgbW9kbmFtZSA9IG9mcy0+c3pQYXRoTmFtZTsKICAgICAgICBpZiAoKHM9c3RycmNocihtb2RuYW1lLCdcXCcpKSkgbW9kbmFtZSA9IHMrMTsKICAgIH0KICAgIHdtLT5tb2RuYW1lID0gSEVBUF9zdHJkdXBBKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBtb2RuYW1lICk7CgogICAgcmVzdWx0ID0gR2V0TG9uZ1BhdGhOYW1lQSggb2ZzLT5zelBhdGhOYW1lLCBOVUxMLCAwICk7CiAgICB3bS0+bG9uZ25hbWUgPSAoY2hhciAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVzdWx0KzEgKTsKICAgIEdldExvbmdQYXRoTmFtZUEoIG9mcy0+c3pQYXRoTmFtZSwgd20tPmxvbmduYW1lLCByZXN1bHQrMSApOwoKICAgIHdtLT5zaG9ydG5hbWUgPSBIRUFQX3N0cmR1cEEoIEdldFByb2Nlc3NIZWFwKCksIDAsIG9mcy0+c3pQYXRoTmFtZSApOwoKICAgIC8qIExpbmsgTU9EUkVGIGludG8gcHJvY2VzcyBsaXN0ICovCgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgd20tPm5leHQgPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7CiAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3QgPSB3bTsKICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtOwoKICAgIGlmICggIShudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgKQogICAgewogICAgICAgIGlmICggUFJPQ0VTU19DdXJyZW50KCktPmV4ZV9tb2RyZWYgKQogICAgICAgICAgICBGSVhNRV8od2luMzIpKCJvdmVyd3JpdGluZyBvbGQgZXhlX21vZHJlZi4uLiBhcnJnaFxuIiApOwogICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmID0gd207CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmICggcGVfZXhwb3J0ICkKICAgICAgICBkdW1wX2V4cG9ydHMoIGhNb2R1bGUgKTsKCiAgICAvKiBGaXh1cCBJbXBvcnRzICovCgogICAgaWYgKCAgICBwZV9pbXBvcnQKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRSApCiAgICAgICAgICYmICEoIHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTICkgCiAgICAgICAgICYmIGZpeHVwX2ltcG9ydHMoIHdtICkgKSAKICAgIHsKICAgICAgICAvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCiAgICAgICAgaWYgKCAhd20tPnByZXYgKQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5wcmV2LT5uZXh0ID0gd20tPm5leHQ7CgogICAgICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtLT5wcmV2OwogICAgICAgIHdtLT5uZXh0ID0gd20tPnByZXYgPSBOVUxMOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIGl0IHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gd207Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpXSU5FX01PRFJFRiAqUEVfTG9hZExpYnJhcnlFeEEgKExQQ1NUUiBuYW1lLCBEV09SRCBmbGFncywgRFdPUkQgKmVycikKewoJTFBDU1RSCQltb2ROYW1lID0gTlVMTDsKCU9GU1RSVUNUCW9mczsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCUhNT0RVTEUxNgloTW9kdWxlMTY7CglORV9NT0RVTEUJKnBNb2R1bGU7CglXSU5FX01PRFJFRgkqd207CgljaGFyICAgICAgICAJZGxsbmFtZVsyNTZdLCAqcDsKCUhGSUxFCQloRmlsZTsKCVdPUkQJCXZlcnNpb24gPSAwOwoKCS8qIEFwcGVuZCAuRExMIHRvIG5hbWUgaWYgbm8gZXh0ZW5zaW9uIHByZXNlbnQgKi8KCXN0cmNweSggZGxsbmFtZSwgbmFtZSApOwoJaWYgKCEocCA9IHN0cnJjaHIoIGRsbG5hbWUsICcuJykpIHx8IHN0cmNociggcCwgJy8nICkgfHwgc3RyY2hyKCBwLCAnXFwnKSkKCQlzdHJjYXQoIGRsbG5hbWUsICIuRExMIiApOwoKCS8qIExvYWQgUEUgbW9kdWxlICovCgloRmlsZSA9IE9wZW5GaWxlKCBkbGxuYW1lLCAmb2ZzLCBPRl9SRUFEIHwgT0ZfU0hBUkVfREVOWV9XUklURSApOwoJaWYgKCBoRmlsZSAhPSBIRklMRV9FUlJPUiApCgl7CgkJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgJm9mcywgJm1vZE5hbWUsICZ2ZXJzaW9uICk7CgkJQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJaWYoIWhNb2R1bGUzMikKCQl7CgkJCSplcnIgPSBFUlJPUl9PVVRPRk1FTU9SWTsJLyogTm90IGVudGlyZWx5IHJpZ2h0LCBidXQgZ29vZCBlbm91Z2ggKi8KCQkJcmV0dXJuIE5VTEw7CgkJfQoJfQoJZWxzZQoJewoJCSplcnIgPSBFUlJPUl9GSUxFX05PVF9GT1VORDsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoJaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoICZvZnMsIG1vZE5hbWUsIHZlcnNpb24gKSkgPCAzMikKCXsKCQkqZXJyID0gKERXT1JEKWhNb2R1bGUxNjsJLyogVGhpcyBzaG91bGQgZ2l2ZSB0aGUgY29ycmVjdCBlcnJvciAqLwoJCXJldHVybiBOVUxMOwoJfQoJcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwoJcE1vZHVsZS0+ZmxhZ3MgICAgPSBORV9GRkxBR1NfTElCTU9EVUxFIHwgTkVfRkZMQUdTX1NJTkdMRURBVEEgfCBORV9GRkxBR1NfV0lOMzI7CglwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsICZvZnMsIGZsYWdzLCBGQUxTRSApKSApCgl7CgkJRVJSXyh3aW4zMikoImNhbid0IGxvYWQgJXNcbiIsb2ZzLnN6UGF0aE5hbWUpOwoJCUZyZWVMaWJyYXJ5MTYoIGhNb2R1bGUxNiApOwoJCSplcnIgPSBFUlJPUl9PVVRPRk1FTU9SWTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpZiAod20tPmJpbmZtdC5wZS5wZV9leHBvcnQpCgkJU05PT1BfUmVnaXN0ZXJETEwod20tPm1vZHVsZSx3bS0+bW9kbmFtZSx3bS0+YmluZm10LnBlLnBlX2V4cG9ydC0+TnVtYmVyT2ZGdW5jdGlvbnMpOwoKCSplcnIgPSAwOwoJcmV0dXJuIHdtOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX1VubG9hZExpYnJhcnkKICoKICogVW5sb2FkIHRoZSBsaWJyYXJ5IHVubWFwcGluZyB0aGUgaW1hZ2UgYW5kIGZyZWVpbmcgdGhlIG1vZHJlZiBzdHJ1Y3R1cmUuCiAqLwp2b2lkIFBFX1VubG9hZExpYnJhcnkoV0lORV9NT0RSRUYgKndtKQp7CgkvKiBGSVhNRSwgZG8gc29tZXRoaW5nIGhlcmUgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIExvYWQgdGhlIFBFIG1haW4gLkVYRS4gQWxsIG90aGVyIGxvYWRpbmcgaXMgZG9uZSBieSBQRV9Mb2FkTGlicmFyeUV4QQogKiBGSVhNRTogdGhpcyBmdW5jdGlvbiBzaG91bGQgdXNlIFBFX0xvYWRMaWJyYXJ5RXhBLCBidXQgY3VycmVudGx5IGNhbid0CiAqIGR1ZSB0byB0aGUgUFJPQ0VTU19DcmVhdGUgc3R1ZmYuCiAqLwpCT09MIFBFX0NyZWF0ZVByb2Nlc3MoIEhGSUxFIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMUENTVFIgY21kX2xpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBwc2EsIExQU0VDVVJJVFlfQVRUUklCVVRFUyB0c2EsCiAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBpbmhlcml0LCBEV09SRCBmbGFncywgTFBTVEFSVFVQSU5GT0Egc3RhcnR1cCwKICAgICAgICAgICAgICAgICAgICAgICBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKICAgIExQQ1NUUiBtb2ROYW1lID0gTlVMTDsKICAgIFdPUkQgdmVyc2lvbiA9IDA7CiAgICBITU9EVUxFMTYgaE1vZHVsZTE2OwogICAgSE1PRFVMRSBoTW9kdWxlMzI7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CgogICAgLyogTG9hZCBmaWxlICovCiAgICBpZiAoIChoTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBvZnMsICZtb2ROYW1lLCAmdmVyc2lvbiApKSA8IDMyICkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIGhNb2R1bGUzMiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KI2lmIDAKICAgIGlmIChQRV9IRUFERVIoaE1vZHVsZTMyKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIDIwICk7ICAvKiBGSVhNRTogbm90IHRoZSByaWdodCBlcnJvciBjb2RlICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQojZW5kaWYKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwogICAgaWYgKCAoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBvZnMsIG1vZE5hbWUsIHZlcnNpb24gKSkgPCAzMiApIAogICAgewogICAgICAgIFNldExhc3RFcnJvciggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgcE1vZHVsZS0+ZmxhZ3MgICAgPSBORV9GRkxBR1NfV0lOMzI7CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCiAgICAvKiBDcmVhdGUgbmV3IHByb2Nlc3MgKi8KICAgIGlmICggIVBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzYSwgdHNhLCBpbmhlcml0LCBmbGFncywgc3RhcnR1cCwgaW5mbyApICkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogTm90ZTogUEVfQ3JlYXRlTW9kdWxlIGFuZCB0aGUgcmVtYWluaW5nIHByb2Nlc3MgaW5pdGlhbGl6YXRpb24gd2lsbAogICAgICAgICAgICAgYmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgbmV3IHByb2Nlc3MsIGluIFRBU0tfQ2FsbFRvU3RhcnQgKi8KCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQRV9VbmxvYWRJbWFnZSBbaW50ZXJuYWxdCiAqLwppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUgaE1vZHVsZSApCnsKCUZJWE1FXyh3aW4zMikoInN0dWIuXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KQk9PTCBQRV9Jbml0RExMKCBXSU5FX01PRFJFRiAqd20sIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkICkKewogICAgQk9PTCByZXR2ID0gVFJVRTsKICAgIGFzc2VydCggd20tPnR5cGUgPT0gTU9EVUxFMzJfUEUgKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopUlZBX1BUUiggd20tPm1vZHVsZSxPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCiAgICAgICAgcmV0diA9IGVudHJ5KCB3bS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9CgogICAgcmV0dXJuIHJldHY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfSW5pdFRscwkJCShpbnRlcm5hbCkKICoKICogSWYgaW5jbHVkZWQsIGluaXRpYWxpc2VzIHRoZSB0aHJlYWQgbG9jYWwgc3RvcmFnZXMgb2YgbW9kdWxlcy4KICogUG9pbnRlcnMgaW4gdGhvc2Ugc3RydWN0cyBhcmUgbm90IFJWQXMgYnV0IHJlYWwgcG9pbnRlcnMgd2hpY2ggaGF2ZSBiZWVuCiAqIHJlbG9jYXRlZCBieSBkb19yZWxvY2F0aW9ucygpIGFscmVhZHkuCiAqLwpzdGF0aWMgTFBWT0lECl9maXh1cF9hZGRyZXNzKFBJTUFHRV9PUFRJT05BTF9IRUFERVIgb3B0LGludCBkZWx0YSxMUFZPSUQgYWRkcikgewoJaWYgKAkoKERXT1JEKWFkZHI+b3B0LT5JbWFnZUJhc2UpICYmCgkJKChEV09SRClhZGRyPG9wdC0+SW1hZ2VCYXNlK29wdC0+U2l6ZU9mSW1hZ2UpCgkpCgkJLyogdGhlIGFkZHJlc3MgaGFzIG5vdCBiZWVuIHJlbG9jYXRlZCEgKi8KCQlyZXR1cm4gKExQVk9JRCkoKChEV09SRClhZGRyKStkZWx0YSk7CgllbHNlCgkJLyogdGhlIGFkZHJlc3MgaGFzIGJlZW4gcmVsb2NhdGVkIGFscmVhZHkgKi8KCQlyZXR1cm4gYWRkcjsKfQp2b2lkIFBFX0luaXRUbHMoIHZvaWQgKQp7CglXSU5FX01PRFJFRgkJKndtOwoJUEVfTU9EUkVGCQkqcGVtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlpZiAod20tPnR5cGUhPU1PRFVMRTMyX1BFKQoJCQljb250aW51ZTsKCQlwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIHBlbS0+dGxzaW5kZXggPT0gLTEgKSB7CgkJCUxQRFdPUkQgeGFkZHI7CgkJCXBlbS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXBlbS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7IAoKCQkgICAgIGNicyA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEscGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKTsKCQkgICAgIGlmICgqY2JzKQoJCSAgICAgICBGSVhNRV8od2luMzIpKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHBlbS0+dGxzaW5kZXgsIG1lbSApOwoJfQp9Cgo=