LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gU29tZXRpbWVzLCB3ZSBjYW4ndCB1c2UgTGludXggbW1hcCgpIHRvIG1tYXAoKSB0aGUgaW1hZ2VzIGRpcmVjdGx5LgogKgogKiAgIFRoZSBwcm9ibGVtIGlzLCB0aGF0IHRoZXJlIGlzIG5vdCBkaXJlY3QgMToxIG1hcHBpbmcgZnJvbSBhIGRpc2tpbWFnZSBhbmQKICogICBhIG1lbW9yeWltYWdlLiBUaGUgaGVhZGVycyBhdCB0aGUgc3RhcnQgYXJlIG1hcHBlZCBsaW5lYXIsIGJ1dCB0aGUgc2VjdGlvbnMKICogICBhcmUgbm90LiBPbGRlciB4ODYgcGUgYmluYXJpZXMgYXJlIDUxMiBieXRlIGFsaWduZWQgaW4gZmlsZSBhbmQgNDA5NiBieXRlCiAqICAgYWxpZ25lZCBpbiBtZW1vcnkuIExpbnV4IGxpa2VzIHRoZW0gNDA5NiBieXRlIGFsaWduZWQgaW4gbWVtb3J5IChkdWUgdG8KICogICB4ODYgcGFnZXNpemUsIHRoaXMgY2Fubm90IGJlIGZpeGVkIHdpdGhvdXQgYSByYXRoZXIgbGFyZ2Uga2VybmVsIHJld3JpdGUpCiAqICAgYW5kICdibG9ja3NpemUnIGZpbGUtYWxpZ25lZCAob2Zmc2V0cykuIFNpbmNlIHdlIGhhdmUgNTEyLzEwMjQvMjA0OCAoQ0RST00pCiAqICAgYW5kIG90aGVyIGJ5dGUgYmxvY2tzaXplcywgd2UgY2FuJ3QgYWx3YXlzIGRvIHRoaXMuICBXZSAqY2FuKiBkbyB0aGlzIGZvcgogKiAgIG5ld2VyIHBlIGJpbmFyaWVzIHByb2R1Y2VkIGJ5IE1TVkMgNSBhbmQgbGF0ZXIsIHNpbmNlIHRoZXkgYXJlIGFsc28gYWxpZ25lZAogKiAgIHRvIDQwOTYgYnl0ZSBib3VuZGFyaWVzIG9uIGRpc2suCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJjYWxsYmFjay5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAiaGVhcC5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luMzIpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChkZWxheWhscCkKREVDTEFSRV9ERUJVR19DSEFOTkVMKGZpeHVwKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzZWdtZW50KQoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodm9pZCAqKSgoY2hhciAqKWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0UoIioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbiIpOwogIFRSQUNFKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKICAgICAgICBNb2R1bGUsIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIFRSQUNFKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCglmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBEUFJJTlRGKCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgRFBSSU5URigiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilSVkEoKmZ1bmN0aW9uKSk7CglEUFJJTlRGKCJcbiIpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCAKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBCT09MIHNub29wICkKewoJdV9zaG9ydAkJCQkqIG9yZGluYWxzOwoJdV9sb25nCQkJCSogZnVuY3Rpb247Cgl1X2NoYXIJCQkJKiogbmFtZSwgKmVuYW1lID0gTlVMTDsKCWludAkJCQlpLCBvcmRpbmFsOwoJUEVfTU9EUkVGCQkJKnBlbSA9ICYod20tPmJpbmZtdC5wZSk7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHMgPSBwZW0tPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0UoIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJLyogTm90IGEgZmF0YWwgcHJvYmxlbSwgc29tZSBhcHBzIGRvCgkJICogR2V0UHJvY0FkZHJlc3MoMCwiUmVnaXN0ZXJQZW5BcHAiKSB3aGljaCB0cmlnZ2VycyB0aGlzCgkJICogY2FzZS4KCQkgKi8KCQlXQVJOKCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWxzPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBmaXJzdCB0cnkgYSBiaW5hcnkgc2VhcmNoICovCiAgICAgICAgICAgIGludCBtaW4gPSAwLCBtYXggPSBleHBvcnRzLT5OdW1iZXJPZk5hbWVzIC0gMTsKICAgICAgICAgICAgd2hpbGUgKG1pbiA8PSBtYXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCByZXMsIHBvcyA9IChtaW4gKyBtYXgpIC8gMjsKICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbcG9zXSk7CiAgICAgICAgICAgICAgICBpZiAoIShyZXMgPSBzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbcG9zXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHJlcyA+IDApIG1heCA9IHBvcyAtIDE7CiAgICAgICAgICAgICAgICBlbHNlIG1pbiA9IHBvcyArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogbm93IHRyeSBhIGxpbmVhciBzZWFyY2ggaW4gY2FzZSB0aGUgbmFtZXMgYXJlbid0IHNvcnRlZCBwcm9wZXJseSAqLwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoICIlcy4lcyByZXF1aXJlZCBhIGxpbmVhciBzZWFyY2hcbiIsIHdtLT5tb2RuYW1lLCBmdW5jTmFtZSApOwogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1tpXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBOVUxMOwoJfQogICAgICAgIGVsc2UgIC8qIGZpbmQgYnkgb3JkaW5hbCAqLwogICAgICAgIHsKICAgICAgICAgICAgb3JkaW5hbCA9IExPV09SRChmdW5jTmFtZSkgLSBleHBvcnRzLT5CYXNlOwogICAgICAgICAgICBpZiAoc25vb3AgJiYgbmFtZSkgIC8qIG5lZWQgdG8gZmluZCBhIG5hbWUgZm9yIGl0ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgaWYgKG9yZGluYWxzW2ldID09IG9yZGluYWwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9Cgl9CgogZm91bmQ6CiAgICAgICAgaWYgKG9yZGluYWwgPj0gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiCW9yZGluYWwgJWxkIG91dCBvZiByYW5nZSFcbiIsIG9yZGluYWwgKyBleHBvcnRzLT5CYXNlICk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBhZGRyID0gZnVuY3Rpb25bb3JkaW5hbF07CiAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICBpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQogICAgICAgIHsKICAgICAgICAgICAgRkFSUFJPQyBwcm9jID0gUlZBKGFkZHIpOwogICAgICAgICAgICBpZiAoc25vb3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZW5hbWUpIGVuYW1lID0gIkAiOwogICAgICAgICAgICAgICAgcHJvYyA9IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsb3JkaW5hbCxwcm9jKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvYzsKICAgICAgICB9CiAgICAgICAgZWxzZSAgLyogZm9yd2FyZCBlbnRyeSBwb2ludCAqLwogICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfTU9EUkVGICp3bTsKICAgICAgICAgICAgICAgIGNoYXIgKmZvcndhcmQgPSBSVkEoYWRkcik7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgaWYgKGVuZCAtIGZvcndhcmQgPj0gc2l6ZW9mKG1vZHVsZSkpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtY3B5KCBtb2R1bGUsIGZvcndhcmQsIGVuZCAtIGZvcndhcmQgKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGlmICghKHdtID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG1vZHVsZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm1vZHVsZSBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJ1xuIiwgZm9yd2FyZCApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoJCXJldHVybiBNT0RVTEVfR2V0UHJvY0FkZHJlc3MoIHdtLT5tb2R1bGUsIGVuZCArIDEsIHNub29wICk7Cgl9Cn0KCkRXT1JEIGZpeHVwX2ltcG9ydHMoIFdJTkVfTU9EUkVGICp3bSApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBQRV9NT0RSRUYJCQkqcGVtOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHdtLT5tb2R1bGU7CiAgICBpbnQJCQkJaSxjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uPTE7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICAKICAgIGFzc2VydCh3bS0+dHlwZT09TU9EVUxFMzJfUEUpOwogICAgcGVtID0gJih3bS0+YmluZm10LnBlKTsKICAgIGlmIChwZW0tPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwogICAgZWxzZQogICAgICAgIG1vZG5hbWUgPSAiPHVua25vd24+IjsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0c2ljcyAwIChub3RhYmx5IEJvcmxhbmQpIGFuZAogICAgICogc3dpdGNoIHRoZSBkZXRlY3Rpb24gb2ZmIGZvciB0aGVtLgogICAgICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewoJaWYgKCFpICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gPSAwOwoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CglpKys7CiAgICB9CiAgICBpZiAoIWkpIHJldHVybiAwOyAgLyogbm8gaW1wb3J0cyAqLwoKICAgIC8qIEFsbG9jYXRlIG1vZHVsZSBkZXBlbmRlbmN5IGxpc3QgKi8KICAgIHdtLT5uRGVwcyA9IGk7CiAgICB3bS0+ZGVwcyAgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGkqc2l6ZW9mKFdJTkVfTU9EUkVGICopICk7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlXSU5FX01PRFJFRgkJKndtSW1wOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwogCWNoYXIJCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CgkgICAgRVJSXyhtb2R1bGUpKCJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLCBuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB3bS0+ZGVwc1tpKytdID0gd21JbXA7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0UoIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcy4lZFxuIixuYW1lLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgVFJBQ0UoIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRSgiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIFRSQUNFKCIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPk1pc2MuVmlydHVhbFNpemUpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyggdW5zaWduZWQgaW50IGxvYWRfYWRkciwgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyICkKewogICAgaW50IGRlbHRhID0gbG9hZF9hZGRyIC0gUEVfSEVBREVSKGxvYWRfYWRkciktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIGludAloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwogICAgaW50CWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRV8oZml4dXApKCIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCVRSQUNFXyhmaXh1cCkoInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKCQkJCS8qIEZJWE1FOiBpZiB0aGlzIGlzIGFuIGV4cG9ydGVkIGFkZHJlc3MsIGZpcmUgdXAgZW5oYW5jZWQgbG9naWMgKi8KCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJRklYTUUoIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlGSVhNRSgiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlGSVhNRSgiVW5rbm93biBmaXh1cCB0eXBlXG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXIgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXIgKyByLT5TaXplT2ZCbG9jayk7Cgl9Cn0KCQkKCgkKCQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpITU9EVUxFIFBFX0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIFdPUkQgKnZlcnNpb24gKQp7CiAgICBITU9EVUxFCWhNb2R1bGU7CiAgICBIQU5ETEUJbWFwcGluZzsKCiAgICBJTUFHRV9OVF9IRUFERVJTICpudDsKICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpwZV9zZWM7CiAgICBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gYmhmaTsKICAgIGludAlpLCByYXdzaXplLCBsb3dlc3RfdmEsIHZtYV9zaXplLCBmaWxlX3NpemUgPSAwOwogICAgRFdPUkQgbG9hZF9hZGRyID0gMCwgYW9lcCwgcmVsb2MgPSAwOwogICAgc3RydWN0IGdldF9yZWFkX2ZkX3JlcXVlc3QgKnJlcSA9IGdldF9yZXFfYnVmZmVyKCk7CiAgICBpbnQgdW5peF9oYW5kbGUgPSAtMTsKCiAgICAvKiBSZXRyaWV2ZSBmaWxlIHNpemUgKi8KICAgIGlmICggR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoIGhGaWxlLCAmYmhmaSApICkgCiAgICAJZmlsZV9zaXplID0gYmhmaS5uRmlsZVNpemVMb3c7IC8qIEZJWE1FOiA2NCBiaXQgKi8KCiAgICAvKiBNYXAgdGhlIFBFIGZpbGUgc29tZXdoZXJlICovCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmdBKCBoRmlsZSwgTlVMTCwgUEFHRV9SRUFET05MWSB8IFNFQ19DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBXQVJOKCJDcmVhdGVGaWxlTWFwcGluZyBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBXQVJOKCJNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICggKihXT1JEKiloTW9kdWxlICE9SU1BR0VfRE9TX1NJR05BVFVSRSkKICAgIHsKICAgICAgICBXQVJOKCIlcyBpbWFnZSBkb2Vzbid0IGhhdmUgRE9TIHNpZ25hdHVyZSwgYnV0IDB4JTA0eFxuIiwgZmlsZW5hbWUsKihXT1JEKiloTW9kdWxlKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CgogICAgLyogQ2hlY2sgc2lnbmF0dXJlICovCiAgICBpZiAoIG50LT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFICkKICAgIHsKICAgICAgICBXQVJOKCIlcyBpbWFnZSBkb2Vzbid0IGhhdmUgUEUgc2lnbmF0dXJlLCBidXQgMHglMDhseFxuIiwgZmlsZW5hbWUsIG50LT5TaWduYXR1cmUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENoZWNrIGFyY2hpdGVjdHVyZSAqLwogICAgaWYgKCBudC0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2ICkKICAgIHsKICAgICAgICBNRVNTQUdFKCJUcnlpbmcgdG8gbG9hZCBQRSBpbWFnZSBmb3IgdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0dXJlICgiKTsKICAgICAgICBzd2l0Y2ggKG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpCiAgICAgICAgewogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1VOS05PV046IE1FU1NBR0UoIlVua25vd24iKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfSTg2MDogICAgTUVTU0FHRSgiSTg2MCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMzAwMDogICBNRVNTQUdFKCJSMzAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SNDAwMDogICBNRVNTQUdFKCJSNDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6ICBNRVNTQUdFKCJSMTAwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfQUxQSEE6ICAgTUVTU0FHRSgiQWxwaGEiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzogTUVTU0FHRSgiUG93ZXJQQyIpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBNRVNTQUdFKCJVbmtub3duLSUwNHgiLCBudC0+RmlsZUhlYWRlci5NYWNoaW5lKTsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIE1FU1NBR0UoIilcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogRmluZCBvdXQgaG93IGxhcmdlIHRoaXMgZXhlY3V0ZWFibGUgc2hvdWxkIGJlICovCiAgICBwZV9zZWMgPSBQRV9TRUNUSU9OUyggaE1vZHVsZSApOwogICAgcmF3c2l6ZSA9IDA7IGxvd2VzdF92YSA9IDB4MTAwMDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKSAKICAgIHsKICAgICAgICBpZiAobG93ZXN0X3ZhID4gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzKQogICAgICAgICAgIGxvd2VzdF92YSA9IHBlX3NlY1tpXS5WaXJ0dWFsQWRkcmVzczsKICAgIAlpZiAocGVfc2VjW2ldLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJICAgIGNvbnRpbnVlOwoJaWYgKHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhK3BlX3NlY1tpXS5TaXplT2ZSYXdEYXRhID4gcmF3c2l6ZSkKCSAgICByYXdzaXplID0gcGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGE7CiAgICB9CiAKICAgIC8qIENoZWNrIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBmaWxlX3NpemUgJiYgZmlsZV9zaXplIDwgcmF3c2l6ZSApCiAgICB7CiAgICAgICAgRVJSKCJQRSBtb2R1bGUgaXMgdG9vIHNtYWxsIChoZWFkZXI6ICVkLCBmaWxlc2l6ZTogJWQpLCAiCiAgICAgICAgICAgICAgICAgICAgInByb2JhYmx5IHRydW5jYXRlZCBkb3dubG9hZD9cbiIsIAogICAgICAgICAgICAgICAgICAgIHJhd3NpemUsIGZpbGVfc2l6ZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgZW50cnlwb2ludCBhZGRyZXNzICovCiAgICBhb2VwID0gbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQ7CiAgICBpZiAoYW9lcCAmJiAoYW9lcCA8IGxvd2VzdF92YSkpCiAgICAgICAgRklYTUUoIlZJUlVTIFdBUk5JTkc6ICclcycgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICAgImJlbG93IHRoZSBmaXJzdCB2aXJ0dWFsIGFkZHJlc3MgKDB4JTA4eCkgIgogICAgICAgICAgICAgICAgICAgICAgIihwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGFvZXAsIGxvd2VzdF92YSApOwoKCiAgICAvKiBGSVhNRTogIEhhY2shICBXaGlsZSB3ZSBkb24ndCByZWFsbHkgc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgeWV0LAogICAgICogICAgICAgICB0aGlzIGNoZWNrcyBmb3IgdGhvc2Ugc3BlY2lhbCBjYXNlcyB3aGVyZSB0aGUgd2hvbGUgRExMCiAgICAgKiAgICAgICAgIGNvbnNpc3RzIG9ubHkgb2Ygc2hhcmVkIHNlY3Rpb25zIGFuZCBpcyBtYXBwZWQgaW50byB0aGUKICAgICAqICAgICAgICAgc2hhcmVkIGFkZHJlc3Mgc3BhY2UgPiAyR0IuICBJbiB0aGlzIGNhc2UsIHdlIGFzc3VtZSB0aGF0CiAgICAgKiAgICAgICAgIHRoZSBtb2R1bGUgZ290IG1hcHBlZCBhdCBpdHMgYmFzZSBhZGRyZXNzLiBUaHVzIHdlIHNpbXBseQogICAgICogICAgICAgICBjaGVjayB3aGV0aGVyIHRoZSBtb2R1bGUgaGFzIGFjdHVhbGx5IGJlZW4gbWFwcGVkIHRoZXJlCiAgICAgKiAgICAgICAgIGFuZCB1c2UgaXQsIGlmIHNvLiAgVGhpcyBpcyBuZWVkZWQgdG8gZ2V0IFdpbjk1IFVTRVIzMi5ETEwKICAgICAqICAgICAgICAgdG8gd29yayAodW50aWwgd2Ugc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgcHJvcGVybHkpLgogICAgICovCgogICAgaWYgKCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCApCiAgICB7CiAgICAgICAgSE1PRFVMRSBzaGFyZWRNb2QgPSAoSE1PRFVMRSludC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOyAKICAgICAgICBJTUFHRV9OVF9IRUFERVJTICpzaGFyZWROdCA9IChQSU1BR0VfTlRfSEVBREVSUykKICAgICAgICAgICAgICAgKCAoTFBCWVRFKXNoYXJlZE1vZCArICgoTFBCWVRFKW50IC0gKExQQllURSloTW9kdWxlKSApOwoKICAgICAgICAvKiBXZWxsLCB0aGlzIGNoZWNrIGlzIG5vdCByZWFsbHkgY29tcHJlaGVuc2l2ZSwgCiAgICAgICAgICAgYnV0IHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3Igbm93IC4uLiAqLwogICAgICAgIGlmICggICAgIUlzQmFkUmVhZFB0ciggKExQQllURSlzaGFyZWRNb2QsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIChMUEJZVEUpc2hhcmVkTW9kLCAoTFBCWVRFKWhNb2R1bGUsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApID09IDAKICAgICAgICAgICAgICYmICFJc0JhZFJlYWRQdHIoIHNoYXJlZE50LCBzaXplb2YoSU1BR0VfTlRfSEVBREVSUykgKQogICAgICAgICAgICAgJiYgbWVtY21wKCBzaGFyZWROdCwgbnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApID09IDAgKQogICAgICAgIHsKICAgICAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgICAgICAgICAgcmV0dXJuIHNoYXJlZE1vZDsKICAgICAgICB9CiAgICB9CgoKICAgIC8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgbW9kdWxlICovCiAgICBsb2FkX2FkZHIgPSBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwogICAgdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CgogICAgbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICBpZiAobG9hZF9hZGRyID09IDApIAogICAgewogICAgICAgIC8qIFdlIG5lZWQgdG8gcGVyZm9ybSBiYXNlIHJlbG9jYXRpb25zICovCiAgICAgICAgRklYTUUoIldlIG5lZWQgdG8gcGVyZm9ybSBiYXNlIHJlbG9jYXRpb25zIGZvciAlc1xuIiwgZmlsZW5hbWUpOwoJZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQzsKICAgICAgICBpZiAoZGlyLT5TaXplKQogICAgICAgICAgICByZWxvYyA9IGRpci0+VmlydHVhbEFkZHJlc3M7CiAgICAgICAgZWxzZSAKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCAiRkFUQUw6IE5lZWQgdG8gcmVsb2NhdGUgJXMsIGJ1dCBubyByZWxvY2F0aW9uIHJlY29yZHMgcHJlc2VudCAoJXMpLiBUcnkgdG8gcnVuIHRoYXQgZmlsZSBkaXJlY3RseSAhXG4iLAogICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzJklNQUdFX0ZJTEVfUkVMT0NTX1NUUklQUEVEKT8KICAgICAgICAgICAgICAgICAgICJzdHJpcHBlZCBkdXJpbmcgbGluayIgOiAidW5rbm93biByZWFzb24iICk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICAvKiBGSVhNRTogSWYgd2UgbmVlZCB0byByZWxvY2F0ZSBhIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpIHdlIHNob3VsZAogICAgICAgICAqICAgICAgICByZWFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlICpuZXcqIGJhc2UgYWRkcmVzcyBpcyBhbHNvID4gMkdCLgogICAgICAgICAqICAgICAgICBTb21lIERMTHMgcmVhbGx5IGNoZWNrIHRoZSBNU0Igb2YgdGhlIG1vZHVsZSBoYW5kbGUgOi0vCiAgICAgICAgICovCiAgICAgICAgaWYgKCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCApCiAgICAgICAgICAgIEVSUiggIkZvcmNlZCB0byByZWxvY2F0ZSBzeXN0ZW0gRExMIChiYXNlID4gMkdCKS4gVGhpcyBpcyBub3QgZ29vZC5cbiIgKTsKCiAgICAgICAgbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggTlVMTCwgdm1hX3NpemUsCgkJCQkJIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKCQkJCQkgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJaWYgKCFsb2FkX2FkZHIpIHsKICAgICAgICAgICAgRklYTUVfKHdpbjMyKSgKICAgICAgICAgICAgICAgICAgICJGQVRBTDogQ291bGRuJ3QgbG9hZCBtb2R1bGUgJXMgKG91dCBvZiBtZW1vcnksICVkIG5lZWRlZCkhXG4iLCBmaWxlbmFtZSwgdm1hX3NpemUpOwogICAgICAgICAgICBnb3RvIGVycm9yOwoJfQogICAgfQoKICAgIFRSQUNFKCJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgbG9hZF9hZGRyLCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlLCB2bWFfc2l6ZSApOwogICAgVFJBQ0VfKHNlZ21lbnQpKCJMb2FkaW5nICVzIGF0ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiNpZiAwCiAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIgKi8KICAgICooUElNQUdFX0RPU19IRUFERVIpbG9hZF9hZGRyID0gKihQSU1BR0VfRE9TX0hFQURFUiloTW9kdWxlOwogICAgKlBFX0hFQURFUiggbG9hZF9hZGRyICkgPSAqbnQ7CiAgICBtZW1jcHkoIFBFX1NFQ1RJT05TKGxvYWRfYWRkciksIFBFX1NFQ1RJT05TKGhNb2R1bGUpLAogICAgICAgICAgICBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyApOwoKICAgIC8qIENvcGllcyBhbGwgc3R1ZmYgdXAgdG8gdGhlIGZpcnN0IHNlY3Rpb24uIEluY2x1ZGluZyB3aW4zMiB2aXJ1c2VzLiAqLwogICAgbWVtY3B5KCBsb2FkX2FkZHIsIGhNb2R1bGUsIGxvd2VzdF9mYSApOwojZW5kaWYKCiAgICByZXEtPmhhbmRsZSA9IGhGaWxlOwogICAgc2VydmVyX2NhbGxfZmQoIFJFUV9HRVRfUkVBRF9GRCwgLTEsICZ1bml4X2hhbmRsZSApOwogICAgaWYgKHVuaXhfaGFuZGxlID09IC0xKSBnb3RvIGVycm9yOwoKICAgIC8qIE1hcCB0aGUgaGVhZGVyICovCiAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCAqKWxvYWRfYWRkciwgMCwgbnQtPk9wdGlvbmFsSGVhZGVyLlNpemVPZkhlYWRlcnMsCiAgICAgICAgICAgICAgICAgICAgIDAsIDAsIFBST1RfRVhFQyB8IFBST1RfV1JJVEUgfCBQUk9UX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgIE1BUF9QUklWQVRFIHwgTUFQX0ZJWEVEICkgIT0gbG9hZF9hZGRyKQogICAgewogICAgICAgIEVSUl8od2luMzIpKCAiQ3JpdGljYWwgRXJyb3I6IGZhaWxlZCB0byBtYXAgUEUgaGVhZGVyIHRvIG5lY2Vzc2FyeSBhZGRyZXNzLlxuIik7CQogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ29weSBzZWN0aW9ucyBpbnRvIG1vZHVsZSBpbWFnZSAqLwogICAgcGVfc2VjID0gUEVfU0VDVElPTlMoIGhNb2R1bGUgKTsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlYysrKQogICAgewogICAgICAgIGlmICghcGVfc2VjLT5TaXplT2ZSYXdEYXRhKSBjb250aW51ZTsKICAgICAgICBUUkFDRSgiJXM6IG1tYXBpbmcgc2VjdGlvbiAlcyBhdCAlcCBvZmYgJWx4XG4iLAogICAgICAgICAgICAgIGZpbGVuYW1lLCBwZV9zZWMtPk5hbWUsICh2b2lkKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgcGVfc2VjLT5Qb2ludGVyVG9SYXdEYXRhKTsKICAgICAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgMCwgbWluKHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSwgcGVfc2VjLT5TaXplT2ZSYXdEYXRhKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAwLCBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEsIFBST1RfRVhFQyB8IFBST1RfV1JJVEUgfCBQUk9UX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICBNQVBfUFJJVkFURSB8IE1BUF9GSVhFRCApICE9ICh2b2lkKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBmYWlsZWQgdG8gbWFwIHRvIHRoZSByaWdodCBwbGFjZSAoaHVoPykgKi8KICAgICAgICAgICAgRVJSXyh3aW4zMikoICJDcml0aWNhbCBFcnJvcjogZmFpbGVkIHRvIG1hcCBQRSBzZWN0aW9uIHRvIG5lY2Vzc2FyeSBhZGRyZXNzLlxuIik7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFBlcmZvcm0gYmFzZSByZWxvY2F0aW9uLCBpZiBuZWNlc3NhcnkgKi8KICAgIGlmICggcmVsb2MgKQogICAgICAgIGRvX3JlbG9jYXRpb25zKCBsb2FkX2FkZHIsIChJTUFHRV9CQVNFX1JFTE9DQVRJT04gKilSVkEocmVsb2MpICk7CgogICAgLyogR2V0IGV4cGVjdGVkIE9TIC8gU3Vic3lzdGVtIHZlcnNpb24gKi8KICAgICp2ZXJzaW9uID0gICAoIChudC0+T3B0aW9uYWxIZWFkZXIuTWFqb3JTdWJzeXN0ZW1WZXJzaW9uICYgMHhmZikgPDwgOCApCiAgICAgICAgICAgICAgIHwgICAobnQtPk9wdGlvbmFsSGVhZGVyLk1pbm9yU3Vic3lzdGVtVmVyc2lvbiAmIDB4ZmYpOwoKICAgIC8qIFdlIGRvbid0IG5lZWQgdGhlIG9yaWduYWwgbWFwcGluZyBhbnkgbW9yZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAoSE1PRFVMRSlsb2FkX2FkZHI7CgplcnJvcjoKICAgIGlmICh1bml4X2hhbmRsZSAhPSAtMSkgY2xvc2UoIHVuaXhfaGFuZGxlICk7CiAgICBpZiAobG9hZF9hZGRyKSBWaXJ0dWFsRnJlZSggKExQVk9JRClsb2FkX2FkZHIsIDAsIE1FTV9SRUxFQVNFICk7CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wb3J0ID0gTlVMTDsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkgKnBlX3Jlc291cmNlID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIGludAlyZXN1bHQ7CgoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfaW1wb3J0ID0gKFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9yZXNvdXJjZSA9IChQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkRlYnVnIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVDsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICB3bSA9IChXSU5FX01PRFJFRiAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCp3bSkgKTsKICAgIHdtLT5tb2R1bGUgPSBoTW9kdWxlOwoKICAgIGlmICggYnVpbHRpbiApIAogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIGlmICggZmxhZ3MgJiBET05UX1JFU09MVkVfRExMX1JFRkVSRU5DRVMgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUzsKICAgIGlmICggZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFOwoKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICB3bS0+YmluZm10LnBlLnBlX2V4cG9ydCA9IHBlX2V4cG9ydDsKICAgIHdtLT5iaW5mbXQucGUucGVfaW1wb3J0ID0gcGVfaW1wb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9yZXNvdXJjZSA9IHBlX3Jlc291cmNlOwogICAgd20tPmJpbmZtdC5wZS50bHNpbmRleCA9IC0xOwoKICAgIHdtLT5maWxlbmFtZSA9IEhFQVBfc3RyZHVwQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZmlsZW5hbWUgKTsKICAgIHdtLT5tb2RuYW1lID0gc3RycmNociggd20tPmZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5tb2RuYW1lKSB3bS0+bW9kbmFtZSA9IHdtLT5maWxlbmFtZTsKICAgIGVsc2Ugd20tPm1vZG5hbWUrKzsKCiAgICByZXN1bHQgPSBHZXRTaG9ydFBhdGhOYW1lQSggd20tPmZpbGVuYW1lLCBOVUxMLCAwICk7CiAgICB3bS0+c2hvcnRfZmlsZW5hbWUgPSAoY2hhciAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVzdWx0KzEgKTsKICAgIEdldFNob3J0UGF0aE5hbWVBKCB3bS0+ZmlsZW5hbWUsIHdtLT5zaG9ydF9maWxlbmFtZSwgcmVzdWx0KzEgKTsKICAgIHdtLT5zaG9ydF9tb2RuYW1lID0gc3RycmNociggd20tPnNob3J0X2ZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5zaG9ydF9tb2RuYW1lKSB3bS0+c2hvcnRfbW9kbmFtZSA9IHdtLT5zaG9ydF9maWxlbmFtZTsKICAgIGVsc2Ugd20tPnNob3J0X21vZG5hbWUrKzsKCiAgICAvKiBMaW5rIE1PRFJFRiBpbnRvIHByb2Nlc3MgbGlzdCAqLwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKICAgIHdtLT5uZXh0ID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0OwogICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd207CiAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bTsKCiAgICBpZiAoICAgICEoIG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMICkKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRSApICkKCiAgICB7CiAgICAgICAgaWYgKCBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiApCiAgICAgICAgICAgIEZJWE1FKCAiVHJ5aW5nIHRvIGxvYWQgc2Vjb25kIC5FWEUgZmlsZTogJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiA9IHdtOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKCiAgICAvKiBEdW1wIEV4cG9ydHMgKi8KCiAgICBpZiAoIHBlX2V4cG9ydCApCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICggICAgcGVfaW1wb3J0CiAgICAgICAgICYmICEoIHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0xPQURfQVNfREFUQUZJTEUgKQogICAgICAgICAmJiAhKCB3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUyApIAogICAgICAgICAmJiBmaXh1cF9pbXBvcnRzKCB3bSApICkgCiAgICB7CiAgICAgICAgLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIGlmICggIXdtLT5wcmV2ICkKICAgICAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd20tPm5leHQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+cHJldi0+bmV4dCA9IHdtLT5uZXh0OwoKICAgICAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bS0+cHJldjsKICAgICAgICB3bS0+bmV4dCA9IHdtLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKICAgICAgICBzdHJ1Y3QgbG9hZF9kbGxfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCUhNT0RVTEUxNgloTW9kdWxlMTY7CglXSU5FX01PRFJFRgkqd207CgljaGFyICAgICAgICAJZmlsZW5hbWVbMjU2XTsKCUhBTkRMRQkJaEZpbGU7CglXT1JECQl2ZXJzaW9uID0gMDsKCgkvKiBTZWFyY2ggZm9yIGFuZCBvcGVuIFBFIGZpbGUgKi8KCWlmICggU2VhcmNoUGF0aEEoIE5VTEwsIG5hbWUsICIuRExMIiwgCgkgICAgICAgICAgICAgICAgICBzaXplb2YoZmlsZW5hbWUpLCBmaWxlbmFtZSwgTlVMTCApID09IDAgKSByZXR1cm4gTlVMTDsKICAgICAgIAoJaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgJnZlcnNpb24gKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJU2V0TGFzdEVycm9yKCBFUlJPUl9PVVRPRk1FTU9SWSApOwkvKiBOb3QgZW50aXJlbHkgcmlnaHQsIGJ1dCBnb29kIGVub3VnaCAqLwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCglpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggZmlsZW5hbWUsIGhNb2R1bGUzMiApKSA8IDMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJU2V0TGFzdEVycm9yKCAoRFdPUkQpaE1vZHVsZTE2ICk7CS8qIFRoaXMgc2hvdWxkIGdpdmUgdGhlIGNvcnJlY3QgZXJyb3IgKi8KCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIGZpbGVuYW1lLCBmbGFncywgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIGZpbGVuYW1lICk7CgkJRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlTZXRMYXN0RXJyb3IoIEVSUk9SX09VVE9GTUVNT1JZICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYgKHdtLT5iaW5mbXQucGUucGVfZXhwb3J0KQoJCVNOT09QX1JlZ2lzdGVyRExMKHdtLT5tb2R1bGUsd20tPm1vZG5hbWUsd20tPmJpbmZtdC5wZS5wZV9leHBvcnQtPk51bWJlck9mRnVuY3Rpb25zKTsKICAgICAgICByZXEtPmhhbmRsZSAgICAgPSBoRmlsZTsKICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGUzMjsKICAgICAgICByZXEtPmRiZ19vZmZzZXQgPSAwOwogICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IDA7CiAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5tb2RuYW1lOwogICAgICAgIHNlcnZlcl9jYWxsX25vZXJyKCBSRVFfTE9BRF9ETEwgKTsKICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCXJldHVybiB3bTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9VbmxvYWRMaWJyYXJ5CiAqCiAqIFVubG9hZCB0aGUgbGlicmFyeSB1bm1hcHBpbmcgdGhlIGltYWdlIGFuZCBmcmVlaW5nIHRoZSBtb2RyZWYgc3RydWN0dXJlLgogKi8Kdm9pZCBQRV9VbmxvYWRMaWJyYXJ5KFdJTkVfTU9EUkVGICp3bSkKewogICAgVFJBQ0UoIiB1bmxvYWRpbmcgJXNcbiIsIHdtLT5maWxlbmFtZSk7CiAgICBWaXJ0dWFsRnJlZSggKExQVk9JRCl3bS0+bW9kdWxlLCAwLCBNRU1fUkVMRUFTRSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5zaG9ydF9maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeEEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4QSwgYnV0IGN1cnJlbnRseSBjYW4ndAogKiBkdWUgdG8gdGhlIFBST0NFU1NfQ3JlYXRlIHN0dWZmLgogKi8KQk9PTCBQRV9DcmVhdGVQcm9jZXNzKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgTFBDU1RSIGNtZF9saW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgcHNhLCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgdHNhLAogICAgICAgICAgICAgICAgICAgICAgIEJPT0wgaW5oZXJpdCwgRFdPUkQgZmxhZ3MsIExQU1RBUlRVUElORk9BIHN0YXJ0dXAsCiAgICAgICAgICAgICAgICAgICAgICAgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiAgICBXT1JEIHZlcnNpb24gPSAwOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUgaE1vZHVsZTMyOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIC8qIExvYWQgZmlsZSAqLwogICAgaWYgKCAoaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsICZ2ZXJzaW9uICkpIDwgMzIgKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggaE1vZHVsZTMyICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQojaWYgMAogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlMzIpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggMjAgKTsgIC8qIEZJWE1FOiBub3QgdGhlIHJpZ2h0IGVycm9yIGNvZGUgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiNlbmRpZgoKICAgIC8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCiAgICBpZiAoIChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIGZpbGVuYW1lLCBoTW9kdWxlMzIgKSkgPCAzMiApIAogICAgewogICAgICAgIFNldExhc3RFcnJvciggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwoKICAgIC8qIENyZWF0ZSBuZXcgcHJvY2VzcyAqLwogICAgaWYgKCAhUFJPQ0VTU19DcmVhdGUoIHBNb2R1bGUsIGhGaWxlLCBjbWRfbGluZSwgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBzYSwgdHNhLCBpbmhlcml0LCBmbGFncywgc3RhcnR1cCwgaW5mbyApICkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogTm90ZTogUEVfQ3JlYXRlTW9kdWxlIGFuZCB0aGUgcmVtYWluaW5nIHByb2Nlc3MgaW5pdGlhbGl6YXRpb24gd2lsbAogICAgICAgICAgICAgYmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgbmV3IHByb2Nlc3MsIGluIFRBU0tfQ2FsbFRvU3RhcnQgKi8KCiAgICByZXR1cm4gVFJVRTsKfQoKCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpCT09MIFBFX0luaXRETEwoIFdJTkVfTU9EUkVGICp3bSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQgKQp7CiAgICBCT09MIHJldHYgPSBUUlVFOwogICAgYXNzZXJ0KCB3bS0+dHlwZSA9PSBNT0RVTEUzMl9QRSApOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChQRV9IRUFERVIod20tPm1vZHVsZSktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKilSVkFfUFRSKCB3bS0+bW9kdWxlLE9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgICAgICBUUkFDRV8ocmVsYXkpKCJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwoKICAgICAgICByZXR2ID0gZW50cnkoIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgIH0KCiAgICByZXR1cm4gcmV0djsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9Jbml0VGxzCQkJKGludGVybmFsKQogKgogKiBJZiBpbmNsdWRlZCwgaW5pdGlhbGlzZXMgdGhlIHRocmVhZCBsb2NhbCBzdG9yYWdlcyBvZiBtb2R1bGVzLgogKiBQb2ludGVycyBpbiB0aG9zZSBzdHJ1Y3RzIGFyZSBub3QgUlZBcyBidXQgcmVhbCBwb2ludGVycyB3aGljaCBoYXZlIGJlZW4KICogcmVsb2NhdGVkIGJ5IGRvX3JlbG9jYXRpb25zKCkgYWxyZWFkeS4KICovCnN0YXRpYyBMUFZPSUQKX2ZpeHVwX2FkZHJlc3MoUElNQUdFX09QVElPTkFMX0hFQURFUiBvcHQsaW50IGRlbHRhLExQVk9JRCBhZGRyKSB7CglpZiAoCSgoRFdPUkQpYWRkcj5vcHQtPkltYWdlQmFzZSkgJiYKCQkoKERXT1JEKWFkZHI8b3B0LT5JbWFnZUJhc2Urb3B0LT5TaXplT2ZJbWFnZSkKCSkKCQkvKiB0aGUgYWRkcmVzcyBoYXMgbm90IGJlZW4gcmVsb2NhdGVkISAqLwoJCXJldHVybiAoTFBWT0lEKSgoKERXT1JEKWFkZHIpK2RlbHRhKTsKCWVsc2UKCQkvKiB0aGUgYWRkcmVzcyBoYXMgYmVlbiByZWxvY2F0ZWQgYWxyZWFkeSAqLwoJCXJldHVybiBhZGRyOwp9CnZvaWQgUEVfSW5pdFRscyggdm9pZCApCnsKCVdJTkVfTU9EUkVGCQkqd207CglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwogICAgICAgIGludCBkZWx0YTsKCQoJZm9yICh3bSA9IFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewoJCWlmICh3bS0+dHlwZSE9TU9EVUxFMzJfUEUpCgkJCWNvbnRpbnVlOwoJCXBlbSA9ICYod20tPmJpbmZtdC5wZSk7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggcGVtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJcGVtLT50bHNpbmRleCA9IFRsc0FsbG9jKCk7CgkJCXhhZGRyID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwKCQkJCQlwZGlyLT5BZGRyZXNzT2ZJbmRleAoJCQkpOwoJCQkqeGFkZHI9cGVtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHBlbS0+dGxzaW5kZXgsIG1lbSApOwoJfQp9Cgo=