LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgUEVfZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTCh3aW4zMik7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChkZWxheWhscCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChmaXh1cCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2VnbWVudCk7CgoKc3RhdGljIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmdldF9leHBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqKSgoY2hhciAqKWhtb2QgKyBkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqZ2V0X2ltcG9ydHMoIEhNT0RVTEUgaG1vZCApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh2b2lkICopKChjaGFyICopbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKSkKCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgV09SRAkJKm9yZGluYWw7CiAgRFdPUkQJCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIEJZVEUJCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSgiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0UoIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAogICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsID0gUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zID0gZnVuY3Rpb24gPSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lID0gUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0UoIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKQogICAgICB7CglEUFJJTlRGKCAiJTRsZCAlMDhseCAlcCIsIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCURQUklOVEYoIlxuIik7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnQgbGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIG5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYW4gb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9uIGxpc3QKICovCnN0YXRpYyBGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCAKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBCT09MIHNub29wICkKewoJV09SRAkJCQkqIG9yZGluYWxzOwoJRFdPUkQJCQkJKiBmdW5jdGlvbjsKCUJZVEUJCQkJKiogbmFtZSwgKmVuYW1lID0gTlVMTDsKCWludAkJCQlpLCBvcmRpbmFsOwoJdW5zaWduZWQgaW50CQkJbG9hZF9hZGRyID0gd20tPm1vZHVsZTsKCURXT1JECQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqZXhwb3J0cyA9IGdldF9leHBvcnRzKHdtLT5tb2R1bGUpOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFKCIoJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlUUkFDRSgiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTigiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWxzPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBmaXJzdCB0cnkgYSBiaW5hcnkgc2VhcmNoICovCiAgICAgICAgICAgIGludCBtaW4gPSAwLCBtYXggPSBleHBvcnRzLT5OdW1iZXJPZk5hbWVzIC0gMTsKICAgICAgICAgICAgd2hpbGUgKG1pbiA8PSBtYXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCByZXMsIHBvcyA9IChtaW4gKyBtYXgpIC8gMjsKICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbcG9zXSk7CiAgICAgICAgICAgICAgICBpZiAoIShyZXMgPSBzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbcG9zXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHJlcyA+IDApIG1heCA9IHBvcyAtIDE7CiAgICAgICAgICAgICAgICBlbHNlIG1pbiA9IHBvcyArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogbm93IHRyeSBhIGxpbmVhciBzZWFyY2ggaW4gY2FzZSB0aGUgbmFtZXMgYXJlbid0IHNvcnRlZCBwcm9wZXJseSAqLwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoICIlcy4lcyByZXF1aXJlZCBhIGxpbmVhciBzZWFyY2hcbiIsIHdtLT5tb2RuYW1lLCBmdW5jTmFtZSApOwogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1tpXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBOVUxMOwoJfQogICAgICAgIGVsc2UgIC8qIGZpbmQgYnkgb3JkaW5hbCAqLwogICAgICAgIHsKICAgICAgICAgICAgb3JkaW5hbCA9IExPV09SRChmdW5jTmFtZSkgLSBleHBvcnRzLT5CYXNlOwogICAgICAgICAgICBpZiAoc25vb3AgJiYgbmFtZSkgIC8qIG5lZWQgdG8gZmluZCBhIG5hbWUgZm9yIGl0ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgaWYgKG9yZGluYWxzW2ldID09IG9yZGluYWwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9Cgl9CgogZm91bmQ6CiAgICAgICAgaWYgKG9yZGluYWwgPj0gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiCW9yZGluYWwgJWxkIG91dCBvZiByYW5nZSFcbiIsIG9yZGluYWwgKyBleHBvcnRzLT5CYXNlICk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBhZGRyID0gZnVuY3Rpb25bb3JkaW5hbF07CiAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICBpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQogICAgICAgIHsKICAgICAgICAgICAgRkFSUFJPQyBwcm9jID0gUlZBKGFkZHIpOwogICAgICAgICAgICBpZiAoc25vb3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZW5hbWUpIGVuYW1lID0gIkAiOwogICAgICAgICAgICAgICAgcHJvYyA9IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsb3JkaW5hbCxwcm9jKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvYzsKICAgICAgICB9CiAgICAgICAgZWxzZSAgLyogZm9yd2FyZCBlbnRyeSBwb2ludCAqLwogICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfTU9EUkVGICp3bV9mdzsKICAgICAgICAgICAgICAgIEZBUlBST0MgcHJvYzsKICAgICAgICAgICAgICAgIGNoYXIgKmZvcndhcmQgPSBSVkEoYWRkcik7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgaWYgKGVuZCAtIGZvcndhcmQgPj0gc2l6ZW9mKG1vZHVsZSkpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtY3B5KCBtb2R1bGUsIGZvcndhcmQsIGVuZCAtIGZvcndhcmQgKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGlmICghKHdtX2Z3ID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG1vZHVsZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm1vZHVsZSBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJyB1c2VkIGJ5ICclcydcbiIsIGZvcndhcmQsIHdtLT5tb2RuYW1lICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJaWYgKCEocHJvYyA9IE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd21fZnctPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKSkpCiAgICAgICAgICAgICAgICAgICAgRVJSKCJmdW5jdGlvbiBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJyB1c2VkIGJ5ICclcycuIElmIHlvdSBhcmUgdXNpbmcgYnVpbHRpbiAnJXMnLCB0cnkgdXNpbmcgdGhlIG5hdGl2ZSBvbmUgaW5zdGVhZC5cbiIsIGZvcndhcmQsIHdtLT5tb2RuYW1lLCB3bS0+bW9kbmFtZSApOwoJCXJldHVybiBwcm9jOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJUEVfZml4dXBfaW1wb3J0cwogKi8KRFdPUkQgUEVfZml4dXBfaW1wb3J0cyggV0lORV9NT0RSRUYgKndtICkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmltcG9ydHMgPSBnZXRfaW1wb3J0cyh3bS0+bW9kdWxlKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gaW1wb3J0czsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIFdlIGFzc3VtZSB0aGF0IHdlIGhhdmUgYXQgbGVhc3Qgb25lIGltcG9ydCB3aXRoICEwIGNoYXJhY3RlcmlzdGljcyBhbmQKICAgICAqIGRldGVjdCBicm9rZW4gaW1wb3J0cyB3aXRoIGFsbCBjaGFyYWN0ZXJpc3RpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gaW1wb3J0czsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlXSU5FX01PRFJFRgkJKndtSW1wOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwogCWNoYXIJCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CgkgICAgRVJSXyhtb2R1bGUpKCJNb2R1bGUgKGZpbGUpICVzICh3aGljaCBpcyBuZWVkZWQgYnkgJXMpIG5vdCBmb3VuZFxuIiwgbmFtZSwgd20tPmZpbGVuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB3bS0+ZGVwc1tpKytdID0gd21JbXA7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpb3JkaW5hbCwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIG9yZGluYWwsIHdtLT5maWxlbmFtZSApOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcykgaW1wb3J0ZWQgZnJvbSAlcywgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUsd20tPmZpbGVuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKCJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMuJWRcbiIsbmFtZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLG9yZGluYWwsIHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIHBlX25hbWUtPkhpbnQsIHBlX25hbWUtPk5hbWUsIHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBkb19yZWxvY2F0aW9ucwogKgogKiBBcHBseSB0aGUgcmVsb2NhdGlvbnMgdG8gYSBtYXBwZWQgUEUgaW1hZ2UKICovCnN0YXRpYyBpbnQgZG9fcmVsb2NhdGlvbnMoIGNoYXIgKmJhc2UsIGNvbnN0IElNQUdFX05UX0hFQURFUlMgKm50LCBjb25zdCBjaGFyICpmaWxlbmFtZSApCnsKICAgIGNvbnN0IElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBjb25zdCBJTUFHRV9CQVNFX1JFTE9DQVRJT04gKnJlbDsKICAgIGludCBkZWx0YSA9IGJhc2UgLSAoY2hhciAqKW50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgogICAgZGlyID0gJm50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwogICAgcmVsID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiAqKShiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgV0FSTigiSW5mbzogYmFzZSByZWxvY2F0aW9ucyBuZWVkZWQgZm9yICVzXG4iLCBmaWxlbmFtZSk7CiAgICBpZiAoIWRpci0+VmlydHVhbEFkZHJlc3MgfHwgIWRpci0+U2l6ZSkKICAgIHsKICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSA9PSAweDQwMDAwMCkKICAgICAgICAgICAgRVJSKCJTdGFuZGFyZCBsb2FkIGFkZHJlc3MgZm9yIGEgV2luMzIgcHJvZ3JhbSAoMHgwMDQwMDAwMCkgbm90IGF2YWlsYWJsZSAtIHNlY3VyaXR5LXBhdGNoZWQga2VybmVsID9cbiIpOwogICAgICAgIEVSUiggIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgIGZpbGVuYW1lLAogICAgICAgICAgICAgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyZJTUFHRV9GSUxFX1JFTE9DU19TVFJJUFBFRCk/CiAgICAgICAgICAgICAic3RyaXBwZWQgZHVyaW5nIGxpbmsiIDogInVua25vd24gcmVhc29uIiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qIEZJWE1FOiBJZiB3ZSBuZWVkIHRvIHJlbG9jYXRlIGEgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikgd2Ugc2hvdWxkCiAgICAgKiAgICAgICAgcmVhbGx5IG1ha2Ugc3VyZSB0aGF0IHRoZSAqbmV3KiBiYXNlIGFkZHJlc3MgaXMgYWxzbyA+IDJHQi4KICAgICAqICAgICAgICBTb21lIERMTHMgcmVhbGx5IGNoZWNrIHRoZSBNU0Igb2YgdGhlIG1vZHVsZSBoYW5kbGUgOi0vCiAgICAgKi8KICAgIGlmICgobnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSAmIDB4ODAwMDAwMDApICYmICEoKERXT1JEKWJhc2UgJiAweDgwMDAwMDAwKSkKICAgICAgICBFUlIoICJGb3JjZWQgdG8gcmVsb2NhdGUgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikuIFRoaXMgaXMgbm90IGdvb2QuXG4iICk7CgogICAgZm9yICggOyAoKGNoYXIgKilyZWwgPCBiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyArIGRpci0+U2l6ZSkgJiYgcmVsLT5TaXplT2ZCbG9jazsKICAgICAgICAgIHJlbCA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopcmVsICsgcmVsLT5TaXplT2ZCbG9jaykpCiAgICB7CiAgICAgICAgY2hhciAqcGFnZSA9IGJhc2UgKyByZWwtPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIFdPUkQgKlR5cGVPZmZzZXQgPSAoV09SRCAqKShyZWwgKyAxKTsKICAgICAgICBpbnQgaSwgY291bnQgPSAocmVsLT5TaXplT2ZCbG9jayAtIHNpemVvZigqcmVsKSkgLyBzaXplb2YoKlR5cGVPZmZzZXQpOwoKICAgICAgICBpZiAoIWNvdW50KSBjb250aW51ZTsKCiAgICAgICAgLyogc2FuaXR5IGNoZWNrcyAqLwogICAgICAgIGlmICgoY2hhciAqKXJlbCArIHJlbC0+U2l6ZU9mQmxvY2sgPiBiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyArIGRpci0+U2l6ZSB8fAogICAgICAgICAgICBwYWdlID4gYmFzZSArIG50LT5PcHRpb25hbEhlYWRlci5TaXplT2ZJbWFnZSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUl8obW9kdWxlKSgiaW52YWxpZCByZWxvY2F0aW9uICVwLCVseCwlbGQgYXQgJXAsJWx4LCVseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlbCwgcmVsLT5WaXJ0dWFsQWRkcmVzcywgcmVsLT5TaXplT2ZCbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UsIGRpci0+VmlydHVhbEFkZHJlc3MsIGRpci0+U2l6ZSApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIFRSQUNFXyhtb2R1bGUpKCIlbGQgcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLCByZWwtPlNpemVPZkJsb2NrLCByZWwtPlZpcnR1YWxBZGRyZXNzKTsKCiAgICAgICAgLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwogICAgICAgIGZvciAoaSA9IDAgOyBpIDwgY291bnQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGludCBvZmZzZXQgPSBUeXBlT2Zmc2V0W2ldICYgMHhGRkY7CiAgICAgICAgICAgIGludCB0eXBlID0gVHlwZU9mZnNldFtpXSA+PiAxMjsKICAgICAgICAgICAgc3dpdGNoKHR5cGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKICAgICAgICAgICAgICAgICooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gSElXT1JEKGRlbHRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CiAgICAgICAgICAgICAgICAqKHNob3J0KikocGFnZStvZmZzZXQpICs9IExPV09SRChkZWx0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKICAgICAgICAgICAgICAgICooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwogICAgICAgICAgICAgICAgLyogRklYTUU6IGlmIHRoaXMgaXMgYW4gZXhwb3J0ZWQgYWRkcmVzcywgZmlyZSB1cCBlbmhhbmNlZCBsb2dpYyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRV8obW9kdWxlKSgiVW5rbm93bi91bnN1cHBvcnRlZCBmaXh1cCB0eXBlICVkLlxuIiwgdHlwZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiBpdCkKICovCkhNT0RVTEUgUEVfTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudDsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIEhBTkRMRSBtYXBwaW5nOwogICAgdm9pZCAqYmFzZTsKCiAgICBUUkFDRV8obW9kdWxlKSggImxvYWRpbmcgJXNcbiIsIGZpbGVuYW1lICk7CgogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nQSggaEZpbGUsIE5VTEwsIFNFQ19JTUFHRSwgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKSByZXR1cm4gMDsKICAgIGJhc2UgPSBNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFiYXNlKSByZXR1cm4gMDsKCiAgICBoTW9kdWxlID0gKEhNT0RVTEUpYmFzZTsKICAgIGlmIChmbGFncyAmIExPQURfTElCUkFSWV9BU19EQVRBRklMRSkgcmV0dXJuIGhNb2R1bGU7ICAvKiBub3RoaW5nIGVsc2UgdG8gZG8gKi8KCiAgICAvKiBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCgogICAgbnQgPSBQRV9IRUFERVIoIGhNb2R1bGUgKTsKICAgIGlmIChoTW9kdWxlICE9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UpCiAgICB7CiAgICAgICAgaWYgKCFkb19yZWxvY2F0aW9ucyggYmFzZSwgbnQsIGZpbGVuYW1lICkpCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIGJhc2UgKTsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgLyogdmlydXMgY2hlY2sgKi8KCiAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICB7CiAgICAgICAgaW50IGk7CiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnNlYyA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKChjaGFyKikmbnQtPk9wdGlvbmFsSGVhZGVyICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnQtPkZpbGVIZWFkZXIuU2l6ZU9mT3B0aW9uYWxIZWFkZXIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHNlYysrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50IDwgc2VjLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgPCBzZWMtPlZpcnR1YWxBZGRyZXNzK3NlYy0+U2l6ZU9mUmF3RGF0YSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zKQogICAgICAgICAgICBNRVNTQUdFKCJWSVJVUyBXQVJOSU5HOiBQRSBtb2R1bGUgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICJvdXRzaWRlIGFsbCBzZWN0aW9ucyAocG9zc2libHkgaW5mZWN0ZWQgYnkgVGNoZXJub2J5bC9TcGFjZUZpbGxlciB2aXJ1cykhXG4iLAogICAgICAgICAgICAgICAgICAgIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICB9CgogICAgcmV0dXJuIGhNb2R1bGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKgogKiBOb3RlOiBBc3N1bWVzIHRoYXQgdGhlIHByb2Nlc3MgY3JpdGljYWwgc2VjdGlvbiBpcyBoZWxkCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9leHBvcnQgPSAoUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZSApKSA8IDMyKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpCiAgICB7CiAgICAgICAgRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB3bS0+aER1bW15TW9kID0gaE1vZHVsZTE2OwoKICAgIGlmICggYnVpbHRpbiApIAogICAgewogICAgICAgIE5FX01PRFVMRSAqcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgICAgIHBNb2R1bGUtPmZsYWdzIHw9IE5FX0ZGTEFHU19CVUlMVElOOwogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIH0KICAgIGVsc2UgaWYgKCBmbGFncyAmIERPTlRfUkVTT0xWRV9ETExfUkVGRVJFTkNFUyApCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTOwoKICAgIHdtLT5maW5kX2V4cG9ydCA9IFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uOwoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmICggcGVfZXhwb3J0ICkKICAgICAgICBkdW1wX2V4cG9ydHMoIGhNb2R1bGUgKTsKCiAgICAvKiBGaXh1cCBJbXBvcnRzICovCgogICAgaWYgKCEod20tPmZsYWdzICYgV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlMpICYmCiAgICAgICAgUEVfZml4dXBfaW1wb3J0cyggd20gKSkKICAgIHsKICAgICAgICAvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KCiAgICAgICAgaWYgKCAhd20tPnByZXYgKQogICAgICAgICAgICBNT0RVTEVfbW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5wcmV2LT5uZXh0ID0gd20tPm5leHQ7CgogICAgICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtLT5wcmV2OwogICAgICAgIHdtLT5uZXh0ID0gd20tPnByZXYgPSBOVUxMOwoKICAgICAgICAvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCiAgICAgICAgICogbGVmdC4gSW5jbHVkaW5nIGRsbHMgbG9hZGVkIGJ5IHRoaXMgZGxsIGJlZm9yZSB0aGUKICAgICAgICAgKiBmYWlsZWQgb25lLiBVbnJvbGxpbmcgaXMgcmF0aGVyIGRpZmZpY3VsdCB3aXRoIHRoZQogICAgICAgICAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwogICAgICAgICAqIGFyb3VuZCB3aXRoIG5vIHByb2JsZW1zLCBzbyB3ZSBkb24ndCBjYXJlLgogICAgICAgICAqIEFzIHRoZXNlIG1pZ2h0IHJlZmVyZW5jZSBvdXIgd20sIHdlIGRvbid0IGZyZWUgaXQuCiAgICAgICAgICovCiAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICghYnVpbHRpbiAmJiBwZV9leHBvcnQpCiAgICAgICAgU05PT1BfUmVnaXN0ZXJETEwoIGhNb2R1bGUsIHdtLT5tb2RuYW1lLCBwZV9leHBvcnQtPkJhc2UsIHBlX2V4cG9ydC0+TnVtYmVyT2ZGdW5jdGlvbnMgKTsKCiAgICAvKiBTZW5kIERMTCBsb2FkIGV2ZW50ICovCiAgICAvKiB3ZSBkb24ndCBuZWVkIHRvIHNlbmQgYSBkbGwgZXZlbnQgZm9yIHRoZSBtYWluIGV4ZSAqLwoKICAgIGlmIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBpZiAoaEZpbGUpCiAgICAgICAgewogICAgICAgICAgICBVSU5UIGRyaXZlX3R5cGUgPSBHZXREcml2ZVR5cGVBKCB3bS0+c2hvcnRfZmlsZW5hbWUgKTsKICAgICAgICAgICAgLyogZG9uJ3Qga2VlcCB0aGUgZmlsZSBoYW5kbGUgb3BlbiBvbiByZW1vdmFibGUgbWVkaWEgKi8KICAgICAgICAgICAgaWYgKGRyaXZlX3R5cGUgPT0gRFJJVkVfUkVNT1ZBQkxFIHx8IGRyaXZlX3R5cGUgPT0gRFJJVkVfQ0RST00pIGhGaWxlID0gMDsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9kbGwgKQogICAgICAgIHsKICAgICAgICAgICAgcmVxLT5oYW5kbGUgICAgID0gaEZpbGU7CiAgICAgICAgICAgIHJlcS0+YmFzZSAgICAgICA9ICh2b2lkICopaE1vZHVsZTsKICAgICAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gbnQtPkZpbGVIZWFkZXIuUG9pbnRlclRvU3ltYm9sVGFibGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU3ltYm9sczsKICAgICAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5maWxlbmFtZTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfY2FsbCggcmVxICk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCldJTkVfTU9EUkVGICpQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzKQp7CglITU9EVUxFCQloTW9kdWxlMzI7CglXSU5FX01PRFJFRgkqd207CglIQU5ETEUJCWhGaWxlOwogICAgICAgCgloRmlsZSA9IENyZWF0ZUZpbGVBKCBuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBmbGFncyApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIG5hbWUsIGZsYWdzLCBoRmlsZSwgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KdHlwZWRlZiBEV09SRCBDQUxMQkFDSygqRExMRU5UUllQUk9DKShITU9EVUxFLERXT1JELExQVk9JRCk7CgpCT09MIFBFX0luaXRETEwoIEhNT0RVTEUgbW9kdWxlLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihtb2R1bGUpOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpKQogICAgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKikoKGNoYXIqKW1vZHVsZSArIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpDYWxsIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRUaHJlYWRJZCgpLCBlbnRyeSwgbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgcmV0diA9IGVudHJ5KCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpSZXQgIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApIHJldHZhbD0leFxuIiwKICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50VGhyZWFkSWQoKSwgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCwgcmV0diApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCVBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CiAgICAgICAgaW50IGRlbHRhOwoJCglmb3IgKHdtID0gTU9EVUxFX21vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggd20tPnRsc2luZGV4ID09IC0xICkgewoJCQlMUERXT1JEIHhhZGRyOwoJCQl3bS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXdtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0KCg==