LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInNub29wLmgiCiNpbmNsdWRlICJzZXJ2ZXIuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTCh3aW4zMik7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChkZWxheWhscCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChmaXh1cCk7CkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwocmVsYXkpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2VnbWVudCk7CgoKc3RhdGljIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmdldF9leHBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqKSgoY2hhciAqKWhtb2QgKyBkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqZ2V0X2ltcG9ydHMoIEhNT0RVTEUgaG1vZCApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICpyZXQgPSBOVUxMOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpciA9IFBFX0hFQURFUihobW9kKS0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUgJiYgZGlyLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICByZXQgPSAoSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh2b2lkICopKChjaGFyICopbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKSkKCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUgaE1vZHVsZSApCnsgCiAgY2hhcgkJKk1vZHVsZTsKICBpbnQJCWksIGo7CiAgdV9zaG9ydAkqb3JkaW5hbDsKICB1X2xvbmcJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgdV9jaGFyCSoqbmFtZTsKICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyID0gaE1vZHVsZTsKCiAgRFdPUkQgcnZhX3N0YXJ0ID0gUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CiAgRFdPUkQgcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0cyA9IChJTUFHRV9FWFBPUlRfRElSRUNUT1JZKilSVkEocnZhX3N0YXJ0KTsKCiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBUUkFDRSgiKioqKioqKkVYUE9SVCBEQVRBKioqKioqKlxuIik7CiAgVFJBQ0UoIk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAogICAgICAgIE1vZHVsZSwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsIHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXMpOwoKICBvcmRpbmFsPSh1X3Nob3J0KikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zPWZ1bmN0aW9uPSh1X2xvbmcqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKICBuYW1lPSh1X2NoYXIqKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCiAgVFJBQ0UoIiBPcmQgICAgUlZBICAgICBBZGRyICAgTmFtZVxuIiApOwogIGZvciAoaT0wO2k8cGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnM7aSsrLCBmdW5jdGlvbisrKQogIHsKICAgICAgaWYgKCEqZnVuY3Rpb24pIGNvbnRpbnVlOyAgLyogTm8gc3VjaCBmdW5jdGlvbiAqLwogICAgICBpZiAoVFJBQ0VfT04od2luMzIpKQogICAgICB7CglEUFJJTlRGKCAiJTRsZCAlMDhseCAlcCIsIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCURQUklOVEYoIlxuIik7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCnN0YXRpYyBGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCAKCVdJTkVfTU9EUkVGICp3bSwJLyogW2luXSBXSU5FIG1vZHJlZmVyZW5jZSAqLwoJTFBDU1RSIGZ1bmNOYW1lLAkvKiBbaW5dIGZ1bmN0aW9uIG5hbWUgKi8KICAgICAgICBCT09MIHNub29wICkKewoJdV9zaG9ydAkJCQkqIG9yZGluYWxzOwoJdV9sb25nCQkJCSogZnVuY3Rpb247Cgl1X2NoYXIJCQkJKiogbmFtZSwgKmVuYW1lID0gTlVMTDsKCWludAkJCQlpLCBvcmRpbmFsOwoJdW5zaWduZWQgaW50CQkJbG9hZF9hZGRyID0gd20tPm1vZHVsZTsKCXVfbG9uZwkJCQlydmFfc3RhcnQsIHJ2YV9lbmQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmV4cG9ydHMgPSBnZXRfZXhwb3J0cyh3bS0+bW9kdWxlKTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKCQlUUkFDRSgiKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJVFJBQ0UoIiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQkvKiBOb3QgYSBmYXRhbCBwcm9ibGVtLCBzb21lIGFwcHMgZG8KCQkgKiBHZXRQcm9jQWRkcmVzcygwLCJSZWdpc3RlclBlbkFwcCIpIHdoaWNoIHRyaWdnZXJzIHRoaXMKCQkgKiBjYXNlLgoJCSAqLwoJCVdBUk4oIk1vZHVsZSAlMDh4KCVzKS9NT0RSRUYgJXAgZG9lc24ndCBoYXZlIGEgZXhwb3J0cyB0YWJsZS5cbiIsd20tPm1vZHVsZSx3bS0+bW9kbmFtZSx3bSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFscz0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogZmlyc3QgdHJ5IGEgYmluYXJ5IHNlYXJjaCAqLwogICAgICAgICAgICBpbnQgbWluID0gMCwgbWF4ID0gZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyAtIDE7CiAgICAgICAgICAgIHdoaWxlIChtaW4gPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcmVzLCBwb3MgPSAobWluICsgbWF4KSAvIDI7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW3Bvc10pOwogICAgICAgICAgICAgICAgaWYgKCEocmVzID0gc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW3Bvc107CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZXMgPiAwKSBtYXggPSBwb3MgLSAxOwogICAgICAgICAgICAgICAgZWxzZSBtaW4gPSBwb3MgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIG5vdyB0cnkgYSBsaW5lYXIgc2VhcmNoIGluIGNhc2UgdGhlIG5hbWVzIGFyZW4ndCBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCAiJXMuJXMgcmVxdWlyZWQgYSBsaW5lYXIgc2VhcmNoXG4iLCB3bS0+bW9kbmFtZSwgZnVuY05hbWUgKTsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbaV07CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KICAgICAgICBlbHNlICAvKiBmaW5kIGJ5IG9yZGluYWwgKi8KICAgICAgICB7CiAgICAgICAgICAgIG9yZGluYWwgPSBMT1dPUkQoZnVuY05hbWUpIC0gZXhwb3J0cy0+QmFzZTsKICAgICAgICAgICAgaWYgKHNub29wICYmIG5hbWUpICAvKiBuZWVkIHRvIGZpbmQgYSBuYW1lIGZvciBpdCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChvcmRpbmFsc1tpXSA9PSBvcmRpbmFsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJfQoKIGZvdW5kOgogICAgICAgIGlmIChvcmRpbmFsID49IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIglvcmRpbmFsICVsZCBvdXQgb2YgcmFuZ2UhXG4iLCBvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgYWRkciA9IGZ1bmN0aW9uW29yZGluYWxdOwogICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICB7CiAgICAgICAgICAgIEZBUlBST0MgcHJvYyA9IFJWQShhZGRyKTsKICAgICAgICAgICAgaWYgKHNub29wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWVuYW1lKSBlbmFtZSA9ICJAIjsKICAgICAgICAgICAgICAgIHByb2MgPSBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLG9yZGluYWwscHJvYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHByb2M7CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIGZvcndhcmQgZW50cnkgcG9pbnQgKi8KICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd207CiAgICAgICAgICAgICAgICBGQVJQUk9DIHByb2M7CiAgICAgICAgICAgICAgICBjaGFyICpmb3J3YXJkID0gUlZBKGFkZHIpOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChlbmQgLSBmb3J3YXJkID49IHNpemVvZihtb2R1bGUpKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG1lbWNweSggbW9kdWxlLCBmb3J3YXJkLCBlbmQgLSBmb3J3YXJkICk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJtb2R1bGUgbm90IGZvdW5kIGZvciBmb3J3YXJkICclcydcbiIsIGZvcndhcmQgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KCQlpZiAoIShwcm9jID0gTU9EVUxFX0dldFByb2NBZGRyZXNzKCB3bS0+bW9kdWxlLCBlbmQgKyAxLCBzbm9vcCApKSkKICAgICAgICAgICAgICAgICAgICBFUlIoImZ1bmN0aW9uIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CgkJcmV0dXJuIHByb2M7Cgl9Cn0KCkRXT1JEIGZpeHVwX2ltcG9ydHMoIFdJTkVfTU9EUkVGICp3bSApCnsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gd20tPm1vZHVsZTsKICAgIGludAkJCQlpLGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb249MTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmV4cG9ydHMgPSBnZXRfZXhwb3J0cyh3bS0+bW9kdWxlKTsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICppbXBvcnRzID0gZ2V0X2ltcG9ydHMod20tPm1vZHVsZSk7CiAgICAKICAgIGlmIChleHBvcnRzKQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShleHBvcnRzLT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogZmlyc3QsIGNvdW50IHRoZSBudW1iZXIgb2YgaW1wb3J0ZWQgbm9uLWludGVybmFsIG1vZHVsZXMgKi8KICAgIHBlX2ltcCA9IGltcG9ydHM7CiAgICBpZiAoIXBlX2ltcCkgcmV0dXJuIDA7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0UoIkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBXZSBhc3N1bWUgdGhhdCB3ZSBoYXZlIGF0IGxlYXN0IG9uZSBpbXBvcnQgd2l0aCAhMCBjaGFyYWN0ZXJpc3RpY3MgYW5kCiAgICAgKiBkZXRlY3QgYnJva2VuIGltcG9ydHMgd2l0aCBhbGwgY2hhcmFjdGVyaXN0aWNzIDAgKG5vdGFibHkgQm9ybGFuZCkgYW5kCiAgICAgKiBzd2l0Y2ggdGhlIGRldGVjdGlvbiBvZmYgZm9yIHRoZW0uCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CglpZiAoIWkgJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiA9IDA7CglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCWkrKzsKICAgIH0KICAgIGlmICghaSkgcmV0dXJuIDA7ICAvKiBubyBpbXBvcnRzICovCgogICAgLyogQWxsb2NhdGUgbW9kdWxlIGRlcGVuZGVuY3kgbGlzdCAqLwogICAgd20tPm5EZXBzID0gaTsKICAgIHdtLT5kZXBzICA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaSpzaXplb2YoV0lORV9NT0RSRUYgKikgKTsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IGltcG9ydHM7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CiAgICAJV0lORV9NT0RSRUYJCSp3bUltcDsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKIAljaGFyCQkJKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCgl3bUltcCA9IE1PRFVMRV9Mb2FkTGlicmFyeUV4QSggbmFtZSwgMCwgMCApOwoJaWYgKCF3bUltcCkgewoJICAgIEVSUl8obW9kdWxlKSgiTW9kdWxlIChmaWxlKSAlcyBuZWVkZWQgYnkgJXMgbm90IGZvdW5kXG4iLCBuYW1lLCB3bS0+ZmlsZW5hbWUpOwoJICAgIHJldHVybiAxOwoJfQogICAgICAgIHdtLT5kZXBzW2krK10gPSB3bUltcDsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIFRSQUNFKCJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9KFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgoJICAgIHdoaWxlIChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMsJWRcbiIsIG5hbWUsIG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpb3JkaW5hbCwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoUElNQUdFX0lNUE9SVF9CWV9OQU1FKVJWQShpbXBvcnRfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIG5hbWUsIHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCglcyksIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRSgiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLiVkXG4iLG5hbWUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgKExQQ1NUUikgb3JkaW5hbCwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPShQSU1BR0VfSU1QT1JUX0JZX05BTUUpIFJWQSh0aHVua19saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwKCQkgICAJCSAgcGVfbmFtZS0+TmFtZSxuYW1lLHBlX25hbWUtPkhpbnQpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIHBlX25hbWUtPk5hbWUsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCSAgICAJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIHBlX25hbWUtPkhpbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0KICAgIH0KICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIGRvX3JlbG9jYXRpb25zCiAqCiAqIEFwcGx5IHRoZSByZWxvY2F0aW9ucyB0byBhIG1hcHBlZCBQRSBpbWFnZQogKi8Kc3RhdGljIGludCBkb19yZWxvY2F0aW9ucyggY2hhciAqYmFzZSwgY29uc3QgSU1BR0VfTlRfSEVBREVSUyAqbnQsIGNvbnN0IGNoYXIgKmZpbGVuYW1lICkKewogICAgY29uc3QgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIGNvbnN0IElNQUdFX0JBU0VfUkVMT0NBVElPTiAqcmVsOwogICAgaW50IGRlbHRhID0gYmFzZSAtIChjaGFyICopbnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCiAgICBkaXIgPSAmbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQ107CiAgICByZWwgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICopKGJhc2UgKyBkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBXQVJOKCJJbmZvOiBiYXNlIHJlbG9jYXRpb25zIG5lZWRlZCBmb3IgJXNcbiIsIGZpbGVuYW1lKTsKICAgIGlmICghZGlyLT5WaXJ0dWFsQWRkcmVzcyB8fCAhZGlyLT5TaXplKQogICAgewogICAgICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlID09IDB4NDAwMDAwKQogICAgICAgICAgICBFUlIoIlN0YW5kYXJkIGxvYWQgYWRkcmVzcyBmb3IgYSBXaW4zMiBwcm9ncmFtIG5vdCBhdmFpbGFibGUgLSBwYXRjaGVkIGtlcm5lbCA/XG4iKTsKICAgICAgICBFUlIoICJGQVRBTDogTmVlZCB0byByZWxvY2F0ZSAlcywgYnV0IG5vIHJlbG9jYXRpb24gcmVjb3JkcyBwcmVzZW50ICglcykuIFRyeSB0byBydW4gdGhhdCBmaWxlIGRpcmVjdGx5ICFcbiIsCiAgICAgICAgICAgICBmaWxlbmFtZSwKICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBGSVhNRTogSWYgd2UgbmVlZCB0byByZWxvY2F0ZSBhIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpIHdlIHNob3VsZAogICAgICogICAgICAgIHJlYWxseSBtYWtlIHN1cmUgdGhhdCB0aGUgKm5ldyogYmFzZSBhZGRyZXNzIGlzIGFsc28gPiAyR0IuCiAgICAgKiAgICAgICAgU29tZSBETExzIHJlYWxseSBjaGVjayB0aGUgTVNCIG9mIHRoZSBtb2R1bGUgaGFuZGxlIDotLwogICAgICovCiAgICBpZiAoKG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwKSAmJiAhKChEV09SRCliYXNlICYgMHg4MDAwMDAwMCkpCiAgICAgICAgRVJSKCAiRm9yY2VkIHRvIHJlbG9jYXRlIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpLiBUaGlzIGlzIG5vdCBnb29kLlxuIiApOwoKICAgIGZvciAoIDsgKChjaGFyICopcmVsIDwgYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MgKyBkaXItPlNpemUpICYmIHJlbC0+VmlydHVhbEFkZHJlc3M7CiAgICAgICAgICByZWwgPSAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKikoKGNoYXIqKXJlbCArIHJlbC0+U2l6ZU9mQmxvY2spKQogICAgewogICAgICAgIGNoYXIgKnBhZ2UgPSBiYXNlICsgcmVsLT5WaXJ0dWFsQWRkcmVzczsKICAgICAgICBpbnQgaSwgY291bnQgPSAocmVsLT5TaXplT2ZCbG9jayAtIDgpIC8gc2l6ZW9mKHJlbC0+VHlwZU9mZnNldCk7CgogICAgICAgIGlmICghY291bnQpIGNvbnRpbnVlOwoKICAgICAgICAvKiBzYW5pdHkgY2hlY2tzICovCiAgICAgICAgaWYgKChjaGFyICopcmVsICsgcmVsLT5TaXplT2ZCbG9jayA+IGJhc2UgKyBkaXItPlZpcnR1YWxBZGRyZXNzICsgZGlyLT5TaXplIHx8CiAgICAgICAgICAgIHBhZ2UgPiBiYXNlICsgbnQtPk9wdGlvbmFsSGVhZGVyLlNpemVPZkltYWdlKQogICAgICAgIHsKICAgICAgICAgICAgRVJSXyhtb2R1bGUpKCJpbnZhbGlkIHJlbG9jYXRpb24gJXAsJWx4LCVsZCBhdCAlcCwlbHgsJWx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVsLCByZWwtPlZpcnR1YWxBZGRyZXNzLCByZWwtPlNpemVPZkJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSwgZGlyLT5WaXJ0dWFsQWRkcmVzcywgZGlyLT5TaXplICk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgVFJBQ0VfKG1vZHVsZSkoIiVsZCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsIHJlbC0+U2l6ZU9mQmxvY2ssIHJlbC0+VmlydHVhbEFkZHJlc3MpOwoKICAgICAgICAvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCiAgICAgICAgZm9yIChpID0gMCA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaW50IG9mZnNldCA9IHJlbC0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwogICAgICAgICAgICBpbnQgdHlwZSA9IHJlbC0+VHlwZU9mZnNldFtpXSA+PiAxMjsKICAgICAgICAgICAgc3dpdGNoKHR5cGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKICAgICAgICAgICAgICAgICooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gSElXT1JEKGRlbHRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CiAgICAgICAgICAgICAgICAqKHNob3J0KikocGFnZStvZmZzZXQpICs9IExPV09SRChkZWx0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKICAgICAgICAgICAgICAgICooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwogICAgICAgICAgICAgICAgLyogRklYTUU6IGlmIHRoaXMgaXMgYW4gZXhwb3J0ZWQgYWRkcmVzcywgZmlyZSB1cCBlbmhhbmNlZCBsb2dpYyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRV8obW9kdWxlKSgiVW5rbm93bi91bnN1cHBvcnRlZCBmaXh1cCB0eXBlICVkLlxuIiwgdHlwZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpITU9EVUxFIFBFX0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzICkKewogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBITU9EVUxFIGhNb2R1bGU7CiAgICBIQU5ETEUgbWFwcGluZzsKICAgIHZvaWQgKmJhc2U7CgogICAgVFJBQ0VfKG1vZHVsZSkoICJsb2FkaW5nICVzXG4iLCBmaWxlbmFtZSApOwoKICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBTRUNfSU1BR0UsIDAsIDAsIE5VTEwgKTsKICAgIGJhc2UgPSBNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFiYXNlKSByZXR1cm4gMDsKCiAgICBoTW9kdWxlID0gKEhNT0RVTEUpYmFzZTsKICAgIGlmIChmbGFncyAmIExPQURfTElCUkFSWV9BU19EQVRBRklMRSkgcmV0dXJuIGhNb2R1bGU7ICAvKiBub3RoaW5nIGVsc2UgdG8gZG8gKi8KCiAgICAvKiBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCgogICAgbnQgPSBQRV9IRUFERVIoIGhNb2R1bGUgKTsKICAgIGlmIChoTW9kdWxlICE9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UpCiAgICB7CiAgICAgICAgaWYgKCFkb19yZWxvY2F0aW9ucyggYmFzZSwgbnQsIGZpbGVuYW1lICkpCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIGJhc2UgKTsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgLyogdmlydXMgY2hlY2sgKi8KCiAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICB7CiAgICAgICAgaW50IGk7CiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnNlYyA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKChjaGFyKikmbnQtPk9wdGlvbmFsSGVhZGVyICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnQtPkZpbGVIZWFkZXIuU2l6ZU9mT3B0aW9uYWxIZWFkZXIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHNlYysrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50IDwgc2VjLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgPCBzZWMtPlZpcnR1YWxBZGRyZXNzK3NlYy0+U2l6ZU9mUmF3RGF0YSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zKQogICAgICAgICAgICBNRVNTQUdFKCJWSVJVUyBXQVJOSU5HOiBQRSBtb2R1bGUgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICJvdXRzaWRlIGFsbCBzZWN0aW9ucyAocG9zc2libHkgaW5mZWN0ZWQgYnkgVGNoZXJub2J5bC9TcGFjZUZpbGxlciB2aXJ1cykhXG4iLAogICAgICAgICAgICAgICAgICAgIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICB9CgogICAgcmV0dXJuIGhNb2R1bGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKgogKiBOb3RlOiBBc3N1bWVzIHRoYXQgdGhlIHByb2Nlc3MgY3JpdGljYWwgc2VjdGlvbiBpcyBoZWxkCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhGSUxFIGhGaWxlLCBCT09MIGJ1aWx0aW4gKQp7CiAgICBEV09SRCBsb2FkX2FkZHIgPSAoRFdPUkQpaE1vZHVsZTsgIC8qIGZvciBSVkEgKi8KICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUEVfSEVBREVSKGhNb2R1bGUpOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBXSU5FX01PRFJFRiAqd207CiAgICBITU9EVUxFMTYgaE1vZHVsZTE2OwoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFk7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DIGhhbmRsZWQgaW4gUEVfTG9hZEltYWdlICovCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUcgaGFuZGxlZCBieSBkZWJ1Z2dlciAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFI7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTIGhhbmRsZWQgaW4gUEVfVGxzSW5pdCAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJRzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVMQVlfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgIHsKCQlUUkFDRSgiRGVsYXllZCBpbXBvcnQsIHN0dWIgY2FsbHMgTG9hZExpYnJhcnlcbiIgKTsKCQkvKgoJCSAqIE5vdGhpbmcgdG8gZG8gaGVyZS4KCQkgKi8KCiNpZmRlZiBJbWdEZWxheURlc2NyCgkJLyoKCQkgKiBUaGlzIGNvZGUgaXMgdXNlZnVsIHRvIG9ic2VydmUgd2hhdCB0aGUgaGVjayBpcyBnb2luZyBvbi4KCQkgKi8KCQl7CgkJSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgIHBlX2RlbGF5ID0gKFBJbWdEZWxheURlc2NyKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+c3pOYW1lID0gJXNcbiIsIHBlX2RlbGF5LT5zek5hbWUpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5waG1vZCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5waG1vZCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJTlQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElOVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBCb3VuZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wQm91bmRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5kd1RpbWVTdGFtcCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5kd1RpbWVTdGFtcCk7CiAgICAgICAgfQojZW5kaWYgLyogSW1nRGVsYXlEZXNjciAqLwoJfQoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT01fREVTQ1JJUFRPUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNCBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrMTU7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTUgaWdub3JlZFxuIiApOwoKICAgIC8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCgogICAgaWYgKChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIGZpbGVuYW1lLCBoTW9kdWxlICkpIDwgMzIpCiAgICB7CiAgICAgICAgU2V0TGFzdEVycm9yKCAoRFdPUkQpaE1vZHVsZTE2ICk7CS8qIFRoaXMgc2hvdWxkIGdpdmUgdGhlIGNvcnJlY3QgZXJyb3IgKi8KICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBBbGxvY2F0ZSBhbmQgZmlsbCBXSU5FX01PRFJFRiAqLwoKICAgIGlmICghKHdtID0gTU9EVUxFX0FsbG9jTW9kUmVmKCBoTW9kdWxlLCBmaWxlbmFtZSApKSkKICAgIHsKICAgICAgICBGcmVlTGlicmFyeTE2KCBoTW9kdWxlMTYgKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIGJ1aWx0aW4gKSAKICAgIHsKICAgICAgICBORV9NT0RVTEUgKnBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgICAgICBwTW9kdWxlLT5mbGFncyB8PSBORV9GRkxBR1NfQlVJTFRJTjsKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfSU5URVJOQUw7CiAgICB9CgogICAgaWYgKCBmbGFncyAmIERPTlRfUkVTT0xWRV9ETExfUkVGRVJFTkNFUyApCiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTOwoKICAgIHdtLT5maW5kX2V4cG9ydCA9IFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uOwoKICAgIC8qIER1bXAgRXhwb3J0cyAqLwoKICAgIGlmICggcGVfZXhwb3J0ICkKICAgICAgICBkdW1wX2V4cG9ydHMoIGhNb2R1bGUgKTsKCiAgICAvKiBUaGUgZXhlX21vZHJlZiBtdXN0IGJlIGluIHBsYWNlLCBiZWZvcmUgaW1wbGljaXQgbGlua2VkIERMTHMgYXJlIGxvYWRlZCAKICAgICAgIGJ5IGZpeHVwX2ltcG9ydHMsIG90aGVyd2hpc2UgR2V0TW9kdWxlRmlsZU5hbWUgd2lsbCBub3Qgd29yayBhbmQgbW9kdWxlcyAKICAgICAgIGluIHRoZSBleGVjdXRhYmxlcyBkaXJlY3RvcnkgY2FuIG5vdCBiZSBmb3VuZCAqLwoKICAgIGlmICghKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkKICAgIHsKICAgICAgaWYgKCBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiApCglGSVhNRSggIlRyeWluZyB0byBsb2FkIHNlY29uZCAuRVhFIGZpbGU6ICVzXG4iLCBmaWxlbmFtZSApOwogICAgICBlbHNlICAKICAgICAgewoJUFJPQ0VTU19DdXJyZW50KCktPmV4ZV9tb2RyZWYgPSB3bTsKICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kdWxlID0gd20tPm1vZHVsZTsKICAgICAgfQogICAgfQoKICAgIC8qIEZpeHVwIEltcG9ydHMgKi8KCiAgICBpZiAoISh3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUykgJiYgZml4dXBfaW1wb3J0cyggd20gKSkKICAgIHsKICAgICAgICAvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KCiAgICAgICAgaWYgKCAhd20tPnByZXYgKQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5wcmV2LT5uZXh0ID0gd20tPm5leHQ7CgogICAgICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtLT5wcmV2OwogICAgICAgIHdtLT5uZXh0ID0gd20tPnByZXYgPSBOVUxMOwoKICAgICAgICAvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCiAgICAgICAgICogbGVmdC4gSW5jbHVkaW5nIGRsbHMgbG9hZGVkIGJ5IHRoaXMgZGxsIGJlZm9yZSB0aGUKICAgICAgICAgKiBmYWlsZWQgb25lLiBVbnJvbGxpbmcgaXMgcmF0aGVyIGRpZmZpY3VsdCB3aXRoIHRoZQogICAgICAgICAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwogICAgICAgICAqIGFyb3VuZCB3aXRoIG5vIHByb2JsZW1zLCBzbyB3ZSBkb24ndCBjYXJlLgogICAgICAgICAqIEFzIHRoZXNlIG1pZ2h0IHJlZmVyZW5jZSBvdXIgd20sIHdlIGRvbid0IGZyZWUgaXQuCiAgICAgICAgICovCiAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChwZV9leHBvcnQpCiAgICAgICAgU05PT1BfUmVnaXN0ZXJETEwoIGhNb2R1bGUsIHdtLT5tb2RuYW1lLCBwZV9leHBvcnQtPk51bWJlck9mRnVuY3Rpb25zICk7CgogICAgLyogU2VuZCBETEwgbG9hZCBldmVudCAqLwogICAgLyogd2UgZG9uJ3QgbmVlZCB0byBzZW5kIGEgZGxsIGV2ZW50IGZvciB0aGUgbWFpbiBleGUgKi8KCiAgICBpZiAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICB7CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGxvYWRfZGxsX3JlcXVlc3QgKnJlcSA9IHNlcnZlcl9hbGxvY19yZXEoIHNpemVvZigqcmVxKSwgMCApOwogICAgICAgICAgICByZXEtPmhhbmRsZSAgICAgPSBoRmlsZTsKICAgICAgICAgICAgcmVxLT5iYXNlICAgICAgID0gKHZvaWQgKiloTW9kdWxlOwogICAgICAgICAgICByZXEtPmRiZ19vZmZzZXQgPSBudC0+RmlsZUhlYWRlci5Qb2ludGVyVG9TeW1ib2xUYWJsZTsKICAgICAgICAgICAgcmVxLT5kYmdfc2l6ZSAgID0gbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTeW1ib2xzOwogICAgICAgICAgICByZXEtPm5hbWUgICAgICAgPSAmd20tPmZpbGVuYW1lOwogICAgICAgICAgICBzZXJ2ZXJfY2FsbF9ub2VyciggUkVRX0xPQURfRExMICk7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9FTkRfUkVROwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCldJTkVfTU9EUkVGICpQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzKQp7CglITU9EVUxFCQloTW9kdWxlMzI7CglXSU5FX01PRFJFRgkqd207CglIQU5ETEUJCWhGaWxlOwogICAgICAgCgloRmlsZSA9IENyZWF0ZUZpbGVBKCBuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAtMSApOwoJaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoJCgkvKiBMb2FkIFBFIG1vZHVsZSAqLwoJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgbmFtZSwgZmxhZ3MgKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJLyogQ3JlYXRlIDMyLWJpdCBNT0RSRUYgKi8KCWlmICggISh3bSA9IFBFX0NyZWF0ZU1vZHVsZSggaE1vZHVsZTMyLCBuYW1lLCBmbGFncywgaEZpbGUsIEZBTFNFICkpICkKCXsKCQlFUlIoICJjYW4ndCBsb2FkICVzXG4iLCBuYW1lICk7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlTZXRMYXN0RXJyb3IoIEVSUk9SX09VVE9GTUVNT1JZICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgogICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJcmV0dXJuIHdtOwp9CgoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnR5cGVkZWYgRFdPUkQgQ0FMTEJBQ0soKkRMTEVOVFJZUFJPQykoSE1PRFVMRSxEV09SRCxMUFZPSUQpOwoKQk9PTCBQRV9Jbml0RExMKCBITU9EVUxFIG1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQgKQp7CiAgICBCT09MIHJldHYgPSBUUlVFOwogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQgPSBQRV9IRUFERVIobW9kdWxlKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSkKICAgIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopKChjaGFyKiltb2R1bGUgKyBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwoKICAgICAgICByZXR2ID0gZW50cnkoIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCVBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CiAgICAgICAgaW50IGRlbHRhOwoJCglmb3IgKHdtID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggd20tPnRsc2luZGV4ID09IC0xICkgewoJCQlMUERXT1JEIHhhZGRyOwoJCQl3bS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXdtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0KCg==