LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgUEVfZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTCh3aW4zMik7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChkZWxheWhscCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChmaXh1cCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2VnbWVudCk7CgoKc3RhdGljIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmdldF9leHBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqKSgoY2hhciAqKWhtb2QgKyBkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqZ2V0X2ltcG9ydHMoIEhNT0RVTEUgaG1vZCApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh2b2lkICopKChjaGFyICopbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKSkKCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgV09SRAkJKm9yZGluYWw7CiAgRFdPUkQJCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIEJZVEUJCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSgiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0UoIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAogICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsID0gUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zID0gZnVuY3Rpb24gPSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lID0gUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0UoIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKQogICAgICB7CglEUFJJTlRGKCAiJTRsZCAlMDhseCAlcCIsIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCURQUklOVEYoIlxuIik7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnQgbGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIG5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYW4gb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9uIGxpc3QKICovCnN0YXRpYyBGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCAKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBCT09MIHNub29wICkKewoJV09SRAkJCQkqIG9yZGluYWxzOwoJRFdPUkQJCQkJKiBmdW5jdGlvbjsKCUJZVEUJCQkJKiogbmFtZSwgKmVuYW1lID0gTlVMTDsKCWludAkJCQlpLCBvcmRpbmFsOwoJdW5zaWduZWQgaW50CQkJbG9hZF9hZGRyID0gd20tPm1vZHVsZTsKCURXT1JECQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqZXhwb3J0cyA9IGdldF9leHBvcnRzKHdtLT5tb2R1bGUpOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFKCIoJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlUUkFDRSgiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTigiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWxzPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBmaXJzdCB0cnkgYSBiaW5hcnkgc2VhcmNoICovCiAgICAgICAgICAgIGludCBtaW4gPSAwLCBtYXggPSBleHBvcnRzLT5OdW1iZXJPZk5hbWVzIC0gMTsKICAgICAgICAgICAgd2hpbGUgKG1pbiA8PSBtYXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCByZXMsIHBvcyA9IChtaW4gKyBtYXgpIC8gMjsKICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbcG9zXSk7CiAgICAgICAgICAgICAgICBpZiAoIShyZXMgPSBzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbcG9zXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHJlcyA+IDApIG1heCA9IHBvcyAtIDE7CiAgICAgICAgICAgICAgICBlbHNlIG1pbiA9IHBvcyArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogbm93IHRyeSBhIGxpbmVhciBzZWFyY2ggaW4gY2FzZSB0aGUgbmFtZXMgYXJlbid0IHNvcnRlZCBwcm9wZXJseSAqLwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoICIlcy4lcyByZXF1aXJlZCBhIGxpbmVhciBzZWFyY2hcbiIsIHdtLT5tb2RuYW1lLCBmdW5jTmFtZSApOwogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1tpXTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGZvdW5kOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBOVUxMOwoJfQogICAgICAgIGVsc2UgIC8qIGZpbmQgYnkgb3JkaW5hbCAqLwogICAgICAgIHsKICAgICAgICAgICAgb3JkaW5hbCA9IExPV09SRChmdW5jTmFtZSkgLSBleHBvcnRzLT5CYXNlOwogICAgICAgICAgICBpZiAoc25vb3AgJiYgbmFtZSkgIC8qIG5lZWQgdG8gZmluZCBhIG5hbWUgZm9yIGl0ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgaWYgKG9yZGluYWxzW2ldID09IG9yZGluYWwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9Cgl9CgogZm91bmQ6CiAgICAgICAgaWYgKG9yZGluYWwgPj0gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiCW9yZGluYWwgJWxkIG91dCBvZiByYW5nZSFcbiIsIG9yZGluYWwgKyBleHBvcnRzLT5CYXNlICk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBhZGRyID0gZnVuY3Rpb25bb3JkaW5hbF07CiAgICAgICAgaWYgKCFhZGRyKSByZXR1cm4gTlVMTDsKICAgICAgICBpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQogICAgICAgIHsKICAgICAgICAgICAgRkFSUFJPQyBwcm9jID0gUlZBKGFkZHIpOwogICAgICAgICAgICBpZiAoc25vb3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZW5hbWUpIGVuYW1lID0gIkAiOwogICAgICAgICAgICAgICAgcHJvYyA9IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsb3JkaW5hbCxwcm9jKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvYzsKICAgICAgICB9CiAgICAgICAgZWxzZSAgLyogZm9yd2FyZCBlbnRyeSBwb2ludCAqLwogICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfTU9EUkVGICp3bV9mdzsKICAgICAgICAgICAgICAgIEZBUlBST0MgcHJvYzsKICAgICAgICAgICAgICAgIGNoYXIgKmZvcndhcmQgPSBSVkEoYWRkcik7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgaWYgKGVuZCAtIGZvcndhcmQgPj0gc2l6ZW9mKG1vZHVsZSkpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtY3B5KCBtb2R1bGUsIGZvcndhcmQsIGVuZCAtIGZvcndhcmQgKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGlmICghKHdtX2Z3ID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG1vZHVsZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm1vZHVsZSBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJyB1c2VkIGJ5ICclcydcbiIsIGZvcndhcmQsIHdtLT5tb2RuYW1lICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJaWYgKCEocHJvYyA9IE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd21fZnctPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKSkpCiAgICAgICAgICAgICAgICAgICAgRVJSKCJmdW5jdGlvbiBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJyB1c2VkIGJ5ICclcycuIElmIHlvdSBhcmUgdXNpbmcgYnVpbHRpbiAnJXMnLCB0cnkgdXNpbmcgdGhlIG5hdGl2ZSBvbmUgaW5zdGVhZC5cbiIsIGZvcndhcmQsIHdtLT5tb2RuYW1lLCB3bS0+bW9kbmFtZSApOwoJCXJldHVybiBwcm9jOwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJUEVfZml4dXBfaW1wb3J0cwogKi8KRFdPUkQgUEVfZml4dXBfaW1wb3J0cyggV0lORV9NT0RSRUYgKndtICkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmltcG9ydHMgPSBnZXRfaW1wb3J0cyh3bS0+bW9kdWxlKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gaW1wb3J0czsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIFdlIGFzc3VtZSB0aGF0IHdlIGhhdmUgYXQgbGVhc3Qgb25lIGltcG9ydCB3aXRoICEwIGNoYXJhY3RlcmlzdGljcyBhbmQKICAgICAqIGRldGVjdCBicm9rZW4gaW1wb3J0cyB3aXRoIGFsbCBjaGFyYWN0ZXJpc3RpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gaW1wb3J0czsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlXSU5FX01PRFJFRgkJKndtSW1wOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwogCWNoYXIJCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CgkgICAgRVJSXyhtb2R1bGUpKCJNb2R1bGUgKGZpbGUpICVzIG5lZWRlZCBieSAlcyBub3QgZm91bmRcbiIsIG5hbWUsIHdtLT5maWxlbmFtZSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0UoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcywlZFxuIiwgbmFtZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBvcmRpbmFsLCB3bS0+ZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lLHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRSgiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLiVkXG4iLG5hbWUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQgaW1wb3J0ZWQgZnJvbSAlcywgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50LCBwZV9uYW1lLT5OYW1lLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZG9fcmVsb2NhdGlvbnMKICoKICogQXBwbHkgdGhlIHJlbG9jYXRpb25zIHRvIGEgbWFwcGVkIFBFIGltYWdlCiAqLwpzdGF0aWMgaW50IGRvX3JlbG9jYXRpb25zKCBjaGFyICpiYXNlLCBjb25zdCBJTUFHRV9OVF9IRUFERVJTICpudCwgY29uc3QgY2hhciAqZmlsZW5hbWUgKQp7CiAgICBjb25zdCBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgY29uc3QgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyZWw7CiAgICBpbnQgZGVsdGEgPSBiYXNlIC0gKGNoYXIgKiludC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoKICAgIGRpciA9ICZudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKICAgIHJlbCA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04gKikoYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIFdBUk4oIkluZm86IGJhc2UgcmVsb2NhdGlvbnMgbmVlZGVkIGZvciAlc1xuIiwgZmlsZW5hbWUpOwogICAgaWYgKCFkaXItPlZpcnR1YWxBZGRyZXNzIHx8ICFkaXItPlNpemUpCiAgICB7CiAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgPT0gMHg0MDAwMDApCiAgICAgICAgICAgIEVSUigiU3RhbmRhcmQgbG9hZCBhZGRyZXNzIGZvciBhIFdpbjMyIHByb2dyYW0gKDB4MDA0MDAwMDApIG5vdCBhdmFpbGFibGUgLSBwYXRjaGVkIGtlcm5lbCA/XG4iKTsKICAgICAgICBFUlIoICJGQVRBTDogTmVlZCB0byByZWxvY2F0ZSAlcywgYnV0IG5vIHJlbG9jYXRpb24gcmVjb3JkcyBwcmVzZW50ICglcykuIFRyeSB0byBydW4gdGhhdCBmaWxlIGRpcmVjdGx5ICFcbiIsCiAgICAgICAgICAgICBmaWxlbmFtZSwKICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBGSVhNRTogSWYgd2UgbmVlZCB0byByZWxvY2F0ZSBhIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpIHdlIHNob3VsZAogICAgICogICAgICAgIHJlYWxseSBtYWtlIHN1cmUgdGhhdCB0aGUgKm5ldyogYmFzZSBhZGRyZXNzIGlzIGFsc28gPiAyR0IuCiAgICAgKiAgICAgICAgU29tZSBETExzIHJlYWxseSBjaGVjayB0aGUgTVNCIG9mIHRoZSBtb2R1bGUgaGFuZGxlIDotLwogICAgICovCiAgICBpZiAoKG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwKSAmJiAhKChEV09SRCliYXNlICYgMHg4MDAwMDAwMCkpCiAgICAgICAgRVJSKCAiRm9yY2VkIHRvIHJlbG9jYXRlIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpLiBUaGlzIGlzIG5vdCBnb29kLlxuIiApOwoKICAgIGZvciAoIDsgKChjaGFyICopcmVsIDwgYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MgKyBkaXItPlNpemUpICYmIHJlbC0+VmlydHVhbEFkZHJlc3M7CiAgICAgICAgICByZWwgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXJlbCArIHJlbC0+U2l6ZU9mQmxvY2spKQogICAgewogICAgICAgIGNoYXIgKnBhZ2UgPSBiYXNlICsgcmVsLT5WaXJ0dWFsQWRkcmVzczsKICAgICAgICBpbnQgaSwgY291bnQgPSAocmVsLT5TaXplT2ZCbG9jayAtIDgpIC8gc2l6ZW9mKHJlbC0+VHlwZU9mZnNldCk7CgogICAgICAgIGlmICghY291bnQpIGNvbnRpbnVlOwoKICAgICAgICAvKiBzYW5pdHkgY2hlY2tzICovCiAgICAgICAgaWYgKChjaGFyICopcmVsICsgcmVsLT5TaXplT2ZCbG9jayA+IGJhc2UgKyBkaXItPlZpcnR1YWxBZGRyZXNzICsgZGlyLT5TaXplIHx8CiAgICAgICAgICAgIHBhZ2UgPiBiYXNlICsgbnQtPk9wdGlvbmFsSGVhZGVyLlNpemVPZkltYWdlKQogICAgICAgIHsKICAgICAgICAgICAgRVJSXyhtb2R1bGUpKCJpbnZhbGlkIHJlbG9jYXRpb24gJXAsJWx4LCVsZCBhdCAlcCwlbHgsJWx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVsLCByZWwtPlZpcnR1YWxBZGRyZXNzLCByZWwtPlNpemVPZkJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSwgZGlyLT5WaXJ0dWFsQWRkcmVzcywgZGlyLT5TaXplICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgVFJBQ0VfKG1vZHVsZSkoIiVsZCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsIHJlbC0+U2l6ZU9mQmxvY2ssIHJlbC0+VmlydHVhbEFkZHJlc3MpOwoKICAgICAgICAvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCiAgICAgICAgZm9yIChpID0gMCA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaW50IG9mZnNldCA9IHJlbC0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwogICAgICAgICAgICBpbnQgdHlwZSA9IHJlbC0+VHlwZU9mZnNldFtpXSA+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+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBTRVJWRVJfU1RBUlRfUkVRKCBsb2FkX2RsbCApCiAgICAgICAgewogICAgICAgICAgICByZXEtPmhhbmRsZSAgICAgPSBoRmlsZTsKICAgICAgICAgICAgcmVxLT5iYXNlICAgICAgID0gKHZvaWQgKiloTW9kdWxlOwogICAgICAgICAgICByZXEtPmRiZ19vZmZzZXQgPSBudC0+RmlsZUhlYWRlci5Qb2ludGVyVG9TeW1ib2xUYWJsZTsKICAgICAgICAgICAgcmVxLT5kYmdfc2l6ZSAgID0gbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTeW1ib2xzOwogICAgICAgICAgICByZXEtPm5hbWUgICAgICAgPSAmd20tPmZpbGVuYW1lOwogICAgICAgICAgICBTRVJWRVJfQ0FMTCgpOwogICAgICAgIH0KICAgICAgICBTRVJWRVJfRU5EX1JFUTsKICAgIH0KCiAgICByZXR1cm4gd207Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpXSU5FX01PRFJFRiAqUEVfTG9hZExpYnJhcnlFeEEgKExQQ1NUUiBuYW1lLCBEV09SRCBmbGFncykKewoJSE1PRFVMRQkJaE1vZHVsZTMyOwoJV0lORV9NT0RSRUYJKndtOwoJSEFORExFCQloRmlsZTsKICAgICAgIAoJaEZpbGUgPSBDcmVhdGVGaWxlQSggbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwoJaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoJCgkvKiBMb2FkIFBFIG1vZHVsZSAqLwoJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgbmFtZSwgZmxhZ3MgKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQ3JlYXRlIDMyLWJpdCBNT0RSRUYgKi8KCWlmICggISh3bSA9IFBFX0NyZWF0ZU1vZHVsZSggaE1vZHVsZTMyLCBuYW1lLCBmbGFncywgaEZpbGUsIEZBTFNFICkpICkKCXsKCQlFUlIoICJjYW4ndCBsb2FkICVzXG4iLCBuYW1lICk7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlTZXRMYXN0RXJyb3IoIEVSUk9SX09VVE9GTUVNT1JZICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgogICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJcmV0dXJuIHdtOwp9CgoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnR5cGVkZWYgRFdPUkQgQ0FMTEJBQ0soKkRMTEVOVFJZUFJPQykoSE1PRFVMRSxEV09SRCxMUFZPSUQpOwoKQk9PTCBQRV9Jbml0RExMKCBITU9EVUxFIG1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQgKQp7CiAgICBCT09MIHJldHYgPSBUUlVFOwogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQgPSBQRV9IRUFERVIobW9kdWxlKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSkKICAgIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopKChjaGFyKiltb2R1bGUgKyBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgICAgICAgICAgRFBSSU5URigiJTA4bHg6Q2FsbCBQRSBETEwgKHByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50VGhyZWFkSWQoKSwgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgICAgIHJldHYgPSBlbnRyeSggbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgICAgICAgICAgRFBSSU5URigiJTA4bHg6UmV0ICBQRSBETEwgKHByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKSByZXR2YWw9JXhcbiIsCiAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFRocmVhZElkKCksIGVudHJ5LCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQsIHJldHYgKTsKICAgIH0KCiAgICByZXR1cm4gcmV0djsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9Jbml0VGxzCQkJKGludGVybmFsKQogKgogKiBJZiBpbmNsdWRlZCwgaW5pdGlhbGlzZXMgdGhlIHRocmVhZCBsb2NhbCBzdG9yYWdlcyBvZiBtb2R1bGVzLgogKiBQb2ludGVycyBpbiB0aG9zZSBzdHJ1Y3RzIGFyZSBub3QgUlZBcyBidXQgcmVhbCBwb2ludGVycyB3aGljaCBoYXZlIGJlZW4KICogcmVsb2NhdGVkIGJ5IGRvX3JlbG9jYXRpb25zKCkgYWxyZWFkeS4KICovCnN0YXRpYyBMUFZPSUQKX2ZpeHVwX2FkZHJlc3MoUElNQUdFX09QVElPTkFMX0hFQURFUiBvcHQsaW50IGRlbHRhLExQVk9JRCBhZGRyKSB7CglpZiAoCSgoRFdPUkQpYWRkcj5vcHQtPkltYWdlQmFzZSkgJiYKCQkoKERXT1JEKWFkZHI8b3B0LT5JbWFnZUJhc2Urb3B0LT5TaXplT2ZJbWFnZSkKCSkKCQkvKiB0aGUgYWRkcmVzcyBoYXMgbm90IGJlZW4gcmVsb2NhdGVkISAqLwoJCXJldHVybiAoTFBWT0lEKSgoKERXT1JEKWFkZHIpK2RlbHRhKTsKCWVsc2UKCQkvKiB0aGUgYWRkcmVzcyBoYXMgYmVlbiByZWxvY2F0ZWQgYWxyZWFkeSAqLwoJCXJldHVybiBhZGRyOwp9CnZvaWQgUEVfSW5pdFRscyggdm9pZCApCnsKCVdJTkVfTU9EUkVGCQkqd207CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwogICAgICAgIGludCBkZWx0YTsKCQoJZm9yICh3bSA9IE1PRFVMRV9tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIHdtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJd20tPnRsc2luZGV4ID0gVGxzQWxsb2MoKTsKCQkJeGFkZHIgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLAoJCQkJCXBkaXItPkFkZHJlc3NPZkluZGV4CgkJCSk7CgkJCSp4YWRkcj13bS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7IAoKCQkgICAgIGNicyA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEscGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKTsKCQkgICAgIGlmICgqY2JzKQoJCSAgICAgICBGSVhNRSgiVExTIENhbGxiYWNrcyBhcmVuJ3QgZ29pbmcgdG8gYmUgY2FsbGVkXG4iKTsKCQl9CgoJCVRsc1NldFZhbHVlKCB3bS0+dGxzaW5kZXgsIG1lbSApOwoJfQp9Cgo=