LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICogLSBBbGwgdGhvc2UgZnVuY3Rpb24gbWFwIHRoaW5ncyBpbnRvIGEgbmV3IGFkZHJlc3NwYWNlLiBGcm9tIHRoZSB3cm9uZwogKiAgIHByb2Nlc3MgYW5kIHRoZSB3cm9uZyB0aHJlYWQuIFNvIGNhbGxpbmcgb3RoZXIgQVBJIGZ1bmN0aW9ucyB3aWxsIG1lc3MgCiAqICAgdGhpbmdzIHVwIGJhZGx5IHNvbWV0aW1lcy4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAiZGVidWcuaCIKCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGKiBtb2RyZWYsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkKTsKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodW5zaWduZWQgaW50KWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFMzIgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSh3aW4zMiwiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0Uod2luMzIsIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsPSh1X3Nob3J0KikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zPWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lPSh1X2NoYXIqKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0Uod2luMzIsIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKXsKCWRiZ19kZWNsX3N0cih3aW4zMiwgMTAyNCk7CgoJZHNwcmludGYod2luMzIsIiU0bGQgJTA4bHggJTA4eCIsCgkJIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQoJICAgIGRzcHJpbnRmKHdpbjMyLCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgZHNwcmludGYod2luMzIsICIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCVRSQUNFKHdpbjMyLCIlc1xuIiwgZGJnX3N0cih3aW4zMikpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIFBEQjMyICpwcm9jZXNzLCBITU9EVUxFMzIgaE1vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZnVuY05hbWUpCnsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgCQkqZXhwb3J0czsKCXVuc2lnbmVkCQkJbG9hZF9hZGRyOwoJdV9zaG9ydAkJCQkqIG9yZGluYWw7Cgl1X2xvbmcJCQkJKiBmdW5jdGlvbjsKCXVfY2hhcgkJCQkqKiBuYW1lLCAqZW5hbWU7CglpbnQJCQkJaTsKCVBFX01PRFJFRgkJCSpwZW07Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtICYmIChwZW0tPm1vZHVsZSAhPSBoTW9kdWxlKSkKCQlwZW09cGVtLT5uZXh0OwoJaWYgKCFwZW0pIHsKCQlmcHJpbnRmKHN0ZGVyciwiTm8gTU9EUkVGIGZvdW5kIGZvciBQRV9NT0RVTEUgJTA4eCBpbiBwcm9jZXNzICVwXG4iLGhNb2R1bGUscHJvY2Vzcyk7CgkJcmV0dXJuIE5VTEw7Cgl9Cglsb2FkX2FkZHIgPSBoTW9kdWxlOwoJZXhwb3J0cyAgID0gcGVtLT5wZV9leHBvcnQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0Uod2luMzIsIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKHdpbjMyLCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJZnByaW50ZihzdGRlcnIsIk1vZHVsZSAlMDh4L01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIixoTW9kdWxlLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFsCT0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKSB7CgkJZm9yKGk9MDsgaTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspIHsKCQkJZW5hbWU9KGNoYXIqKVJWQSgqbmFtZSk7CgkJCWlmKCFzdHJjbXAoZW5hbWUsZnVuY05hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyID0gZnVuY3Rpb25bKm9yZGluYWxdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCX0KCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIHsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJVFJBQ0Uod2luMzIsIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlhZGRyID0gZnVuY3Rpb25bKGludClmdW5jTmFtZS1leHBvcnRzLT5CYXNlXTsKICAgICAgICAgICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CgkJaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwoJCWZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKCX0KCWlmIChmb3J3YXJkKQogICAgICAgIHsKICAgICAgICAgICAgICAgIEhNT0RVTEUzMiBoTW9kOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwoJCXN0cm5jcHkobW9kdWxlLCBmb3J3YXJkLCAoZW5kIC0gZm9yd2FyZCkpOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaE1vZCA9IE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggTU9EVUxFX0ZpbmRNb2R1bGUobW9kdWxlKSApOwoJCXJldHVybiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggcHJvY2VzcywgaE1vZCwgZW5kICsgMSk7Cgl9CglyZXR1cm4gTlVMTDsKfQoKRFdPUkQgZml4dXBfaW1wb3J0cyAoUERCMzIgKnByb2Nlc3MsUEVfTU9EUkVGICpwZW0pCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBpbnQJZml4dXBfZmFpbGVkCQk9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gcGVtLT5tb2R1bGU7CiAgICBpbnQJCQkJaTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIAogICAgaWYgKHBlbS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIFRSQUNFKHdpbjMyLCAiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSAKICAgIAlFUlIod2luMzIsICJubyBpbXBvcnQgZGlyZWN0b3J5Pz8/P1xuIik7CgogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspCglpKys7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZTsgcGVfaW1wKyspIHsKICAgIAlITU9EVUxFMzIJcmVzOwoJUEVfTU9EUkVGCSp4cGVtLCoqeXBlbTsKCgogCWNoYXIgKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCgkvKiBkb24ndCB1c2UgTU9EVUxFX0xvYWQsIFdpbjMyIGNyZWF0ZXMgbmV3IHRhc2sgZGlmZmVyZW50bHkgKi8KCXJlcyA9IFBFX0xvYWRMaWJyYXJ5RXgzMkEoIG5hbWUsIHByb2Nlc3MsIDAsIDAgKTsKCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBjaGFyIGJ1ZmZlclsxMDI0XTsKCgkgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KCSAgICBpZiAoR2V0TW9kdWxlRmlsZU5hbWUzMkEoIHBlbS0+bW9kdWxlLCBidWZmZXIsIHNpemVvZiAoYnVmZmVyKSkpIHsKCSAgICAgICAgY2hhciAqcDsKCgkJaWYgKCEocCA9IHN0cnJjaHIgKGJ1ZmZlciwgJ1xcJykpKQoJCSAgICBwID0gYnVmZmVyOwoJCXN0cmNweSAocCArIDEsIG5hbWUpOwoJCXJlcyA9IFBFX0xvYWRMaWJyYXJ5RXgzMkEoIGJ1ZmZlciwgcHJvY2VzcywgMCwgMCApOwoJICAgIH0gZWxzZQoJICAgIAlFUlIod2luMzIsImNhbm5vdCBmaW5kIHRoZSBtb2R1bGUganVzdCBsb2FkZWQhXG4iKTsKCX0KCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLCBuYW1lKTsKCSAgICByZXR1cm4gcmVzOwoJfQoJcmVzID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKHJlcyk7Cgl4cGVtID0gcGVtLT5uZXh0OwoJd2hpbGUgKHhwZW0pIHsKCQlpZiAoeHBlbS0+bW9kdWxlID09IHJlcykKCQkJYnJlYWs7CgkJeHBlbSA9IHhwZW0tPm5leHQ7Cgl9CglpZiAoeHBlbSkgewoJCS8qIEl0IGhhcyBiZWVuIGxvYWRlZCAqQkVGT1JFKiB1cywgc28gd2UgaGF2ZSB0byBpbml0aWFsaXplCgkJICogaXQgYmVmb3JlIHVzLiBXZSBjYW5ub3QganVzdCBsaW5rIGluIHRoZSB4cGVtIGJlZm9yZSBwZW0sCgkJICogc2luY2UgeHBlbSBtaWdodCByZWZlcmVuY2UgbW9yZSBkbGxzIHdoaWNoIHdvdWxkIGJlIGluIHRoZQoJCSAqIHdyb25nIG9yZGVyIGFmdGVyIHRoYXQuCgkJICogSW5zdGVhZCB3ZSBsaW5rIGluIHBlbSByaWdodCBBRlRFUiB4cGVtLCB3aGljaCBzaG91bGQga2VlcAoJCSAqIHRoZSBjb3JyZWN0IG9yZGVyLiAoSSBhbSBub3QgMTAwJSBzdXJlIGFib3V0IHRoYXQuKQoJCSAqLwoJCS8qIHVubGluayBwZW0gZnJvbSBjaGFpbiAqLwoJCXlwZW0gPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQl3aGlsZSAoKnlwZW0pIHsKCQkJaWYgKCgqeXBlbSk9PXBlbSkKCQkJCWJyZWFrOwoJCQl5cGVtID0gJigoKnlwZW0pLT5uZXh0KTsKCQl9CgkJKnlwZW0JCT0gcGVtLT5uZXh0OwoKCQkvKiBsaW5rIHBlbSBkaXJlY3RseSBBRlRFUiB4cGVtICovCgkJcGVtLT5uZXh0CT0geHBlbS0+bmV4dDsKCQl4cGVtLT5uZXh0CT0gcGVtOwoJCQoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICB3aGlsZSAocGVfaW1wLT5OYW1lKSB7CgljaGFyCQkJKk1vZHVsZTsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJTFBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAgICAgICAgSE1PRFVMRTMyIGhJbXBNb2R1bGU7CgoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CiAgICAgICAgaEltcE1vZHVsZSA9IE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSApOwoJVFJBQ0Uod2luMzIsICIlc1xuIiwgTW9kdWxlKTsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIFRSQUNFKHdpbjMyLCAiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgoJICAgIHdoaWxlIChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSh3aW4zMiwgIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBNb2R1bGUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcywgaEltcE1vZHVsZSwgKExQQ1NUUilvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKExQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0Uod2luMzIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKVBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCBwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRSh3aW4zMiwgIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSh3aW4zMiwiLS0tIE9yZGluYWwgJXMuJWRcbiIsTW9kdWxlLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcywgaEltcE1vZHVsZSwgKExQQ1NUUikgb3JkaW5hbCk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJZnByaW50ZihzdGRlcnIsICJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSxvcmRpbmFsKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPShMUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKHdpbjMyLCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsTW9kdWxlLHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj0oTFBEV09SRClQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbigKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcywgaEltcE1vZHVsZSwgcGVfbmFtZS0+TmFtZSApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIHJldHVybiAyMjsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNhbGNfdm1hX3NpemUoIEhNT0RVTEUzMiBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIFRSQUNFKHdpbjMyLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICAgIFRSQUNFKHdpbjMyLCAiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIFRSQUNFKHdpbjMyLCAiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZSA9IE1BWCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyhQRV9NT0RSRUYgKnBlbSkKewogICAgaW50IGRlbHRhID0gcGVtLT5tb2R1bGUgLSBQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyPSBwZW0tPm1vZHVsZTsKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkJKnIgPSBwZW0tPnBlX3JlbG9jOwoJaW50CQkJCWhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CglpbnQJCQkJbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRShmaXh1cCwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlZpcnR1YWxBZGRyZXNzKTsKCQkvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCgkJZm9yKGk9MDtpPGNvdW50O2krKykKCQl7CgkJCWludCBvZmZzZXQgPSByLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+VHlwZU9mZnNldFtpXSA+PiAxMjsKCQkJVFJBQ0UoZml4dXAsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+VHlwZU9mZnNldFsrK2ldOwoJCQkJICAqKHVuc2lnbmVkIGludCopKHBhZ2UgKyBvZmZzZXQpID0gKGg8PDE2KSArIGwgKyBkZWx0YTsKCQkJCX0KI2VuZGlmCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCWZwcmludGYoc3RkZXJyLCAiRG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggSU1BR0VfUkVMX0JBU0VEX0hJR0hBREpcbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX01JUFNfSk1QQUREUjoKCQkJCWZwcmludGYoc3RkZXJyLCAiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8Kc3RhdGljIEhNT0RVTEUzMiBQRV9Mb2FkSW1hZ2UoIEhGSUxFMzIgaEZpbGUgKQp7CiAgICBITU9EVUxFMzIgaE1vZHVsZTsKICAgIEhBTkRMRTMyIG1hcHBpbmc7CgogICAgLyogbWFwIHRoZSBQRSBmaWxlIHNvbWV3aGVyZSAqLwogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nMzJBKCBoRmlsZSwgTlVMTCwgUEFHRV9SRUFET05MWSB8IFNFQ19DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBmcHJpbnRmKCBzdGRlcnIsICJQRV9Mb2FkSW1hZ2U6IENyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwKICAgICAgICAgICAgICAgICBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaE1vZHVsZSA9IChITU9EVUxFMzIpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBmcHJpbnRmKCBzdGRlcnIsICJQRV9Mb2FkSW1hZ2U6IE1hcFZpZXdPZkZpbGUgZXJyb3IgJWxkXG4iLAogICAgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlKS0+U2lnbmF0dXJlICE9IElNQUdFX05UX1NJR05BVFVSRSkKICAgIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIGZwcmludGYoc3RkZXJyLCJ0cnlpbmcgdG8gbG9hZCBQRSBpbWFnZSBmb3IgdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0dXJlICgiKTsKICAgICAgICBzd2l0Y2ggKFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lKQogICAgICAgIHsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOiBmcHJpbnRmKHN0ZGVyciwiVW5rbm93biIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOiAgICBmcHJpbnRmKHN0ZGVyciwiSTg2MCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMzAwMDogICBmcHJpbnRmKHN0ZGVyciwiUjMwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6ICAgZnByaW50ZihzdGRlcnIsIlI0MDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDogIGZwcmludGYoc3RkZXJyLCJSMTAwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfQUxQSEE6ICAgZnByaW50ZihzdGRlcnIsIkFscGhhIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6IGZwcmludGYoc3RkZXJyLCJQb3dlclBDIik7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IGZwcmludGYoc3RkZXJyLCJVbmtub3duLSUwNHgiLAogICAgICAgICAgICAgICAgICAgICAgICAgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgZnByaW50ZihzdGRlcnIsIilcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByZXR1cm4gaE1vZHVsZTsKCmVycm9yOgogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGlzIG1hcHMgYSBsb2FkZWQgUEUgZGxsIGludG8gdGhlIGFkZHJlc3Mgc3BhY2Ugb2YgdGhlIHNwZWNpZmllZCBwcm9jZXNzLgogKi8Kc3RhdGljIEJPT0wzMiBQRV9NYXBJbWFnZSggSE1PRFVMRTMyICpwaE1vZHVsZSwgUERCMzIgKnByb2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIE9GU1RSVUNUICpvZnMsIERXT1JEIGZsYWdzICkKewoJUEVfTU9EUkVGCQkqcGVtOwoJaW50CQkJaSwgcmVzdWx0OwoJRFdPUkQJCQlsb2FkX2FkZHI7CglJTUFHRV9EQVRBX0RJUkVDVE9SWQlkaXI7CgljaGFyCQkJKm1vZG5hbWU7CglpbnQJCQl2bWFfc2l6ZTsKCUhNT0RVTEUzMgkJaE1vZHVsZSA9ICpwaE1vZHVsZTsKCiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZzsKICAgICAgICBJTUFHRV9ET1NfSEVBREVSICpkb3NfaGVhZGVyID0gKElNQUdFX0RPU19IRUFERVIgKiloTW9kdWxlOwogICAgICAgIElNQUdFX05UX0hFQURFUlMgKm50X2hlYWRlciA9IFBFX0hFQURFUihoTW9kdWxlKTsKCQoJcGVtID0gKFBFX01PRFJFRiopSGVhcEFsbG9jKHByb2Nlc3MtPmhlYXAsSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKCpwZW0pKTsKCS8qIE5PVEU6IGZpeHVwX2ltcG9ydHMgdGFrZXMgY2FyZSBvZiB0aGUgY29ycmVjdCBvcmRlciAqLwoJcGVtLT5uZXh0CT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cglwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHBlbTsKCglpZiAoIShudF9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgICAgIHsKCQlpZiAocHJvY2Vzcy0+ZXhlX21vZHJlZikKCQkJZnByaW50ZihzdGRlcnIsIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iKTsKCQlwcm9jZXNzLT5leGVfbW9kcmVmID0gcGVtOwoJfQoKCWxvYWRfYWRkciA9IG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CglUUkFDRSh3aW4zMiwgIkxvYWQgYWRkciBpcyAlbHhcbiIsbG9hZF9hZGRyKTsKCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAobG9hZF9hZGRyID09IDApIHsKCQlsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkJIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKCQkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCX0KCS8qICpwaE1vZHVsZSBpcyB0aGUgbW9kdWxlMzIgZW50cnkgaW4gdGhlIE5FX01PRFVMRS4gV2UgbmVlZCB0bwoJICogY2hhbmdlIGl0IGhlcmUsIHNpbmNlIGl0IGNhbiBnZXQgcmVmZXJlbmNlZCBieSBmaXh1cF9pbXBvcnRzKCkKCSAqLwoJcGVtLT5tb2R1bGUgPSAqcGhNb2R1bGUgPSAoSE1PRFVMRTMyKWxvYWRfYWRkcjsKCglUUkFDRSh3aW4zMiwgIkxvYWQgYWRkciBpcyByZWFsbHkgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICAgIGxvYWRfYWRkciwgdm1hX3NpemUpOwoJCiAgICAgICAgLyogU3RvcmUgdGhlIE5UIGhlYWRlciBhdCB0aGUgbG9hZCBhZGRyCiAgICAgICAgICogKEZJWE1FOiBzaG91bGQgcmVhbGx5IHVzZSBtbWFwKQogICAgICAgICAqLwogICAgICAgICooSU1BR0VfRE9TX0hFQURFUiAqKWxvYWRfYWRkciA9ICpkb3NfaGVhZGVyOwogICAgICAgICooSU1BR0VfTlRfSEVBREVSUyAqKShsb2FkX2FkZHIgKyBkb3NfaGVhZGVyLT5lX2xmYW5ldykgPSAqbnRfaGVhZGVyOwoKICAgICAgICBwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCWZvciAoaSA9IDA7IGkgPCBudF9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWcrKykKCXsKCQkvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQoJCSAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKCQkgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCgkJICovCgkJaWYoIShwZV9zZWctPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKCQkgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VnLT5WaXJ0dWFsQWRkcmVzcyksCgkJICAgIAkoY2hhciopKGhNb2R1bGUgKyBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEpLAoJCQlwZV9zZWctPlNpemVPZlJhd0RhdGEKCQkgICAgKTsKCgkJcmVzdWx0ID0gUlZBIChwZV9zZWctPlZpcnR1YWxBZGRyZXNzKTsKI2lmIDEKCQkvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuYnNzIikgPT0gMCkKCQkgICAgbWVtc2V0KCh2b2lkICopcmVzdWx0LCAwLCAKCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplID8KCQkJICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplIDoKCQkJICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuaWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIuZWRhdGEiKSA9PSAwKQoJCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5yc3JjIikgPT0gMCkKCQkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJlbG9jIikgPT0gMCkKCQkJcGVtLT5wZV9yZWxvYyA9IChMUElNQUdFX0JBU0VfUkVMT0NBVElPTikgcmVzdWx0OwoJfQoKCS8qIFRoZXJlIGlzIHdvcmQgdGhhdCB0aGUgYWN0dWFsIGxvYWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IHRoZQoJICAgc2VjdGlvbiBuYW1lcywgYW5kIG9ubHkgZ29lcyBmb3IgdGhlIERhdGFEaXJlY3RvcnkgKi8KCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX2V4cG9ydCAmJiAoaW50KXBlbS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQkvKiAKCQlpZihwZW0tPnBlX2ltcG9ydCAmJiAoaW50KXBlbS0+cGVfaW1wb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGltcG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJICovCgkJcGVtLT5wZV9pbXBvcnQgPSAoTFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0VdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZXNvdXJjZSAmJiAoaW50KXBlbS0+cGVfcmVzb3VyY2UhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVzb3VyY2UgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlbS0+cGVfcmVzb3VyY2UgPSAoTFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFldLlNpemUpCgkJRklYTUUod2luMzIsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1udF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3JlbG9jICYmIChpbnQpcGVtLT5wZV9yZWxvYyE9IFJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgcmVsb2NhdGlvbiBsaXN0Pz9cbiIpOwoJCXBlbS0+cGVfcmVsb2MgPSAodm9pZCAqKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiQ29weXJpZ2h0IHN0cmluZyBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUddLlNpemUpCgkJRklYTUUod2luMzIsIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlRdLlNpemUpCgkJRklYTUUod2luMzIsIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVRdLlNpemUpCgkJRklYTUUod2luMzIsIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxM10uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiVW5rbm93biBkaXJlY3RvcnkgMTMgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTRdLlNpemUpCgkJRklYTUUod2luMzIsIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE1XS5TaXplKQoJCUZJWE1FKHdpbjMyLCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iKTsKCglpZihwZW0tPnBlX3JlbG9jKQlkb19yZWxvY2F0aW9ucyhwZW0pOwoJaWYocGVtLT5wZV9leHBvcnQpCWR1bXBfZXhwb3J0cyhwZW0tPm1vZHVsZSk7CglpZihwZW0tPnBlX2ltcG9ydCkJewoJCWlmIChmaXh1cF9pbXBvcnRzKHByb2Nlc3MscGVtKSkgewoJCQlQRV9NT0RSRUYJKip4cGVtOwoKCQkJLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCgkJCXhwZW0gPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQkJd2hpbGUgKCp4cGVtKSB7CgkJCQlpZiAoKnhwZW09PXBlbSkgewoJCQkJCSp4cGVtID0gcGVtLT5uZXh0OwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJeHBlbSA9ICYoKCp4cGVtKS0+bmV4dCk7CgkJCX0KCQkJLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwoJCQkgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQoJCQkgKiBmYWlsZWQgb25lLiBVbnJvbGxpbmcgaXMgcmF0aGVyIGRpZmZpY3VsdCB3aXRoIHRoZQoJCQkgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIGl0IHRoZW0gbHlpbmcKCQkJICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUKCQkJICovCgkJCXJldHVybiAwOwoJCX0KCX0KICAJCQoJaWYgKHBlbS0+cGVfZXhwb3J0KQoJCW1vZG5hbWUgPSAoY2hhciopUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKCWVsc2UgewoJCWNoYXIgKnM7CgkJbW9kbmFtZSA9IHMgPSBvZnMtPnN6UGF0aE5hbWU7CgkJd2hpbGUgKChzPXN0cmNocihtb2RuYW1lLCdcXCcpKSkKCQkJbW9kbmFtZSA9IHMrMTsKCQlpZiAoKHM9c3RyY2hyKG1vZG5hbWUsJy4nKSkpCgkJCSpzPSdcMCc7Cgl9CgogICAgICAgIC8qIE5vdyB0aGF0IHdlIGdvdCBldmVyeXRoaW5nIGF0IHRoZSByaWdodCBhZGRyZXNzLAogICAgICAgICAqIHdlIGNhbiB1bm1hcCB0aGUgcHJldmlvdXMgbW9kdWxlICovCiAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgICAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICogICAgICAgIGludGVybmFsIG1vZHVsZSBoYW5kbGluZyBzaG91bGQgYmUgbWFkZSBiZXR0ZXIgaGVyZSAoYW5kIGluIGJ1aWx0aW4uYykKICovCkhNT0RVTEUzMiBQRV9Mb2FkTGlicmFyeUV4MzJBIChMUENTVFIgbmFtZSwgUERCMzIgKnByb2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIRklMRTMyIGhGaWxlLCBEV09SRCBmbGFncykKewoJT0ZTVFJVQ1QJb2ZzOwoJSE1PRFVMRTMyCWhNb2R1bGU7CglORV9NT0RVTEUJKnBNb2R1bGU7CglQRV9NT0RSRUYJKnBlbTsKCglpZiAoKGhNb2R1bGUgPSBNT0RVTEVfRmluZE1vZHVsZSggbmFtZSApKSkgewoJCS8qIHRoZSAuRExMIGlzIGVpdGhlciBsb2FkZWQgb3IgaW50ZXJuYWwgKi8KCQloTW9kdWxlID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKGhNb2R1bGUpOwoJCWlmICghSElXT1JEKGhNb2R1bGUpKSAvKiBpbnRlcm5hbCAob3IgYmFkKSAqLwoJCQlyZXR1cm4gaE1vZHVsZTsKCQkvKiBjaGVjayBpZiB0aGlzIG1vZHVsZSBpcyBhbHJlYWR5IG1hcHBlZCAqLwoJCXBlbSAJPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQlwTW9kdWxlID0gTU9EVUxFX0dldFB0cihoTW9kdWxlKTsKCQl3aGlsZSAocGVtKSB7CgkJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKSB7CgkJCQlwTW9kdWxlLT5jb3VudCsrOwoJCQkJcmV0dXJuIGhNb2R1bGU7CgkJCX0KCQkJcGVtID0gcGVtLT5uZXh0OwoJCX0KCQlpZiAocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfQlVJTFRJTikgewoJCQlJTUFHRV9ET1NfSEVBREVSCSpkaDsKCQkJSU1BR0VfTlRfSEVBREVSUwkqbmg7CgkJCUlNQUdFX1NFQ1RJT05fSEVBREVSCSpzaDsKCgkJCS8qIHdlIG9ubHkgY29tZSBoZXJlIGlmIHdlIGFscmVhZHkgaGF2ZSAnbG9hZGVkJyB0aGUKCQkJICogaW50ZXJuYWwgZGxsIGJ1dCBpbiBhbm90aGVyIHByb2Nlc3MuIEp1c3QgY3JlYXRlCgkJCSAqIGEgUEVfTU9EUkVGIGFuZCByZXR1cm4uCgkJCSAqLwoJCQlwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MocHJvY2Vzcy0+aGVhcCwKCQkJCUhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCQkJcGVtLT5tb2R1bGUgCSAgICAgPSBoTW9kdWxlOwoJCQlkaCA9IChJTUFHRV9ET1NfSEVBREVSKilwZW0tPm1vZHVsZTsKCQkJbmggPSAoSU1BR0VfTlRfSEVBREVSUyopKGRoKzEpOwoJCQlzaCA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKG5oKzEpOwoJCQlwZW0tPnBlX2V4cG9ydAkgICAgID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKShzaCsyKTsKCQkJcGVtLT5uZXh0CSAgICAgPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQkJcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSBwZW07CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCX0gZWxzZSB7CgoJCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU4zMl9Mb2FkTW9kdWxlKCBuYW1lLCBGQUxTRSwgcHJvY2VzcyApKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBoTW9kdWxlICk7CgoJCS8qIHRyeSB0byBvcGVuIHRoZSBzcGVjaWZpZWQgZmlsZSAqLwoJCWlmIChIRklMRV9FUlJPUjMyPT0oaEZpbGU9T3BlbkZpbGUzMihuYW1lLCZvZnMsT0ZfUkVBRCkpKSB7CgkJCS8qIE5vdyB0cnkgdGhlIGJ1aWx0LWluIGV2ZW4gaWYgZGlzYWJsZWQgKi8KCQkJaWYgKChoTW9kdWxlID0gQlVJTFRJTjMyX0xvYWRNb2R1bGUoIG5hbWUsIFRSVUUsIHByb2Nlc3MgKSkpIHsKCQkJCWZwcmludGYoIHN0ZGVyciwgIldhcm5pbmc6IGNvdWxkIG5vdCBsb2FkIFdpbmRvd3MgRExMICclcycsIHVzaW5nIGJ1aWx0LWluIG1vZHVsZS5cbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBoTW9kdWxlICk7CgkJCX0KCQkJcmV0dXJuIDE7CgkJfQoJCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSB7CgkJCV9sY2xvc2UzMihoRmlsZSk7CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCQlwTW9kdWxlCQk9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKCQlwTW9kdWxlLT5mbGFncwk9IE5FX0ZGTEFHU19XSU4zMjsKCQlwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKCQlDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlpZiAocE1vZHVsZS0+bW9kdWxlMzIgPCAzMikgcmV0dXJuIDIxOwoJfQoJLyogcmVjdXJzZSAqLwoJaWYgKCFQRV9NYXBJbWFnZSggJihwTW9kdWxlLT5tb2R1bGUzMiksIHByb2Nlc3MsICZvZnMsZmxhZ3MpKSB7CgkJLyogc2hvdWxkIGZyZWUgdGhpcyBtb2R1bGUgYW5kIHRoZSBhbHJlYWR5IHJlZmVyZW5jZWQgb25lcyAqLwoJCXJldHVybiAwOwoJfQoJcmV0dXJuIHBNb2R1bGUtPm1vZHVsZTMyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTG9hZCB0aGUgUEUgbWFpbiAuRVhFLiBBbGwgb3RoZXIgbG9hZGluZyBpcyBkb25lIGJ5IFBFX0xvYWRMaWJyYXJ5RXgzMkEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4MzJBLCBidXQgY3VycmVudGx5IGNhbid0CiAqIGR1ZSB0byB0aGUgUFJPQ0VTU19DcmVhdGUgc3R1ZmYuCiAqLwpISU5TVEFOQ0UxNiBQRV9Mb2FkTW9kdWxlKCBIRklMRTMyIGhGaWxlLCBPRlNUUlVDVCAqb2ZzLCBMUENTVFIgY21kX2xpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIFVJTlQxNiBzaG93X2NtZCApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlMTY7CiAgICBITU9EVUxFMzIgaE1vZHVsZTMyOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgVEhEQiAqdGhkYiA9IFRIUkVBRF9DdXJyZW50KCk7CiAgICAKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBvZnMgKSkgPCAzMikgcmV0dXJuIGhNb2R1bGUxNjsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwogICAgaWYgKGhNb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlMTYsIChjbWRfbGluZSA9PSBOVUxMKSApOwogICAgaWYgKGNtZF9saW5lICYmCiAgICAgICAgIShQRV9IRUFERVIoaE1vZHVsZTMyKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgUERCMzIgKnBkYiA9IFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEluc3RhbmNlLCAwLCBzaG93X2NtZCApOwogICAgICAgIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBwZGItPnRhc2sgKTsKICAgICAgICB0aGRiID0gcFRhc2stPnRoZGI7CiAgICB9CiAgICBpZiAoIVBFX01hcEltYWdlKCAmKHBNb2R1bGUtPm1vZHVsZTMyKSwgdGhkYi0+cHJvY2Vzcywgb2ZzLCAwICkpCiAgICB7CiAgICAgCS8qIEZJWE1FOiBzaG91bGQgZGVzdHJveSB0aGUgdGFzayBjcmVhdGVkIGFuZCBmcmVlIHJlZmVyZW5jZWQgc3R1ZmYgKi8KICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIC8qIEZJWE1FOiBZdWNrLiBJcyB0aGVyZSBubyBvdGhlciBnb29kIHBsYWNlIHRvIGRvIHRoYXQ/ICovCiAgICBQRV9Jbml0VGxzKCB0aGRiICk7CiAgICByZXR1cm4gaEluc3RhbmNlOwp9CgppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlICkKewoJZnByaW50ZihzdGRlcnIsIlBFdW5sb2FkSW1hZ2UoKSBjYWxsZWQhXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kc3RhdGljIHZvaWQgUEVfSW5pdERMTChQRV9NT0RSRUYgKnBlbSwgRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkKewogICAgaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkKCXBlbS0+ZmxhZ3MgfD0gUEVfTU9EUkVGX1BST0NFU1NfQVRUQUNIRUQ7CgogICAgLyogIERMTF9BVFRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgZm9yIGR5bmFtaWMgbG9hZHMsIG5vdC1OVUxMIGZvciBzdGF0aWMgbG9hZHMKICAgICAqICBETExfREVUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGlmIGNhbGxlZCBieSBGcmVlTGlicmFyeSwgbm90LU5VTEwgb3RoZXJ3aXNlCiAgICAgKiAgdGhlIFNESyBkb2Vzbid0IG1lbnRpb24gYW55dGhpbmcgZm9yIERMTF9USFJFQURfKgogICAgICovCiAgICAgICAgCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgoUEVfSEVBREVSKHBlbS0+bW9kdWxlKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAoUEVfSEVBREVSKHBlbS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIEZBUlBST0MzMiBlbnRyeSA9IChGQVJQUk9DMzIpUlZBX1BUUiggcGVtLT5tb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgICAgICBUUkFDRShyZWxheSwgIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LCBwZW0tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgICAgIGVudHJ5KCBwZW0tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQp9CgovKiBDYWxsIHRoZSBETExlbnRyeSBmdW5jdGlvbiBvZiBhbGwgZGxscyB1c2VkIGJ5IHRoYXQgcHJvY2Vzcy4KICogKE5PVEU6IHRoaXMgbWF5IHJlY3Vyc2l2ZWx5IGNhbGwgdGhpcyBmdW5jdGlvbiAoaWYgYSBsaWJyYXJ5IGNhbGxzCiAqIExvYWRMaWJyYXJ5KSAuLi4gYnV0IGl0IHdvbid0IG1hdHRlcikKICovCnZvaWQgUEVfSW5pdGlhbGl6ZURMTHMoUERCMzIgKnByb2Nlc3MsRFdPUkQgdHlwZSxMUFZPSUQgbHBSZXNlcnZlZCkgewoJUEVfTU9EUkVGCSpwZW07CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtKSB7CgkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfTk9fRExMX0NBTExTKSB7CgkJCXBlbSA9IHBlbS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCWlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpIHsKCQkJaWYgKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRCkgewoJCQkJcGVtID0gcGVtLT5uZXh0OwoJCQkJY29udGludWU7CgkJCX0KCQl9CgkJUEVfSW5pdERMTCggcGVtLCB0eXBlLCBscFJlc2VydmVkICk7CgkJcGVtID0gcGVtLT5uZXh0OwoJfQp9Cgp2b2lkIFBFX0luaXRUbHMoVEhEQiAqdGhkYikKewoJLyogRklYTUU6IHRscyBjYWxsYmFja3MgPz8/ICovCglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglMUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKCVBEQjMyCQkJKnBkYiA9IHRoZGItPnByb2Nlc3M7CgoJcGVtID0gcGRiLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0pIHsKCQlwZWggPSBQRV9IRUFERVIocGVtLT5tb2R1bGUpOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKSB7CgkJCXBlbSA9IHBlbS0+bmV4dDsKCQkJY29udGludWU7CgkJfQoJCXBkaXIgPSAoTFBWT0lEKShwZW0tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCWlmICghKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfVExTX0FMTE9DRUQpKSB7CgkJCXBlbS0+dGxzaW5kZXggPSBUSFJFQURfVGxzQWxsb2ModGhkYik7CgkJCSoocGRpci0+QWRkcmVzc09mSW5kZXgpPXBlbS0+dGxzaW5kZXg7ICAgCgkJfQoJCXBlbS0+ZmxhZ3MgfD0gUEVfTU9EUkVGX1RMU19BTExPQ0VEOwoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwoJCS8qIGRvbid0IHVzZSBUbHNTZXRWYWx1ZSwgd2UgYXJlIGluIHRoZSB3cm9uZyB0aHJlYWQgKi8KCQl0aGRiLT50bHNfYXJyYXlbcGVtLT50bHNpbmRleF0gPSBtZW07CgkJcGVtPXBlbS0+bmV4dDsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMgKEtFUk5FTDMyLjc0KQogKiBEb24ndCBjYWxsIERsbEVudHJ5UG9pbnQgZm9yIERMTF9USFJFQURfe0FUVEFDSCxERVRBQ0h9IGlmIHNldC4KICovCkJPT0wzMiBXSU5BUEkgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhITU9EVUxFMzIgaE1vZHVsZSkKewoJUERCMzIJKnByb2Nlc3MgPSBQUk9DRVNTX0N1cnJlbnQoKTsKCVBFX01PRFJFRgkqcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgoJd2hpbGUgKHBlbSkgewoJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKQoJCQlwZW0tPmZsYWdzfD1QRV9NT0RSRUZfTk9fRExMX0NBTExTOwoJCXBlbSA9IHBlbS0+bmV4dDsKCX0KCXJldHVybiBUUlVFOwp9Cg==