LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICogLSBBbGwgdGhvc2UgZnVuY3Rpb24gbWFwIHRoaW5ncyBpbnRvIGEgbmV3IGFkZHJlc3NwYWNlLiBGcm9tIHRoZSB3cm9uZwogKiAgIHByb2Nlc3MgYW5kIHRoZSB3cm9uZyB0aHJlYWQuIFNvIGNhbGxpbmcgb3RoZXIgQVBJIGZ1bmN0aW9ucyB3aWxsIG1lc3MgCiAqICAgdGhpbmdzIHVwIGJhZGx5IHNvbWV0aW1lcy4KICovCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAiZGVidWcuaCIKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFMzIgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSh3aW4zMiwiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0Uod2luMzIsIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsPSh1X3Nob3J0KikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zPWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lPSh1X2NoYXIqKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0Uod2luMzIsIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKXsKCWRiZ19kZWNsX3N0cih3aW4zMiwgMTAyNCk7CgoJZHNwcmludGYod2luMzIsIiU0bGQgJTA4bHggJTA4eCIsCgkJIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQoJICAgIGRzcHJpbnRmKHdpbjMyLCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgZHNwcmludGYod2luMzIsICIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCVRSQUNFKHdpbjMyLCIlc1xuIiwgZGJnX3N0cih3aW4zMikpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DMzIgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIAoJUERCMzIgKnByb2Nlc3MsCQkvKiBbaW5dIHByb2Nlc3MgY29udGV4dCAqLwoJV0lORV9NT0RSRUYgKndtLAkvKiBbaW5dIFdJTkUgbW9kcmVmZXJlbmNlICovCglMUENTVFIgZnVuY05hbWUsCS8qIFtpbl0gZnVuY3Rpb24gbmFtZSAqLwogICAgICAgIEJPT0wzMiBzbm9vcCApCnsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsOwoJdV9sb25nCQkJCSogZnVuY3Rpb247Cgl1X2NoYXIJCQkJKiogbmFtZSwgKmVuYW1lOwoJaW50CQkJCWk7CglQRV9NT0RSRUYJCQkqcGVtID0gJih3bS0+YmluZm10LnBlKTsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgCQkqZXhwb3J0cyA9IHBlbS0+cGVfZXhwb3J0OwoJdW5zaWduZWQgaW50CQkJbG9hZF9hZGRyID0gd20tPm1vZHVsZTsKCXVfbG9uZwkJCQlydmFfc3RhcnQsIHJ2YV9lbmQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKCQlUUkFDRSh3aW4zMiwiKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJVFJBQ0Uod2luMzIsIiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQkvKiBOb3QgYSBmYXRhbCBwcm9ibGVtLCBzb21lIGFwcHMgZG8KCQkgKiBHZXRQcm9jQWRkcmVzcygwLCJSZWdpc3RlclBlbkFwcCIpIHdoaWNoIHRyaWdnZXJzIHRoaXMKCQkgKiBjYXNlLgoJCSAqLwoJCVdBUk4od2luMzIsIk1vZHVsZSAlMDh4KCVzKS9NT0RSRUYgJXAgZG9lc24ndCBoYXZlIGEgZXhwb3J0cyB0YWJsZS5cbiIsd20tPm1vZHVsZSx3bS0+bW9kbmFtZSxwZW0pOwoJCXJldHVybiBOVUxMOwoJfQoJb3JkaW5hbAk9ICh1X3Nob3J0KikgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwoJZnVuY3Rpb249ICh1X2xvbmcqKSAgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZQk9ICh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7Cglmb3J3YXJkID0gTlVMTDsKCXJ2YV9zdGFydCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKCXJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKilSVkEoKm5hbWUpOwoJCQlpZighc3RyY21wKGVuYW1lLGZ1bmNOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkciA9IGZ1bmN0aW9uWypvcmRpbmFsXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQoJCQkJcmV0dXJuIHNub29wPyBTTk9PUF9HZXRQcm9jQWRkcmVzczMyKHdtLT5tb2R1bGUsZW5hbWUsKm9yZGluYWwsKEZBUlBST0MzMilSVkEoYWRkcikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRkFSUFJPQzMyKVJWQShhZGRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcndhcmQgPSAoY2hhciAqKVJWQShhZGRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJCQl9CgkJCW9yZGluYWwrKzsKCQkJbmFtZSsrOwoJCX0KCX0gZWxzZSAJewoJCWludCBpOwoJCWlmIChMT1dPUkQoZnVuY05hbWUpLWV4cG9ydHMtPkJhc2UgPiBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykgewoJCQlUUkFDRSh3aW4zMiwiCW9yZGluYWwgJWQgb3V0IG9mIHJhbmdlIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dPUkQoZnVuY05hbWUpKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJCWFkZHIgPSBmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdOwogICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKCQllbmFtZSA9ICIiOwoJCWlmIChuYW1lKSB7CgkJICAgIGZvciAoaT0wO2k8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcztpKyspIHsKCQkJICAgIGVuYW1lID0gKGNoYXIqKVJWQSgqbmFtZSk7CgkJCSAgICBpZiAoKm9yZGluYWwgPT0gTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlKQoJCQkgICAgCWJyZWFrOwoJCQkgICAgb3JkaW5hbCsrOwoJCQkgICAgbmFtZSsrOwoJCSAgICB9CgkJICAgIGlmIChpPT1leHBvcnRzLT5OdW1iZXJPZk5hbWVzKQoJCSAgICAJZW5hbWUgPSAiIjsKCQl9CgkJaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJcmV0dXJuIHNub29wPyBTTk9PUF9HZXRQcm9jQWRkcmVzczMyKHdtLT5tb2R1bGUsZW5hbWUsKERXT1JEKWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2UsKEZBUlBST0MzMilSVkEoYWRkcikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKEZBUlBST0MzMilSVkEoYWRkcik7CgkJZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwoJfQoJaWYgKGZvcndhcmQpCiAgICAgICAgewogICAgICAgICAgICAgICAgSE1PRFVMRTMyIGhNb2Q7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwoJCWFzc2VydChlbmQtZm9yd2FyZDwyNTYpOwoJCXN0cm5jcHkobW9kdWxlLCBmb3J3YXJkLCAoZW5kIC0gZm9yd2FyZCkpOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaE1vZCA9IE1PRFVMRV9GaW5kTW9kdWxlMzIocHJvY2Vzcyxtb2R1bGUpOwoJCWFzc2VydChoTW9kKTsKCQlyZXR1cm4gTU9EVUxFX0dldFByb2NBZGRyZXNzMzIoIHByb2Nlc3MsIGhNb2QsIGVuZCArIDEsIHNub29wICk7Cgl9CglyZXR1cm4gTlVMTDsKfQoKRFdPUkQgZml4dXBfaW1wb3J0cyAoUERCMzIgKnByb2Nlc3MsV0lORV9NT0RSRUYgKndtKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgV0lORV9NT0RSRUYJCQkqeHdtOwogICAgUEVfTU9EUkVGCQkJKnBlbTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBhc3NlcnQod20tPnR5cGU9PU1PRFVMRTMyX1BFKTsKICAgIHBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0Uod2luMzIsICJEdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OwogICAgaWYgKCFwZV9pbXApIAogICAgCUVSUih3aW4zMiwgIm5vIGltcG9ydCBkaXJlY3Rvcnk/Pz8/XG4iKTsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0c2ljcyAwIChub3RhYmx5IEJvcmxhbmQpIGFuZAogICAgICogc3dpdGNoIHRoZSBkZXRlY3Rpb24gb2ZmIGZvciB0aGVtLgogICAgICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewoJaWYgKCFpICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gPSAwOwoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CglpKys7CiAgICB9CgogICAgLyogQWxsb2NhdGUgbW9kdWxlIGRlcGVuZGVuY3kgbGlzdCAqLwogICAgd20tPm5EZXBzID0gaTsKICAgIHdtLT5kZXBzICA9IEhlYXBBbGxvYyhwcm9jZXNzLT5oZWFwLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSk7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlITU9EVUxFMzIJCWhJbXBNb2R1bGU7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCVBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAJY2hhcgkJCSpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CgoJLyogZG9uJ3QgdXNlIE1PRFVMRV9Mb2FkLCBXaW4zMiBjcmVhdGVzIG5ldyB0YXNrIGRpZmZlcmVudGx5ICovCgloSW1wTW9kdWxlID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXgzMkEoIG5hbWUsIHByb2Nlc3MsIDAsIDAgKTsKCWlmICghaEltcE1vZHVsZSkgewoJICAgIGNoYXIgKnAsYnVmZmVyWzIwMDBdOwoJICAgIAoJICAgIC8qIEdldE1vZHVsZUZpbGVOYW1lIHdvdWxkIHVzZSB0aGUgd3JvbmcgcHJvY2Vzcywgc28gZG9uJ3QgdXNlIGl0ICovCgkgICAgc3RyY3B5KGJ1ZmZlcix3bS0+c2hvcnRuYW1lKTsKCSAgICBpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJcCA9IGJ1ZmZlcjsKCSAgICBzdHJjcHkgKHAgKyAxLCBuYW1lKTsKCSAgICBoSW1wTW9kdWxlID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXgzMkEoIGJ1ZmZlciwgcHJvY2VzcywgMCwgMCApOwoJfQoJaWYgKCFoSW1wTW9kdWxlKSB7CgkgICAgRVJSIChtb2R1bGUsICJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLCBuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB4d20gPSBNT0RVTEUzMl9Mb29rdXBITU9EVUxFKHByb2Nlc3MsIGhJbXBNb2R1bGUpOwogICAgICAgIGFzc2VydCggeHdtICk7CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHh3bTsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIFRSQUNFKHdpbjMyLCAiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0Uod2luMzIsICItLS0gT3JkaW5hbCAlcywlZFxuIiwgbmFtZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIod2luMzIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MzMikweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKHdpbjMyLCAiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzMzIoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIod2luMzIsIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQzMyKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKHdpbjMyLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0Uod2luMzIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLG5hbWUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKHdpbjMyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DMzIpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSh3aW4zMiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzczMyKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUih3aW4zMiwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgcGVfbmFtZS0+SGludCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MzMikweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFMzIgaE1vZHVsZSApCnsKICAgIGludCBpLHZtYV9zaXplID0gMDsKICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpwZV9zZWcgPSBQRV9TRUNUSU9OUyhoTW9kdWxlKTsKCiAgICBUUkFDRSh3aW4zMiwgIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRSh3aW4zMiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBUUkFDRSh3aW4zMiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlZpcnR1YWxBZGRyZXNzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5TaXplT2ZSYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SYXdEYXRhLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9SZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk51bWJlck9mTGluZW51bWJlcnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPkNoYXJhY3RlcmlzdGljcyk7CiAgICAgICAgdm1hX3NpemU9TUFYKHZtYV9zaXplLCBwZV9zZWctPlZpcnR1YWxBZGRyZXNzK3BlX3NlZy0+U2l6ZU9mUmF3RGF0YSk7CiAgICAgICAgdm1hX3NpemU9TUFYKHZtYV9zaXplLCBwZV9zZWctPlZpcnR1YWxBZGRyZXNzK3BlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSk7CiAgICAgICAgcGVfc2VnKys7CiAgICB9CiAgICByZXR1cm4gdm1hX3NpemU7Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKCB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyLCBJTUFHRV9CQVNFX1JFTE9DQVRJT04gKnIgKQp7CiAgICBpbnQgZGVsdGEgPSBsb2FkX2FkZHIgLSBQRV9IRUFERVIobG9hZF9hZGRyKS0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwogICAgaW50CWhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CiAgICBpbnQJbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+VmlydHVhbEFkZHJlc3MpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKikgUlZBKHItPlZpcnR1YWxBZGRyZXNzKTsKCQlpbnQgY291bnQgPSAoci0+U2l6ZU9mQmxvY2sgLSA4KS8yOwoJCWludCBpOwoJCVRSQUNFKGZpeHVwLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRShmaXh1cCwicGF0Y2hpbmcgJXggdHlwZSAleFxuIiwgb2Zmc2V0LCB0eXBlKTsKCQkJc3dpdGNoKHR5cGUpCgkJCXsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6IGJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBoZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBsZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKI2lmIDEKCQkJCSooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwojZWxzZQoJCQkJeyBpbnQgaD0qKHVuc2lnbmVkIHNob3J0KikocGFnZStvZmZzZXQpOwoJCQkJICBpbnQgbD1yLT5UeXBlT2Zmc2V0WysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJRklYTUUod2luMzIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJRklYTUUod2luMzIsICJJcyB0aGlzIGEgTUlQUyBtYWNoaW5lID8/P1xuIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCUZJWE1FKHdpbjMyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpzdGF0aWMgSE1PRFVMRTMyIFBFX0xvYWRJbWFnZSggTFBDU1RSIG5hbWUsIE9GU1RSVUNUICpvZnMgKQp7CiAgICBITU9EVUxFMzIJaE1vZHVsZTsKICAgIEhGSUxFMzIJaEZpbGU7CiAgICBIQU5ETEUzMgltYXBwaW5nOwoKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlYzsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBpbnQJaSwgcmF3c2l6ZSwgbG93ZXN0X3ZhLCBsb3dlc3RfZmEsIHZtYV9zaXplLCBmaWxlX3NpemUgPSAwOwogICAgRFdPUkQgbG9hZF9hZGRyLCBhb2VwLCByZWxvYyA9IDA7CiAgICBjaGFyIGRsbG5hbWVbMjU2XSwgKnA7CgogICAgLyogQXBwZW5kIC5ETEwgdG8gbmFtZSBpZiBubyBleHRlbnNpb24gcHJlc2VudCAqLwogICAgc3RyY3B5KCBkbGxuYW1lLCBuYW1lICk7CiAgICBpZiAoKHAgPSBzdHJyY2hyKCBkbGxuYW1lLCAnXFwnICkpKSBwKys7IGVsc2UgcCA9IGRsbG5hbWU7CiAgICBpZiAoIXN0cmNociggcCwgJy4nICkpIHN0cmNhdCggZGxsbmFtZSwgIi5ETEwiICk7IAoKICAgIC8qIE9wZW4gUEUgZmlsZSAqLwogICAgaEZpbGUgPSBPcGVuRmlsZTMyKCBkbGxuYW1lLCBvZnMsIE9GX1JFQUQgfCBPRl9TSEFSRV9ERU5ZX1dSSVRFICk7CiAgICBpZiAoIGhGaWxlID09IEhGSUxFX0VSUk9SMzIgKQogICAgewogICAgICAgIFdBUk4oIHdpbjMyLCAiT3BlbkZpbGUgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAyOwogICAgfQoKICAgIC8qIFJldHJpZXZlIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSggaEZpbGUsICZiaGZpICkgKSAKICAgIAlmaWxlX3NpemUgPSBiaGZpLm5GaWxlU2l6ZUxvdzsgLyogRklYTUU6IDY0IGJpdCAqLwoKICAgIC8qIE1hcCB0aGUgUEUgZmlsZSBzb21ld2hlcmUgKi8KICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZzMyQSggaEZpbGUsIE5VTEwsIFBBR0VfUkVBRE9OTFkgfCBTRUNfQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCBOVUxMICk7CiAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBXQVJOKCB3aW4zMiwgIkNyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGhNb2R1bGUgPSAoSE1PRFVMRTMyKU1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWhNb2R1bGUpCiAgICB7CiAgICAgICAgV0FSTiggd2luMzIsICJNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CgogICAgLyogQ2hlY2sgc2lnbmF0dXJlICovCiAgICBpZiAoIG50LT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFICkKICAgIHsKICAgICAgICBXQVJOKHdpbjMyLCAiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgYXJjaGl0ZWN0dXJlICovCiAgICBpZiAoIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYgKQogICAgewogICAgICAgIE1TRygiVHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CiAgICAgICAgc3dpdGNoIChudC0+RmlsZUhlYWRlci5NYWNoaW5lKQogICAgICAgIHsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOiBNU0coIlVua25vd24iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDogICAgTVNHKCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIE1TRygiUjMwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6ICAgTVNHKCJSNDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6ICBNU0coIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBNU0coIkFscGhhIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6IE1TRygiUG93ZXJQQyIpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBNU0coIlVua25vd24tJTA0eCIsIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgTVNHKCIpXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIEZpbmQgb3V0IGhvdyBsYXJnZSB0aGlzIGV4ZWN1dGVhYmxlIHNob3VsZCBiZSAqLwogICAgcGVfc2VjID0gUEVfU0VDVElPTlMoIGhNb2R1bGUgKTsKICAgIHJhd3NpemUgPSAwOyBsb3dlc3RfdmEgPSAweDEwMDAwOyBsb3dlc3RfZmEgPSAweDEwMDAwOwogICAgZm9yIChpID0gMDsgaSA8IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykgCiAgICB7CiAgICAgICAgaWYgKGxvd2VzdF92YSA+IHBlX3NlY1tpXS5WaXJ0dWFsQWRkcmVzcykKICAgICAgICAgICBsb3dlc3RfdmEgPSBwZV9zZWNbaV0uVmlydHVhbEFkZHJlc3M7CiAgICAJaWYgKHBlX3NlY1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkKCSAgICBjb250aW51ZTsKICAgIAlpZiAocGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGEgPCBsb3dlc3RfZmEpCiAgICAgICAgICAgIGxvd2VzdF9mYSA9IHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhOwoJaWYgKHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhK3BlX3NlY1tpXS5TaXplT2ZSYXdEYXRhID4gcmF3c2l6ZSkKCSAgICByYXdzaXplID0gcGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGE7CiAgICB9CiAKICAgIC8qIENoZWNrIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBmaWxlX3NpemUgJiYgZmlsZV9zaXplIDwgcmF3c2l6ZSApCiAgICB7CiAgICAgICAgRVJSKCB3aW4zMiwgIlBFIG1vZHVsZSBpcyB0b28gc21hbGwgKGhlYWRlcjogJWQsIGZpbGVzaXplOiAlZCksICIKICAgICAgICAgICAgICAgICAgICAicHJvYmFibHkgdHJ1bmNhdGVkIGRvd25sb2FkP1xuIiwgCiAgICAgICAgICAgICAgICAgICAgcmF3c2l6ZSwgZmlsZV9zaXplICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBDaGVjayBlbnRyeXBvaW50IGFkZHJlc3MgKi8KICAgIGFvZXAgPSBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludDsKICAgIGlmIChhb2VwICYmIChhb2VwIDwgbG93ZXN0X3ZhKSkKICAgICAgICBGSVhNRSggd2luMzIsICJXQVJOSU5HOiAnJXMnIGhhcyBhbiBpbnZhbGlkIGVudHJ5cG9pbnQgKDB4JTA4bHgpICIKICAgICAgICAgICAgICAgICAgICAgICJiZWxvdyB0aGUgZmlyc3QgdmlydHVhbCBhZGRyZXNzICgweCUwOHgpICIKICAgICAgICAgICAgICAgICAgICAgICIocG9zc2libGUgVmlydXMgSW5mZWN0aW9uIG9yIGJyb2tlbiBiaW5hcnkpIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBvZnMtPnN6UGF0aE5hbWUsIGFvZXAsIGxvd2VzdF92YSApOwoKCiAgICAvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIG1vZHVsZSAqLwogICAgbG9hZF9hZGRyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIHZtYV9zaXplID0gY2FsY192bWFfc2l6ZSggaE1vZHVsZSApOwoKICAgIGxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwogICAgaWYgKGxvYWRfYWRkciA9PSAwKSAKICAgIHsKICAgICAgICAvKiBXZSBuZWVkIHRvIHBlcmZvcm0gYmFzZSByZWxvY2F0aW9ucyAqLwogICAgICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CglkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DOwogICAgICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgICAgIHJlbG9jID0gZGlyLT5WaXJ0dWFsQWRkcmVzczsKICAgICAgICBlbHNlIAogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIHdpbjMyLAogICAgICAgICAgICAgICAgICAgIk5lZWQgdG8gcmVsb2NhdGUgJXMsIGJ1dCBubyByZWxvY2F0aW9uIHJlY29yZHMgcHJlc2VudCAoJXMpLlxuIiwKICAgICAgICAgICAgICAgICAgIG9mcy0+c3pQYXRoTmFtZSwKICAgICAgICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIGxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCSBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCgkJCQkJIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIH0KCiAgICBUUkFDRSggd2luMzIsICJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgICAgICBsb2FkX2FkZHIsIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UsIHZtYV9zaXplICk7CiAgICBUUkFDRSggc2VnbWVudCwgIkxvYWRpbmcgJXMgYXQgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICBvZnMtPnN6UGF0aE5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIgKi8KICAgICooUElNQUdFX0RPU19IRUFERVIpbG9hZF9hZGRyID0gKihQSU1BR0VfRE9TX0hFQURFUiloTW9kdWxlOwogICAgKlBFX0hFQURFUiggbG9hZF9hZGRyICkgPSAqbnQ7CiAgICBtZW1jcHkoIFBFX1NFQ1RJT05TKGxvYWRfYWRkciksIFBFX1NFQ1RJT05TKGhNb2R1bGUpLAogICAgICAgICAgICBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyApOwojaWYgMAogICAgLyogQ29waWVzIGFsbCBzdHVmZiB1cCB0byB0aGUgZmlyc3Qgc2VjdGlvbi4gSW5jbHVkaW5nIHdpbjMyIHZpcnVzZXMuICovCiAgICBtZW1jcHkoIGxvYWRfYWRkciwgaE1vZHVsZSwgbG93ZXN0X2ZhICk7CiNlbmRpZgoKICAgIC8qIENvcHkgc2VjdGlvbnMgaW50byBtb2R1bGUgaW1hZ2UgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWMrKykKICAgIHsKICAgICAgICAvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCiAgICAgICAgLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQogICAgICAgICAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMKICAgICAgICAgKiBhIHBhZ2UtYWxpZ25lZCBvZmZzZXQuCiAgICAgICAgICovCiAgICAgICAgaWYoIShwZV9zZWMtPkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKSkKICAgICAgICAgICAgbWVtY3B5KChjaGFyKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgICAgICAoY2hhciopKGhNb2R1bGUgKyBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEpLAogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2lmIDAKICAgICAgICAvKiBub3QgbmVlZGVkLCBtZW1vcnkgaXMgemVybyAqLwogICAgICAgIGlmKHN0cmNtcChwZV9zZWMtPk5hbWUsICIuYnNzIikgPT0gMCkKICAgICAgICAgICAgbWVtc2V0KCh2b2lkICopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLCAwLCAKICAgICAgICAgICAgICAgICAgIHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSA/CiAgICAgICAgICAgICAgICAgICBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemUgOgogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKTsKI2VuZGlmCiAgICB9CgogICAgLyogUGVyZm9ybSBiYXNlIHJlbG9jYXRpb24sIGlmIG5lY2Vzc2FyeSAqLwogICAgaWYgKCByZWxvYyApCiAgICAgICAgZG9fcmVsb2NhdGlvbnMoIGxvYWRfYWRkciwgKElNQUdFX0JBU0VfUkVMT0NBVElPTiAqKVJWQShyZWxvYykgKTsKCiAgICAvKiBXZSBkb24ndCBuZWVkIHRoZSBvcmlnbmFsIG1hcHBpbmcgYW55IG1vcmUgKi8KICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gKEhNT0RVTEUzMilsb2FkX2FkZHI7CgplcnJvcjoKICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRTMyLCBsaW5rIGl0IGludG8KICogcHJvY2VzcyBtb2RyZWZfbGlzdCwgYW5kIGZpeHVwIGFsbCBpbXBvcnRzLgogKgogKiBOb3RlOiBoTW9kdWxlIG11c3QgcG9pbnQgdG8gYSBjb3JyZWN0bHkgYWxsb2NhdGVkIFBFIGltYWdlLAogKiAgICAgICB3aXRoIGJhc2UgcmVsb2NhdGlvbnMgYXBwbGllZDsgdGhlIDE2LWJpdCBkdW1teSBtb2R1bGUKICogICAgICAgYXNzb2NpYXRlZCB0byBoTW9kdWxlIG11c3QgYWxyZWFkeSBleGlzdC4KICovCnN0YXRpYyBXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBQREIzMiAqcHJvY2VzcywgSE1PRFVMRTMyIGhNb2R1bGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0ZTVFJVQ1QgKm9mcywgRFdPUkQgZmxhZ3MsIEJPT0wzMiBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wb3J0ID0gTlVMTDsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkgKnBlX3Jlc291cmNlID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIGludAlyZXN1bHQ7CiAgICBjaGFyICptb2RuYW1lOwoKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9leHBvcnQgPSAoUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2ltcG9ydCA9IChQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRTsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfcmVzb3VyY2UgPSAoUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCB3aW4zMiwgIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCB3aW4zMiwgIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUc7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSggd2luMzIsICJEZWJ1ZyBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFQ7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSggd2luMzIsICJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIHdpbjMyLCAiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTIGhhbmRsZWQgaW4gUEVfVGxzSW5pdCAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJRzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FICh3aW4zMiwgIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSggd2luMzIsICJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIHdpbjMyLCAiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxMzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCB3aW4zMiwgIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNDsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCB3aW4zMiwgIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCB3aW4zMiwgIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICB3bSA9IChXSU5FX01PRFJFRiAqKUhlYXBBbGxvYyggcHJvY2Vzcy0+aGVhcCwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCp3bSkgKTsKICAgIHdtLT5tb2R1bGUgPSBoTW9kdWxlOwoKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICB3bS0+YmluZm10LnBlLmZsYWdzID0gYnVpbHRpbj8gUEVfTU9EUkVGX0lOVEVSTkFMIDogMDsKICAgIHdtLT5iaW5mbXQucGUucGVfZXhwb3J0ID0gcGVfZXhwb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9pbXBvcnQgPSBwZV9pbXBvcnQ7CiAgICB3bS0+YmluZm10LnBlLnBlX3Jlc291cmNlID0gcGVfcmVzb3VyY2U7CgogICAgaWYgKCBwZV9leHBvcnQgKSAKICAgICAgICBtb2RuYW1lID0gKGNoYXIgKilSVkEoIHBlX2V4cG9ydC0+TmFtZSApOwogICAgZWxzZSAKICAgIHsKICAgICAgICAvKiB0cnkgdG8gZmluZCBvdXQgdGhlIG5hbWUgZnJvbSB0aGUgT0ZTVFJVQ1QgKi8KICAgICAgICBjaGFyICpzOwogICAgICAgIG1vZG5hbWUgPSBvZnMtPnN6UGF0aE5hbWU7CiAgICAgICAgd2hpbGUgKChzPXN0cmNocihtb2RuYW1lLCdcXCcpKSkKICAgICAgICAgICAgbW9kbmFtZSA9IHMrMTsKICAgIH0KICAgIHdtLT5tb2RuYW1lID0gSEVBUF9zdHJkdXBBKCBwcm9jZXNzLT5oZWFwLCAwLCBtb2RuYW1lICk7CgogICAgcmVzdWx0ID0gR2V0TG9uZ1BhdGhOYW1lMzJBKCBvZnMtPnN6UGF0aE5hbWUsIE5VTEwsIDAgKTsKICAgIHdtLT5sb25nbmFtZSA9IChjaGFyICopSGVhcEFsbG9jKCBwcm9jZXNzLT5oZWFwLCAwLCByZXN1bHQrMSApOwogICAgR2V0TG9uZ1BhdGhOYW1lMzJBKCBvZnMtPnN6UGF0aE5hbWUsIHdtLT5sb25nbmFtZSwgcmVzdWx0KzEgKTsKCiAgICB3bS0+c2hvcnRuYW1lID0gSEVBUF9zdHJkdXBBKCBwcm9jZXNzLT5oZWFwLCAwLCBvZnMtPnN6UGF0aE5hbWUgKTsKCiAgICAvKiBMaW5rIE1PRFJFRiBpbnRvIHByb2Nlc3MgbGlzdCAqLwoKICAgIHdtLT5uZXh0ID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CiAgICBwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHdtOwoKICAgIGlmICggIShudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgKQogICAgewogICAgICAgIGlmICggcHJvY2Vzcy0+ZXhlX21vZHJlZiApCiAgICAgICAgICAgIEZJWE1FKCB3aW4zMiwgIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iICk7CiAgICAgICAgcHJvY2Vzcy0+ZXhlX21vZHJlZiA9IHdtOwogICAgfQoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmICggcGVfZXhwb3J0ICkKICAgICAgICBkdW1wX2V4cG9ydHMoIGhNb2R1bGUgKTsKCiAgICAvKiBGaXh1cCBJbXBvcnRzICovCgogICAgaWYgKCBwZV9pbXBvcnQgJiYgZml4dXBfaW1wb3J0cyggcHJvY2Vzcywgd20gKSApIAogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwogICAgICAgIFdJTkVfTU9EUkVGICoqeHdtOwogICAgICAgIGZvciAoIHh3bSA9ICZwcm9jZXNzLT5tb2RyZWZfbGlzdDsgKnh3bTsgeHdtID0gJigqeHdtKS0+bmV4dCApCiAgICAgICAgICAgIGlmICggKnh3bSA9PSB3bSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICp4d20gPSB3bS0+bmV4dDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIGl0IHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gd207Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpITU9EVUxFMzIgUEVfTG9hZExpYnJhcnlFeDMyQSAoTFBDU1RSIG5hbWUsIFBEQjMyICpwcm9jZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEZJTEUzMiBoRmlsZSwgRFdPUkQgZmxhZ3MpCnsKICAgIE9GU1RSVUNUCW9mczsKICAgIEhNT0RVTEUzMgloTW9kdWxlMzI7CiAgICBITU9EVUxFMTYJaE1vZHVsZTE2OwogICAgTkVfTU9EVUxFCSpwTW9kdWxlOwogICAgV0lORV9NT0RSRUYJKndtOwogICAgQk9PTDMyCWJ1aWx0aW47CgogICAgLyogQ2hlY2sgZm9yIGFscmVhZHkgbG9hZGVkIG1vZHVsZSAqLwogICAgaWYgKChoTW9kdWxlMzIgPSBNT0RVTEVfRmluZE1vZHVsZTMyKCBwcm9jZXNzLCBuYW1lICkpKSAKICAgICAgICByZXR1cm4gaE1vZHVsZTMyOwoKICAgIC8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwogICAgaWYgKChoTW9kdWxlMzIgPSBCVUlMVElOMzJfTG9hZEltYWdlKCBuYW1lLCAmb2ZzLCBGQUxTRSApKSkKICAgICAgICBidWlsdGluID0gVFJVRTsKICAgIC8qIHRyeSB0byBsb2FkIHRoZSBzcGVjaWZpZWQgZGxsL2V4ZSAqLwogICAgZWxzZSBpZiAoKGhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggbmFtZSwgJm9mcyApKSA+PSAzMikKICAgICAgICBidWlsdGluID0gRkFMU0U7CiAgICAvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCiAgICBlbHNlIGlmICgoaE1vZHVsZTMyID0gQlVJTFRJTjMyX0xvYWRJbWFnZSggbmFtZSwgJm9mcywgVFJVRSApKSkgCiAgICB7CiAgICAgICAgV0FSTiggbW9kdWxlLCAiQ291bGQgbm90IGxvYWQgZXh0ZXJuYWwgRExMICclcycsIHVzaW5nIGJ1aWx0LWluIG1vZHVsZS5cbiIsIG5hbWUgKTsKICAgICAgICBidWlsdGluID0gVFJVRTsKICAgIH0KICAgIGVsc2UKICAgICAgICByZXR1cm4gMDsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwogICAgaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoICZvZnMgKSkgPCAzMikgcmV0dXJuIGhNb2R1bGUxNjsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgIHBNb2R1bGUtPmZsYWdzICAgID0gTkVfRkZMQUdTX0xJQk1PRFVMRSB8IE5FX0ZGTEFHU19TSU5HTEVEQVRBIHwKICAgICAgICAgICAgICAgICAgICAgICAgTkVfRkZMQUdTX1dJTjMyIHwgKGJ1aWx0aW4/IE5FX0ZGTEFHU19CVUlMVElOIDogMCk7CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCiAgICAvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwogICAgaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBwcm9jZXNzLCBoTW9kdWxlMzIsICZvZnMsIGZsYWdzLCBidWlsdGluICkpICkKICAgIHsKICAgICAgICBFUlIod2luMzIsImNhbid0IGxvYWQgJXNcbiIsb2ZzLnN6UGF0aE5hbWUpOwogICAgICAgIEZyZWVMaWJyYXJ5MTYoIGhNb2R1bGUxNiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICh3bS0+YmluZm10LnBlLnBlX2V4cG9ydCkKICAgICAgICBTTk9PUF9SZWdpc3RlckRMTCh3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtLT5iaW5mbXQucGUucGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyk7CgogICAgcmV0dXJuIHdtLT5tb2R1bGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeDMyQQogKiBGSVhNRTogdGhpcyBmdW5jdGlvbiBzaG91bGQgdXNlIFBFX0xvYWRMaWJyYXJ5RXgzMkEsIGJ1dCBjdXJyZW50bHkgY2FuJ3QKICogZHVlIHRvIHRoZSBQUk9DRVNTX0NyZWF0ZSBzdHVmZi4KICovCkhJTlNUQU5DRTE2IFBFX0NyZWF0ZVByb2Nlc3MoIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kX2xpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIEJPT0wzMiBpbmhlcml0LCBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUzMiBoTW9kdWxlMzI7CiAgICBISU5TVEFOQ0UxNiBoSW5zdGFuY2U7CiAgICBORV9NT0RVTEUgKnBNb2R1bGU7CiAgICBPRlNUUlVDVCBvZnM7CiAgICBQREIzMiAqcHJvY2VzczsKICAgIFREQiAqcFRhc2s7CiAgICBXSU5FX01PRFJFRgkqd207CgogICAgLyogTG9hZCBmaWxlICovCiAgICBpZiAoKGhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggbmFtZSwgJm9mcyApKSA8IDMyKQogICAgICAgIHJldHVybiBoTW9kdWxlMzI7CiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUzMiktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICAgICAgcmV0dXJuIDIwOyAgLyogRklYTUU6IG5vdCB0aGUgcmlnaHQgZXJyb3IgY29kZSAqLwoKICAgIC8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCiAgICBpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSByZXR1cm4gaE1vZHVsZTE2OwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgcE1vZHVsZS0+ZmxhZ3MgICAgPSBORV9GRkxBR1NfV0lOMzI7CiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCiAgICAvKiBDcmVhdGUgbmV3IHByb2Nlc3MgKi8KICAgIGhJbnN0YW5jZSA9IE5FX0NyZWF0ZUluc3RhbmNlKCBwTW9kdWxlLCBOVUxMLCBGQUxTRSApOwogICAgcHJvY2VzcyA9IFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSW5zdGFuY2UsIDAsIGluaGVyaXQsIHN0YXJ0dXAsIGluZm8gKTsKCiAgICAvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwogICAgaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBwcm9jZXNzLCBoTW9kdWxlMzIsICZvZnMsIDAsIEZBTFNFICkpICkKICAgIHsKICAgICAJLyogRklYTUU6IHNob3VsZCBkZXN0cm95IHRoZSB0YXNrIGNyZWF0ZWQgYW5kIGZyZWUgcmVmZXJlbmNlZCBzdHVmZiAqLwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qIEZJWE1FOiBZdWNrLiBJcyB0aGVyZSBubyBvdGhlciBnb29kIHBsYWNlIHRvIGRvIHRoYXQ/ICovCiAgICBwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIHByb2Nlc3MtPnRhc2sgKTsKICAgIFBFX0luaXRUbHMoIHBUYXNrLT50aGRiICk7CgogICAgcmV0dXJuIGhJbnN0YW5jZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQRV9VbmxvYWRJbWFnZSBbaW50ZXJuYWxdCiAqLwppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlICkKewoJRklYTUUod2luMzIsInN0dWIuXG4iKTsKCS8qIGZyZWUgcmVzb3VyY2VzLCBpbWFnZSwgdW5tYXAgKi8KCXJldHVybiAxOwp9CgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8Kdm9pZCBQRV9Jbml0RExMKFdJTkVfTU9EUkVGICp3bSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpCnsKICAgIGlmICh3bS0+dHlwZSE9TU9EVUxFMzJfUEUpCiAgICAJcmV0dXJuOwogICAgaWYgKHdtLT5iaW5mbXQucGUuZmxhZ3MgJiBQRV9NT0RSRUZfTk9fRExMX0NBTExTKQogICAgCXJldHVybjsKICAgIGlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgaWYgKHdtLT5iaW5mbXQucGUuZmxhZ3MgJiBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRCkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICB3bS0+YmluZm10LnBlLmZsYWdzIHw9IFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEOwogICAgfQoKICAgIC8qICBETExfQVRUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGZvciBkeW5hbWljIGxvYWRzLCBub3QtTlVMTCBmb3Igc3RhdGljIGxvYWRzCiAgICAgKiAgRExMX0RFVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBpZiBjYWxsZWQgYnkgRnJlZUxpYnJhcnksIG5vdC1OVUxMIG90aGVyd2lzZQogICAgICogIHRoZSBTREsgZG9lc24ndCBtZW50aW9uIGFueXRoaW5nIGZvciBETExfVEhSRUFEXyoKICAgICAqLwogICAgICAgIAogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/IEFuZCBoYXMgaXQgZ290IGFuIGVudHJ5cG9pbnQ/ICovCiAgICBpZiAoKFBFX0hFQURFUih3bS0+bW9kdWxlKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgKSB7CiAgICAgICAgRExMRU5UUllQUk9DMzIgZW50cnkgPSAodm9pZCopUlZBX1BUUiggd20tPm1vZHVsZSxPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgVFJBQ0UocmVsYXksICJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwoKICAgICAgICBlbnRyeSggd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kdm9pZCBQRV9Jbml0VGxzKFRIREIgKnRoZGIpCnsKCVdJTkVfTU9EUkVGCQkqd207CglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoJUERCMzIJCQkqcGRiID0gdGhkYi0+cHJvY2VzczsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBwZGItPm1vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJaWYgKHdtLT50eXBlIT1NT0RVTEUzMl9QRSkKCQkJY29udGludWU7CgkJcGVtID0gJih3bS0+YmluZm10LnBlKTsKCQlwZWggPSBQRV9IRUFERVIod20tPm1vZHVsZSk7CgkJZGVsdGEgPSB3bS0+bW9kdWxlIC0gcGVoLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCgkJCWNvbnRpbnVlOwoJCUZJWE1FKHdpbjMyLCIlcyBoYXMgVExTIGRpcmVjdG9yeS5cbiIsd20tPmxvbmduYW1lKTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICghKHBlbS0+ZmxhZ3MgJiBQRV9NT0RSRUZfVExTX0FMTE9DRUQpKSB7CgkJCXBlbS0+dGxzaW5kZXggPSBUSFJFQURfVGxzQWxsb2ModGhkYik7CgkJCSpwZGlyLT5BZGRyZXNzT2ZJbmRleD1wZW0tPnRsc2luZGV4OyAgIAoJCX0KCQlwZW0tPmZsYWdzIHw9IFBFX01PRFJFRl9UTFNfQUxMT0NFRDsKCQlkYXRhc2l6ZT0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CgkJc2l6ZQk9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CgkJbWVtPVZpcnR1YWxBbGxvYygwLHNpemUsTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CgkJbWVtY3B5KG1lbSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSxkYXRhc2l6ZSk7CgkJaWYgKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcykgewoJCSAgICAgUElNQUdFX1RMU19DQUxMQkFDSyAqY2JzID0gCgkJICAgICAgIChQSU1BR0VfVExTX0NBTExCQUNLICopcGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzOwoKCQkgICAgIGlmICgqY2JzKQoJCSAgICAgICBGSVhNRSh3aW4zMiwgIlRMUyBDYWxsYmFja3MgYXJlbid0IGdvaW5nIHRvIGJlIGNhbGxlZFxuIik7CgkJfQoJCS8qIERvbid0IHVzZSBUbHNTZXRWYWx1ZSwgd2UgYXJlIGluIHRoZSB3cm9uZyB0aHJlYWQgKi8KCQl0aGRiLT50bHNfYXJyYXlbcGVtLT50bHNpbmRleF0gPSBtZW07Cgl9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzIChLRVJORUwzMi43NCkKICogRG9uJ3QgY2FsbCBEbGxFbnRyeVBvaW50IGZvciBETExfVEhSRUFEX3tBVFRBQ0gsREVUQUNIfSBpZiBzZXQuCiAqLwpCT09MMzIgV0lOQVBJIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoSE1PRFVMRTMyIGhNb2R1bGUpCnsKCVdJTkVfTU9EUkVGCSp3bTsKCglmb3IgKHdtPVBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkKCQlpZiAoKHdtLT5tb2R1bGUgPT0gaE1vZHVsZSkgJiYgKHdtLT50eXBlPT1NT0RVTEUzMl9QRSkpCgkJCXdtLT5iaW5mbXQucGUuZmxhZ3N8PVBFX01PRFJFRl9OT19ETExfQ0FMTFM7CglyZXR1cm4gVFJVRTsKfQo=