LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gU29tZXRpbWVzLCB3ZSBjYW4ndCB1c2UgTGludXggbW1hcCgpIHRvIG1tYXAoKSB0aGUgaW1hZ2VzIGRpcmVjdGx5LgogKgogKiAgIFRoZSBwcm9ibGVtIGlzLCB0aGF0IHRoZXJlIGlzIG5vdCBkaXJlY3QgMToxIG1hcHBpbmcgZnJvbSBhIGRpc2tpbWFnZSBhbmQKICogICBhIG1lbW9yeWltYWdlLiBUaGUgaGVhZGVycyBhdCB0aGUgc3RhcnQgYXJlIG1hcHBlZCBsaW5lYXIsIGJ1dCB0aGUgc2VjdGlvbnMKICogICBhcmUgbm90LiBPbGRlciB4ODYgcGUgYmluYXJpZXMgYXJlIDUxMiBieXRlIGFsaWduZWQgaW4gZmlsZSBhbmQgNDA5NiBieXRlCiAqICAgYWxpZ25lZCBpbiBtZW1vcnkuIExpbnV4IGxpa2VzIHRoZW0gNDA5NiBieXRlIGFsaWduZWQgaW4gbWVtb3J5IChkdWUgdG8KICogICB4ODYgcGFnZXNpemUsIHRoaXMgY2Fubm90IGJlIGZpeGVkIHdpdGhvdXQgYSByYXRoZXIgbGFyZ2Uga2VybmVsIHJld3JpdGUpCiAqICAgYW5kICdibG9ja3NpemUnIGZpbGUtYWxpZ25lZCAob2Zmc2V0cykuIFNpbmNlIHdlIGhhdmUgNTEyLzEwMjQvMjA0OCAoQ0RST00pCiAqICAgYW5kIG90aGVyIGJ5dGUgYmxvY2tzaXplcywgd2UgY2FuJ3QgYWx3YXlzIGRvIHRoaXMuICBXZSAqY2FuKiBkbyB0aGlzIGZvcgogKiAgIG5ld2VyIHBlIGJpbmFyaWVzIHByb2R1Y2VkIGJ5IE1TVkMgNSBhbmQgbGF0ZXIsIHNpbmNlIHRoZXkgYXJlIGFsc28gYWxpZ25lZAogKiAgIHRvIDQwOTYgYnl0ZSBib3VuZGFyaWVzIG9uIGRpc2suCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiY2FsbGJhY2suaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAic25vb3AuaCIKI2luY2x1ZGUgInNlcnZlci5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbjMyKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKGRlbGF5aGxwKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKGZpeHVwKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChzZWdtZW50KTsKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHZvaWQgKikoKGNoYXIgKilsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpKQoKI2RlZmluZSBBZGp1c3RQdHIocHRyLGRlbHRhKSAoKGNoYXIgKikocHRyKSArIChkZWx0YSkpCgp2b2lkIGR1bXBfZXhwb3J0cyggSE1PRFVMRSBoTW9kdWxlICkKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBoTW9kdWxlOwoKICBEV09SRCBydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKICBEV09SRCBydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnRzID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKVJWQShydmFfc3RhcnQpOwoKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIFRSQUNFKCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBUUkFDRSgiTW9kdWxlIG5hbWUgaXMgJXMsICVsZCBmdW5jdGlvbnMsICVsZCBuYW1lc1xuIiwgCiAgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBUUkFDRSgiIE9yZCAgICBSVkEgICAgIEFkZHIgICBOYW1lXG4iICk7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyssIGZ1bmN0aW9uKyspCiAgewogICAgICBpZiAoISpmdW5jdGlvbikgY29udGludWU7ICAvKiBObyBzdWNoIGZ1bmN0aW9uICovCiAgICAgIGlmIChUUkFDRV9PTih3aW4zMikpCiAgICAgIHsKCURQUklOVEYoICIlNGxkICUwOGx4ICVwIiwgaSArIHBlX2V4cG9ydHMtPkJhc2UsICpmdW5jdGlvbiwgUlZBKCpmdW5jdGlvbikgKTsKCS8qIENoZWNrIGlmIHdlIGhhdmUgYSBuYW1lIGZvciBpdCAqLwoJZm9yIChqID0gMDsgaiA8IHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXM7IGorKykKICAgICAgICAgIGlmIChvcmRpbmFsW2pdID09IGkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgRFBSSU5URiggIiAgJXMiLCAoY2hhciopUlZBKG5hbWVbal0pICk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CglpZiAoKCpmdW5jdGlvbiA+PSBydmFfc3RhcnQpICYmICgqZnVuY3Rpb24gPD0gcnZhX2VuZCkpCgkgIERQUklOVEYoIiAoZm9yd2FyZGVkIC0+ICVzKSIsIChjaGFyICopUlZBKCpmdW5jdGlvbikpOwoJRFBSSU5URigiXG4iKTsKICAgICAgfQogIH0KfQoKLyogTG9vayB1cCB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uIG9yIG9yZGluYWwgaW4gdGhlIGV4cG9ydGxpc3Q6CiAqIElmIGl0IGlzIGEgc3RyaW5nOgogKiAJLSBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBOYW1lIGxpc3QuIAogKgktIGxvb2sgdXAgdGhlIG9yZGluYWwgd2l0aCB0aGF0IGluZGV4LgogKgktIHVzZSB0aGUgb3JkaW5hbCBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqIElmIGl0IGlzIGEgb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKi8KRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSwJLyogW2luXSBmdW5jdGlvbiBuYW1lICovCiAgICAgICAgQk9PTCBzbm9vcCApCnsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsczsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZSA9IE5VTEw7CglpbnQJCQkJaSwgb3JkaW5hbDsKCVBFX01PRFJFRgkJCSpwZW0gPSAmKHdtLT5iaW5mbXQucGUpOwoJSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAJCSpleHBvcnRzID0gcGVtLT5wZV9leHBvcnQ7Cgl1bnNpZ25lZCBpbnQJCQlsb2FkX2FkZHIgPSB3bS0+bW9kdWxlOwoJdV9sb25nCQkJCXJ2YV9zdGFydCwgcnZhX2VuZCwgYWRkcjsKCWNoYXIJCQkJKiBmb3J3YXJkOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQoJCVRSQUNFKCIoJXMpXG4iLGZ1bmNOYW1lKTsKCWVsc2UKCQlUUkFDRSgiKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCS8qIE5vdCBhIGZhdGFsIHByb2JsZW0sIHNvbWUgYXBwcyBkbwoJCSAqIEdldFByb2NBZGRyZXNzKDAsIlJlZ2lzdGVyUGVuQXBwIikgd2hpY2ggdHJpZ2dlcnMgdGhpcwoJCSAqIGNhc2UuCgkJICovCgkJV0FSTigiTW9kdWxlICUwOHgoJXMpL01PRFJFRiAlcCBkb2Vzbid0IGhhdmUgYSBleHBvcnRzIHRhYmxlLlxuIix3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFscz0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogZmlyc3QgdHJ5IGEgYmluYXJ5IHNlYXJjaCAqLwogICAgICAgICAgICBpbnQgbWluID0gMCwgbWF4ID0gZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyAtIDE7CiAgICAgICAgICAgIHdoaWxlIChtaW4gPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcmVzLCBwb3MgPSAobWluICsgbWF4KSAvIDI7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW3Bvc10pOwogICAgICAgICAgICAgICAgaWYgKCEocmVzID0gc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW3Bvc107CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZXMgPiAwKSBtYXggPSBwb3MgLSAxOwogICAgICAgICAgICAgICAgZWxzZSBtaW4gPSBwb3MgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIG5vdyB0cnkgYSBsaW5lYXIgc2VhcmNoIGluIGNhc2UgdGhlIG5hbWVzIGFyZW4ndCBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCAiJXMuJXMgcmVxdWlyZWQgYSBsaW5lYXIgc2VhcmNoXG4iLCB3bS0+bW9kbmFtZSwgZnVuY05hbWUgKTsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbaV07CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KICAgICAgICBlbHNlICAvKiBmaW5kIGJ5IG9yZGluYWwgKi8KICAgICAgICB7CiAgICAgICAgICAgIG9yZGluYWwgPSBMT1dPUkQoZnVuY05hbWUpIC0gZXhwb3J0cy0+QmFzZTsKICAgICAgICAgICAgaWYgKHNub29wICYmIG5hbWUpICAvKiBuZWVkIHRvIGZpbmQgYSBuYW1lIGZvciBpdCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChvcmRpbmFsc1tpXSA9PSBvcmRpbmFsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJfQoKIGZvdW5kOgogICAgICAgIGlmIChvcmRpbmFsID49IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIglvcmRpbmFsICVsZCBvdXQgb2YgcmFuZ2UhXG4iLCBvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgYWRkciA9IGZ1bmN0aW9uW29yZGluYWxdOwogICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICB7CiAgICAgICAgICAgIEZBUlBST0MgcHJvYyA9IFJWQShhZGRyKTsKICAgICAgICAgICAgaWYgKHNub29wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWVuYW1lKSBlbmFtZSA9ICJAIjsKICAgICAgICAgICAgICAgIHByb2MgPSBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLG9yZGluYWwscHJvYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHByb2M7CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIGZvcndhcmQgZW50cnkgcG9pbnQgKi8KICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd207CiAgICAgICAgICAgICAgICBjaGFyICpmb3J3YXJkID0gUlZBKGFkZHIpOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChlbmQgLSBmb3J3YXJkID49IHNpemVvZihtb2R1bGUpKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG1lbWNweSggbW9kdWxlLCBmb3J3YXJkLCBlbmQgLSBmb3J3YXJkICk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJtb2R1bGUgbm90IGZvdW5kIGZvciBmb3J3YXJkICclcydcbiIsIGZvcndhcmQgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KCQlyZXR1cm4gTU9EVUxFX0dldFByb2NBZGRyZXNzKCB3bS0+bW9kdWxlLCBlbmQgKyAxLCBzbm9vcCApOwoJfQp9CgpEV09SRCBmaXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgUEVfTU9EUkVGCQkJKnBlbTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBhc3NlcnQod20tPnR5cGU9PU1PRFVMRTMyX1BFKTsKICAgIHBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0UoIkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICBpZiAoIXBlX2ltcCkgcmV0dXJuIDA7CgogICAgLyogV2UgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgaW1wb3J0IHdpdGggITAgY2hhcmFjdGVyaXN0aWNzIGFuZAogICAgICogZGV0ZWN0IGJyb2tlbiBpbXBvcnRzIHdpdGggYWxsIGNoYXJhY3RlcmlzdHNpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CiAgICAJV0lORV9NT0RSRUYJCSp3bUltcDsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKIAljaGFyCQkJKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCgl3bUltcCA9IE1PRFVMRV9Mb2FkTGlicmFyeUV4QSggbmFtZSwgMCwgMCApOwoJaWYgKCF3bUltcCkgewoJICAgIEVSUl8obW9kdWxlKSgiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0UoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcywlZFxuIiwgbmFtZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgKExQQ1NUUilvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKCJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMuJWRcbiIsbmFtZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgcGVfbmFtZS0+SGludCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZSggSE1PRFVMRSBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIFRSQUNFKCJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogICAgVFJBQ0UoIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBUUkFDRSgiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZT1tYXgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKICAgICAgICB2bWFfc2l6ZT1tYXgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplKTsKICAgICAgICBwZV9zZWcrKzsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoIHVuc2lnbmVkIGludCBsb2FkX2FkZHIsIElNQUdFX0JBU0VfUkVMT0NBVElPTiAqciApCnsKICAgIGludCBkZWx0YSA9IGxvYWRfYWRkciAtIFBFX0hFQURFUihsb2FkX2FkZHIpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICBpbnQJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKICAgIGludAlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJVFJBQ0VfKGZpeHVwKSgiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRV8oZml4dXApKCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CgkJCQkvKiBGSVhNRTogaWYgdGhpcyBpcyBhbiBleHBvcnRlZCBhZGRyZXNzLCBmaXJlIHVwIGVuaGFuY2VkIGxvZ2ljICovCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCUZJWE1FKCJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJRklYTUUoIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJRklYTUUoIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lICkKewogICAgSE1PRFVMRQloTW9kdWxlOwogICAgSEFORExFCW1hcHBpbmc7CgogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VjOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBpbnQJaSwgcmF3c2l6ZSwgbG93ZXN0X3ZhLCB2bWFfc2l6ZSwgZmlsZV9zaXplID0gMDsKICAgIERXT1JEIGxvYWRfYWRkciA9IDAsIGFvZXAsIHJlbG9jID0gMDsKICAgIHN0cnVjdCBnZXRfcmVhZF9mZF9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwogICAgaW50IHVuaXhfaGFuZGxlID0gLTE7CiAgICBpbnQgcGFnZV9zaXplID0gVklSVFVBTF9HZXRQYWdlU2l6ZSgpOwoKICAgIC8qIFJldHJpZXZlIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZSggaEZpbGUsICZiaGZpICkgKSAKICAgIAlmaWxlX3NpemUgPSBiaGZpLm5GaWxlU2l6ZUxvdzsgLyogRklYTUU6IDY0IGJpdCAqLwoKICAgIC8qIE1hcCB0aGUgUEUgZmlsZSBzb21ld2hlcmUgKi8KICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBQQUdFX1JFQURPTkxZIHwgU0VDX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKQogICAgewogICAgICAgIFdBUk4oIkNyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGhNb2R1bGUgPSAoSE1PRFVMRSlNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFoTW9kdWxlKQogICAgewogICAgICAgIFdBUk4oIk1hcFZpZXdPZkZpbGUgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaWYgKCAqKFdPUkQqKWhNb2R1bGUgIT1JTUFHRV9ET1NfU0lHTkFUVVJFKQogICAgewogICAgICAgIFdBUk4oIiVzIGltYWdlIGRvZXNuJ3QgaGF2ZSBET1Mgc2lnbmF0dXJlLCBidXQgMHglMDR4XG4iLCBmaWxlbmFtZSwqKFdPUkQqKWhNb2R1bGUpOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CgogICAgLyogQ2hlY2sgc2lnbmF0dXJlICovCiAgICBpZiAoIG50LT5TaWduYXR1cmUgIT0gSU1BR0VfTlRfU0lHTkFUVVJFICkKICAgIHsKICAgICAgICBXQVJOKCIlcyBpbWFnZSBkb2Vzbid0IGhhdmUgUEUgc2lnbmF0dXJlLCBidXQgMHglMDhseFxuIiwgZmlsZW5hbWUsIG50LT5TaWduYXR1cmUgKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBDaGVjayBhcmNoaXRlY3R1cmUgKi8KICAgIGlmICggbnQtPkZpbGVIZWFkZXIuTWFjaGluZSAhPSBJTUFHRV9GSUxFX01BQ0hJTkVfSTM4NiApCiAgICB7CiAgICAgICAgTUVTU0FHRSgiVHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CiAgICAgICAgc3dpdGNoIChudC0+RmlsZUhlYWRlci5NYWNoaW5lKQogICAgICAgIHsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOiBNRVNTQUdFKCJVbmtub3duIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6ICAgIE1FU1NBR0UoIkk4NjAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6ICAgTUVTU0FHRSgiUjMwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6ICAgTUVTU0FHRSgiUjQwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjEwMDAwOiAgTUVTU0FHRSgiUjEwMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0FMUEhBOiAgIE1FU1NBR0UoIkFscGhhIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6IE1FU1NBR0UoIlBvd2VyUEMiKTsgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogTUVTU0FHRSgiVW5rbm93bi0lMDR4IiwgbnQtPkZpbGVIZWFkZXIuTWFjaGluZSk7IGJyZWFrOwogICAgICAgIH0KICAgICAgICBNRVNTQUdFKCIpXG4iKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBGaW5kIG91dCBob3cgbGFyZ2UgdGhpcyBleGVjdXRlYWJsZSBzaG91bGQgYmUgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICByYXdzaXplID0gMDsgbG93ZXN0X3ZhID0gMHgxMDAwMDsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspIAogICAgewogICAgICAgIGlmIChsb3dlc3RfdmEgPiBwZV9zZWNbaV0uVmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgbG93ZXN0X3ZhID0gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzOwogICAgCWlmIChwZV9zZWNbaV0uQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkgICAgY29udGludWU7CglpZiAocGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGEgPiByYXdzaXplKQoJICAgIHJhd3NpemUgPSBwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YStwZV9zZWNbaV0uU2l6ZU9mUmF3RGF0YTsKICAgIH0KIAogICAgLyogQ2hlY2sgZmlsZSBzaXplICovCiAgICBpZiAoIGZpbGVfc2l6ZSAmJiBmaWxlX3NpemUgPCByYXdzaXplICkKICAgIHsKICAgICAgICBFUlIoIlBFIG1vZHVsZSBpcyB0b28gc21hbGwgKGhlYWRlcjogJWQsIGZpbGVzaXplOiAlZCksICIKICAgICAgICAgICAgICAgICAgICAicHJvYmFibHkgdHJ1bmNhdGVkIGRvd25sb2FkP1xuIiwgCiAgICAgICAgICAgICAgICAgICAgcmF3c2l6ZSwgZmlsZV9zaXplICk7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgZW50cnlwb2ludCBhZGRyZXNzICovCiAgICBhb2VwID0gbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQ7CiAgICBpZiAoYW9lcCAmJiAoYW9lcCA8IGxvd2VzdF92YSkpCiAgICAgICAgRklYTUUoIlZJUlVTIFdBUk5JTkc6ICclcycgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICAgImJlbG93IHRoZSBmaXJzdCB2aXJ0dWFsIGFkZHJlc3MgKDB4JTA4eCkgIgogICAgICAgICAgICAgICAgICAgICAgIihwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGFvZXAsIGxvd2VzdF92YSApOwoKCiNpZiAwCiAgICAvKiBGSVhNRTogIEhhY2shICBXaGlsZSB3ZSBkb24ndCByZWFsbHkgc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgeWV0LAogICAgICogICAgICAgICB0aGlzIGNoZWNrcyBmb3IgdGhvc2Ugc3BlY2lhbCBjYXNlcyB3aGVyZSB0aGUgd2hvbGUgRExMCiAgICAgKiAgICAgICAgIGNvbnNpc3RzIG9ubHkgb2Ygc2hhcmVkIHNlY3Rpb25zIGFuZCBpcyBtYXBwZWQgaW50byB0aGUKICAgICAqICAgICAgICAgc2hhcmVkIGFkZHJlc3Mgc3BhY2UgPiAyR0IuICBJbiB0aGlzIGNhc2UsIHdlIGFzc3VtZSB0aGF0CiAgICAgKiAgICAgICAgIHRoZSBtb2R1bGUgZ290IG1hcHBlZCBhdCBpdHMgYmFzZSBhZGRyZXNzLiBUaHVzIHdlIHNpbXBseQogICAgICogICAgICAgICBjaGVjayB3aGV0aGVyIHRoZSBtb2R1bGUgaGFzIGFjdHVhbGx5IGJlZW4gbWFwcGVkIHRoZXJlCiAgICAgKiAgICAgICAgIGFuZCB1c2UgaXQsIGlmIHNvLiAgVGhpcyBpcyBuZWVkZWQgdG8gZ2V0IFdpbjk1IFVTRVIzMi5ETEwKICAgICAqICAgICAgICAgdG8gd29yayAodW50aWwgd2Ugc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgcHJvcGVybHkpLgogICAgICovCgogICAgaWYgKCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCApCiAgICB7CiAgICAgICAgSE1PRFVMRSBzaGFyZWRNb2QgPSAoSE1PRFVMRSludC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOyAKICAgICAgICBJTUFHRV9OVF9IRUFERVJTICpzaGFyZWROdCA9IChQSU1BR0VfTlRfSEVBREVSUykKICAgICAgICAgICAgICAgKCAoTFBCWVRFKXNoYXJlZE1vZCArICgoTFBCWVRFKW50IC0gKExQQllURSloTW9kdWxlKSApOwoKICAgICAgICAvKiBXZWxsLCB0aGlzIGNoZWNrIGlzIG5vdCByZWFsbHkgY29tcHJlaGVuc2l2ZSwgCiAgICAgICAgICAgYnV0IHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3Igbm93IC4uLiAqLwogICAgICAgIGlmICggICAgIUlzQmFkUmVhZFB0ciggKExQQllURSlzaGFyZWRNb2QsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIChMUEJZVEUpc2hhcmVkTW9kLCAoTFBCWVRFKWhNb2R1bGUsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApID09IDAKICAgICAgICAgICAgICYmICFJc0JhZFJlYWRQdHIoIHNoYXJlZE50LCBzaXplb2YoSU1BR0VfTlRfSEVBREVSUykgKQogICAgICAgICAgICAgJiYgbWVtY21wKCBzaGFyZWROdCwgbnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApID09IDAgKQogICAgICAgIHsKICAgICAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgICAgICAgICAgcmV0dXJuIHNoYXJlZE1vZDsKICAgICAgICB9CiAgICB9CiNlbmRpZgoKICAgIC8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgbW9kdWxlICovCiAgICBsb2FkX2FkZHIgPSBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwogICAgdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CgogICAgbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICBpZiAobG9hZF9hZGRyID09IDApIAogICAgewogICAgICAgIC8qIFdlIG5lZWQgdG8gcGVyZm9ybSBiYXNlIHJlbG9jYXRpb25zICovCiAgICAgICAgRklYTUUoIldlIG5lZWQgdG8gcGVyZm9ybSBiYXNlIHJlbG9jYXRpb25zIGZvciAlc1xuIiwgZmlsZW5hbWUpOwoJZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQzsKICAgICAgICBpZiAoZGlyLT5TaXplKQogICAgICAgICAgICByZWxvYyA9IGRpci0+VmlydHVhbEFkZHJlc3M7CiAgICAgICAgZWxzZSAKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCAiRkFUQUw6IE5lZWQgdG8gcmVsb2NhdGUgJXMsIGJ1dCBubyByZWxvY2F0aW9uIHJlY29yZHMgcHJlc2VudCAoJXMpLiBUcnkgdG8gcnVuIHRoYXQgZmlsZSBkaXJlY3RseSAhXG4iLAogICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgICAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzJklNQUdFX0ZJTEVfUkVMT0NTX1NUUklQUEVEKT8KICAgICAgICAgICAgICAgICAgICJzdHJpcHBlZCBkdXJpbmcgbGluayIgOiAidW5rbm93biByZWFzb24iICk7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIC8qIEZJWE1FOiBJZiB3ZSBuZWVkIHRvIHJlbG9jYXRlIGEgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikgd2Ugc2hvdWxkCiAgICAgICAgICogICAgICAgIHJlYWxseSBtYWtlIHN1cmUgdGhhdCB0aGUgKm5ldyogYmFzZSBhZGRyZXNzIGlzIGFsc28gPiAyR0IuCiAgICAgICAgICogICAgICAgIFNvbWUgRExMcyByZWFsbHkgY2hlY2sgdGhlIE1TQiBvZiB0aGUgbW9kdWxlIGhhbmRsZSA6LS8KICAgICAgICAgKi8KICAgICAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgICAgICAgICAgRVJSKCAiRm9yY2VkIHRvIHJlbG9jYXRlIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpLiBUaGlzIGlzIG5vdCBnb29kLlxuIiApOwoKICAgICAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCSBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAoIWxvYWRfYWRkcikgewogICAgICAgICAgICBGSVhNRV8od2luMzIpKAogICAgICAgICAgICAgICAgICAgIkZBVEFMOiBDb3VsZG4ndCBsb2FkIG1vZHVsZSAlcyAob3V0IG9mIG1lbW9yeSwgJWQgbmVlZGVkKSFcbiIsIGZpbGVuYW1lLCB2bWFfc2l6ZSk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7Cgl9CiAgICB9CgogICAgVFJBQ0UoIkxvYWQgYWRkciBpcyAlbHggKGJhc2UgJWx4KSwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICBsb2FkX2FkZHIsIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UsIHZtYV9zaXplICk7CiAgICBUUkFDRV8oc2VnbWVudCkoIkxvYWRpbmcgJXMgYXQgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbG9hZF9hZGRyLCB2bWFfc2l6ZSApOwoKI2lmIDAKICAgIC8qIFN0b3JlIHRoZSBOVCBoZWFkZXIgYXQgdGhlIGxvYWQgYWRkciAqLwogICAgKihQSU1BR0VfRE9TX0hFQURFUilsb2FkX2FkZHIgPSAqKFBJTUFHRV9ET1NfSEVBREVSKWhNb2R1bGU7CiAgICAqUEVfSEVBREVSKCBsb2FkX2FkZHIgKSA9ICpudDsKICAgIG1lbWNweSggUEVfU0VDVElPTlMobG9hZF9hZGRyKSwgUEVfU0VDVElPTlMoaE1vZHVsZSksCiAgICAgICAgICAgIHNpemVvZihJTUFHRV9TRUNUSU9OX0hFQURFUikgKiBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zICk7CgogICAgLyogQ29waWVzIGFsbCBzdHVmZiB1cCB0byB0aGUgZmlyc3Qgc2VjdGlvbi4gSW5jbHVkaW5nIHdpbjMyIHZpcnVzZXMuICovCiAgICBtZW1jcHkoIGxvYWRfYWRkciwgaE1vZHVsZSwgbG93ZXN0X2ZhICk7CiNlbmRpZgoKICAgIHJlcS0+aGFuZGxlID0gaEZpbGU7CiAgICBzZXJ2ZXJfY2FsbF9mZCggUkVRX0dFVF9SRUFEX0ZELCAtMSwgJnVuaXhfaGFuZGxlICk7CiAgICBpZiAodW5peF9oYW5kbGUgPT0gLTEpIGdvdG8gZXJyb3I7CgogICAgLyogTWFwIHRoZSBoZWFkZXIgKi8KICAgIGlmIChGSUxFX2RvbW1hcCggdW5peF9oYW5kbGUsICh2b2lkICopbG9hZF9hZGRyLCAwLCBudC0+T3B0aW9uYWxIZWFkZXIuU2l6ZU9mSGVhZGVycywKICAgICAgICAgICAgICAgICAgICAgMCwgMCwgUFJPVF9FWEVDIHwgUFJPVF9XUklURSB8IFBST1RfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgTUFQX1BSSVZBVEUgfCBNQVBfRklYRUQgKSAhPSAodm9pZCopbG9hZF9hZGRyKQogICAgewogICAgICAgIEVSUl8od2luMzIpKCAiQ3JpdGljYWwgRXJyb3I6IGZhaWxlZCB0byBtYXAgUEUgaGVhZGVyIHRvIG5lY2Vzc2FyeSBhZGRyZXNzLlxuIik7CQogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ29weSBzZWN0aW9ucyBpbnRvIG1vZHVsZSBpbWFnZSAqLwogICAgcGVfc2VjID0gUEVfU0VDVElPTlMoIGhNb2R1bGUgKTsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlYysrKQogICAgewogICAgICAgIGlmICghcGVfc2VjLT5TaXplT2ZSYXdEYXRhIHx8ICFwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEpIGNvbnRpbnVlOwogICAgICAgIFRSQUNFKCIlczogbW1hcGluZyBzZWN0aW9uICVzIGF0ICVwIG9mZiAlbHggc2l6ZSAlbHgvJWx4XG4iLAogICAgICAgICAgICAgIGZpbGVuYW1lLCBwZV9zZWMtPk5hbWUsICh2b2lkKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgcGVfc2VjLT5Qb2ludGVyVG9SYXdEYXRhLCBwZV9zZWMtPlNpemVPZlJhd0RhdGEsIHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSApOwogICAgICAgIGlmIChGSUxFX2RvbW1hcCggdW5peF9oYW5kbGUsICh2b2lkKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAwLCBwZV9zZWMtPlNpemVPZlJhd0RhdGEsIDAsIHBlX3NlYy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIFBST1RfRVhFQyB8IFBST1RfV1JJVEUgfCBQUk9UX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICBNQVBfUFJJVkFURSB8IE1BUF9GSVhFRCApICE9ICh2b2lkKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBmYWlsZWQgdG8gbWFwIHRvIHRoZSByaWdodCBwbGFjZSAoaHVoPykgKi8KICAgICAgICAgICAgRVJSXyh3aW4zMikoICJDcml0aWNhbCBFcnJvcjogZmFpbGVkIHRvIG1hcCBQRSBzZWN0aW9uIHRvIG5lY2Vzc2FyeSBhZGRyZXNzLlxuIik7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIGlmICgocGVfc2VjLT5TaXplT2ZSYXdEYXRhIDwgcGVfc2VjLT5NaXNjLlZpcnR1YWxTaXplKSAmJgogICAgICAgICAgICAocGVfc2VjLT5TaXplT2ZSYXdEYXRhICYgKHBhZ2Vfc2l6ZS0xKSkpCiAgICAgICAgewogICAgICAgICAgICBEV09SRCBlbmQgPSAocGVfc2VjLT5TaXplT2ZSYXdEYXRhICYgfihwYWdlX3NpemUtMSkpICsgcGFnZV9zaXplOwogICAgICAgICAgICBpZiAoZW5kID4gcGVfc2VjLT5NaXNjLlZpcnR1YWxTaXplKSBlbmQgPSBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemU7CiAgICAgICAgICAgIFRSQUNFKCJjbGVhcmluZyAlcCAtICVwXG4iLAogICAgICAgICAgICAgICAgICBSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykgKyBwZV9zZWMtPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgIFJWQShwZV9zZWMtPlZpcnR1YWxBZGRyZXNzKSArIGVuZCApOwogICAgICAgICAgICBtZW1zZXQoIChjaGFyKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykgKyBwZV9zZWMtPlNpemVPZlJhd0RhdGEsIDAsCiAgICAgICAgICAgICAgICAgICAgZW5kIC0gcGVfc2VjLT5TaXplT2ZSYXdEYXRhICk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFBlcmZvcm0gYmFzZSByZWxvY2F0aW9uLCBpZiBuZWNlc3NhcnkgKi8KICAgIGlmICggcmVsb2MgKQogICAgICAgIGRvX3JlbG9jYXRpb25zKCBsb2FkX2FkZHIsIChJTUFHRV9CQVNFX1JFTE9DQVRJT04gKilSVkEocmVsb2MpICk7CgogICAgLyogV2UgZG9uJ3QgbmVlZCB0aGUgb3JpZ25hbCBtYXBwaW5nIGFueSBtb3JlICovCiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIChITU9EVUxFKWxvYWRfYWRkcjsKCmVycm9yOgogICAgaWYgKHVuaXhfaGFuZGxlICE9IC0xKSBjbG9zZSggdW5peF9oYW5kbGUgKTsKICAgIGlmIChsb2FkX2FkZHIpIFZpcnR1YWxGcmVlKCAoTFBWT0lEKWxvYWRfYWRkciwgMCwgTUVNX1JFTEVBU0UgKTsKICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRTMyLCBsaW5rIGl0IGludG8KICogcHJvY2VzcyBtb2RyZWZfbGlzdCwgYW5kIGZpeHVwIGFsbCBpbXBvcnRzLgogKgogKiBOb3RlOiBoTW9kdWxlIG11c3QgcG9pbnQgdG8gYSBjb3JyZWN0bHkgYWxsb2NhdGVkIFBFIGltYWdlLAogKiAgICAgICB3aXRoIGJhc2UgcmVsb2NhdGlvbnMgYXBwbGllZDsgdGhlIDE2LWJpdCBkdW1teSBtb2R1bGUKICogICAgICAgYXNzb2NpYXRlZCB0byBoTW9kdWxlIG11c3QgYWxyZWFkeSBleGlzdC4KICoKICogTm90ZTogVGhpcyByb3V0aW5lIG11c3QgYWx3YXlzIGJlIGNhbGxlZCBpbiB0aGUgY29udGV4dCBvZiB0aGUKICogICAgICAgcHJvY2VzcyB0aGF0IGlzIHRvIG93biB0aGUgbW9kdWxlIHRvIGJlIGNyZWF0ZWQuCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzLCBCT09MIGJ1aWx0aW4gKQp7CiAgICBEV09SRCBsb2FkX2FkZHIgPSAoRFdPUkQpaE1vZHVsZTsgIC8qIGZvciBSVkEgKi8KICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUEVfSEVBREVSKGhNb2R1bGUpOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpwZV9pbXBvcnQgPSBOVUxMOwogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0ID0gTlVMTDsKICAgIElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSAqcGVfcmVzb3VyY2UgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgaW50CXJlc3VsdDsKCgogICAgLyogUmV0cmlldmUgRGF0YURpcmVjdG9yeSBlbnRyaWVzICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfZXhwb3J0ID0gKFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9pbXBvcnQgPSAoUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfUkVTT1VSQ0U7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX3Jlc291cmNlID0gKFBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUc7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiRGVidWcgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09QWVJJR0hUOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkNvcHlyaWdodCBzdHJpbmcgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFI7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTIGhhbmRsZWQgaW4gUEVfVGxzSW5pdCAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJRzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVMQVlfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgIHsKCQlUUkFDRSgiRGVsYXllZCBpbXBvcnQsIHN0dWIgY2FsbHMgTG9hZExpYnJhcnlcbiIgKTsKCQkvKgoJCSAqIE5vdGhpbmcgdG8gZG8gaGVyZS4KCQkgKi8KCiNpZmRlZiBJbWdEZWxheURlc2NyCgkJLyoKCQkgKiBUaGlzIGNvZGUgaXMgdXNlZnVsIHRvIG9ic2VydmUgd2hhdCB0aGUgaGVjayBpcyBnb2luZyBvbi4KCQkgKi8KCQl7CgkJSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgIHBlX2RlbGF5ID0gKFBJbWdEZWxheURlc2NyKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+c3pOYW1lID0gJXNcbiIsIHBlX2RlbGF5LT5zek5hbWUpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5waG1vZCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5waG1vZCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJTlQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElOVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBCb3VuZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wQm91bmRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5kd1RpbWVTdGFtcCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5kd1RpbWVTdGFtcCk7CiAgICAgICAgfQojZW5kaWYgLyogSW1nRGVsYXlEZXNjciAqLwoJfQoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT01fREVTQ1JJUFRPUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrMTU7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIiApOwoKCiAgICAvKiBBbGxvY2F0ZSBhbmQgZmlsbCBXSU5FX01PRFJFRiAqLwoKICAgIHdtID0gKFdJTkVfTU9EUkVGICopSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKndtKSApOwogICAgd20tPm1vZHVsZSA9IGhNb2R1bGU7CgogICAgaWYgKCBidWlsdGluICkgCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0lOVEVSTkFMOwogICAgaWYgKCBmbGFncyAmIERPTlRfUkVTT0xWRV9ETExfUkVGRVJFTkNFUyApCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTOwogICAgaWYgKCBmbGFncyAmIExPQURfTElCUkFSWV9BU19EQVRBRklMRSApCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0xPQURfQVNfREFUQUZJTEU7CgogICAgd20tPnR5cGUgPSBNT0RVTEUzMl9QRTsKICAgIHdtLT5iaW5mbXQucGUucGVfZXhwb3J0ID0gcGVfZXhwb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9pbXBvcnQgPSBwZV9pbXBvcnQ7CiAgICB3bS0+YmluZm10LnBlLnBlX3Jlc291cmNlID0gcGVfcmVzb3VyY2U7CiAgICB3bS0+YmluZm10LnBlLnRsc2luZGV4ID0gLTE7CgogICAgd20tPmZpbGVuYW1lID0gSEVBUF9zdHJkdXBBKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBmaWxlbmFtZSApOwogICAgd20tPm1vZG5hbWUgPSBzdHJyY2hyKCB3bS0+ZmlsZW5hbWUsICdcXCcgKTsKICAgIGlmICghd20tPm1vZG5hbWUpIHdtLT5tb2RuYW1lID0gd20tPmZpbGVuYW1lOwogICAgZWxzZSB3bS0+bW9kbmFtZSsrOwoKICAgIHJlc3VsdCA9IEdldFNob3J0UGF0aE5hbWVBKCB3bS0+ZmlsZW5hbWUsIE5VTEwsIDAgKTsKICAgIHdtLT5zaG9ydF9maWxlbmFtZSA9IChjaGFyICopSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCByZXN1bHQrMSApOwogICAgR2V0U2hvcnRQYXRoTmFtZUEoIHdtLT5maWxlbmFtZSwgd20tPnNob3J0X2ZpbGVuYW1lLCByZXN1bHQrMSApOwogICAgd20tPnNob3J0X21vZG5hbWUgPSBzdHJyY2hyKCB3bS0+c2hvcnRfZmlsZW5hbWUsICdcXCcgKTsKICAgIGlmICghd20tPnNob3J0X21vZG5hbWUpIHdtLT5zaG9ydF9tb2RuYW1lID0gd20tPnNob3J0X2ZpbGVuYW1lOwogICAgZWxzZSB3bS0+c2hvcnRfbW9kbmFtZSsrOwoKICAgIC8qIExpbmsgTU9EUkVGIGludG8gcHJvY2VzcyBsaXN0ICovCgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgd20tPm5leHQgPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7CiAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3QgPSB3bTsKICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtOwoKICAgIGlmICggICAgISggbnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwgKQogICAgICAgICAmJiAhKCB3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFICkgKQoKICAgIHsKICAgICAgICBpZiAoIFBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmICkKICAgICAgICAgICAgRklYTUUoICJUcnlpbmcgdG8gbG9hZCBzZWNvbmQgLkVYRSBmaWxlOiAlc1xuIiwgZmlsZW5hbWUgKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmID0gd207CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmICggcGVfZXhwb3J0ICkKICAgICAgICBkdW1wX2V4cG9ydHMoIGhNb2R1bGUgKTsKCiAgICAvKiBGaXh1cCBJbXBvcnRzICovCgogICAgaWYgKCAgICBwZV9pbXBvcnQKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRSApCiAgICAgICAgICYmICEoIHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTICkgCiAgICAgICAgICYmIGZpeHVwX2ltcG9ydHMoIHdtICkgKSAKICAgIHsKICAgICAgICAvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCiAgICAgICAgaWYgKCAhd20tPnByZXYgKQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5wcmV2LT5uZXh0ID0gd20tPm5leHQ7CgogICAgICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtLT5wcmV2OwogICAgICAgIHdtLT5uZXh0ID0gd20tPnByZXYgPSBOVUxMOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlBST0NFU1NfQ3VycmVudCgpLT5jcml0X3NlY3Rpb24gKTsKCiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIGl0IHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gd207Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFBFIExpYnJhcnkgTG9hZGVyIGZyb250ZW5kLiAKICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpXSU5FX01PRFJFRiAqUEVfTG9hZExpYnJhcnlFeEEgKExQQ1NUUiBuYW1lLCBEV09SRCBmbGFncykKewogICAgICAgIHN0cnVjdCBsb2FkX2RsbF9yZXF1ZXN0ICpyZXEgPSBnZXRfcmVxX2J1ZmZlcigpOwoJSE1PRFVMRQkJaE1vZHVsZTMyOwoJSE1PRFVMRTE2CWhNb2R1bGUxNjsKCVdJTkVfTU9EUkVGCSp3bTsKCWNoYXIgICAgICAgIAlmaWxlbmFtZVsyNTZdOwoJSEFORExFCQloRmlsZTsKCgkvKiBTZWFyY2ggZm9yIGFuZCBvcGVuIFBFIGZpbGUgKi8KCWlmICggU2VhcmNoUGF0aEEoIE5VTEwsIG5hbWUsICIuRExMIiwgCgkgICAgICAgICAgICAgICAgICBzaXplb2YoZmlsZW5hbWUpLCBmaWxlbmFtZSwgTlVMTCApID09IDAgKSByZXR1cm4gTlVMTDsKICAgICAgIAoJaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoJaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIGZpbGVuYW1lLCBoTW9kdWxlMzIgKSkgPCAzMikKCXsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQ3JlYXRlIDMyLWJpdCBNT0RSRUYgKi8KCWlmICggISh3bSA9IFBFX0NyZWF0ZU1vZHVsZSggaE1vZHVsZTMyLCBmaWxlbmFtZSwgZmxhZ3MsIEZBTFNFICkpICkKCXsKCQlFUlIoICJjYW4ndCBsb2FkICVzXG4iLCBmaWxlbmFtZSApOwoJCUZyZWVMaWJyYXJ5MTYoIGhNb2R1bGUxNiApOwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJU2V0TGFzdEVycm9yKCBFUlJPUl9PVVRPRk1FTU9SWSApOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmICh3bS0+YmluZm10LnBlLnBlX2V4cG9ydCkKCQlTTk9PUF9SZWdpc3RlckRMTCh3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtLT5iaW5mbXQucGUucGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyk7CiAgICAgICAgcmVxLT5oYW5kbGUgICAgID0gaEZpbGU7CiAgICAgICAgcmVxLT5iYXNlICAgICAgID0gKHZvaWQgKiloTW9kdWxlMzI7CiAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gMDsKICAgICAgICByZXEtPmRiZ19zaXplICAgPSAwOwogICAgICAgIHJlcS0+bmFtZSAgICAgICA9ICZ3bS0+bW9kbmFtZTsKICAgICAgICBzZXJ2ZXJfY2FsbF9ub2VyciggUkVRX0xPQURfRExMICk7CiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfVW5sb2FkTGlicmFyeQogKgogKiBVbmxvYWQgdGhlIGxpYnJhcnkgdW5tYXBwaW5nIHRoZSBpbWFnZSBhbmQgZnJlZWluZyB0aGUgbW9kcmVmIHN0cnVjdHVyZS4KICovCnZvaWQgUEVfVW5sb2FkTGlicmFyeShXSU5FX01PRFJFRiAqd20pCnsKICAgIFRSQUNFKCIgdW5sb2FkaW5nICVzXG4iLCB3bS0+ZmlsZW5hbWUpOwovKiAgICBWaXJ0dWFsRnJlZSggKExQVk9JRCl3bS0+bW9kdWxlLCAwLCBNRU1fUkVMRUFTRSApOyAqLyAgLyogRklYTUUgKi8KICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3bS0+ZmlsZW5hbWUgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3bS0+c2hvcnRfZmlsZW5hbWUgKTsKICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCB3bSApOwp9CgoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCkJPT0wgUEVfSW5pdERMTCggV0lORV9NT0RSRUYgKndtLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBhc3NlcnQoIHdtLT50eXBlID09IE1PRFVMRTMyX1BFICk7CgogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/IEFuZCBoYXMgaXQgZ290IGFuIGVudHJ5cG9pbnQ/ICovCiAgICBpZiAoKFBFX0hFQURFUih3bS0+bW9kdWxlKS0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAoUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgKSB7CiAgICAgICAgRExMRU5UUllQUk9DIGVudHJ5ID0gKHZvaWQqKVJWQV9QVFIoIHdtLT5tb2R1bGUsT3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgICAgIFRSQUNFXyhyZWxheSkoIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LCB3bS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CgogICAgICAgIHJldHYgPSBlbnRyeSggd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCVBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CiAgICAgICAgaW50IGRlbHRhOwoJCglmb3IgKHdtID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJaWYgKHdtLT50eXBlIT1NT0RVTEUzMl9QRSkKCQkJY29udGludWU7CgkJcGVtID0gJih3bS0+YmluZm10LnBlKTsKCQlwZWggPSBQRV9IRUFERVIod20tPm1vZHVsZSk7CgkJZGVsdGEgPSB3bS0+bW9kdWxlIC0gcGVoLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCgkJCWNvbnRpbnVlOwoJCXBkaXIgPSAoTFBWT0lEKSh3bS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJCgkJaWYgKCBwZW0tPnRsc2luZGV4ID09IC0xICkgewoJCQlMUERXT1JEIHhhZGRyOwoJCQlwZW0tPnRsc2luZGV4ID0gVGxzQWxsb2MoKTsKCQkJeGFkZHIgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLAoJCQkJCXBkaXItPkFkZHJlc3NPZkluZGV4CgkJCSk7CgkJCSp4YWRkcj1wZW0tPnRsc2luZGV4OwoJCX0KCQlkYXRhc2l6ZT0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CgkJc2l6ZQk9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CgkJbWVtPVZpcnR1YWxBbGxvYygwLHNpemUsTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CgkJbWVtY3B5KG1lbSxfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLChMUFZPSUQpcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhKSxkYXRhc2l6ZSk7CgkJaWYgKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcykgewoJCSAgICAgUElNQUdFX1RMU19DQUxMQkFDSyAqY2JzOyAKCgkJICAgICBjYnMgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcyk7CgkJICAgICBpZiAoKmNicykKCQkgICAgICAgRklYTUUoIlRMUyBDYWxsYmFja3MgYXJlbid0IGdvaW5nIHRvIGJlIGNhbGxlZFxuIik7CgkJfQoKCQlUbHNTZXRWYWx1ZSggcGVtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0KCg==