LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSBjYW5ub3QgdXNlIExpbnV4IG1tYXAoKSB0byBtbWFwKCkgdGhlIGltYWdlcyBkaXJlY3RseS4gTGludXggYWxpZ25zCiAqICAgdGhlbSBhdCBwYWdlc2l6ZSAoNDA5NiksIFdpbjMyIHJlcXVpcmVzIDUxMiBieXRlIGFsaWdubWVudC4KICogLSBBbGwgdGhvc2UgZnVuY3Rpb24gbWFwIHRoaW5ncyBpbnRvIGEgbmV3IGFkZHJlc3NwYWNlLiBGcm9tIHRoZSB3cm9uZwogKiAgIHByb2Nlc3MgYW5kIHRoZSB3cm9uZyB0aHJlYWQuIFNvIGNhbGxpbmcgb3RoZXIgQVBJIGZ1bmN0aW9ucyB3aWxsIG1lc3MgCiAqICAgdGhpbmdzIHVwIGJhZGx5IHNvbWV0aW1lcy4KICovCgovKiNpbmNsdWRlIDxjdHlwZS5oPiovCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlICJ3aW5kb3dzLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInBlZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChQRV9NT0RSRUYqIG1vZHJlZiwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpOwoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh1bnNpZ25lZCBpbnQpbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUzMiBoTW9kdWxlICkKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBoTW9kdWxlOwoKICBEV09SRCBydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKICBEV09SRCBydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnRzID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKVJWQShydmFfc3RhcnQpOwoKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIFRSQUNFKHdpbjMyLCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBUUkFDRSh3aW4zMiwiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCgkgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRSh3aW4zMiwiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGlmIChUUkFDRV9PTih3aW4zMikpewoJZGJnX2RlY2xfc3RyKHdpbjMyLCAxMDI0KTsKCglkc3ByaW50Zih3aW4zMiwiJTRsZCAlMDhseCAlMDh4IiwKCQkgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKCS8qIENoZWNrIGlmIHdlIGhhdmUgYSBuYW1lIGZvciBpdCAqLwoJZm9yIChqID0gMDsgaiA8IHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXM7IGorKykKICAgICAgICAgIGlmIChvcmRpbmFsW2pdID09IGkpCgkgICAgZHNwcmludGYod2luMzIsICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBkc3ByaW50Zih3aW4zMiwgIiAoZm9yd2FyZGVkIC0+ICVzKSIsIChjaGFyICopUlZBKCpmdW5jdGlvbikpOwoJVFJBQ0Uod2luMzIsIiVzXG4iLCBkYmdfc3RyKHdpbjMyKSk7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MzMiBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggUERCMzIgKnByb2Nlc3MsIEhNT0RVTEUzMiBoTW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBmdW5jTmFtZSkKewoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzOwoJdW5zaWduZWQJCQlsb2FkX2FkZHI7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUEVfTU9EUkVGCQkJKnBlbTsKCXVfbG9uZwkJCQlydmFfc3RhcnQsIHJ2YV9lbmQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0gJiYgKHBlbS0+bW9kdWxlICE9IGhNb2R1bGUpKQoJCXBlbT1wZW0tPm5leHQ7CglpZiAoIXBlbSkgewoJCWZwcmludGYoc3RkZXJyLCJObyBNT0RSRUYgZm91bmQgZm9yIFBFX01PRFVMRSAlMDh4IGluIHByb2Nlc3MgJXBcbiIsaE1vZHVsZSxwcm9jZXNzKTsKCQlyZXR1cm4gTlVMTDsKCX0KCWxvYWRfYWRkciA9IGhNb2R1bGU7CglleHBvcnRzICAgPSBwZW0tPnBlX2V4cG9ydDsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKCQlUUkFDRSh3aW4zMiwiKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJVFJBQ0Uod2luMzIsIiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQlmcHJpbnRmKHN0ZGVyciwiTW9kdWxlICUwOHgvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLGhNb2R1bGUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWwJPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHIgPSBmdW5jdGlvblsqb3JkaW5hbF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfQoJCQlvcmRpbmFsKys7CgkJCW5hbWUrKzsKCQl9Cgl9IGVsc2UgewoJCWlmIChMT1dPUkQoZnVuY05hbWUpLWV4cG9ydHMtPkJhc2UgPiBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykgewoJCQlUUkFDRSh3aW4zMiwiCW9yZGluYWwgJWQgb3V0IG9mIHJhbmdlIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1dPUkQoZnVuY05hbWUpKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJCWFkZHIgPSBmdW5jdGlvblsoaW50KWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2VdOwogICAgICAgICAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKCQlpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQoJCQlyZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CgkJZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwoJfQoJaWYgKGZvcndhcmQpCiAgICAgICAgewogICAgICAgICAgICAgICAgSE1PRFVMRTMyIGhNb2Q7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCQlpZiAoIWVuZCkgcmV0dXJuIE5VTEw7CgkJc3RybmNweShtb2R1bGUsIGZvcndhcmQsIChlbmQgLSBmb3J3YXJkKSk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBoTW9kID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBNT0RVTEVfRmluZE1vZHVsZShtb2R1bGUpICk7CgkJcmV0dXJuIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCBwcm9jZXNzLCBoTW9kLCBlbmQgKyAxKTsKCX0KCXJldHVybiBOVUxMOwp9CgpEV09SRCBmaXh1cF9pbXBvcnRzIChQREIzMiAqcHJvY2VzcyxQRV9NT0RSRUYgKnBlbSkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIGludAlmaXh1cF9mYWlsZWQJCT0gMDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSBwZW0tPm1vZHVsZTsKICAgIGludAkJCQlpOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0Uod2luMzIsICJEdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OwogICAgaWYgKCFwZV9pbXApIAogICAgCUVSUih3aW4zMiwgIm5vIGltcG9ydCBkaXJlY3Rvcnk/Pz8/XG4iKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykKCWkrKzsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykgewogICAgCUhNT0RVTEUzMglyZXM7CglQRV9NT0RSRUYJKnhwZW0sKip5cGVtOwoKCiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCS8qIGRvbid0IHVzZSBNT0RVTEVfTG9hZCwgV2luMzIgY3JlYXRlcyBuZXcgdGFzayBkaWZmZXJlbnRseSAqLwoJcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggbmFtZSwgcHJvY2VzcywgMCwgMCApOwoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGNoYXIgYnVmZmVyWzEwMjRdOwoKCSAgICAvKiBUcnkgd2l0aCBwcmVwZW5kaW5nIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IG1vZHVsZSAqLwoJICAgIGlmIChHZXRNb2R1bGVGaWxlTmFtZTMyQSggcGVtLT5tb2R1bGUsIGJ1ZmZlciwgc2l6ZW9mIChidWZmZXIpKSkgewoJICAgICAgICBjaGFyICpwOwoKCQlpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJICAgIHAgPSBidWZmZXI7CgkJc3RyY3B5IChwICsgMSwgbmFtZSk7CgkJcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggYnVmZmVyLCBwcm9jZXNzLCAwLCAwICk7CgkgICAgfSBlbHNlCgkgICAgCUVSUih3aW4zMiwiY2Fubm90IGZpbmQgdGhlIG1vZHVsZSBqdXN0IGxvYWRlZCFcbiIpOwoJfQoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGZwcmludGYgKHN0ZGVyciwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIHJldHVybiByZXM7Cgl9CglyZXMgPSBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIocmVzKTsKCXhwZW0gPSBwZW0tPm5leHQ7Cgl3aGlsZSAoeHBlbSkgewoJCWlmICh4cGVtLT5tb2R1bGUgPT0gcmVzKQoJCQlicmVhazsKCQl4cGVtID0geHBlbS0+bmV4dDsKCX0KCWlmICh4cGVtKSB7CgkJLyogSXQgaGFzIGJlZW4gbG9hZGVkICpCRUZPUkUqIHVzLCBzbyB3ZSBoYXZlIHRvIGluaXRpYWxpemUKCQkgKiBpdCBiZWZvcmUgdXMuIFdlIGNhbm5vdCBqdXN0IGxpbmsgaW4gdGhlIHhwZW0gYmVmb3JlIHBlbSwKCQkgKiBzaW5jZSB4cGVtIG1pZ2h0IHJlZmVyZW5jZSBtb3JlIGRsbHMgd2hpY2ggd291bGQgYmUgaW4gdGhlCgkJICogd3Jvbmcgb3JkZXIgYWZ0ZXIgdGhhdC4KCQkgKiBJbnN0ZWFkIHdlIGxpbmsgaW4gcGVtIHJpZ2h0IEFGVEVSIHhwZW0sIHdoaWNoIHNob3VsZCBrZWVwCgkJICogdGhlIGNvcnJlY3Qgb3JkZXIuIChJIGFtIG5vdCAxMDAlIHN1cmUgYWJvdXQgdGhhdC4pCgkJICovCgkJLyogdW5saW5rIHBlbSBmcm9tIGNoYWluICovCgkJeXBlbSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCXdoaWxlICgqeXBlbSkgewoJCQlpZiAoKCp5cGVtKT09cGVtKQoJCQkJYnJlYWs7CgkJCXlwZW0gPSAmKCgqeXBlbSktPm5leHQpOwoJCX0KCQkqeXBlbQkJPSBwZW0tPm5leHQ7CgoJCS8qIGxpbmsgcGVtIGRpcmVjdGx5IEFGVEVSIHhwZW0gKi8KCQlwZW0tPm5leHQJPSB4cGVtLT5uZXh0OwoJCXhwZW0tPm5leHQJPSBwZW07CgkJCgl9CglpKys7CiAgICB9CiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIHdoaWxlIChwZV9pbXAtPk5hbWUpIHsKCWNoYXIJCQkqTW9kdWxlOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglMUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKICAgICAgICBITU9EVUxFMzIgaEltcE1vZHVsZTsKCglNb2R1bGUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKICAgICAgICBoSW1wTW9kdWxlID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpICk7CglUUkFDRSh3aW4zMiwgIiVzXG4iLCBNb2R1bGUpOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0Uod2luMzIsICJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9KExQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKHdpbjMyLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKVBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSh3aW4zMiwgIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3MsIGhJbXBNb2R1bGUsIHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKCQkJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKHdpbjMyLCAiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKHdpbjMyLCItLS0gT3JkaW5hbCAlcy4lZFxuIixNb2R1bGUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKVBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLG9yZGluYWwpOwoJCQkvKiBmaXh1cF9mYWlsZWQ9MTsgKi8KCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KExQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0Uod2luMzIsIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxNb2R1bGUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKVBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLCBoSW1wTW9kdWxlLCBwZV9uYW1lLT5OYW1lICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICAJLyogZml4dXBfZmFpbGVkPTE7ICovCgkJICAgIH0KCQl9CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0KCXBlX2ltcCsrOwogICAgfQogICAgaWYgKGZpeHVwX2ZhaWxlZCkgcmV0dXJuIDIyOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZSggSE1PRFVMRTMyIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgVFJBQ0Uod2luMzIsICJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogICAgVFJBQ0Uod2luMzIsICIgICBOYW1lICAgIFZTeiAgVmFkZHIgICAgIFN6UmF3ICAgRmlsZWFkciAgKlJlbG9jICpMaW5ldW0gI1JlbG9jICNMaW51bSBDaGFyXG4iKTsKICAgIGZvciAoaSA9IDA7IGk8IFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspCiAgICB7CiAgICAgICAgVFJBQ0Uod2luMzIsICIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplID0gTUFYKHZtYV9zaXplLCBwZV9zZWctPlZpcnR1YWxBZGRyZXNzK3BlX3NlZy0+U2l6ZU9mUmF3RGF0YSk7CiAgICAgICAgcGVfc2VnKys7CiAgICB9CiAgICByZXR1cm4gdm1hX3NpemU7Cn0KCnN0YXRpYyB2b2lkIGRvX3JlbG9jYXRpb25zKFBFX01PRFJFRiAqcGVtKQp7CiAgICBpbnQgZGVsdGEgPSBwZW0tPm1vZHVsZSAtIFBFX0hFQURFUihwZW0tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHI9IHBlbS0+bW9kdWxlOwoJSU1BR0VfQkFTRV9SRUxPQ0FUSU9OCQkqciA9IHBlbS0+cGVfcmVsb2M7CglpbnQJCQkJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKCWludAkJCQlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCgkvKiBpbnQgcmVsb2Nfc2l6ZSA9ICovCgoJaWYoZGVsdGEgPT0gMCkKCQkvKiBOb3RoaW5nIHRvIGRvICovCgkJcmV0dXJuOwoJd2hpbGUoci0+VmlydHVhbEFkZHJlc3MpCgl7CgkJY2hhciAqcGFnZSA9IChjaGFyKikgUlZBKHItPlZpcnR1YWxBZGRyZXNzKTsKCQlpbnQgY291bnQgPSAoci0+U2l6ZU9mQmxvY2sgLSA4KS8yOwoJCWludCBpOwoJCVRSQUNFKGZpeHVwLCAiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRShmaXh1cCwicGF0Y2hpbmcgJXggdHlwZSAleFxuIiwgb2Zmc2V0LCB0eXBlKTsKCQkJc3dpdGNoKHR5cGUpCgkJCXsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6IGJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBoZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTE9XOgoJCQkJKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBsZGVsdGE7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKI2lmIDEKCQkJCSooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwojZWxzZQoJCQkJeyBpbnQgaD0qKHVuc2lnbmVkIHNob3J0KikocGFnZStvZmZzZXQpOwoJCQkJICBpbnQgbD1yLT5UeXBlT2Zmc2V0WysraV07CgkJCQkgICoodW5zaWduZWQgaW50KikocGFnZSArIG9mZnNldCkgPSAoaDw8MTYpICsgbCArIGRlbHRhOwoJCQkJfQojZW5kaWYKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJZnByaW50ZihzdGRlcnIsICJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJZnByaW50ZihzdGRlcnIsICJJcyB0aGlzIGEgTUlQUyBtYWNoaW5lID8/P1xuIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWZwcmludGYoc3RkZXJyLCAiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpzdGF0aWMgSE1PRFVMRTMyIFBFX0xvYWRJbWFnZSggSEZJTEUzMiBoRmlsZSApCnsKICAgIEhNT0RVTEUzMiBoTW9kdWxlOwogICAgSEFORExFMzIgbWFwcGluZzsKCiAgICAvKiBtYXAgdGhlIFBFIGZpbGUgc29tZXdoZXJlICovCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmczMkEoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIGZwcmludGYoIHN0ZGVyciwgIlBFX0xvYWRJbWFnZTogQ3JlYXRlRmlsZU1hcHBpbmcgZXJyb3IgJWxkXG4iLAogICAgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUzMilNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFoTW9kdWxlKQogICAgewogICAgICAgIGZwcmludGYoIHN0ZGVyciwgIlBFX0xvYWRJbWFnZTogTWFwVmlld09mRmlsZSBlcnJvciAlbGRcbiIsCiAgICAgICAgICAgICAgICAgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUpLT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFKQogICAgewogICAgICAgIGZwcmludGYoc3RkZXJyLCJpbWFnZSBkb2Vzbid0IGhhdmUgUEUgc2lnbmF0dXJlLCBidXQgMHglMDhseFxuIiwKICAgICAgICAgICAgICAgIFBFX0hFQURFUihoTW9kdWxlKS0+U2lnbmF0dXJlICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAoUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpCiAgICB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsInRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAoUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUpCiAgICAgICAgewogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046IGZwcmludGYoc3RkZXJyLCJVbmtub3duIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6ICAgIGZwcmludGYoc3RkZXJyLCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIGZwcmludGYoc3RkZXJyLCJSMzAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDogICBmcHJpbnRmKHN0ZGVyciwiUjQwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOiAgZnByaW50ZihzdGRlcnIsIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBmcHJpbnRmKHN0ZGVyciwiQWxwaGEiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzogZnByaW50ZihzdGRlcnIsIlBvd2VyUEMiKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogZnByaW50ZihzdGRlcnIsIlVua25vd24tJTA0eCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTWFjaGluZSk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICBmcHJpbnRmKHN0ZGVyciwiKVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIHJldHVybiBoTW9kdWxlOwoKZXJyb3I6CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoaXMgbWFwcyBhIGxvYWRlZCBQRSBkbGwgaW50byB0aGUgYWRkcmVzcyBzcGFjZSBvZiB0aGUgc3BlY2lmaWVkIHByb2Nlc3MuCiAqLwpzdGF0aWMgQk9PTDMyIFBFX01hcEltYWdlKCBITU9EVUxFMzIgKnBoTW9kdWxlLCBQREIzMiAqcHJvY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgT0ZTVFJVQ1QgKm9mcywgRFdPUkQgZmxhZ3MgKQp7CglQRV9NT0RSRUYJCSpwZW07CglpbnQJCQlpLCByZXN1bHQ7CglEV09SRAkJCWxvYWRfYWRkcjsKCUlNQUdFX0RBVEFfRElSRUNUT1JZCWRpcjsKCWNoYXIJCQkqbW9kbmFtZTsKCWludAkJCXZtYV9zaXplOwoJSE1PRFVMRTMyCQloTW9kdWxlID0gKnBoTW9kdWxlOwoKICAgICAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnOwogICAgICAgIElNQUdFX0RPU19IRUFERVIgKmRvc19oZWFkZXIgPSAoSU1BR0VfRE9TX0hFQURFUiAqKWhNb2R1bGU7CiAgICAgICAgSU1BR0VfTlRfSEVBREVSUyAqbnRfaGVhZGVyID0gUEVfSEVBREVSKGhNb2R1bGUpOwoJCglwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MocHJvY2Vzcy0+aGVhcCxIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoKnBlbSkpOwoJLyogTk9URTogZml4dXBfaW1wb3J0cyB0YWtlcyBjYXJlIG9mIHRoZSBjb3JyZWN0IG9yZGVyICovCglwZW0tPm5leHQJPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXByb2Nlc3MtPm1vZHJlZl9saXN0ID0gcGVtOwoKCWlmICghKG50X2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICAgICAgewoJCWlmIChwcm9jZXNzLT5leGVfbW9kcmVmKQoJCQlmcHJpbnRmKHN0ZGVyciwib3ZlcndyaXRpbmcgb2xkIGV4ZV9tb2RyZWYuLi4gYXJyZ2hcbiIpOwoJCXByb2Nlc3MtPmV4ZV9tb2RyZWYgPSBwZW07Cgl9CgoJbG9hZF9hZGRyID0gbnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7Cgl2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCVRSQUNFKHdpbjMyLCAiTG9hZCBhZGRyIGlzICVseFxuIixsb2FkX2FkZHIpOwoJbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKCWlmIChsb2FkX2FkZHIgPT0gMCkgewoJCWxvYWRfYWRkciA9IChEV09SRClWaXJ0dWFsQWxsb2MoIE5VTEwsIHZtYV9zaXplLAoJCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCQkgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJfQoJLyogKnBoTW9kdWxlIGlzIHRoZSBtb2R1bGUzMiBlbnRyeSBpbiB0aGUgTkVfTU9EVUxFLiBXZSBuZWVkIHRvCgkgKiBjaGFuZ2UgaXQgaGVyZSwgc2luY2UgaXQgY2FuIGdldCByZWZlcmVuY2VkIGJ5IGZpeHVwX2ltcG9ydHMoKQoJICovCglwZW0tPm1vZHVsZSA9ICpwaE1vZHVsZSA9IChITU9EVUxFMzIpbG9hZF9hZGRyOwoKCVRSQUNFKHdpbjMyLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAlbHgsIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgbG9hZF9hZGRyLCB2bWFfc2l6ZSk7CgkKICAgICAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIKICAgICAgICAgKiAoRklYTUU6IHNob3VsZCByZWFsbHkgdXNlIG1tYXApCiAgICAgICAgICovCiAgICAgICAgKihJTUFHRV9ET1NfSEVBREVSICopbG9hZF9hZGRyID0gKmRvc19oZWFkZXI7CiAgICAgICAgKihJTUFHRV9OVF9IRUFERVJTICopKGxvYWRfYWRkciArIGRvc19oZWFkZXItPmVfbGZhbmV3KSA9ICpudF9oZWFkZXI7CgogICAgICAgIHBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoJZm9yIChpID0gMDsgaSA8IG50X2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlZysrKQoJewoJCS8qIG1lbWNweSBvbmx5IG5vbi1CU1Mgc2VnbWVudHMgKi8KCQkvKiBGSVhNRTogdGhpcyBzaG91bGQgYmUgZG9uZSBieSBtbWFwKC4uTUFQX1BSSVZBVEV8TUFQX0ZJWEVELi4pCgkJICogYnV0IGl0IGlzIG5vdCBwb3NzaWJsZSBmb3IgKGF0IGxlYXN0KSBMaW51eCBuZWVkcwoJCSAqIGEgcGFnZS1hbGlnbmVkIG9mZnNldC4KCQkgKi8KCQlpZighKHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpKQoJCSAgICBtZW1jcHkoKGNoYXIqKVJWQShwZV9zZWctPlZpcnR1YWxBZGRyZXNzKSwKCQkgICAgCShjaGFyKikoaE1vZHVsZSArIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSksCgkJCXBlX3NlZy0+U2l6ZU9mUmF3RGF0YQoJCSAgICApOwoKCQlyZXN1bHQgPSBSVkEgKHBlX3NlZy0+VmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZV9zZWctPlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZW0tPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7Cgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfZXhwb3J0ICYmIChpbnQpcGVtLT5wZV9leHBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgZXhwb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkvKiBhbHdheXMgdHJ1c3QgdGhlIGRpcmVjdG9yeSAqLwoJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCS8qIAoJCWlmKHBlbS0+cGVfaW1wb3J0ICYmIChpbnQpcGVtLT5wZV9pbXBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgaW1wb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkgKi8KCQlwZW0tPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3Jlc291cmNlICYmIChpbnQpcGVtLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJRklYTUUod2luMzIsIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfcmVsb2MgJiYgKGludClwZW0tPnBlX3JlbG9jIT0gUlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZWxvY2F0aW9uIGxpc3Q/P1xuIik7CgkJcGVtLT5wZV9yZWxvYyA9ICh2b2lkICopIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIik7CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJR10uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzEzXS5TaXplKQoJCUZJWE1FKHdpbjMyLCJVbmtub3duIGRpcmVjdG9yeSAxMyBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlGSVhNRSh3aW4zMiwiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJRklYTUUod2luMzIsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlbS0+cGVfcmVsb2MpCWRvX3JlbG9jYXRpb25zKHBlbSk7CglpZihwZW0tPnBlX2V4cG9ydCkJZHVtcF9leHBvcnRzKHBlbS0+bW9kdWxlKTsKCWlmKHBlbS0+cGVfaW1wb3J0KQl7CgkJaWYgKGZpeHVwX2ltcG9ydHMocHJvY2VzcyxwZW0pKSB7CgkJCVBFX01PRFJFRgkqKnhwZW07CgoJCQkvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KCQkJeHBlbSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCQl3aGlsZSAoKnhwZW0pIHsKCQkJCWlmICgqeHBlbT09cGVtKSB7CgkJCQkJKnhwZW0gPSBwZW0tPm5leHQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQl4cGVtID0gJigoKnhwZW0pLT5uZXh0KTsKCQkJfQoJCQkvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCgkJCSAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCgkJCSAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCgkJCSAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwoJCQkgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZQoJCQkgKi8KCQkJcmV0dXJuIDA7CgkJfQoJfQogIAkJCglpZiAocGVtLT5wZV9leHBvcnQpCgkJbW9kbmFtZSA9IChjaGFyKilSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwoJZWxzZSB7CgkJY2hhciAqczsKCQltb2RuYW1lID0gcyA9IG9mcy0+c3pQYXRoTmFtZTsKCQl3aGlsZSAoKHM9c3RyY2hyKG1vZG5hbWUsJ1xcJykpKQoJCQltb2RuYW1lID0gcysxOwoJCWlmICgocz1zdHJjaHIobW9kbmFtZSwnLicpKSkKCQkJKnM9J1wwJzsKCX0KCiAgICAgICAgLyogTm93IHRoYXQgd2UgZ290IGV2ZXJ5dGhpbmcgYXQgdGhlIHJpZ2h0IGFkZHJlc3MsCiAgICAgICAgICogd2UgY2FuIHVubWFwIHRoZSBwcmV2aW91cyBtb2R1bGUgKi8KICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgIHJldHVybiAxOwp9CgpISU5TVEFOQ0UxNiBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoSE1PRFVMRTE2IGhNb2R1bGUsTE9BRFBBUkFNUyAqcGFyYW1zKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqICAgICAgICBpbnRlcm5hbCBtb2R1bGUgaGFuZGxpbmcgc2hvdWxkIGJlIG1hZGUgYmV0dGVyIGhlcmUgKGFuZCBpbiBidWlsdGluLmMpCiAqLwpITU9EVUxFMzIgUEVfTG9hZExpYnJhcnlFeDMyQSAoTFBDU1RSIG5hbWUsIFBEQjMyICpwcm9jZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEZJTEUzMiBoRmlsZSwgRFdPUkQgZmxhZ3MpCnsKCU9GU1RSVUNUCW9mczsKCUhNT0RVTEUzMgloTW9kdWxlOwoJTkVfTU9EVUxFCSpwTW9kdWxlOwoJUEVfTU9EUkVGCSpwZW07CgoJaWYgKChoTW9kdWxlID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG5hbWUgKSkpIHsKCQkvKiB0aGUgLkRMTCBpcyBlaXRoZXIgbG9hZGVkIG9yIGludGVybmFsICovCgkJaE1vZHVsZSA9IE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMihoTW9kdWxlKTsKCQlpZiAoIUhJV09SRChoTW9kdWxlKSkgLyogaW50ZXJuYWwgKG9yIGJhZCkgKi8KCQkJcmV0dXJuIGhNb2R1bGU7CgkJLyogY2hlY2sgaWYgdGhpcyBtb2R1bGUgaXMgYWxyZWFkeSBtYXBwZWQgKi8KCQlwZW0gCT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgkJd2hpbGUgKHBlbSkgewoJCQlpZiAocGVtLT5tb2R1bGUgPT0gaE1vZHVsZSkgcmV0dXJuIGhNb2R1bGU7CgkJCXBlbSA9IHBlbS0+bmV4dDsKCQl9CgkJcE1vZHVsZSA9IE1PRFVMRV9HZXRQdHIoaE1vZHVsZSk7CgkJaWYgKHBNb2R1bGUtPmZsYWdzICYgTkVfRkZMQUdTX0JVSUxUSU4pIHsKCQkJSU1BR0VfRE9TX0hFQURFUgkqZGg7CgkJCUlNQUdFX05UX0hFQURFUlMJKm5oOwoJCQlJTUFHRV9TRUNUSU9OX0hFQURFUgkqc2g7CgoJCQkvKiB3ZSBvbmx5IGNvbWUgaGVyZSBpZiB3ZSBhbHJlYWR5IGhhdmUgJ2xvYWRlZCcgdGhlCgkJCSAqIGludGVybmFsIGRsbCBidXQgaW4gYW5vdGhlciBwcm9jZXNzLiBKdXN0IGNyZWF0ZQoJCQkgKiBhIFBFX01PRFJFRiBhbmQgcmV0dXJuLgoJCQkgKi8KCQkJcGVtID0gKFBFX01PRFJFRiopSGVhcEFsbG9jKHByb2Nlc3MtPmhlYXAsCgkJCQlIRUFQX1pFUk9fTUVNT1JZLHNpemVvZigqcGVtKSk7CgkJCXBlbS0+bW9kdWxlIAkgICAgID0gaE1vZHVsZTsKCQkJZGggPSAoSU1BR0VfRE9TX0hFQURFUiopcGVtLT5tb2R1bGU7CgkJCW5oID0gKElNQUdFX05UX0hFQURFUlMqKShkaCsxKTsKCQkJc2ggPSAoSU1BR0VfU0VDVElPTl9IRUFERVIqKShuaCsxKTsKCQkJcGVtLT5wZV9leHBvcnQJICAgICA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKikoc2grMik7CgkJCXBlbS0+bmV4dAkgICAgID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgkJCXByb2Nlc3MtPm1vZHJlZl9saXN0ID0gcGVtOwoJCQlyZXR1cm4gaE1vZHVsZTsKCQl9Cgl9IGVsc2UgewoKCQkvKiB0cnkgdG8gbG9hZCBidWlsdGluLCBlbmFibGVkIG1vZHVsZXMgZmlyc3QgKi8KCQlpZiAoKGhNb2R1bGUgPSBCVUlMVElOMzJfTG9hZE1vZHVsZSggbmFtZSwgRkFMU0UsIHByb2Nlc3MgKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggaE1vZHVsZSApOwoKCQkvKiB0cnkgdG8gb3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgKi8KCQlpZiAoSEZJTEVfRVJST1IzMj09KGhGaWxlPU9wZW5GaWxlMzIobmFtZSwmb2ZzLE9GX1JFQUQpKSkgewoJCQkvKiBOb3cgdHJ5IHRoZSBidWlsdC1pbiBldmVuIGlmIGRpc2FibGVkICovCgkJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU4zMl9Mb2FkTW9kdWxlKCBuYW1lLCBUUlVFLCBwcm9jZXNzICkpKSB7CgkJCQlmcHJpbnRmKCBzdGRlcnIsICJXYXJuaW5nOiBjb3VsZCBub3QgbG9hZCBXaW5kb3dzIERMTCAnJXMnLCB1c2luZyBidWlsdC1pbiBtb2R1bGUuXG4iLCBuYW1lICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMiggaE1vZHVsZSApOwoJCQl9CgkJCXJldHVybiAxOwoJCX0KCQlpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoICZvZnMgKSkgPCAzMikgewoJCQlfbGNsb3NlMzIoaEZpbGUpOwoJCQlyZXR1cm4gaE1vZHVsZTsKCQl9CgkJcE1vZHVsZQkJPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlICk7CgkJcE1vZHVsZS0+ZmxhZ3MJPSBORV9GRkxBR1NfV0lOMzI7CgkJcE1vZHVsZS0+bW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlICk7CgkJQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJaWYgKHBNb2R1bGUtPm1vZHVsZTMyIDwgMzIpIHJldHVybiAyMTsKCX0KCS8qIHJlY3Vyc2UgKi8KCWlmICghUEVfTWFwSW1hZ2UoICYocE1vZHVsZS0+bW9kdWxlMzIpLCBwcm9jZXNzLCAmb2ZzLGZsYWdzKSkgewoJCS8qIHNob3VsZCBmcmVlIHRoaXMgbW9kdWxlIGFuZCB0aGUgYWxyZWFkeSByZWZlcmVuY2VkIG9uZXMgKi8KCQlyZXR1cm4gMDsKCX0KCXJldHVybiBwTW9kdWxlLT5tb2R1bGUzMjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIExvYWQgdGhlIFBFIG1haW4gLkVYRS4gQWxsIG90aGVyIGxvYWRpbmcgaXMgZG9uZSBieSBQRV9Mb2FkTGlicmFyeUV4MzJBCiAqIEZJWE1FOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCB1c2UgUEVfTG9hZExpYnJhcnlFeDMyQSwgYnV0IGN1cnJlbnRseSBjYW4ndAogKiBkdWUgdG8gdGhlIFRBU0tfQ3JlYXRlVGFzayBzdHVmZi4KICovCkhJTlNUQU5DRTE2IFBFX0xvYWRNb2R1bGUoIEhGSUxFMzIgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlMTY7CiAgICBITU9EVUxFMzIgaE1vZHVsZTMyOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwogICAgVEhEQiAqdGhkYiA9IFRIUkVBRF9DdXJyZW50KCk7CiAgICAKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBvZnMgKSkgPCAzMikgcmV0dXJuIGhNb2R1bGUxNjsKICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIHBNb2R1bGUtPm1vZHVsZTMyID0gaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSApOwogICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CiAgICBpZiAoaE1vZHVsZTMyIDwgMzIpIHJldHVybiAyMTsKCiAgICBoSW5zdGFuY2UgPSBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoIGhNb2R1bGUxNiwgcGFyYW1zICk7CiAgICBpZiAoIShQRV9IRUFERVIoaE1vZHVsZTMyKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpCiAgICB7CiAgICAgICAgSFRBU0sxNiBoVGFzayA9IFRBU0tfQ3JlYXRlVGFzayggaE1vZHVsZTE2LCBoSW5zdGFuY2UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5oRW52aXJvbm1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQU1RSKVBUUl9TRUdfVE9fTElOKCBwYXJhbXMtPmNtZExpbmUgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICooKFdPUkQqKVBUUl9TRUdfVE9fTElOKHBhcmFtcy0+c2hvd0NtZCkgKyAxKSApOwogICAgICAgIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBoVGFzayApOwogICAgICAgIHRoZGIgPSBwVGFzay0+dGhkYjsKICAgIH0KICAgIGlmICghUEVfTWFwSW1hZ2UoICYocE1vZHVsZS0+bW9kdWxlMzIpLCB0aGRiLT5wcm9jZXNzLCBvZnMsIDAgKSkKICAgIHsKICAgICAJLyogRklYTUU6IHNob3VsZCBkZXN0cm95IHRoZSB0YXNrIGNyZWF0ZWQgYW5kIGZyZWUgcmVmZXJlbmNlZCBzdHVmZiAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgLyogRklYTUU6IFl1Y2suIElzIHRoZXJlIG5vIG90aGVyIGdvb2QgcGxhY2UgdG8gZG8gdGhhdD8gKi8KICAgIFBFX0luaXRUbHMoIHRoZGIgKTsKICAgIHJldHVybiBoSW5zdGFuY2U7Cn0KCmludCBQRV9VbmxvYWRJbWFnZSggSE1PRFVMRTMyIGhNb2R1bGUgKQp7CglmcHJpbnRmKHN0ZGVyciwiUEV1bmxvYWRJbWFnZSgpIGNhbGxlZCFcbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKFBFX01PRFJFRiAqcGVtLCBEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKQp7CiAgICBpZiAodHlwZT09RExMX1BST0NFU1NfQVRUQUNIKQoJcGVtLT5mbGFncyB8PSBQRV9NT0RSRUZfUFJPQ0VTU19BVFRBQ0hFRDsKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgKSB7CiAgICAgICAgRkFSUFJPQzMyIGVudHJ5ID0gKEZBUlBST0MzMilSVkFfUFRSKCBwZW0tPm1vZHVsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgICAgIFRSQUNFKHJlbGF5LCAiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgZW50cnkoIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9Cn0KCi8qIENhbGwgdGhlIERMTGVudHJ5IGZ1bmN0aW9uIG9mIGFsbCBkbGxzIHVzZWQgYnkgdGhhdCBwcm9jZXNzLgogKiAoTk9URTogdGhpcyBtYXkgcmVjdXJzaXZlbHkgY2FsbCB0aGlzIGZ1bmN0aW9uIChpZiBhIGxpYnJhcnkgY2FsbHMKICogTG9hZExpYnJhcnkpIC4uLiBidXQgaXQgd29uJ3QgbWF0dGVyKQogKi8Kdm9pZCBQRV9Jbml0aWFsaXplRExMcyhQREIzMiAqcHJvY2VzcyxEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKSB7CglQRV9NT0RSRUYJKnBlbTsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0pIHsKCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9OT19ETExfQ0FMTFMpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkgewoJCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEKSB7CgkJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlQRV9Jbml0RExMKCBwZW0sIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCQlwZW0gPSBwZW0tPm5leHQ7Cgl9Cn0KCnZvaWQgUEVfSW5pdFRscyhUSERCICp0aGRiKQp7CgkvKiBGSVhNRTogdGxzIGNhbGxiYWNrcyA/Pz8gKi8KCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCUxQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoJUERCMzIJCQkqcGRiID0gdGhkYi0+cHJvY2VzczsKCglwZW0gPSBwZGItPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSkgewoJCXBlaCA9IFBFX0hFQURFUihwZW0tPm1vZHVsZSk7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJcGRpciA9IChMUFZPSUQpKHBlbS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJaWYgKCEocGVtLT5mbGFncyAmIFBFX01PRFJFRl9UTFNfQUxMT0NFRCkpIHsKCQkJcGVtLT50bHNpbmRleCA9IFRIUkVBRF9UbHNBbGxvYyh0aGRiKTsKCQkJKihwZGlyLT5BZGRyZXNzT2ZJbmRleCk9cGVtLT50bHNpbmRleDsgICAKCQl9CgkJcGVtLT5mbGFncyB8PSBQRV9NT0RSRUZfVExTX0FMTE9DRUQ7CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sKExQVk9JRCkgcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhLCBkYXRhc2l6ZSk7CgkJLyogZG9uJ3QgdXNlIFRsc1NldFZhbHVlLCB3ZSBhcmUgaW4gdGhlIHdyb25nIHRocmVhZCAqLwoJCXRoZGItPnRsc19hcnJheVtwZW0tPnRsc2luZGV4XSA9IG1lbTsKCQlwZW09cGVtLT5uZXh0OwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyAoS0VSTkVMMzIuNzQpCiAqIERvbid0IGNhbGwgRGxsRW50cnlQb2ludCBmb3IgRExMX1RIUkVBRF97QVRUQUNILERFVEFDSH0gaWYgc2V0LgogKi8KQk9PTDMyIFdJTkFQSSBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKEhNT0RVTEUzMiBoTW9kdWxlKQp7CglQREIzMgkqcHJvY2VzcyA9IFBST0NFU1NfQ3VycmVudCgpOwoJUEVfTU9EUkVGCSpwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCgl3aGlsZSAocGVtKSB7CgkJaWYgKHBlbS0+bW9kdWxlID09IGhNb2R1bGUpCgkJCXBlbS0+ZmxhZ3N8PVBFX01PRFJFRl9OT19ETExfQ0FMTFM7CgkJcGVtID0gcGVtLT5uZXh0OwoJfQoJcmV0dXJuIFRSVUU7Cn0K