LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gU29tZXRpbWVzLCB3ZSBjYW4ndCB1c2UgTGludXggbW1hcCgpIHRvIG1tYXAoKSB0aGUgaW1hZ2VzIGRpcmVjdGx5LgogKgogKiAgIFRoZSBwcm9ibGVtIGlzLCB0aGF0IHRoZXJlIGlzIG5vdCBkaXJlY3QgMToxIG1hcHBpbmcgZnJvbSBhIGRpc2tpbWFnZSBhbmQKICogICBhIG1lbW9yeWltYWdlLiBUaGUgaGVhZGVycyBhdCB0aGUgc3RhcnQgYXJlIG1hcHBlZCBsaW5lYXIsIGJ1dCB0aGUgc2VjdGlvbnMKICogICBhcmUgbm90LiBPbGRlciB4ODYgcGUgYmluYXJpZXMgYXJlIDUxMiBieXRlIGFsaWduZWQgaW4gZmlsZSBhbmQgNDA5NiBieXRlCiAqICAgYWxpZ25lZCBpbiBtZW1vcnkuIExpbnV4IGxpa2VzIHRoZW0gNDA5NiBieXRlIGFsaWduZWQgaW4gbWVtb3J5IChkdWUgdG8KICogICB4ODYgcGFnZXNpemUsIHRoaXMgY2Fubm90IGJlIGZpeGVkIHdpdGhvdXQgYSByYXRoZXIgbGFyZ2Uga2VybmVsIHJld3JpdGUpCiAqICAgYW5kICdibG9ja3NpemUnIGZpbGUtYWxpZ25lZCAob2Zmc2V0cykuIFNpbmNlIHdlIGhhdmUgNTEyLzEwMjQvMjA0OCAoQ0RST00pCiAqICAgYW5kIG90aGVyIGJ5dGUgYmxvY2tzaXplcywgd2UgY2FuJ3QgYWx3YXlzIGRvIHRoaXMuICBXZSAqY2FuKiBkbyB0aGlzIGZvcgogKiAgIG5ld2VyIHBlIGJpbmFyaWVzIHByb2R1Y2VkIGJ5IE1TVkMgNSBhbmQgbGF0ZXIsIHNpbmNlIHRoZXkgYXJlIGFsc28gYWxpZ25lZAogKiAgIHRvIDQwOTYgYnl0ZSBib3VuZGFyaWVzIG9uIGRpc2suCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiY2FsbGJhY2suaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAic25vb3AuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbjMyKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKGRlbGF5aGxwKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKGZpeHVwKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzZWdtZW50KTsKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHZvaWQgKikoKGNoYXIgKilsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpKQoKI2RlZmluZSBBZGp1c3RQdHIocHRyLGRlbHRhKSAoKGNoYXIgKikocHRyKSArIChkZWx0YSkpCgp2b2lkIGR1bXBfZXhwb3J0cyggSE1PRFVMRSBoTW9kdWxlICkKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBoTW9kdWxlOwoKICBEV09SRCBydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKICBEV09SRCBydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnRzID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKVJWQShydmFfc3RhcnQpOwoKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIFRSQUNFKCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBUUkFDRSgiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCiAgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRSgiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGlmIChUUkFDRV9PTih3aW4zMikpCiAgICAgIHsKCURQUklOVEYoICIlNGxkICUwOGx4ICVwIiwgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKCS8qIENoZWNrIGlmIHdlIGhhdmUgYSBuYW1lIGZvciBpdCAqLwoJZm9yIChqID0gMDsgaiA8IHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXM7IGorKykKICAgICAgICAgIGlmIChvcmRpbmFsW2pdID09IGkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgRFBSSU5URiggIiAgJXMiLCAoY2hhciopUlZBKG5hbWVbal0pICk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CglpZiAoKCpmdW5jdGlvbiA+PSBydmFfc3RhcnQpICYmICgqZnVuY3Rpb24gPD0gcnZhX2VuZCkpCgkgIERQUklOVEYoIiAoZm9yd2FyZGVkIC0+ICVzKSIsIChjaGFyICopUlZBKCpmdW5jdGlvbikpOwoJRFBSSU5URigiXG4iKTsKICAgICAgfQogIH0KfQoKLyogTG9vayB1cCB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uIG9yIG9yZGluYWwgaW4gdGhlIGV4cG9ydGxpc3Q6CiAqIElmIGl0IGlzIGEgc3RyaW5nOgogKiAJLSBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBOYW1lIGxpc3QuIAogKgktIGxvb2sgdXAgdGhlIG9yZGluYWwgd2l0aCB0aGF0IGluZGV4LgogKgktIHVzZSB0aGUgb3JkaW5hbCBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqIElmIGl0IGlzIGEgb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKi8KRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSwJLyogW2luXSBmdW5jdGlvbiBuYW1lICovCiAgICAgICAgQk9PTCBzbm9vcCApCnsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsczsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZSA9IE5VTEw7CglpbnQJCQkJaSwgb3JkaW5hbDsKCVBFX01PRFJFRgkJCSpwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzID0gcGVtLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBpbnQJCQlsb2FkX2FkZHIgPSB3bS0+bW9kdWxlOwoJdV9sb25nCQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFKCIoJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlUUkFDRSgiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTigiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFscz0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogZmlyc3QgdHJ5IGEgYmluYXJ5IHNlYXJjaCAqLwogICAgICAgICAgICBpbnQgbWluID0gMCwgbWF4ID0gZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyAtIDE7CiAgICAgICAgICAgIHdoaWxlIChtaW4gPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcmVzLCBwb3MgPSAobWluICsgbWF4KSAvIDI7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW3Bvc10pOwogICAgICAgICAgICAgICAgaWYgKCEocmVzID0gc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW3Bvc107CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZXMgPiAwKSBtYXggPSBwb3MgLSAxOwogICAgICAgICAgICAgICAgZWxzZSBtaW4gPSBwb3MgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIG5vdyB0cnkgYSBsaW5lYXIgc2VhcmNoIGluIGNhc2UgdGhlIG5hbWVzIGFyZW4ndCBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCAiJXMuJXMgcmVxdWlyZWQgYSBsaW5lYXIgc2VhcmNoXG4iLCB3bS0+bW9kbmFtZSwgZnVuY05hbWUgKTsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbaV07CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KICAgICAgICBlbHNlICAvKiBmaW5kIGJ5IG9yZGluYWwgKi8KICAgICAgICB7CiAgICAgICAgICAgIG9yZGluYWwgPSBMT1dPUkQoZnVuY05hbWUpIC0gZXhwb3J0cy0+QmFzZTsKICAgICAgICAgICAgaWYgKHNub29wICYmIG5hbWUpICAvKiBuZWVkIHRvIGZpbmQgYSBuYW1lIGZvciBpdCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChvcmRpbmFsc1tpXSA9PSBvcmRpbmFsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJfQoKIGZvdW5kOgogICAgICAgIGlmIChvcmRpbmFsID49IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIglvcmRpbmFsICVsZCBvdXQgb2YgcmFuZ2UhXG4iLCBvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgYWRkciA9IGZ1bmN0aW9uW29yZGluYWxdOwogICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICB7CiAgICAgICAgICAgIEZBUlBST0MgcHJvYyA9IFJWQShhZGRyKTsKICAgICAgICAgICAgaWYgKHNub29wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWVuYW1lKSBlbmFtZSA9ICJAIjsKICAgICAgICAgICAgICAgIHByb2MgPSBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLG9yZGluYWwscHJvYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHByb2M7CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIGZvcndhcmQgZW50cnkgcG9pbnQgKi8KICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd207CiAgICAgICAgICAgICAgICBGQVJQUk9DIHByb2M7CiAgICAgICAgICAgICAgICBjaGFyICpmb3J3YXJkID0gUlZBKGFkZHIpOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChlbmQgLSBmb3J3YXJkID49IHNpemVvZihtb2R1bGUpKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG1lbWNweSggbW9kdWxlLCBmb3J3YXJkLCBlbmQgLSBmb3J3YXJkICk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJtb2R1bGUgbm90IGZvdW5kIGZvciBmb3J3YXJkICclcydcbiIsIGZvcndhcmQgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KCQlpZiAoIShwcm9jID0gTU9EVUxFX0dldFByb2NBZGRyZXNzKCB3bS0+bW9kdWxlLCBlbmQgKyAxLCBzbm9vcCApKSkKICAgICAgICAgICAgICAgICAgICBFUlIoImZ1bmN0aW9uIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CgkJcmV0dXJuIHByb2M7Cgl9Cn0KCkRXT1JEIGZpeHVwX2ltcG9ydHMoIFdJTkVfTU9EUkVGICp3bSApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBQRV9NT0RSRUYJCQkqcGVtOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHdtLT5tb2R1bGU7CiAgICBpbnQJCQkJaSxjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uPTE7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICAKICAgIGFzc2VydCh3bS0+dHlwZT09TU9EVUxFMzJfUEUpOwogICAgcGVtID0gJih3bS0+YmluZm10LnBlKTsKICAgIGlmIChwZW0tPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwogICAgZWxzZQogICAgICAgIG1vZG5hbWUgPSAiPHVua25vd24+IjsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0aWNzIDAgKG5vdGFibHkgQm9ybGFuZCkgYW5kCiAgICAgKiBzd2l0Y2ggdGhlIGRldGVjdGlvbiBvZmYgZm9yIHRoZW0uCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CglpZiAoIWkgJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiA9IDA7CglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCWkrKzsKICAgIH0KICAgIGlmICghaSkgcmV0dXJuIDA7ICAvKiBubyBpbXBvcnRzICovCgogICAgLyogQWxsb2NhdGUgbW9kdWxlIGRlcGVuZGVuY3kgbGlzdCAqLwogICAgd20tPm5EZXBzID0gaTsKICAgIHdtLT5kZXBzICA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaSpzaXplb2YoV0lORV9NT0RSRUYgKikgKTsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewogICAgCVdJTkVfTU9EUkVGCQkqd21JbXA7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCVBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAJY2hhcgkJCSpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CgoJd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIG5hbWUsIDAsIDAgKTsKCWlmICghd21JbXApIHsKCSAgICBFUlJfKG1vZHVsZSkoIk1vZHVsZSAoZmlsZSkgJXMgbmVlZGVkIGJ5ICVzIG5vdCBmb3VuZFxuIiwgbmFtZSwgd20tPmZpbGVuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB3bS0+ZGVwc1tpKytdID0gd21JbXA7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0UoIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcy4lZFxuIixuYW1lLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgVFJBQ0UoIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRSgiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIFRSQUNFKCIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPk1pc2MuVmlydHVhbFNpemUpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyggdW5zaWduZWQgaW50IGxvYWRfYWRkciwgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyICkKewogICAgaW50IGRlbHRhID0gbG9hZF9hZGRyIC0gUEVfSEVBREVSKGxvYWRfYWRkciktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIGludAloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwogICAgaW50CWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRV8oZml4dXApKCIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCVRSQUNFXyhmaXh1cCkoInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKCQkJCS8qIEZJWE1FOiBpZiB0aGlzIGlzIGFuIGV4cG9ydGVkIGFkZHJlc3MsIGZpcmUgdXAgZW5oYW5jZWQgbG9naWMgKi8KCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJRklYTUUoIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlGSVhNRSgiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlGSVhNRSgiVW5rbm93biBmaXh1cCB0eXBlICVkLlxuIiwgdHlwZSk7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lICkKewogICAgSE1PRFVMRQloTW9kdWxlOwogICAgSEFORExFCW1hcHBpbmc7CgogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VjOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBpbnQJaSwgcmF3c2l6ZSwgbG93ZXN0X3ZhLCB2bWFfc2l6ZSwgZmlsZV9zaXplID0gMDsKICAgIERXT1JEIGxvYWRfYWRkciA9IDAsIGFvZXAsIHJlbG9jID0gMDsKICAgIHN0cnVjdCBnZXRfcmVhZF9mZF9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgaW50IHVuaXhfaGFuZGxlID0gLTE7CiAgICBpbnQgcGFnZV9zaXplID0gVklSVFVBTF9HZXRQYWdlU2l6ZSgpOwoKICAgIC8qIFJldHJpZXZlIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSggaEZpbGUsICZiaGZpICkgKSAKICAgIAlmaWxlX3NpemUgPSBiaGZpLm5GaWxlU2l6ZUxvdzsgLyogRklYTUU6IDY0IGJpdCAqLwoKICAgIC8qIE1hcCB0aGUgUEUgZmlsZSBzb21ld2hlcmUgKi8KICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIFdBUk4oIkNyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGhNb2R1bGUgPSAoSE1PRFVMRSlNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFoTW9kdWxlKQogICAgewogICAgICAgIFdBUk4oIk1hcFZpZXdPZkZpbGUgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCAqKFdPUkQqKWhNb2R1bGUgIT1JTUFHRV9ET1NfU0lHTkFUVVJFKQogICAgewogICAgICAgIFdBUk4oIiVzIGltYWdlIGRvZXNuJ3QgaGF2ZSBET1Mgc2lnbmF0dXJlLCBidXQgMHglMDR4XG4iLCBmaWxlbmFtZSwqKFdPUkQqKWhNb2R1bGUpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CgogICAgLyogQ2hlY2sgc2lnbmF0dXJlICovCiAgICBpZiAoIG50LT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFICkKICAgIHsKICAgICAgICBXQVJOKCIlcyBpbWFnZSBkb2Vzbid0IGhhdmUgUEUgc2lnbmF0dXJlLCBidXQgMHglMDhseFxuIiwgZmlsZW5hbWUsIG50LT5TaWduYXR1cmUgKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBDaGVjayBhcmNoaXRlY3R1cmUgKi8KICAgIGlmICggbnQtPkZpbGVIZWFkZXIuTWFjaGluZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NiApCiAgICB7CiAgICAgICAgTUVTU0FHRSgiVHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CiAgICAgICAgc3dpdGNoIChudC0+RmlsZUhlYWRlci5NYWNoaW5lKQogICAgICAgIHsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOiBNRVNTQUdFKCJVbmtub3duIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6ICAgIE1FU1NBR0UoIkk4NjAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6ICAgTUVTU0FHRSgiUjMwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6ICAgTUVTU0FHRSgiUjQwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOiAgTUVTU0FHRSgiUjEwMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0FMUEhBOiAgIE1FU1NBR0UoIkFscGhhIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6IE1FU1NBR0UoIlBvd2VyUEMiKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogTUVTU0FHRSgiVW5rbm93bi0lMDR4IiwgbnQtPkZpbGVIZWFkZXIuTWFjaGluZSk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICBNRVNTQUdFKCIpXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBGaW5kIG91dCBob3cgbGFyZ2UgdGhpcyBleGVjdXRlYWJsZSBzaG91bGQgYmUgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICByYXdzaXplID0gMDsgbG93ZXN0X3ZhID0gMHgxMDAwMDsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspIAogICAgewogICAgICAgIGlmIChsb3dlc3RfdmEgPiBwZV9zZWNbaV0uVmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgbG93ZXN0X3ZhID0gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzOwogICAgCWlmIChwZV9zZWNbaV0uQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkgICAgY29udGludWU7CglpZiAocGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGEgPiByYXdzaXplKQoJICAgIHJhd3NpemUgPSBwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YStwZV9zZWNbaV0uU2l6ZU9mUmF3RGF0YTsKICAgIH0KIAogICAgLyogQ2hlY2sgZmlsZSBzaXplICovCiAgICBpZiAoIGZpbGVfc2l6ZSAmJiBmaWxlX3NpemUgPCByYXdzaXplICkKICAgIHsKICAgICAgICBFUlIoIlBFIG1vZHVsZSBpcyB0b28gc21hbGwgKGhlYWRlcjogJWQsIGZpbGVzaXplOiAlZCksICIKICAgICAgICAgICAgICAgICAgICAicHJvYmFibHkgdHJ1bmNhdGVkIGRvd25sb2FkP1xuIiwgCiAgICAgICAgICAgICAgICAgICAgcmF3c2l6ZSwgZmlsZV9zaXplICk7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgZW50cnlwb2ludCBhZGRyZXNzICovCiAgICBhb2VwID0gbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQ7CiAgICBpZiAoYW9lcCAmJiAoYW9lcCA8IGxvd2VzdF92YSkpCiAgICAgICAgTUVTU0FHRSgiVklSVVMgV0FSTklORzogJyVzJyBoYXMgYW4gaW52YWxpZCBlbnRyeXBvaW50ICgweCUwOGx4KSAiCiAgICAgICAgICAgICAgICAgICAgICAiYmVsb3cgdGhlIGZpcnN0IHZpcnR1YWwgYWRkcmVzcyAoMHglMDh4KSAiCiAgICAgICAgICAgICAgICAgICAgICAiKHBvc3NpYmx5IGluZmVjdGVkIGJ5IFRjaGVybm9ieWwvU3BhY2VGaWxsZXIgdmlydXMpIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgYW9lcCwgbG93ZXN0X3ZhICk7CgoKI2lmIDAKICAgIC8qIEZJWE1FOiAgSGFjayEgIFdoaWxlIHdlIGRvbid0IHJlYWxseSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyB5ZXQsCiAgICAgKiAgICAgICAgIHRoaXMgY2hlY2tzIGZvciB0aG9zZSBzcGVjaWFsIGNhc2VzIHdoZXJlIHRoZSB3aG9sZSBETEwKICAgICAqICAgICAgICAgY29uc2lzdHMgb25seSBvZiBzaGFyZWQgc2VjdGlvbnMgYW5kIGlzIG1hcHBlZCBpbnRvIHRoZQogICAgICogICAgICAgICBzaGFyZWQgYWRkcmVzcyBzcGFjZSA+IDJHQi4gIEluIHRoaXMgY2FzZSwgd2UgYXNzdW1lIHRoYXQKICAgICAqICAgICAgICAgdGhlIG1vZHVsZSBnb3QgbWFwcGVkIGF0IGl0cyBiYXNlIGFkZHJlc3MuIFRodXMgd2Ugc2ltcGx5CiAgICAgKiAgICAgICAgIGNoZWNrIHdoZXRoZXIgdGhlIG1vZHVsZSBoYXMgYWN0dWFsbHkgYmVlbiBtYXBwZWQgdGhlcmUKICAgICAqICAgICAgICAgYW5kIHVzZSBpdCwgaWYgc28uICBUaGlzIGlzIG5lZWRlZCB0byBnZXQgV2luOTUgVVNFUjMyLkRMTAogICAgICogICAgICAgICB0byB3b3JrICh1bnRpbCB3ZSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyBwcm9wZXJseSkuCiAgICAgKi8KCiAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgIHsKICAgICAgICBITU9EVUxFIHNoYXJlZE1vZCA9IChITU9EVUxFKW50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7IAogICAgICAgIElNQUdFX05UX0hFQURFUlMgKnNoYXJlZE50ID0gKFBJTUFHRV9OVF9IRUFERVJTKQogICAgICAgICAgICAgICAoIChMUEJZVEUpc2hhcmVkTW9kICsgKChMUEJZVEUpbnQgLSAoTFBCWVRFKWhNb2R1bGUpICk7CgogICAgICAgIC8qIFdlbGwsIHRoaXMgY2hlY2sgaXMgbm90IHJlYWxseSBjb21wcmVoZW5zaXZlLCAKICAgICAgICAgICBidXQgc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBub3cgLi4uICovCiAgICAgICAgaWYgKCAgICAhSXNCYWRSZWFkUHRyKCAoTFBCWVRFKXNoYXJlZE1vZCwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkKICAgICAgICAgICAgICYmIG1lbWNtcCggKExQQllURSlzaGFyZWRNb2QsIChMUEJZVEUpaE1vZHVsZSwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkgPT0gMAogICAgICAgICAgICAgJiYgIUlzQmFkUmVhZFB0ciggc2hhcmVkTnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIHNoYXJlZE50LCBudCwgc2l6ZW9mKElNQUdFX05UX0hFQURFUlMpICkgPT0gMCApCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgICAgICByZXR1cm4gc2hhcmVkTW9kOwogICAgICAgIH0KICAgIH0KI2VuZGlmCgogICAgLyogQWxsb2NhdGUgbWVtb3J5IGZvciBtb2R1bGUgKi8KICAgIGxvYWRfYWRkciA9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCiAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCAodm9pZCopbG9hZF9hZGRyLCB2bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIGlmIChsb2FkX2FkZHIgPT0gMCkgCiAgICB7CiAgICAgICAgLyogV2UgbmVlZCB0byBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbnMgKi8KICAgICAgICBXQVJOKCJXZSBuZWVkIHRvIHBlcmZvcm0gYmFzZSByZWxvY2F0aW9ucyBmb3IgJXNcbiIsIGZpbGVuYW1lKTsKCWRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0M7CiAgICAgICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICAgICAgcmVsb2MgPSBkaXItPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSggIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyZJTUFHRV9GSUxFX1JFTE9DU19TVFJJUFBFRCk/CiAgICAgICAgICAgICAgICAgICAic3RyaXBwZWQgZHVyaW5nIGxpbmsiIDogInVua25vd24gcmVhc29uIiApOwogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICAvKiBGSVhNRTogSWYgd2UgbmVlZCB0byByZWxvY2F0ZSBhIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpIHdlIHNob3VsZAogICAgICAgICAqICAgICAgICByZWFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlICpuZXcqIGJhc2UgYWRkcmVzcyBpcyBhbHNvID4gMkdCLgogICAgICAgICAqICAgICAgICBTb21lIERMTHMgcmVhbGx5IGNoZWNrIHRoZSBNU0Igb2YgdGhlIG1vZHVsZSBoYW5kbGUgOi0vCiAgICAgICAgICovCiAgICAgICAgaWYgKCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCApCiAgICAgICAgICAgIEVSUiggIkZvcmNlZCB0byByZWxvY2F0ZSBzeXN0ZW0gRExMIChiYXNlID4gMkdCKS4gVGhpcyBpcyBub3QgZ29vZC5cbiIgKTsKCiAgICAgICAgbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggTlVMTCwgdm1hX3NpemUsCgkJCQkJIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKCQkJCQkgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJaWYgKCFsb2FkX2FkZHIpIHsKICAgICAgICAgICAgRklYTUVfKHdpbjMyKSgKICAgICAgICAgICAgICAgICAgICJGQVRBTDogQ291bGRuJ3QgbG9hZCBtb2R1bGUgJXMgKG91dCBvZiBtZW1vcnksICVkIG5lZWRlZCkhXG4iLCBmaWxlbmFtZSwgdm1hX3NpemUpOwogICAgICAgICAgICBnb3RvIGVycm9yOwoJfQogICAgfQoKICAgIFRSQUNFKCJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgbG9hZF9hZGRyLCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlLCB2bWFfc2l6ZSApOwogICAgVFJBQ0VfKHNlZ21lbnQpKCJMb2FkaW5nICVzIGF0ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiNpZiAwCiAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIgKi8KICAgICooUElNQUdFX0RPU19IRUFERVIpbG9hZF9hZGRyID0gKihQSU1BR0VfRE9TX0hFQURFUiloTW9kdWxlOwogICAgKlBFX0hFQURFUiggbG9hZF9hZGRyICkgPSAqbnQ7CiAgICBtZW1jcHkoIFBFX1NFQ1RJT05TKGxvYWRfYWRkciksIFBFX1NFQ1RJT05TKGhNb2R1bGUpLAogICAgICAgICAgICBzaXplb2YoSU1BR0VfU0VDVElPTl9IRUFERVIpICogbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucyApOwoKICAgIC8qIENvcGllcyBhbGwgc3R1ZmYgdXAgdG8gdGhlIGZpcnN0IHNlY3Rpb24uIEluY2x1ZGluZyB3aW4zMiB2aXJ1c2VzLiAqLwogICAgbWVtY3B5KCBsb2FkX2FkZHIsIGhNb2R1bGUsIGxvd2VzdF9mYSApOwojZW5kaWYKCiAgICByZXEtPmhhbmRsZSA9IGhGaWxlOwogICAgc2VydmVyX2NhbGxfZmQoIFJFUV9HRVRfUkVBRF9GRCwgLTEsICZ1bml4X2hhbmRsZSApOwogICAgaWYgKHVuaXhfaGFuZGxlID09IC0xKSBnb3RvIGVycm9yOwoKICAgIC8qIE1hcCB0aGUgaGVhZGVyICovCiAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCAqKWxvYWRfYWRkciwgMCwgbnQtPk9wdGlvbmFsSGVhZGVyLlNpemVPZkhlYWRlcnMsCiAgICAgICAgICAgICAgICAgICAgIDAsIDAsIFBST1RfRVhFQyB8IFBST1RfV1JJVEUgfCBQUk9UX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgIE1BUF9QUklWQVRFIHwgTUFQX0ZJWEVEICkgIT0gKHZvaWQqKWxvYWRfYWRkcikKICAgIHsKICAgICAgICBFUlJfKHdpbjMyKSggIkNyaXRpY2FsIEVycm9yOiBmYWlsZWQgdG8gbWFwIFBFIGhlYWRlciB0byBuZWNlc3NhcnkgYWRkcmVzcy5cbiIpOwkKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENvcHkgc2VjdGlvbnMgaW50byBtb2R1bGUgaW1hZ2UgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWMrKykKICAgIHsKICAgICAgICBpZiAoIXBlX3NlYy0+U2l6ZU9mUmF3RGF0YSB8fCAhcGVfc2VjLT5Qb2ludGVyVG9SYXdEYXRhKSBjb250aW51ZTsKICAgICAgICBUUkFDRSgiJXM6IG1tYXBpbmcgc2VjdGlvbiAlcyBhdCAlcCBvZmYgJWx4IHNpemUgJWx4LyVseFxuIiwKICAgICAgICAgICAgICBmaWxlbmFtZSwgcGVfc2VjLT5OYW1lLCAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLAogICAgICAgICAgICAgIHBlX3NlYy0+UG9pbnRlclRvUmF3RGF0YSwgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemUgKTsKICAgICAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgMCwgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCAwLCBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBQUk9UX0VYRUMgfCBQUk9UX1dSSVRFIHwgUFJPVF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgTUFQX1BSSVZBVEUgfCBNQVBfRklYRUQgKSAhPSAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpKQogICAgICAgIHsKICAgICAgICAgICAgLyogV2UgZmFpbGVkIHRvIG1hcCB0byB0aGUgcmlnaHQgcGxhY2UgKGh1aD8pICovCiAgICAgICAgICAgIEVSUl8od2luMzIpKCAiQ3JpdGljYWwgRXJyb3I6IGZhaWxlZCB0byBtYXAgUEUgc2VjdGlvbiB0byBuZWNlc3NhcnkgYWRkcmVzcy5cbiIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICBpZiAoKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSA8IHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSkgJiYKICAgICAgICAgICAgKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSAmIChwYWdlX3NpemUtMSkpKQogICAgICAgIHsKICAgICAgICAgICAgRFdPUkQgZW5kID0gKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSAmIH4ocGFnZV9zaXplLTEpKSArIHBhZ2Vfc2l6ZTsKICAgICAgICAgICAgaWYgKGVuZCA+IHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSkgZW5kID0gcGVfc2VjLT5NaXNjLlZpcnR1YWxTaXplOwogICAgICAgICAgICBUUkFDRSgiY2xlYXJpbmcgJXAgLSAlcFxuIiwKICAgICAgICAgICAgICAgICAgUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpICsgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLAogICAgICAgICAgICAgICAgICBSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykgKyBlbmQgKTsKICAgICAgICAgICAgbWVtc2V0KCAoY2hhciopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpICsgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCAwLAogICAgICAgICAgICAgICAgICAgIGVuZCAtIHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSApOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBQZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCiAgICBpZiAoIHJlbG9jICkKICAgICAgICBkb19yZWxvY2F0aW9ucyggbG9hZF9hZGRyLCAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICopUlZBKHJlbG9jKSApOwoKICAgIC8qIFdlIGRvbid0IG5lZWQgdGhlIG9yaWduYWwgbWFwcGluZyBhbnkgbW9yZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAoSE1PRFVMRSlsb2FkX2FkZHI7CgplcnJvcjoKICAgIGlmICh1bml4X2hhbmRsZSAhPSAtMSkgY2xvc2UoIHVuaXhfaGFuZGxlICk7CiAgICBpZiAobG9hZF9hZGRyKSBWaXJ0dWFsRnJlZSggKExQVk9JRClsb2FkX2FkZHIsIDAsIE1FTV9SRUxFQVNFICk7CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wb3J0ID0gTlVMTDsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkgKnBlX3Jlc291cmNlID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIGludAlyZXN1bHQ7CgoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfaW1wb3J0ID0gKFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9yZXNvdXJjZSA9IChQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkRlYnVnIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVDsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICB3bSA9IChXSU5FX01PRFJFRiAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCp3bSkgKTsKICAgIHdtLT5tb2R1bGUgPSBoTW9kdWxlOwoKICAgIGlmICggYnVpbHRpbiApIAogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIGlmICggZmxhZ3MgJiBET05UX1JFU09MVkVfRExMX1JFRkVSRU5DRVMgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUzsKICAgIGlmICggZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFOwoKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICB3bS0+YmluZm10LnBlLnBlX2V4cG9ydCA9IHBlX2V4cG9ydDsKICAgIHdtLT5iaW5mbXQucGUucGVfaW1wb3J0ID0gcGVfaW1wb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9yZXNvdXJjZSA9IHBlX3Jlc291cmNlOwogICAgd20tPmJpbmZtdC5wZS50bHNpbmRleCA9IC0xOwoKICAgIHdtLT5maWxlbmFtZSA9IEhFQVBfc3RyZHVwQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZmlsZW5hbWUgKTsKICAgIHdtLT5tb2RuYW1lID0gc3RycmNociggd20tPmZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5tb2RuYW1lKSB3bS0+bW9kbmFtZSA9IHdtLT5maWxlbmFtZTsKICAgIGVsc2Ugd20tPm1vZG5hbWUrKzsKCiAgICByZXN1bHQgPSBHZXRTaG9ydFBhdGhOYW1lQSggd20tPmZpbGVuYW1lLCBOVUxMLCAwICk7CiAgICB3bS0+c2hvcnRfZmlsZW5hbWUgPSAoY2hhciAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVzdWx0KzEgKTsKICAgIEdldFNob3J0UGF0aE5hbWVBKCB3bS0+ZmlsZW5hbWUsIHdtLT5zaG9ydF9maWxlbmFtZSwgcmVzdWx0KzEgKTsKICAgIHdtLT5zaG9ydF9tb2RuYW1lID0gc3RycmNociggd20tPnNob3J0X2ZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5zaG9ydF9tb2RuYW1lKSB3bS0+c2hvcnRfbW9kbmFtZSA9IHdtLT5zaG9ydF9maWxlbmFtZTsKICAgIGVsc2Ugd20tPnNob3J0X21vZG5hbWUrKzsKCiAgICAvKiBMaW5rIE1PRFJFRiBpbnRvIHByb2Nlc3MgbGlzdCAqLwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKICAgIHdtLT5uZXh0ID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0OwogICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd207CiAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bTsKCiAgICBpZiAoICAgICEoIG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMICkKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRSApICkKCiAgICB7CiAgICAgICAgaWYgKCBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiApCiAgICAgICAgICAgIEZJWE1FKCAiVHJ5aW5nIHRvIGxvYWQgc2Vjb25kIC5FWEUgZmlsZTogJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiA9IHdtOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKCiAgICAvKiBEdW1wIEV4cG9ydHMgKi8KCiAgICBpZiAoIHBlX2V4cG9ydCApCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICggICAgcGVfaW1wb3J0CiAgICAgICAgICYmICEoIHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0xPQURfQVNfREFUQUZJTEUgKQogICAgICAgICAmJiAhKCB3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUyApIAogICAgICAgICAmJiBmaXh1cF9pbXBvcnRzKCB3bSApICkgCiAgICB7CiAgICAgICAgLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIGlmICggIXdtLT5wcmV2ICkKICAgICAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd20tPm5leHQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+cHJldi0+bmV4dCA9IHdtLT5uZXh0OwoKICAgICAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bS0+cHJldjsKICAgICAgICB3bS0+bmV4dCA9IHdtLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKICAgICAgICBzdHJ1Y3QgbG9hZF9kbGxfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCUhNT0RVTEUxNgloTW9kdWxlMTY7CglXSU5FX01PRFJFRgkqd207CgljaGFyICAgICAgICAJZmlsZW5hbWVbMjU2XTsKCUhBTkRMRQkJaEZpbGU7CgoJLyogU2VhcmNoIGZvciBhbmQgb3BlbiBQRSBmaWxlICovCglpZiAoIFNlYXJjaFBhdGhBKCBOVUxMLCBuYW1lLCAiLkRMTCIsIAoJICAgICAgICAgICAgICAgICAgc2l6ZW9mKGZpbGVuYW1lKSwgZmlsZW5hbWUsIE5VTEwgKSA9PSAwICkgcmV0dXJuIE5VTEw7CiAgICAgICAKCWhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAtMSApOwoJaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoJCgkvKiBMb2FkIFBFIG1vZHVsZSAqLwoJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUgKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQ3JlYXRlIDE2LWJpdCBkdW1teSBtb2R1bGUgKi8KCWlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZTMyICkpIDwgMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlTZXRMYXN0RXJyb3IoIChEV09SRCloTW9kdWxlMTYgKTsJLyogVGhpcyBzaG91bGQgZ2l2ZSB0aGUgY29ycmVjdCBlcnJvciAqLwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAzMi1iaXQgTU9EUkVGICovCglpZiAoICEod20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgZmlsZW5hbWUsIGZsYWdzLCBGQUxTRSApKSApCgl7CgkJRVJSKCAiY2FuJ3QgbG9hZCAlc1xuIiwgZmlsZW5hbWUgKTsKCQlGcmVlTGlicmFyeTE2KCBoTW9kdWxlMTYgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCglpZiAod20tPmJpbmZtdC5wZS5wZV9leHBvcnQpCgkJU05PT1BfUmVnaXN0ZXJETEwod20tPm1vZHVsZSx3bS0+bW9kbmFtZSx3bS0+YmluZm10LnBlLnBlX2V4cG9ydC0+TnVtYmVyT2ZGdW5jdGlvbnMpOwogICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgIHJlcS0+YmFzZSAgICAgICA9ICh2b2lkICopaE1vZHVsZTMyOwogICAgICAgIHJlcS0+ZGJnX29mZnNldCA9IFBFX0hFQURFUihoTW9kdWxlMzIpLT5GaWxlSGVhZGVyLlBvaW50ZXJUb1N5bWJvbFRhYmxlOwogICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IFBFX0hFQURFUihoTW9kdWxlMzIpLT5GaWxlSGVhZGVyLk51bWJlck9mU3ltYm9sczsKICAgICAgICByZXEtPm5hbWUgICAgICAgPSAmd20tPmZpbGVuYW1lOwogICAgICAgIHNlcnZlcl9jYWxsX25vZXJyKCBSRVFfTE9BRF9ETEwgKTsKICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCXJldHVybiB3bTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9VbmxvYWRMaWJyYXJ5CiAqCiAqIFVubG9hZCB0aGUgbGlicmFyeSB1bm1hcHBpbmcgdGhlIGltYWdlIGFuZCBmcmVlaW5nIHRoZSBtb2RyZWYgc3RydWN0dXJlLgogKi8Kdm9pZCBQRV9VbmxvYWRMaWJyYXJ5KFdJTkVfTU9EUkVGICp3bSkKewogICAgVFJBQ0UoIiB1bmxvYWRpbmcgJXNcbiIsIHdtLT5maWxlbmFtZSk7Ci8qICAgIFZpcnR1YWxGcmVlKCAoTFBWT0lEKXdtLT5tb2R1bGUsIDAsIE1FTV9SRUxFQVNFICk7ICovICAvKiBGSVhNRSAqLwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5zaG9ydF9maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtICk7Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KQk9PTCBQRV9Jbml0RExMKCBXSU5FX01PRFJFRiAqd20sIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkICkKewogICAgQk9PTCByZXR2ID0gVFJVRTsKICAgIGFzc2VydCggd20tPnR5cGUgPT0gTU9EVUxFMzJfUEUgKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopUlZBX1BUUiggd20tPm1vZHVsZSxPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCiAgICAgICAgcmV0diA9IGVudHJ5KCB3bS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9CgogICAgcmV0dXJuIHJldHY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfSW5pdFRscwkJCShpbnRlcm5hbCkKICoKICogSWYgaW5jbHVkZWQsIGluaXRpYWxpc2VzIHRoZSB0aHJlYWQgbG9jYWwgc3RvcmFnZXMgb2YgbW9kdWxlcy4KICogUG9pbnRlcnMgaW4gdGhvc2Ugc3RydWN0cyBhcmUgbm90IFJWQXMgYnV0IHJlYWwgcG9pbnRlcnMgd2hpY2ggaGF2ZSBiZWVuCiAqIHJlbG9jYXRlZCBieSBkb19yZWxvY2F0aW9ucygpIGFscmVhZHkuCiAqLwpzdGF0aWMgTFBWT0lECl9maXh1cF9hZGRyZXNzKFBJTUFHRV9PUFRJT05BTF9IRUFERVIgb3B0LGludCBkZWx0YSxMUFZPSUQgYWRkcikgewoJaWYgKAkoKERXT1JEKWFkZHI+b3B0LT5JbWFnZUJhc2UpICYmCgkJKChEV09SRClhZGRyPG9wdC0+SW1hZ2VCYXNlK29wdC0+U2l6ZU9mSW1hZ2UpCgkpCgkJLyogdGhlIGFkZHJlc3MgaGFzIG5vdCBiZWVuIHJlbG9jYXRlZCEgKi8KCQlyZXR1cm4gKExQVk9JRCkoKChEV09SRClhZGRyKStkZWx0YSk7CgllbHNlCgkJLyogdGhlIGFkZHJlc3MgaGFzIGJlZW4gcmVsb2NhdGVkIGFscmVhZHkgKi8KCQlyZXR1cm4gYWRkcjsKfQp2b2lkIFBFX0luaXRUbHMoIHZvaWQgKQp7CglXSU5FX01PRFJFRgkJKndtOwoJUEVfTU9EUkVGCQkqcGVtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlpZiAod20tPnR5cGUhPU1PRFVMRTMyX1BFKQoJCQljb250aW51ZTsKCQlwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIHBlbS0+dGxzaW5kZXggPT0gLTEgKSB7CgkJCUxQRFdPUkQgeGFkZHI7CgkJCXBlbS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXBlbS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7IAoKCQkgICAgIGNicyA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEscGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKTsKCQkgICAgIGlmICgqY2JzKQoJCSAgICAgICBGSVhNRSgiVExTIENhbGxiYWNrcyBhcmVuJ3QgZ29pbmcgdG8gYmUgY2FsbGVkXG4iKTsKCQl9CgoJCVRsc1NldFZhbHVlKCBwZW0tPnRsc2luZGV4LCBtZW0gKTsKCX0KfQoK