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+PiAxMjsKICAgICAgICAgICAgc3dpdGNoKHR5cGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfQUJTT0xVVEU6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKICAgICAgICAgICAgICAgICooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gSElXT1JEKGRlbHRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CiAgICAgICAgICAgICAgICAqKHNob3J0KikocGFnZStvZmZzZXQpICs9IExPV09SRChkZWx0YSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSExPVzoKICAgICAgICAgICAgICAgICooaW50KikocGFnZStvZmZzZXQpICs9IGRlbHRhOwogICAgICAgICAgICAgICAgLyogRklYTUU6IGlmIHRoaXMgaXMgYW4gZXhwb3J0ZWQgYWRkcmVzcywgZmlyZSB1cCBlbmhhbmNlZCBsb2dpYyAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRV8obW9kdWxlKSgiVW5rbm93bi91bnN1cHBvcnRlZCBmaXh1cCB0eXBlICVkLlxuIiwgdHlwZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQlQRV9Mb2FkSW1hZ2UKICogTG9hZCBvbmUgUEUgZm9ybWF0IERMTC9FWEUgaW50byBtZW1vcnkKICogCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yIAogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUzMiBwb2ludCB0byB0aGUgc3RhcnQgb2YgaXQpCiAqLwpITU9EVUxFIFBFX0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzICkKewogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBITU9EVUxFIGhNb2R1bGU7CiAgICBIQU5ETEUgbWFwcGluZzsKICAgIHZvaWQgKmJhc2U7CgogICAgVFJBQ0VfKG1vZHVsZSkoICJsb2FkaW5nICVzXG4iLCBmaWxlbmFtZSApOwoKICAgIG1hcHBpbmcgPSBDcmVhdGVGaWxlTWFwcGluZ0EoIGhGaWxlLCBOVUxMLCBTRUNfSU1BR0UsIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykgcmV0dXJuIDA7CiAgICBiYXNlID0gTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghYmFzZSkgcmV0dXJuIDA7CgogICAgaE1vZHVsZSA9IChITU9EVUxFKWJhc2U7CiAgICBpZiAoZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUpIHJldHVybiBoTW9kdWxlOyAgLyogbm90aGluZyBlbHNlIHRvIGRvICovCgogICAgLyogcGVyZm9ybSBiYXNlIHJlbG9jYXRpb24sIGlmIG5lY2Vzc2FyeSAqLwoKICAgIG50ID0gUEVfSEVBREVSKCBoTW9kdWxlICk7CiAgICBpZiAoaE1vZHVsZSAhPSBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlKQogICAgewogICAgICAgIGlmICghZG9fcmVsb2NhdGlvbnMoIGJhc2UsIG50LCBmaWxlbmFtZSApKQogICAgICAgIHsKICAgICAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCBiYXNlICk7CiAgICAgICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qIHZpcnVzIGNoZWNrICovCgogICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KQogICAgewogICAgICAgIGludCBpOwogICAgICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpzZWMgPSAoSU1BR0VfU0VDVElPTl9IRUFERVIqKSgoY2hhciopJm50LT5PcHRpb25hbEhlYWRlciArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG50LT5GaWxlSGVhZGVyLlNpemVPZk9wdGlvbmFsSGVhZGVyKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBzZWMrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCA8IHNlYy0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50IDwgc2VjLT5WaXJ0dWFsQWRkcmVzcytzZWMtPlNpemVPZlJhd0RhdGEpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGkgPT0gbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9ucykKICAgICAgICAgICAgTUVTU0FHRSgiVklSVVMgV0FSTklORzogUEUgbW9kdWxlIGhhcyBhbiBpbnZhbGlkIGVudHJ5cG9pbnQgKDB4JTA4bHgpICIKICAgICAgICAgICAgICAgICAgICAib3V0c2lkZSBhbGwgc2VjdGlvbnMgKHBvc3NpYmx5IGluZmVjdGVkIGJ5IFRjaGVybm9ieWwvU3BhY2VGaWxsZXIgdmlydXMpIVxuIiwKICAgICAgICAgICAgICAgICAgICBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCApOwogICAgfQoKICAgIHJldHVybiBoTW9kdWxlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAgUEVfQ3JlYXRlTW9kdWxlCiAqCiAqIENyZWF0ZSBXSU5FX01PRFJFRiBzdHJ1Y3R1cmUgZm9yIGxvYWRlZCBITU9EVUxFMzIsIGxpbmsgaXQgaW50bwogKiBwcm9jZXNzIG1vZHJlZl9saXN0LCBhbmQgZml4dXAgYWxsIGltcG9ydHMuCiAqCiAqIE5vdGU6IGhNb2R1bGUgbXVzdCBwb2ludCB0byBhIGNvcnJlY3RseSBhbGxvY2F0ZWQgUEUgaW1hZ2UsCiAqICAgICAgIHdpdGggYmFzZSByZWxvY2F0aW9ucyBhcHBsaWVkOyB0aGUgMTYtYml0IGR1bW15IG1vZHVsZQogKiAgICAgICBhc3NvY2lhdGVkIHRvIGhNb2R1bGUgbXVzdCBhbHJlYWR5IGV4aXN0LgogKgogKiBOb3RlOiBUaGlzIHJvdXRpbmUgbXVzdCBhbHdheXMgYmUgY2FsbGVkIGluIHRoZSBjb250ZXh0IG9mIHRoZQogKiAgICAgICBwcm9jZXNzIHRoYXQgaXMgdG8gb3duIHRoZSBtb2R1bGUgdG8gYmUgY3JlYXRlZC4KICoKICogTm90ZTogQXNzdW1lcyB0aGF0IHRoZSBwcm9jZXNzIGNyaXRpY2FsIHNlY3Rpb24gaXMgaGVsZAogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCBMUENTVFIgZmlsZW5hbWUsIERXT1JEIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIRklMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9leHBvcnQgPSAoUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZSApKSA8IDMyKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpCiAgICB7CiAgICAgICAgRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB3bS0+aER1bW15TW9kID0gaE1vZHVsZTE2OwoKICAgIGlmICggYnVpbHRpbiApIAogICAgewogICAgICAgIE5FX01PRFVMRSAqcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgICAgIHBNb2R1bGUtPmZsYWdzIHw9IE5FX0ZGTEFHU19CVUlMVElOOwogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIH0KCiAgICBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgd20tPmZpbmRfZXhwb3J0ID0gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb247CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKCBwZV9leHBvcnQgKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIFRoZSBleGVfbW9kcmVmIG11c3QgYmUgaW4gcGxhY2UsIGJlZm9yZSBpbXBsaWNpdCBsaW5rZWQgRExMcyBhcmUgbG9hZGVkIAogICAgICAgYnkgZml4dXBfaW1wb3J0cywgb3RoZXJ3aGlzZSBHZXRNb2R1bGVGaWxlTmFtZSB3aWxsIG5vdCB3b3JrIGFuZCBtb2R1bGVzIAogICAgICAgaW4gdGhlIGV4ZWN1dGFibGVzIGRpcmVjdG9yeSBjYW4gbm90IGJlIGZvdW5kICovCgogICAgaWYgKCEobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICBpZiAoIFBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmICkKCUZJWE1FKCAiVHJ5aW5nIHRvIGxvYWQgc2Vjb25kIC5FWEUgZmlsZTogJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgIGVsc2UgIAogICAgICB7CglQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiA9IHdtOwogICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2R1bGUgPSB3bS0+bW9kdWxlOwogICAgICB9CiAgICB9CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICghKHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTKSAmJiBmaXh1cF9pbXBvcnRzKCB3bSApKQogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwoKICAgICAgICBpZiAoICF3bS0+cHJldiApCiAgICAgICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPnByZXYtPm5leHQgPSB3bS0+bmV4dDsKCiAgICAgICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd20tPnByZXY7CiAgICAgICAgd20tPm5leHQgPSB3bS0+cHJldiA9IE5VTEw7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKHBlX2V4cG9ydCkKICAgICAgICBTTk9PUF9SZWdpc3RlckRMTCggaE1vZHVsZSwgd20tPm1vZG5hbWUsIHBlX2V4cG9ydC0+TnVtYmVyT2ZGdW5jdGlvbnMgKTsKCiAgICAvKiBTZW5kIERMTCBsb2FkIGV2ZW50ICovCiAgICAvKiB3ZSBkb24ndCBuZWVkIHRvIHNlbmQgYSBkbGwgZXZlbnQgZm9yIHRoZSBtYWluIGV4ZSAqLwoKICAgIGlmIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBTRVJWRVJfU1RBUlRfUkVRCiAgICAgICAgewogICAgICAgICAgICBzdHJ1Y3QgbG9hZF9kbGxfcmVxdWVzdCAqcmVxID0gc2VydmVyX2FsbG9jX3JlcSggc2l6ZW9mKCpyZXEpLCAwICk7CiAgICAgICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX29mZnNldCA9IG50LT5GaWxlSGVhZGVyLlBvaW50ZXJUb1N5bWJvbFRhYmxlOwogICAgICAgICAgICByZXEtPmRiZ19zaXplICAgPSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlN5bWJvbHM7CiAgICAgICAgICAgIHJlcS0+bmFtZSAgICAgICA9ICZ3bS0+ZmlsZW5hbWU7CiAgICAgICAgICAgIHNlcnZlcl9jYWxsX25vZXJyKCBSRVFfTE9BRF9ETEwgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCVdJTkVfTU9EUkVGCSp3bTsKCUhBTkRMRQkJaEZpbGU7CiAgICAgICAKCWhGaWxlID0gQ3JlYXRlRmlsZUEoIG5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBmbGFncyApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIG5hbWUsIGZsYWdzLCBoRmlsZSwgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCVNldExhc3RFcnJvciggRVJST1JfT1VUT0ZNRU1PUlkgKTsKCQlyZXR1cm4gTlVMTDsKCX0KCiAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CglyZXR1cm4gd207Cn0KCgovKiBDYWxsZWQgaWYgdGhlIGxpYnJhcnkgaXMgbG9hZGVkIG9yIGZyZWVkLgogKiBOT1RFOiBpZiBhIHRocmVhZCBhdHRhY2hlcyBhIERMTCwgdGhlIGN1cnJlbnQgdGhyZWFkIHdpbGwgb25seSBkbwogKiBETExfUFJPQ0VTU19BVFRBQ0guIE9ubHkgbmV3IGNyZWF0ZWQgdGhyZWFkcyBkbyBETExfVEhSRUFEX0FUVEFDSAogKiAoU0RLKQogKi8KdHlwZWRlZiBEV09SRCBDQUxMQkFDSygqRExMRU5UUllQUk9DKShITU9EVUxFLERXT1JELExQVk9JRCk7CgpCT09MIFBFX0luaXRETEwoIEhNT0RVTEUgbW9kdWxlLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCApCnsKICAgIEJPT0wgcmV0diA9IFRSVUU7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihtb2R1bGUpOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpKQogICAgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKikoKGNoYXIqKW1vZHVsZSArIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBUUkFDRV8ocmVsYXkpKCJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CgogICAgICAgIHJldHYgPSBlbnRyeSggbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9CgogICAgcmV0dXJuIHJldHY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfSW5pdFRscwkJCShpbnRlcm5hbCkKICoKICogSWYgaW5jbHVkZWQsIGluaXRpYWxpc2VzIHRoZSB0aHJlYWQgbG9jYWwgc3RvcmFnZXMgb2YgbW9kdWxlcy4KICogUG9pbnRlcnMgaW4gdGhvc2Ugc3RydWN0cyBhcmUgbm90IFJWQXMgYnV0IHJlYWwgcG9pbnRlcnMgd2hpY2ggaGF2ZSBiZWVuCiAqIHJlbG9jYXRlZCBieSBkb19yZWxvY2F0aW9ucygpIGFscmVhZHkuCiAqLwpzdGF0aWMgTFBWT0lECl9maXh1cF9hZGRyZXNzKFBJTUFHRV9PUFRJT05BTF9IRUFERVIgb3B0LGludCBkZWx0YSxMUFZPSUQgYWRkcikgewoJaWYgKAkoKERXT1JEKWFkZHI+b3B0LT5JbWFnZUJhc2UpICYmCgkJKChEV09SRClhZGRyPG9wdC0+SW1hZ2VCYXNlK29wdC0+U2l6ZU9mSW1hZ2UpCgkpCgkJLyogdGhlIGFkZHJlc3MgaGFzIG5vdCBiZWVuIHJlbG9jYXRlZCEgKi8KCQlyZXR1cm4gKExQVk9JRCkoKChEV09SRClhZGRyKStkZWx0YSk7CgllbHNlCgkJLyogdGhlIGFkZHJlc3MgaGFzIGJlZW4gcmVsb2NhdGVkIGFscmVhZHkgKi8KCQlyZXR1cm4gYWRkcjsKfQp2b2lkIFBFX0luaXRUbHMoIHZvaWQgKQp7CglXSU5FX01PRFJFRgkJKndtOwoJSU1BR0VfTlRfSEVBREVSUwkqcGVoOwoJRFdPUkQJCQlzaXplLGRhdGFzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgkKCWZvciAod20gPSBQUk9DRVNTX0N1cnJlbnQoKS0+bW9kcmVmX2xpc3Q7d207d209d20tPm5leHQpIHsKCQlwZWggPSBQRV9IRUFERVIod20tPm1vZHVsZSk7CgkJZGVsdGEgPSB3bS0+bW9kdWxlIC0gcGVoLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpCgkJCWNvbnRpbnVlOwoJCXBkaXIgPSAoTFBWT0lEKSh3bS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJCgkJaWYgKCB3bS0+dGxzaW5kZXggPT0gLTEgKSB7CgkJCUxQRFdPUkQgeGFkZHI7CgkJCXdtLT50bHNpbmRleCA9IFRsc0FsbG9jKCk7CgkJCXhhZGRyID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwKCQkJCQlwZGlyLT5BZGRyZXNzT2ZJbmRleAoJCQkpOwoJCQkqeGFkZHI9d20tPnRsc2luZGV4OwoJCX0KCQlkYXRhc2l6ZT0gcGRpci0+RW5kQWRkcmVzc09mUmF3RGF0YS1wZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGE7CgkJc2l6ZQk9IGRhdGFzaXplICsgcGRpci0+U2l6ZU9mWmVyb0ZpbGw7CgkJbWVtPVZpcnR1YWxBbGxvYygwLHNpemUsTUVNX1JFU0VSVkV8TUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CgkJbWVtY3B5KG1lbSxfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLChMUFZPSUQpcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhKSxkYXRhc2l6ZSk7CgkJaWYgKHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcykgewoJCSAgICAgUElNQUdFX1RMU19DQUxMQkFDSyAqY2JzOyAKCgkJICAgICBjYnMgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLHBkaXItPkFkZHJlc3NPZkNhbGxCYWNrcyk7CgkJICAgICBpZiAoKmNicykKCQkgICAgICAgRklYTUUoIlRMUyBDYWxsYmFja3MgYXJlbid0IGdvaW5nIHRvIGJlIGNhbGxlZFxuIik7CgkJfQoKCQlUbHNTZXRWYWx1ZSggd20tPnRsc2luZGV4LCBtZW0gKTsKCX0KfQoK