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+U2l6ZSkgJiYgcmVsLT5WaXJ0dWFsQWRkcmVzczsKICAgICAgICAgIHJlbCA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopcmVsICsgcmVsLT5TaXplT2ZCbG9jaykpCiAgICB7CiAgICAgICAgY2hhciAqcGFnZSA9IGJhc2UgKyByZWwtPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGludCBpLCBjb3VudCA9IChyZWwtPlNpemVPZkJsb2NrIC0gOCkgLyBzaXplb2YocmVsLT5UeXBlT2Zmc2V0KTsKCiAgICAgICAgaWYgKCFjb3VudCkgY29udGludWU7CgogICAgICAgIC8qIHNhbml0eSBjaGVja3MgKi8KICAgICAgICBpZiAoKGNoYXIgKilyZWwgKyByZWwtPlNpemVPZkJsb2NrID4gYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MgKyBkaXItPlNpemUgfHwKICAgICAgICAgICAgcGFnZSA+IGJhc2UgKyBudC0+T3B0aW9uYWxIZWFkZXIuU2l6ZU9mSW1hZ2UpCiAgICAgICAgewogICAgICAgICAgICBFUlJfKG1vZHVsZSkoImludmFsaWQgcmVsb2NhdGlvbiAlcCwlbHgsJWxkIGF0ICVwLCVseCwlbHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICByZWwsIHJlbC0+VmlydHVhbEFkZHJlc3MsIHJlbC0+U2l6ZU9mQmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlLCBkaXItPlZpcnR1YWxBZGRyZXNzLCBkaXItPlNpemUgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBUUkFDRV8obW9kdWxlKSgiJWxkIHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwgcmVsLT5TaXplT2ZCbG9jaywgcmVsLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgICAgIC8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpbnQgb2Zmc2V0ID0gcmVsLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CiAgICAgICAgICAgIGludCB0eXBlID0gcmVsLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwogICAgICAgICAgICBzd2l0Y2godHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURToKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgogICAgICAgICAgICAgICAgKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBISVdPUkQoZGVsdGEpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKICAgICAgICAgICAgICAgICooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gTE9XT1JEKGRlbHRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgogICAgICAgICAgICAgICAgKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiAgICAgICAgICAgICAgICAvKiBGSVhNRTogaWYgdGhpcyBpcyBhbiBleHBvcnRlZCBhZGRyZXNzLCBmaXJlIHVwIGVuaGFuY2VkIGxvZ2ljICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FXyhtb2R1bGUpKCJVbmtub3duL3Vuc3VwcG9ydGVkIGZpeHVwIHR5cGUgJWQuXG4iLCB0eXBlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKiAKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IgCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0cyB3aGljaCBhcmUgcGFnZS1hbGlnbmVkLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRSBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncyApCnsKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSE1PRFVMRSBoTW9kdWxlOwogICAgSEFORExFIG1hcHBpbmc7CiAgICB2b2lkICpiYXNlOwoKICAgIFRSQUNFXyhtb2R1bGUpKCAibG9hZGluZyAlc1xuIiwgZmlsZW5hbWUgKTsKCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmdBKCBoRmlsZSwgTlVMTCwgU0VDX0lNQUdFLCAwLCAwLCBOVUxMICk7CiAgICBpZiAoIW1hcHBpbmcpIHJldHVybiAwOwogICAgYmFzZSA9IE1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWJhc2UpIHJldHVybiAwOwoKICAgIGhNb2R1bGUgPSAoSE1PRFVMRSliYXNlOwogICAgaWYgKGZsYWdzICYgTE9BRF9MSUJSQVJZX0FTX0RBVEFGSUxFKSByZXR1cm4gaE1vZHVsZTsgIC8qIG5vdGhpbmcgZWxzZSB0byBkbyAqLwoKICAgIC8qIHBlcmZvcm0gYmFzZSByZWxvY2F0aW9uLCBpZiBuZWNlc3NhcnkgKi8KCiAgICBudCA9IFBFX0hFQURFUiggaE1vZHVsZSApOwogICAgaWYgKGhNb2R1bGUgIT0gbnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSkKICAgIHsKICAgICAgICBpZiAoIWRvX3JlbG9jYXRpb25zKCBiYXNlLCBudCwgZmlsZW5hbWUgKSkKICAgICAgICB7CiAgICAgICAgICAgIFVubWFwVmlld09mRmlsZSggYmFzZSApOwogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB2aXJ1cyBjaGVjayAqLwoKICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgIHsKICAgICAgICBpbnQgaTsKICAgICAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqc2VjID0gKElNQUdFX1NFQ1RJT05fSEVBREVSKikoKGNoYXIqKSZudC0+T3B0aW9uYWxIZWFkZXIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudC0+RmlsZUhlYWRlci5TaXplT2ZPcHRpb25hbEhlYWRlcik7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKywgc2VjKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgPCBzZWMtPlZpcnR1YWxBZGRyZXNzKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCA8IHNlYy0+VmlydHVhbEFkZHJlc3Mrc2VjLT5TaXplT2ZSYXdEYXRhKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChpID09IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnMpCiAgICAgICAgICAgIE1FU1NBR0UoIlZJUlVTIFdBUk5JTkc6IFBFIG1vZHVsZSBoYXMgYW4gaW52YWxpZCBlbnRyeXBvaW50ICgweCUwOGx4KSAiCiAgICAgICAgICAgICAgICAgICAgIm91dHNpZGUgYWxsIHNlY3Rpb25zIChwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgIH0KCiAgICByZXR1cm4gaE1vZHVsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRTMyLCBsaW5rIGl0IGludG8KICogcHJvY2VzcyBtb2RyZWZfbGlzdCwgYW5kIGZpeHVwIGFsbCBpbXBvcnRzLgogKgogKiBOb3RlOiBoTW9kdWxlIG11c3QgcG9pbnQgdG8gYSBjb3JyZWN0bHkgYWxsb2NhdGVkIFBFIGltYWdlLAogKiAgICAgICB3aXRoIGJhc2UgcmVsb2NhdGlvbnMgYXBwbGllZDsgdGhlIDE2LWJpdCBkdW1teSBtb2R1bGUKICogICAgICAgYXNzb2NpYXRlZCB0byBoTW9kdWxlIG11c3QgYWxyZWFkeSBleGlzdC4KICoKICogTm90ZTogVGhpcyByb3V0aW5lIG11c3QgYWx3YXlzIGJlIGNhbGxlZCBpbiB0aGUgY29udGV4dCBvZiB0aGUKICogICAgICAgcHJvY2VzcyB0aGF0IGlzIHRvIG93biB0aGUgbW9kdWxlIHRvIGJlIGNyZWF0ZWQuCiAqCiAqIE5vdGU6IEFzc3VtZXMgdGhhdCB0aGUgcHJvY2VzcyBjcml0aWNhbCBzZWN0aW9uIGlzIGhlbGQKICovCldJTkVfTU9EUkVGICpQRV9DcmVhdGVNb2R1bGUoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFIGhGaWxlLCBCT09MIGJ1aWx0aW4gKQp7CiAgICBEV09SRCBsb2FkX2FkZHIgPSAoRFdPUkQpaE1vZHVsZTsgIC8qIGZvciBSVkEgKi8KICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUEVfSEVBREVSKGhNb2R1bGUpOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBXSU5FX01PRFJFRiAqd207CiAgICBITU9EVUxFMTYgaE1vZHVsZTE2OwoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFk7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DIGhhbmRsZWQgaW4gUEVfTG9hZEltYWdlICovCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUcgaGFuZGxlZCBieSBkZWJ1Z2dlciAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFI7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTIGhhbmRsZWQgaW4gUEVfVGxzSW5pdCAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJRzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVMQVlfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgIHsKCQlUUkFDRSgiRGVsYXllZCBpbXBvcnQsIHN0dWIgY2FsbHMgTG9hZExpYnJhcnlcbiIgKTsKCQkvKgoJCSAqIE5vdGhpbmcgdG8gZG8gaGVyZS4KCQkgKi8KCiNpZmRlZiBJbWdEZWxheURlc2NyCgkJLyoKCQkgKiBUaGlzIGNvZGUgaXMgdXNlZnVsIHRvIG9ic2VydmUgd2hhdCB0aGUgaGVjayBpcyBnb2luZyBvbi4KCQkgKi8KCQl7CgkJSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgIHBlX2RlbGF5ID0gKFBJbWdEZWxheURlc2NyKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+c3pOYW1lID0gJXNcbiIsIHBlX2RlbGF5LT5zek5hbWUpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5waG1vZCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5waG1vZCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJTlQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElOVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBCb3VuZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wQm91bmRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5kd1RpbWVTdGFtcCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5kd1RpbWVTdGFtcCk7CiAgICAgICAgfQojZW5kaWYgLyogSW1nRGVsYXlEZXNjciAqLwoJfQoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT01fREVTQ1JJUFRPUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrMTU7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIiApOwoKICAgIC8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCgogICAgaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIGZpbGVuYW1lLCBoTW9kdWxlICkpIDwgMzIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCAoRFdPUkQpaE1vZHVsZTE2ICk7CS8qIFRoaXMgc2hvdWxkIGdpdmUgdGhlIGNvcnJlY3QgZXJyb3IgKi8KICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBBbGxvY2F0ZSBhbmQgZmlsbCBXSU5FX01PRFJFRiAqLwoKICAgIGlmICghKHdtID0gTU9EVUxFX0FsbG9jTW9kUmVmKCBoTW9kdWxlLCBmaWxlbmFtZSApKSkKICAgIHsKICAgICAgICBGcmVlTGlicmFyeTE2KCBoTW9kdWxlMTYgKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHdtLT5oRHVtbXlNb2QgPSBoTW9kdWxlMTY7CgogICAgaWYgKCBidWlsdGluICkgCiAgICB7CiAgICAgICAgTkVfTU9EVUxFICpwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcE1vZHVsZS0+ZmxhZ3MgfD0gTkVfRkZMQUdTX0JVSUxUSU47CiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0lOVEVSTkFMOwogICAgfQogICAgZWxzZSBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgd20tPmZpbmRfZXhwb3J0ID0gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb247CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKCBwZV9leHBvcnQgKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIEZpeHVwIEltcG9ydHMgKi8KCiAgICBpZiAoISh3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUykgJiYKICAgICAgICBQRV9maXh1cF9pbXBvcnRzKCB3bSApKQogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwoKICAgICAgICBpZiAoICF3bS0+cHJldiApCiAgICAgICAgICAgIE1PRFVMRV9tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPnByZXYtPm5leHQgPSB3bS0+bmV4dDsKCiAgICAgICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd20tPnByZXY7CiAgICAgICAgd20tPm5leHQgPSB3bS0+cHJldiA9IE5VTEw7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKCFidWlsdGluICYmIHBlX2V4cG9ydCkKICAgICAgICBTTk9PUF9SZWdpc3RlckRMTCggaE1vZHVsZSwgd20tPm1vZG5hbWUsIHBlX2V4cG9ydC0+QmFzZSwgcGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyApOwoKICAgIC8qIFNlbmQgRExMIGxvYWQgZXZlbnQgKi8KICAgIC8qIHdlIGRvbid0IG5lZWQgdG8gc2VuZCBhIGRsbCBldmVudCBmb3IgdGhlIG1haW4gZXhlICovCgogICAgaWYgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfZGxsICkKICAgICAgICB7CiAgICAgICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX29mZnNldCA9IG50LT5GaWxlSGVhZGVyLlBvaW50ZXJUb1N5bWJvbFRhYmxlOwogICAgICAgICAgICByZXEtPmRiZ19zaXplICAgPSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlN5bWJvbHM7CiAgICAgICAgICAgIHJlcS0+bmFtZSAgICAgICA9ICZ3bS0+ZmlsZW5hbWU7CiAgICAgICAgICAgIFNFUlZFUl9DQUxMKCk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCldJTkVfTU9EUkVGICpQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzKQp7CglITU9EVUxFCQloTW9kdWxlMzI7CglXSU5FX01PRFJFRgkqd207CglIQU5ETEUJCWhGaWxlOwogICAgICAgCgloRmlsZSA9IENyZWF0ZUZpbGVBKCBuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBmbGFncyApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIG5hbWUsIGZsYWdzLCBoRmlsZSwgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KdHlwZWRlZiBEV09SRCBDQUxMQkFDSygqRExMRU5UUllQUk9DKShITU9EVUxFLERXT1JELExQVk9JRCk7CgpCT09MIFBFX0luaXRETEwoIEhNT0RVTEUgbW9kdWxlLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihtb2R1bGUpOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpKQogICAgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKikoKGNoYXIqKW1vZHVsZSArIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpDYWxsIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRUaHJlYWRJZCgpLCBlbnRyeSwgbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgcmV0diA9IGVudHJ5KCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpSZXQgIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApIHJldHZhbD0leFxuIiwKICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50VGhyZWFkSWQoKSwgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCwgcmV0diApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCVBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CiAgICAgICAgaW50IGRlbHRhOwoJCglmb3IgKHdtID0gTU9EVUxFX21vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggd20tPnRsc2luZGV4ID09IC0xICkgewoJCQlMUERXT1JEIHhhZGRyOwoJCQl3bS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXdtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0KCg==