LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlCiAqICAgICBuZWVkIHRvIHZhbGlkYXRlIGFsbCBzY2hlbWEgYXR0cmlidXRlcyAocmVmLCB0eXBlLCBuYW1lKQogKiAgICAgYWdhaW5zdCB0aGVpciB0eXBlcy4KICogICAtIEVsaW1pbmF0ZSBpdGVtIGNyZWF0aW9uIGZvcjogPz8KICoKICogVVJHRU5UIFRPRE86CiAqICAgLSBGb3IgeHNpLWRyaXZlbiBzY2hlbWEgYWNxdWlzaXRpb24sIGF1Z21lbnQgdGhlIElEQ3MgYWZ0ZXIgZXZlcnkKICogICAgIGFjcXVpc2l0aW9uIGVwaXNvZGUgKHhtbFNjaGVtYUF1Z21lbnRJREMpLgogKgogKiBOT1RFUzoKICogICAtIEVsaW1hdGVkIGl0ZW0gY3JlYXRpb24gZm9yOiA8cmVzdHJpY3Rpb24+LCA8ZXh0ZW5zaW9uPiwKICogICAgIDxzaW1wbGVDb250ZW50PiwgPGNvbXBsZXhDb250ZW50PiwgPGxpc3Q+LCA8dW5pb24+CiAqCiAqIFBST0JMRU1TOgogKiAgIC0gaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LXhtbC1zY2hlbWEtY29tbWVudHMvMjAwNUp1bFNlcC8wMzM3Lmh0bWwKICogICAgIElEQyBYUGF0aCBleHByZXNzaW9uIGFuZCBjaGFtZWxlb24gaW5jbHVkZXM6IHRoZSB0YXJnZXROYW1lc3BhY2UgaXMgY2hhbmdlZCwgc28KICogICAgIFhQYXRoIHdpbGwgaGF2ZSB0cm91YmxlIHRvIHJlc29sdmUgdG8gdGhpcyBuYW1lc3BhY2UsIHNpbmNlIG5vdCBrbm93bi4KICoKICoKICogQ09OU1RSQUlOVFM6CiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogICBBbGwgR3JvdXAgTGltaXRlZCAoY29zLWFsbC1saW1pdGVkKQogKiAgIFN0YXR1czogY29tcGxldGUKICogICAoMS4yKQogKiAgICAgSW4geG1sU2NoZW1hR3JvdXBEZWZSZWZlcmVuY2VUZXJtRml4dXAoKSBhbmQKICogICAoMikKICogICAgIEluIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cCgpCiAqICAgICBUT0RPOiBBY3R1YWxseSB0aGlzIHNob3VsZCBnbyB0byBjb21wb25lbnQtbGV2ZWwgY2hlY2tzLAogKiAgICAgYnV0IGlzIGRvbmUgaGVyZSBkdWUgdG8gcGVyZm9ybWFuY2UuIE1vdmUgaXQgdG8gYW4gb3RoZXIgbGF5ZXIKICogICAgIGlzIHNjaGVtYSBjb25zdHJ1Y3Rpb24gdmlhIGFuIEFQSSBpcyBpbXBsZW1lbnRlZC4KICovCiNkZWZpbmUgSU5fTElCWE1MCiNpbmNsdWRlICJsaWJ4bWwuaCIKCiNpZmRlZiBMSUJYTUxfU0NIRU1BU19FTkFCTEVECgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CiNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VyLmg+CiNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VySW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgojaW5jbHVkZSA8bGlieG1sL3VyaS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHNjaGVtYXMuaD4KI2luY2x1ZGUgPGxpYnhtbC9zY2hlbWFzSW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hc3R5cGVzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sYXV0b21hdGEuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxyZWdleHAuaD4KI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CiNpbmNsdWRlIDxsaWJ4bWwvZW5jb2RpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxJTy5oPgojaWZkZWYgTElCWE1MX1BBVFRFUk5fRU5BQkxFRAojaW5jbHVkZSA8bGlieG1sL3BhdHRlcm4uaD4KI2VuZGlmCiNpZmRlZiBMSUJYTUxfUkVBREVSX0VOQUJMRUQKI2luY2x1ZGUgPGxpYnhtbC94bWxyZWFkZXIuaD4KI2VuZGlmCgovKiAjZGVmaW5lIERFQlVHIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQ09OVEVOVCAxICovCgovKiAjZGVmaW5lIERFQlVHX1RZUEUgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UX1JFR0VYUCAxICovCgovKiAjZGVmaW5lIERFQlVHX0FVVE9NQVRBIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfSURDICovCgovKiAjZGVmaW5lIERFQlVHX0lEQ19OT0RFX1RBQkxFICovCgovKiAjZGVmaW5lIFdYU19FTEVNX0RFQ0xfQ09OU19FTkFCTEVEICovCgojaWZkZWYgREVCVUdfSURDCiAjaWZuZGVmIERFQlVHX0lEQ19OT0RFX1RBQkxFCiAgI2RlZmluZSBERUJVR19JRENfTk9ERV9UQUJMRQogI2VuZGlmCiNlbmRpZiAgIAoKLyogI2RlZmluZSBFTkFCTEVfUEFSVElDTEVfUkVTVFJJQ1RJT04gMSAqLwoKI2RlZmluZSBFTkFCTEVfUkVERUZJTkUKCi8qICNkZWZpbmUgRU5BQkxFX05BTUVEX0xPQ0FMUyAqLwoKLyogI2RlZmluZSBFTkFCTEVfSURDX05PREVfVEFCTEVTX1RFU1QgKi8KCiNkZWZpbmUgRFVNUF9DT05URU5UX01PREVMCgojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECi8qICNkZWZpbmUgWE1MX1NDSEVNQV9SRUFERVJfRU5BQkxFRCAqLwojZW5kaWYKCiNkZWZpbmUgVU5CT1VOREVEICgxIDw8IDMwKQojZGVmaW5lIFRPRE8gCQkJCQkJCQlcCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwJCQkJXAoJICAgICJVbmltcGxlbWVudGVkIGJsb2NrIGF0ICVzOiVkXG4iLAkJCQlcCiAgICAgICAgICAgIF9fRklMRV9fLCBfX0xJTkVfXyk7CgojZGVmaW5lIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSAoY29uc3QgeG1sQ2hhciAqKSAiIyMiCgovKgogKiBUaGUgWE1MIFNjaGVtYXMgbmFtZXNwYWNlcwogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hSW5zdGFuY2VOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbE5hbWVzcGFjZU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CgovKgoqIENvbWUgY2FzdGluZyBtYWNyb3MuCiovCiNkZWZpbmUgQUNUWFRfQ0FTVCAoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKQojZGVmaW5lIFBDVFhUX0NBU1QgKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpCiNkZWZpbmUgVkNUWFRfQ0FTVCAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKQojZGVmaW5lIFdYU19CQVNJQ19DQVNUICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpCiNkZWZpbmUgV1hTX1RSRUVfQ0FTVCAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCiNkZWZpbmUgV1hTX1BUQ19DQVNUICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKI2RlZmluZSBXWFNfVFlQRV9DQVNUICh4bWxTY2hlbWFUeXBlUHRyKQojZGVmaW5lIFdYU19FTEVNX0NBU1QgKHhtbFNjaGVtYUVsZW1lbnRQdHIpCiNkZWZpbmUgV1hTX0FUVFJfR1JPVVBfQ0FTVCAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpCiNkZWZpbmUgV1hTX0FUVFJfQ0FTVCAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKQojZGVmaW5lIFdYU19BVFRSX1VTRV9DQVNUICh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIpCiNkZWZpbmUgV1hTX0FUVFJfUFJPSElCX0NBU1QgKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cikKI2RlZmluZSBXWFNfTU9ERUxfR1JPVVBERUZfQ0FTVCAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikKI2RlZmluZSBXWFNfTU9ERUxfR1JPVVBfQ0FTVCAoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikKI2RlZmluZSBXWFNfSURDX0NBU1QgKHhtbFNjaGVtYUlEQ1B0cikKI2RlZmluZSBXWFNfUU5BTUVfQ0FTVCAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpCiNkZWZpbmUgV1hTX0xJU1RfQ0FTVCAoeG1sU2NoZW1hSXRlbUxpc3RQdHIpCgovKgoqIE1hY3JvcyB0byBxdWVyeSBjb21tb24gcHJvcGVydGllcyBvZiBjb21wb25lbnRzLgoqLwojZGVmaW5lIFdYU19JVEVNX05PREUoaSkgeG1sU2NoZW1hR2V0Q29tcG9uZW50Tm9kZShXWFNfQkFTSUNfQ0FTVCAoaSkpCgojZGVmaW5lIFdYU19JVEVNX1RZUEVfTkFNRShpKSB4bWxTY2hlbWFHZXRDb21wb25lbnRUeXBlU3RyKFdYU19CQVNJQ19DQVNUIChpKSkKLyoKKiBNYWNyb3MgZm9yIGVsZW1lbnQgZGVjbGFyYXRpb25zLgoqLwojZGVmaW5lIFdYU19FTEVNX1RZUEVERUYoZSkgKGUpLT5zdWJ0eXBlcwoKI2RlZmluZSBXWFNfU1VCU1RfSEVBRChpdGVtKSAoaXRlbSktPnJlZkRlY2wKLyoKKiBNYWNyb3MgZm9yIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMuCiovCiNkZWZpbmUgV1hTX0FUVFJfVFlQRURFRihhKSAoYSktPnN1YnR5cGVzCi8qCiogTWFjcm9zIGZvciBhdHRyaWJ1dGUgdXNlcy4KKi8KI2RlZmluZSBXWFNfQVRUUlVTRV9ERUNMKGF1KSBXWFNfQVRUUl9DQVNUIChXWFNfQVRUUl9VU0VfQ0FTVCAoYXUpKS0+YXR0ckRlY2wKCiNkZWZpbmUgV1hTX0FUVFJVU0VfVFlQRURFRihhdSkgV1hTX0FUVFJfVFlQRURFRihXWFNfQVRUUlVTRV9ERUNMKCBXWFNfQVRUUl9VU0VfQ0FTVCBhdSkpCgojZGVmaW5lIFdYU19BVFRSVVNFX0RFQ0xfTkFNRShhdSkgKFdYU19BVFRSVVNFX0RFQ0woYXUpKS0+bmFtZQoKI2RlZmluZSBXWFNfQVRUUlVTRV9ERUNMX1ROUyhhdSkgKFdYU19BVFRSVVNFX0RFQ0woYXUpKS0+dGFyZ2V0TmFtZXNwYWNlCi8qCiogTWFjcm9zIGZvciBhdHRyaWJ1dGUgZ3JvdXBzLgoqLwojZGVmaW5lIFdYU19BVFRSX0dST1VQX0hBU19SRUZTKGFnKSAoKFdYU19BVFRSX0dST1VQX0NBU1QgKGFnKSktPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0hBU19SRUZTKQojZGVmaW5lIFdYU19BVFRSX0dST1VQX0VYUEFOREVEKGFnKSAoKFdYU19BVFRSX0dST1VQX0NBU1QgKGFnKSktPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQpCi8qCiogTWFjcm9zIGZvciBwYXJ0aWNsZXMuCiovCiNkZWZpbmUgV1hTX1BBUlRJQ0xFKHApIFdYU19QVENfQ0FTVCAocCkKCiNkZWZpbmUgV1hTX1BBUlRJQ0xFX1RFUk0ocCkgKFdYU19QQVJUSUNMRShwKSktPmNoaWxkcmVuCgojZGVmaW5lIFdYU19QQVJUSUNMRV9URVJNX0FTX0VMRU0ocCkgKFdYU19FTEVNX0NBU1QgV1hTX1BBUlRJQ0xFX1RFUk0ocCkpCgojZGVmaW5lIFdYU19QQVJUSUNMRV9NT0RFTChwKSBXWFNfTU9ERUxfR1JPVVBfQ0FTVCBXWFNfUEFSVElDTEUocCktPmNoaWxkcmVuCi8qCiogTWFjcm9zIGZvciBtb2RlbCBncm91cHMgZGVmaW5pdGlvbnMuCiovCiNkZWZpbmUgV1hTX01PREVMR1JPVVBERUZfTU9ERUwobWdkKSAoV1hTX01PREVMX0dST1VQX0NBU1QgKG1nZCkpLT5jaGlsZHJlbgovKgoqIE1hY3JvcyBmb3IgbW9kZWwgZ3JvdXBzLgoqLwojZGVmaW5lIFdYU19JU19NT0RFTF9HUk9VUChpKSBcCiAgICAoKChpKS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8IFwKICAgICAoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHx8IFwKICAgICAoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpKQoKI2RlZmluZSBXWFNfTU9ERUxHUk9VUF9QQVJUSUNMRShtZykgV1hTX1BUQ19DQVNUIChtZyktPmNoaWxkcmVuCi8qCiogTWFjcm9zIGZvciBzY2hlbWEgYnVja2V0cy4KKi8KI2RlZmluZSBXWFNfSVNfQlVDS0VUX0lOQ1JFREVGKHQpICgoKHQpID09IFhNTF9TQ0hFTUFfU0NIRU1BX0lOQ0xVREUpIHx8IFwKICAgICgodCkgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpKQoKI2RlZmluZSBXWFNfSVNfQlVDS0VUX0lNUE1BSU4odCkgKCgodCkgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTikgfHwgXAogICAgKCh0KSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQpKQoKI2RlZmluZSBXWFNfSU1QQlVDS0VUKGIpICgoeG1sU2NoZW1hSW1wb3J0UHRyKSAoYikpCgojZGVmaW5lIFdYU19JTkNCVUNLRVQoYikgKCh4bWxTY2hlbWFJbmNsdWRlUHRyKSAoYikpCi8qCiogTWFjcm9zIGZvciBjb21wbGV4L3NpbXBsZSB0eXBlcy4KKi8KI2RlZmluZSBXWFNfSVNfQU5ZVFlQRShpKSBcCiAgICAgKCggKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoIChXWFNfVFlQRV9DQVNUIChpKSktPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBXWFNfSVNfQ09NUExFWChpKSBcCiAgICAoKChpKS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwgXAogICAgICgoaSktPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBXWFNfSVNfU0lNUExFKGl0ZW0pIFwKICAgICgoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB8fCBcCiAgICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpKQoKI2RlZmluZSBXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKGkpIFwKICAgICgoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoKGkpLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkKCiNkZWZpbmUgV1hTX0lTX1JFU1RSSUNUSU9OKHQpIFwKICAgICgodCktPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikKCiNkZWZpbmUgV1hTX0lTX0VYVEVOU0lPTih0KSBcCiAgICAoKHQpLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKQoKI2RlZmluZSBXWFNfSVNfVFlQRV9OT1RfRklYRUQoaSkgXAogICAgKCgoaSktPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiBcCiAgICAgKCgoaSktPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9SRVNPTFZFRCkgPT0gMCkpCgojZGVmaW5lIFdYU19JU19UWVBFX05PVF9GSVhFRF8xKGl0ZW0pIFwKICAgICgoKGl0ZW0pLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICgoKGl0ZW0pLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklYVVBfMSkgPT0gMCkpCgojZGVmaW5lIFdYU19UWVBFX0lTX0dMT0JBTCh0KSAoKHQpLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKQoKI2RlZmluZSBXWFNfVFlQRV9JU19MT0NBTCh0KSAoKCh0KS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgPT0gMCkKLyoKKiBNYWNyb3MgZm9yIGV4Y2x1c2l2ZWx5IGZvciBjb21wbGV4IHR5cGVzLgoqLwojZGVmaW5lIFdYU19IQVNfQ09NUExFWF9DT05URU5UKGl0ZW0pIFwKICAgICgoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB8fCBcCiAgICAgKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgfHwgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKQoKI2RlZmluZSBXWFNfSEFTX1NJTVBMRV9DT05URU5UKGl0ZW0pIFwKICAgICgoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKQoKI2RlZmluZSBXWFNfSEFTX01JWEVEX0NPTlRFTlQoaXRlbSkgXAogICAgKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkKCiNkZWZpbmUgV1hTX0VNUFRJQUJMRSh0KSBcCiAgICAoeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZShXWFNfUFRDX0NBU1QgKHQpLT5zdWJ0eXBlcykpCgojZGVmaW5lIFdYU19UWVBFX0NPTlRFTlRUWVBFKHQpICh0KS0+c3VidHlwZXMKCiNkZWZpbmUgV1hTX1RZUEVfUEFSVElDTEUodCkgV1hTX1BUQ19DQVNUICh0KS0+c3VidHlwZXMKCiNkZWZpbmUgV1hTX1RZUEVfUEFSVElDTEVfVEVSTSh0KSBXWFNfUEFSVElDTEVfVEVSTShXWFNfVFlQRV9QQVJUSUNMRSh0KSkKLyoKKiBNYWNyb3MgZm9yIGV4Y2x1c2l2ZWx5IGZvciBzaW1wbGUgdHlwZXMuCiovCiNkZWZpbmUgV1hTX0xJU1RfSVRFTVRZUEUodCkgKHQpLT5zdWJ0eXBlcwoKI2RlZmluZSBXWFNfSVNfQVRPTUlDKHQpICh0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpCgojZGVmaW5lIFdYU19JU19MSVNUKHQpICh0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKQoKI2RlZmluZSBXWFNfSVNfVU5JT04odCkgKHQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKQovKgoqIE1pc2MgcGFyc2VyIGNvbnRleHQgbWFjcm9zLgoqLwojZGVmaW5lIFdYU19DT05TVFJVQ1RPUihjdHgpIChjdHgpLT5jb25zdHJ1Y3RvcgoKI2RlZmluZSBXWFNfSEFTX0JVQ0tFVFMoY3R4KSBcCiggKFdYU19DT05TVFJVQ1RPUigoY3R4KSktPmJ1Y2tldHMgIT0gTlVMTCkgJiYgXAooV1hTX0NPTlNUUlVDVE9SKChjdHgpKS0+YnVja2V0cy0+bmJJdGVtcyA+IDApICkKCiNkZWZpbmUgV1hTX1NVQlNUX0dST1VQUyhjdHgpIFdYU19DT05TVFJVQ1RPUigoY3R4KSktPnN1YnN0R3JvdXBzCgojZGVmaW5lIFdYU19CVUNLRVQoY3R4KSBXWFNfQ09OU1RSVUNUT1IoKGN0eCkpLT5idWNrZXQKCiNkZWZpbmUgV1hTX1NDSEVNQShjdHgpIChjdHgpLT5zY2hlbWEKCiNkZWZpbmUgV1hTX0FERF9MT0NBTChjdHgsIGl0ZW0pIFwKICAgIHhtbFNjaGVtYUFkZEl0ZW1TaXplKCYoV1hTX0JVQ0tFVChjdHgpLT5sb2NhbHMpLCAxMCwgaXRlbSkKCiNkZWZpbmUgV1hTX0FERF9HTE9CQUwoY3R4LCBpdGVtKSBcCiAgICB4bWxTY2hlbWFBZGRJdGVtU2l6ZSgmKFdYU19CVUNLRVQoY3R4KS0+Z2xvYmFscyksIDUsIGl0ZW0pCgojZGVmaW5lIFdYU19BRERfUEVORElORyhjdHgsIGl0ZW0pIFwKICAgIHhtbFNjaGVtYUFkZEl0ZW1TaXplKCYoKGN0eCktPmNvbnN0cnVjdG9yLT5wZW5kaW5nKSwgMTAsIGl0ZW0pCi8qCiogeG1sU2NoZW1hSXRlbUxpc3QgbWFjcm9zLgoqLwojZGVmaW5lIFdYU19JTElTVF9JU19FTVBUWShsKSAoKGwgPT0gTlVMTCkgfHwgKChsKS0+bmJJdGVtcyA9PSAwKSkKLyoKKiBNaXNjIG1hY3Jvcy4KKi8KI2RlZmluZSBJU19TQ0hFTUEobm9kZSwgdHlwZSkgXAogICAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPm5zICE9IE5VTEwpICYmIFwKICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0eXBlKSkgJiYgXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKQoKI2RlZmluZSBGUkVFX0FORF9OVUxMKHN0cikgaWYgKChzdHIpICE9IE5VTEwpIHsgeG1sRnJlZSgoeG1sQ2hhciAqKSAoc3RyKSk7IHN0ciA9IE5VTEw7IH0KCi8qCiogU2luY2Ugd2UgcHV0IHRoZSBkZWZhdWx0L2ZpeGVkIHZhbHVlcyBpbnRvIHRoZSBkaWN0LCB3ZSBjYW4KKiB1c2UgcG9pbnRlciBjb21wYXJpc29uIGZvciB0aG9zZSB2YWx1ZXMuCiogUkVNT1ZFRDogKHhtbFN0ckVxdWFsKCh2MSksICh2MikpKQoqLwojZGVmaW5lIFdYU19BUkVfREVGQVVMVF9TVFJfRVFVQUwodjEsIHYyKSAoKHYxKSA9PSAodjIpKQoKI2RlZmluZSBJTk9ERV9OSUxMRUQoaXRlbSkgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fTklMTEVEKQoKI2RlZmluZSBDQU5fUEFSU0VfU0NIRU1BKGIpICgoKGIpLT5kb2MgIT0gTlVMTCkgJiYgKChiKS0+cGFyc2VkID09IDApKQoKI2RlZmluZSBIRkFJTFVSRSBpZiAocmVzID09IC0xKSBnb3RvIGV4aXRfZmFpbHVyZTsKCiNkZWZpbmUgSEVSUk9SIGlmIChyZXMgIT0gMCkgZ290byBleGl0X2Vycm9yOwoKI2RlZmluZSBIU1RPUChjdHgpIGlmICgoY3R4KS0+c3RvcCkgZ290byBleGl0OwovKgoqIFNvbWUgZmxhZ3MgdXNlZCBmb3IgdmFyaW91cyBzY2hlbWEgY29uc3RyYWludHMuCiovCiNkZWZpbmUgU1VCU0VUX1JFU1RSSUNUSU9OICAxPDwwCiNkZWZpbmUgU1VCU0VUX0VYVEVOU0lPTiAgICAxPDwxCiNkZWZpbmUgU1VCU0VUX1NVQlNUSVRVVElPTiAxPDwyCiNkZWZpbmUgU1VCU0VUX0xJU1QgICAgICAgICAxPDwzCiNkZWZpbmUgU1VCU0VUX1VOSU9OICAgICAgICAxPDw0Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTm9kZUluZm8geG1sU2NoZW1hTm9kZUluZm87CnR5cGVkZWYgeG1sU2NoZW1hTm9kZUluZm8gKnhtbFNjaGVtYU5vZGVJbmZvUHRyOwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1MaXN0IHhtbFNjaGVtYUl0ZW1MaXN0Owp0eXBlZGVmIHhtbFNjaGVtYUl0ZW1MaXN0ICp4bWxTY2hlbWFJdGVtTGlzdFB0cjsKc3RydWN0IF94bWxTY2hlbWFJdGVtTGlzdCB7CiAgICB2b2lkICoqaXRlbXM7ICAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgbmJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IHNpemVJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwp9OwoKI2RlZmluZSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSIDEKI2RlZmluZSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SIDIKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBYnN0cmFjdEN0eHQgeG1sU2NoZW1hQWJzdHJhY3RDdHh0Owp0eXBlZGVmIHhtbFNjaGVtYUFic3RyYWN0Q3R4dCAqeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUFic3RyYWN0Q3R4dCB7CiAgICBpbnQgdHlwZTsgLyogRS5nLiBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SICovCn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQnVja2V0IHhtbFNjaGVtYUJ1Y2tldDsKdHlwZWRlZiB4bWxTY2hlbWFCdWNrZXQgKnhtbFNjaGVtYUJ1Y2tldFB0cjsKCiNkZWZpbmUgWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTiAwCiNkZWZpbmUgWE1MX1NDSEVNQV9TQ0hFTUFfSU1QT1JUIDEKI2RlZmluZSBYTUxfU0NIRU1BX1NDSEVNQV9JTkNMVURFIDIKI2RlZmluZSBYTUxfU0NIRU1BX1NDSEVNQV9SRURFRklORSAzCgovKioKICogeG1sU2NoZW1hU2NoZW1hUmVsYXRpb246IAogKgogKiBVc2VkIHRvIGNyZWF0ZSBhIGdyYXBoIG9mIHNjaGVtYSByZWxhdGlvbnNoaXBzLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVNjaGVtYVJlbGF0aW9uIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uOwp0eXBlZGVmIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uICp4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0cjsKc3RydWN0IF94bWxTY2hlbWFTY2hlbWFSZWxhdGlvbiB7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciBuZXh0OwogICAgaW50IHR5cGU7IC8qIEUuZy4gWE1MX1NDSEVNQV9TQ0hFTUFfSU1QT1JUICovCiAgICBjb25zdCB4bWxDaGFyICppbXBvcnROYW1lc3BhY2U7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0Owp9OwoKI2RlZmluZSBYTUxfU0NIRU1BX0JVQ0tFVF9NQVJLRUQgMTw8MAojZGVmaW5lIFhNTF9TQ0hFTUFfQlVDS0VUX0NPTVBTX0FEREVEIDE8PDEKCnN0cnVjdCBfeG1sU2NoZW1hQnVja2V0IHsKICAgIGludCB0eXBlOwogICAgaW50IGZsYWdzOwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICBjb25zdCB4bWxDaGFyICpvcmlnVGFyZ2V0TmFtZXNwYWNlOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbGF0aW9uczsKICAgIGludCBsb2NhdGVkOwogICAgaW50IHBhcnNlZDsKICAgIGludCBpbXBvcnRlZDsKICAgIGludCBwcmVzZXJ2ZURvYzsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGdsb2JhbHM7IC8qIEdsb2JhbCBjb21wb25lbnRzLiAqLyAKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxvY2FsczsgLyogTG9jYWwgY29tcG9uZW50cy4gKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFJbXBvcnQ6IAogKiAoZXh0ZW5kcyB4bWxTY2hlbWFCdWNrZXQpCiAqCiAqIFJlZmxlY3RzIGEgc2NoZW1hLiBIb2xkcyBzb21lIGluZm9ybWF0aW9uCiAqIGFib3V0IHRoZSBzY2hlbWEgYW5kIGl0cyB0b3BsZXZlbCBjb21wb25lbnRzLiBEdXBsaWNhdGUKICogdG9wbGV2ZWwgY29tcG9uZW50cyBhcmUgbm90IGNoZWNrZWQgYXQgdGhpcyBsZXZlbC4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgeG1sU2NoZW1hSW1wb3J0Owp0eXBlZGVmIHhtbFNjaGVtYUltcG9ydCAqeG1sU2NoZW1hSW1wb3J0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUltcG9ydCB7CiAgICBpbnQgdHlwZTsgLyogTWFpbiBPUiBpbXBvcnQgT1IgaW5jbHVkZS4gKi8KICAgIGludCBmbGFnczsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOyAvKiBUaGUgVVJJIG9mIHRoZSBzY2hlbWEgZG9jdW1lbnQuICovCiAgICAvKiBGb3IgY2hhbWVsZW9uIGluY2x1ZGVzLCBAb3JpZ1RhcmdldE5hbWVzcGFjZSB3aWxsIGJlIE5VTEwgKi8KICAgIGNvbnN0IHhtbENoYXIgKm9yaWdUYXJnZXROYW1lc3BhY2U7CiAgICAvKiAKICAgICogRm9yIGNoYW1lbGVvbiBpbmNsdWRlcywgQHRhcmdldE5hbWVzcGFjZSB3aWxsIGJlIHRoZQogICAgKiB0YXJnZXROYW1lc3BhY2Ugb2YgdGhlIGluY2x1ZGluZyBzY2hlbWEuIAogICAgKi8KICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbERvY1B0ciBkb2M7IC8qIFRoZSBzY2hlbWEgbm9kZS10cmVlLiAqLwogICAgLyogQHJlbGF0aW9ucyB3aWxsIGhvbGQgYW55IGluY2x1ZGVkL2ltcG9ydGVkL3JlZGVmaW5lZCBzY2hlbWFzLiAqLwogICAgeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgcmVsYXRpb25zOwogICAgaW50IGxvY2F0ZWQ7CiAgICBpbnQgcGFyc2VkOwogICAgaW50IGltcG9ydGVkOwogICAgaW50IHByZXNlcnZlRG9jOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgZ2xvYmFsczsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxvY2FsczsKICAgIC8qIFRoZSBpbXBvcnRlZCBzY2hlbWEuICovCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOwp9OwoKLyoKKiAoZXh0ZW5kcyB4bWxTY2hlbWFCdWNrZXQpCiovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHhtbFNjaGVtYUluY2x1ZGU7CnR5cGVkZWYgeG1sU2NoZW1hSW5jbHVkZSAqeG1sU2NoZW1hSW5jbHVkZVB0cjsKc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHsKICAgIGludCB0eXBlOwogICAgaW50IGZsYWdzOwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICBjb25zdCB4bWxDaGFyICpvcmlnVGFyZ2V0TmFtZXNwYWNlOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbGF0aW9uczsKICAgIGludCBsb2NhdGVkOwogICAgaW50IHBhcnNlZDsKICAgIGludCBpbXBvcnRlZDsKICAgIGludCBwcmVzZXJ2ZURvYzsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGdsb2JhbHM7IC8qIEdsb2JhbCBjb21wb25lbnRzLiAqLyAKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxvY2FsczsgLyogTG9jYWwgY29tcG9uZW50cy4gKi8KCiAgICAvKiBUaGUgb3duaW5nIG1haW4gb3IgaW1wb3J0IHNjaGVtYSBidWNrZXQuICovCiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgb3duZXJJbXBvcnQ7Cn07CgovKioKICogeG1sU2NoZW1hQmFzaWNJdGVtOgogKgogKiBUaGUgYWJzdHJhY3QgYmFzZSB0eXBlIGZvciBzY2hlbWEgY29tcG9uZW50cy4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFCYXNpY0l0ZW0geG1sU2NoZW1hQmFzaWNJdGVtOwp0eXBlZGVmIHhtbFNjaGVtYUJhc2ljSXRlbSAqeG1sU2NoZW1hQmFzaWNJdGVtUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUJhc2ljSXRlbSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYUFubm90SXRlbToKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3IgYW5ub3RhdGVkIHNjaGVtYSBjb21wb25lbnRzLgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFCYXNpY0l0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQW5ub3RJdGVtIHhtbFNjaGVtYUFubm90SXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFBbm5vdEl0ZW0gKnhtbFNjaGVtYUFubm90SXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFBbm5vdEl0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKLyoqCiAqIHhtbFNjaGVtYVRyZWVJdGVtOgogKgogKiBUaGUgYWJzdHJhY3QgYmFzZSB0eXBlIGZvciB0cmVlLWxpa2Ugc3RydWN0dXJlZCBzY2hlbWEgY29tcG9uZW50cy4KICogKEV4dGVuZHMgeG1sU2NoZW1hQW5ub3RJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVRyZWVJdGVtIHhtbFNjaGVtYVRyZWVJdGVtOwp0eXBlZGVmIHhtbFNjaGVtYVRyZWVJdGVtICp4bWxTY2hlbWFUcmVlSXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFUcmVlSXRlbSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBuZXh0OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2hpbGRyZW47Cn07CgoKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfVVNFX0ZJWEVEIDE8PDAKLyoqCiAqIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cjoKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3IgdHJlZS1saWtlIHN0cnVjdHVyZWQgc2NoZW1hIGNvbXBvbmVudHMuCiAqIChFeHRlbmRzIHhtbFNjaGVtYVRyZWVJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUF0dHJpYnV0ZVVzZSB4bWxTY2hlbWFBdHRyaWJ1dGVVc2U7CnR5cGVkZWYgeG1sU2NoZW1hQXR0cmlidXRlVXNlICp4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXR0cmlidXRlVXNlIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciBuZXh0OyAvKiBUaGUgbmV4dCBhdHRyLiB1c2UuICovCiAgICAvKiAKICAgICogVGhlIGF0dHIuIGRlY2wuIE9SIGEgUU5hbWUtcmVmLiB0byBhbiBhdHRyLiBkZWNsLiBPUgogICAgKiBhIFFOYW1lLXJlZi4gdG8gYW4gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24uCiAgICAqLwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJEZWNsOwoKICAgIGludCBmbGFnczsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBvY2N1cnM7IC8qIHJlcXVpcmVkLCBvcHRpb25hbCAqLwogICAgY29uc3QgeG1sQ2hhciAqIGRlZlZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIGRlZlZhbDsKfTsKCi8qKgogKiB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHI6CiAqCiAqIEEgaGVscGVyIGNvbXBvbmVudCB0byByZWZsZWN0IGF0dHJpYnV0ZSBwcm9oaWJpdGlvbnMuCiAqIChFeHRlbmRzIHhtbFNjaGVtYUJhc2ljSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWIgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYiAqeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOyAvKiA9PSBYTUxfU0NIRU1BX0VYVFJBX0FUVFJfVVNFX1BST0hJQiAqLwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIGludCBpc1JlZjsKfTsKCi8qKgogKiB4bWxTY2hlbWFSZWRlZjoKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFSZWRlZiB4bWxTY2hlbWFSZWRlZjsKdHlwZWRlZiB4bWxTY2hlbWFSZWRlZiAqeG1sU2NoZW1hUmVkZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUmVkZWYgewogICAgeG1sU2NoZW1hUmVkZWZQdHIgbmV4dDsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOyAvKiBUaGUgcmVkZWZpbmluZyBjb21wb25lbnQuICovCiAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgcmVmZXJlbmNlOyAvKiBUaGUgcmVmZXJlbmNpbmcgY29tcG9uZW50LiAqLwogICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIHRhcmdldDsgLyogVGhlIHRvLWJlLXJlZGVmaW5lZCBjb21wb25lbnQuICovCiAgICBjb25zdCB4bWxDaGFyICpyZWZOYW1lOyAvKiBUaGUgbmFtZSBvZiB0aGUgdG8tYmUtcmVkZWZpbmVkIGNvbXBvbmVudC4gKi8KICAgIGNvbnN0IHhtbENoYXIgKnJlZlRhcmdldE5zOyAvKiBUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0by1iZS1yZWRlZmluZWQgY29tcC4gKi8KICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciB0YXJnZXRCdWNrZXQ7IC8qIFRoZSByZWRlZmluZWQgc2NoZW1hLiAqLwp9OwoKLyoqCiAqIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQ6CiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dCB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0Owp0eXBlZGVmIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQgKnhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHI7CnN0cnVjdCBfeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dCB7CiAgICB4bWxTY2hlbWFQdHIgbWFpblNjaGVtYTsgLyogVGhlIG1haW4gc2NoZW1hLiAqLwogICAgeG1sU2NoZW1hQnVja2V0UHRyIG1haW5CdWNrZXQ7IC8qIFRoZSBtYWluIHNjaGVtYSBidWNrZXQgKi8KICAgIHhtbERpY3RQdHIgZGljdDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGJ1Y2tldHM7IC8qIExpc3Qgb2Ygc2NoZW1hIGJ1Y2tldHMuICovCiAgICAvKiB4bWxTY2hlbWFJdGVtTGlzdFB0ciByZWxhdGlvbnM7ICovIC8qIExpc3Qgb2Ygc2NoZW1hIHJlbGF0aW9ucy4gKi8KICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQ7IC8qIFRoZSBjdXJyZW50IHNjaGVtYSBidWNrZXQgKi8gICAgCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBwZW5kaW5nOyAvKiBBbGwgQ29tcG9uZW50cyBvZiBhbGwgc2NoZW1hcyB0aGF0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWVkIHRvIGJlIGZpeGVkLiAqLwogICAgeG1sSGFzaFRhYmxlUHRyIHN1YnN0R3JvdXBzOwogICAgeG1sU2NoZW1hUmVkZWZQdHIgcmVkZWZzOwogICAgeG1sU2NoZW1hUmVkZWZQdHIgbGFzdFJlZGVmOwp9OwoKI2RlZmluZSBYTUxfU0NIRU1BU19QQVJTRV9FUlJPUgkJMQojZGVmaW5lIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyBYTUxfUEFSU0VfTk9FTlQKCnN0cnVjdCBfeG1sU2NoZW1hUGFyc2VyQ3R4dCB7CiAgICBpbnQgdHlwZTsKICAgIHZvaWQgKmVyckN0eHQ7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZXJyb3IgY29udGV4dCAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIGludCBlcnI7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvcjsKCiAgICB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0UHRyIGNvbnN0cnVjdG9yOwogICAgaW50IG93bnNDb25zdHJ1Y3RvcjsgLyogVE9ETzogTW92ZSB0aGlzIHRvIHBhcnNlciAqZmxhZ3MqLiAqLwoKICAgIC8qIHhtbFNjaGVtYVB0ciB0b3BzY2hlbWE7CSovCiAgICAvKiB4bWxIYXNoVGFibGVQdHIgbmFtZXNwYWNlczsgICovCgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBtYWluIHNjaGVtYSBpbiB1c2UgKi8KICAgIGludCBjb3VudGVyOwoKICAgIGNvbnN0IHhtbENoYXIgKlVSTDsKICAgIHhtbERvY1B0ciBkb2M7CiAgICBpbnQgcHJlc2VydmU7CQkvKiBXaGV0aGVyIHRoZSBkb2Mgc2hvdWxkIGJlIGZyZWVkICAqLwoKICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcjsKICAgIGludCBzaXplOwoKICAgIC8qCiAgICAgKiBVc2VkIHRvIGJ1aWxkIGNvbXBsZXggZWxlbWVudCBjb250ZW50IG1vZGVscwogICAgICovCiAgICB4bWxBdXRvbWF0YVB0ciBhbTsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGVuZDsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhdGU7CgogICAgeG1sRGljdFB0ciBkaWN0OwkJLyogZGljdGlvbm5hcnkgZm9yIGludGVybmVkIHN0cmluZyBuYW1lcyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICBpbnQgb3B0aW9uczsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKICAgIGludCBpc1M0UzsKICAgIGludCBpc1JlZGVmaW5lOwogICAgaW50IHhzaUFzc2VtYmxlOwogICAgaW50IHN0b3A7IC8qIElmIHRoZSBwYXJzZXIgc2hvdWxkIHN0b3A7IGkuZS4gYSBjcml0aWNhbCBlcnJvci4gKi8KICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciByZWRlZmluZWQ7IC8qIFRoZSBzY2hlbWEgdG8gYmUgcmVkZWZpbmVkLiAqLwoKICAgIHhtbFNjaGVtYVJlZGVmUHRyIHJlZGVmOyAvKiBVc2VkIGZvciByZWRlZmluaXRpb25zLiAqLwogICAgaW50IHJlZGVmQ291bnRlcjsgLyogVXNlZCBmb3IgcmVkZWZpbml0aW9ucy4gKi8gCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBhdHRyUHJvaGliczsKfTsKCi8qKgogKiB4bWxTY2hlbWFRTmFtZVJlZjoKICoKICogQSBjb21wb25lbnQgcmVmZXJlbmNlIGl0ZW0gKG5vdCBhIHNjaGVtYSBjb21wb25lbnQpCiAqIChFeHRlbmRzIHhtbFNjaGVtYUJhc2ljSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFRTmFtZVJlZiB4bWxTY2hlbWFRTmFtZVJlZjsKdHlwZWRlZiB4bWxTY2hlbWFRTmFtZVJlZiAqeG1sU2NoZW1hUU5hbWVSZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUU5hbWVSZWYgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOyAvKiBUaGUgcmVzb2x2ZWQgcmVmZXJlbmNlZCBpdGVtLiAqLwogICAgeG1sU2NoZW1hVHlwZVR5cGUgaXRlbVR5cGU7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sTm9kZVB0ciBub2RlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBhcnRpY2xlOgogKgogKiBBIHBhcnRpY2xlIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUGFydGljbGUgeG1sU2NoZW1hUGFydGljbGU7CnR5cGVkZWYgeG1sU2NoZW1hUGFydGljbGUgKnhtbFNjaGVtYVBhcnRpY2xlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBhcnRpY2xlIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIG5leHQ7IC8qIG5leHQgcGFydGljbGUgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiB0aGUgInRlcm0iIChlLmcuIGEgbW9kZWwgZ3JvdXAsCglhIGdyb3VwIGRlZmluaXRpb24sIGEgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRiAoaWYgYSByZWZlcmVuY2UpLAogICAgICAgIGV0Yy4pICovCiAgICBpbnQgbWluT2NjdXJzOwogICAgaW50IG1heE9jY3VyczsKICAgIHhtbE5vZGVQdHIgbm9kZTsKfTsKCi8qKgogKiB4bWxTY2hlbWFNb2RlbEdyb3VwOgogKgogKiBBIG1vZGVsIGdyb3VwIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB4bWxTY2hlbWFNb2RlbEdyb3VwOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXAgKnhtbFNjaGVtYU1vZGVsR3JvdXBQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOyAvKiBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIFhNTF9TQ0hFTUFfVFlQRV9BTEwgKi8KICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbm90IHVzZWQgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiBmaXJzdCBwYXJ0aWNsZSAoT1IgImVsZW1lbnQgZGVjbCIgT1IgIndpbGRjYXJkIikgKi8KICAgIHhtbE5vZGVQdHIgbm9kZTsKfTsKCiNkZWZpbmUgWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEIDE8PDAKI2RlZmluZSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9SRURFRklORUQgMTw8MQovKioKICogeG1sU2NoZW1hTW9kZWxHcm91cERlZjoKICoKICogQSBtb2RlbCBncm91cCBkZWZpbml0aW9uIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWYgKnhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOyAvKiBYTUxfU0NIRU1BX1RZUEVfR1JPVVAgKi8KICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbm90IHVzZWQgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiB0aGUgIm1vZGVsIGdyb3VwIiAqLwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBmbGFnczsKfTsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJREMgeG1sU2NoZW1hSURDOwp0eXBlZGVmIHhtbFNjaGVtYUlEQyAqeG1sU2NoZW1hSURDUHRyOwoKLyoqCiAqIHhtbFNjaGVtYUlEQ1NlbGVjdDoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgImZpZWxkIiBhbmQgInNlbGVjdG9yIiBpdGVtLCBob2xkaW5nIHRoZQogKiBYUGF0aCBleHByZXNzaW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1NlbGVjdCB4bWxTY2hlbWFJRENTZWxlY3Q7CnR5cGVkZWYgeG1sU2NoZW1hSURDU2VsZWN0ICp4bWxTY2hlbWFJRENTZWxlY3RQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU2VsZWN0IHsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBuZXh0OwogICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKICAgIGludCBpbmRleDsgLyogYW4gaW5kZXggcG9zaXRpb24gaWYgc2lnbmlmaWNhbnQgZm9yIElEQyBrZXktc2VxdWVuY2VzICovCiAgICBjb25zdCB4bWxDaGFyICp4cGF0aDsgLyogdGhlIFhQYXRoIGV4cHJlc3Npb24gKi8KICAgIHZvaWQgKnhwYXRoQ29tcDsgLyogdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFJREM6CiAqCiAqIFRoZSBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFBbm5vdEl0ZW0pCiAqLwoKc3RydWN0IF94bWxTY2hlbWFJREMgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hSURDUHRyIG5leHQ7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbGVjdG9yOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGZpZWxkczsKICAgIGludCBuYkZpZWxkczsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKfTsKCi8qKgogKiB4bWxTY2hlbWFJRENBdWc6CiAqCiAqIFRoZSBhdWdtZW50ZWQgSURDIGluZm9ybWF0aW9uIHVzZWQgZm9yIHZhbGlkYXRpb24uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDQXVnIHhtbFNjaGVtYUlEQ0F1ZzsKdHlwZWRlZiB4bWxTY2hlbWFJRENBdWcgKnhtbFNjaGVtYUlEQ0F1Z1B0cjsKc3RydWN0IF94bWxTY2hlbWFJRENBdWcgewogICAgeG1sU2NoZW1hSURDQXVnUHRyIG5leHQ7IC8qIG5leHQgaW4gYSBsaXN0ICovCiAgICB4bWxTY2hlbWFJRENQdHIgZGVmOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIGludCBrZXlyZWZEZXB0aDsgLyogdGhlIGxvd2VzdCB0cmVlIGxldmVsIHRvIHdoaWNoIElEQwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZXMgbmVlZCB0byBiZSBidWJibGVkIHVwd2FyZHMgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDS2V5U2VxdWVuY2U6CiAqCiAqIFRoZSBrZXkgc2VxdWVuY2Ugb2YgYSBub2RlIHRhYmxlIGl0ZW0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB4bWxTY2hlbWFQU1ZJSURDS2V5Owp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENLZXkgKnhtbFNjaGVtYVBTVklJRENLZXlQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENOb2RlOgogKgogKiBUaGUgbm9kZSB0YWJsZSBpdGVtIG9mIGEgbm9kZSB0YWJsZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDTm9kZSB4bWxTY2hlbWFQU1ZJSURDTm9kZTsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDTm9kZSAqeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ05vZGUgewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5czsKICAgIGludCBub2RlTGluZTsKICAgIGludCBub2RlUU5hbWVJRDsgICAgCgp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nOgogKgogKiBUaGUgaWRlbnRpdHktY29uc3RyYWludCBiaW5kaW5nIGl0ZW0gb2YgdGhlIFtpZGVudGl0eS1jb25zdHJhaW50IHRhYmxlXS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDQmluZGluZyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZzsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZyAqeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgewogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgbmV4dDsgLyogbmV4dCBiaW5kaW5nIG9mIGEgc3BlY2lmaWMgbm9kZSAqLwogICAgeG1sU2NoZW1hSURDUHRyIGRlZmluaXRpb247IC8qIHRoZSBJREMgZGVmaW5pdGlvbiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKm5vZGVUYWJsZTsgLyogYXJyYXkgb2Yga2V5LXNlcXVlbmNlcyAqLwogICAgaW50IG5iTm9kZXM7IC8qIG51bWJlciBvZiBlbnRyaWVzIGluIHRoZSBub2RlIHRhYmxlICovCiAgICBpbnQgc2l6ZU5vZGVzOyAvKiBzaXplIG9mIHRoZSBub2RlIHRhYmxlICovCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBkdXBsczsKfTsKCgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUiAxCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEIDIKCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX01BVENIRVMgLTIKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfQkxPQ0tFRCAtMwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ01hdGNoZXIgeG1sU2NoZW1hSURDTWF0Y2hlcjsKdHlwZWRlZiB4bWxTY2hlbWFJRENNYXRjaGVyICp4bWxTY2hlbWFJRENNYXRjaGVyUHRyOwoKLyoqCiAqIHhtbFNjaGVtYUlEQ1N0YXRlT2JqOgogKgogKiBUaGUgc3RhdGUgb2JqZWN0IHVzZWQgdG8gZXZhbHVhdGUgWFBhdGggZXhwcmVzc2lvbnMuCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDU3RhdGVPYmogeG1sU2NoZW1hSURDU3RhdGVPYmo7CnR5cGVkZWYgeG1sU2NoZW1hSURDU3RhdGVPYmogKnhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ1N0YXRlT2JqIHsKICAgIGludCB0eXBlOwogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgbmV4dDsgLyogbmV4dCBpZiBpbiBhIGxpc3QgKi8KICAgIGludCBkZXB0aDsgLyogZGVwdGggb2YgY3JlYXRpb24gKi8KICAgIGludCAqaGlzdG9yeTsgLyogbGlzdCBvZiAoZGVwdGgsIHN0YXRlLWlkKSB0dXBsZXMgKi8KICAgIGludCBuYkhpc3Rvcnk7CiAgICBpbnQgc2l6ZUhpc3Rvcnk7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7IC8qIHRoZSBjb3JyZXNwb25kZW50IGZpZWxkL3NlbGVjdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXIgKi8KICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWw7CiAgICB2b2lkICp4cGF0aEN0eHQ7Cn07CgojZGVmaW5lIElEQ19NQVRDSEVSIDAKCi8qKgogKiB4bWxTY2hlbWFJRENNYXRjaGVyOgogKgogKiBVc2VkIHRvIGV2YWx1YXRlIElEQyBzZWxlY3RvcnMgKGFuZCBmaWVsZHMpLgogKi8Kc3RydWN0IF94bWxTY2hlbWFJRENNYXRjaGVyIHsKICAgIGludCB0eXBlOwogICAgaW50IGRlcHRoOyAvKiB0aGUgdHJlZSBkZXB0aCBhdCBjcmVhdGlvbiB0aW1lICovCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbmV4dENhY2hlZDsgLyogbmV4dCBpbiB0aGUgY2FjaGUgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7IC8qIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gKi8KICAgIGludCBpZGNUeXBlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKmtleVNlcXM7IC8qIHRoZSBrZXktc2VxdWVuY2VzIG9mIHRoZSB0YXJnZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyAqLwogICAgaW50IHNpemVLZXlTZXFzOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgdGFyZ2V0czsgLyogbGlzdCBvZiB0YXJnZXQtbm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSBlbnRyaWVzICovCn07CgovKgoqIEVsZW1lbnQgaW5mbyBmbGFncy4KKi8KI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTICAxPDwwCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMgMTw8MQojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRAkgICAgICAgMTw8MgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0xPQ0FMX1RZUEUJICAgICAgIDE8PDMKCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEICAgICAgMTw8NAojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZICAgICAgICAgICAgIDE8PDUKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfQ09OVEVOVCAgICAgICAxPDw2CgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQgIDE8PDcKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQgIDE8PDgKI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEICAxPDw5CiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFICAxPDwxMAoKLyoqCiAqIHhtbFNjaGVtYU5vZGVJbmZvOgogKgogKiBIb2xkcyBpbmZvcm1hdGlvbiBvZiBhbiBlbGVtZW50IG5vZGUuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHsKICAgIGludCBub2RlVHlwZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBub2RlTGluZTsgICAgCiAgICBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWU7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWw7IC8qIHRoZSBwcmUtY29tcHV0ZWQgdmFsdWUgaWYgYW55ICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWY7IC8qIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24gaWYgYW55ICovCgogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBub2RlIGluZm8gZmxhZ3MgKi8KCiAgICBpbnQgdmFsTmVlZGVkOwogICAgaW50IG5vcm1WYWw7CgogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOyAvKiB0aGUgZWxlbWVudC9hdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGlkY1RhYmxlOyAvKiB0aGUgdGFibGUgb2YgUFNWSSBJREMgYmluZGluZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgdGhlIHNjb3BlIGVsZW1lbnQqLwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBpZGNNYXRjaGVyczsgLyogdGhlIElEQyBtYXRjaGVycyBmb3IgdGhlIHNjb3BlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50ICovCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleEN0eHQ7CgogICAgY29uc3QgeG1sQ2hhciAqKm5zQmluZGluZ3M7IC8qIE5hbWVzcGFjZSBiaW5kaW5ncyBvbiB0aGlzIGVsZW1lbnQgKi8KICAgIGludCBuYk5zQmluZGluZ3M7CiAgICBpbnQgc2l6ZU5zQmluZGluZ3M7ICAgIAoKICAgIGludCBoYXNLZXlyZWZzOwogICAgaW50IGFwcGxpZWRYUGF0aDsgLyogSW5kaWNhdGVzIHRoYXQgYW4gWFBhdGggaGFzIGJlZW4gYXBwbGllZC4gKi8KfTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOIDEKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkcgNAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRSA1CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfTk9fVFlQRSA2CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUUgNwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCA4CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRSA5CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9TVFJJQ1RfTk9fREVDTCAxMAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSEFTX0FUVFJfVVNFIDExCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9IQVNfQVRUUl9ERUNMIDEyCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVAgMTMKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1dJTERfTEFYX05PX0RFQ0wgMTQKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0RVUExJQ0FURV9JRCAxNQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfQU5EX1VTRV9JRCAxNgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSAxNwovKgoqIEBtZXRhVHlwZSB2YWx1ZXMgb2YgeG1sU2NoZW1hQXR0ckluZm8uCiovCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSAxCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMIDIKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DIDMKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DIDQKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TIDUKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRySW5mbyB4bWxTY2hlbWFBdHRySW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFBdHRySW5mbyAqeG1sU2NoZW1hQXR0ckluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXR0ckluZm8gewogICAgaW50IG5vZGVUeXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IG5vZGVMaW5lOyAgICAKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbDsgLyogdGhlIHByZS1jb21wdXRlZCB2YWx1ZSBpZiBhbnkgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZjsgLyogdGhlIGNvbXBsZXgvc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpZiBhbnkgKi8KICAgIGludCBmbGFnczsgLyogY29tYmluYXRpb24gb2Ygbm9kZSBpbmZvIGZsYWdzICovCgogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7IC8qIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2U7ICAvKiB0aGUgYXR0cmlidXRlIHVzZSAqLwogICAgaW50IHN0YXRlOwogICAgaW50IG1ldGFUeXBlOwogICAgY29uc3QgeG1sQ2hhciAqdmNWYWx1ZTsgLyogdGhlIHZhbHVlIGNvbnN0cmFpbnQgdmFsdWUgKi8KICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIHBhcmVudDsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFfVkFMSURfQ1RYVF9GTEFHX1NUUkVBTSAxCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHQ6CiAqCiAqIEEgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQKICovCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIGludCB0eXBlOwogICAgdm9pZCAqZXJyQ3R4dDsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CiAgICB4bWxDaGFyRW5jb2RpbmcgZW5jOwogICAgeG1sU0FYSGFuZGxlclB0ciBzYXg7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CiAgICB2b2lkICp1c2VyX2RhdGE7IC8qIFRPRE86IFdoYXQgaXMgdGhpcyBmb3I/ICovCgogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKCiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIC8qIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsgKi8KCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleHA7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsdWU7CgogICAgaW50IHZhbHVlV1M7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbE5vZGVQdHIgdmFsaWRhdGlvblJvb3Q7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgaW50IHhzaUFzc2VtYmxlOwoKICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyICplbGVtSW5mb3M7IC8qIGFycmF5IG9mIGVsZW1lbnQgaW5mb3JtYXRpb25zICovCiAgICBpbnQgc2l6ZUVsZW1JbmZvczsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlOyAvKiB0aGUgY3VycmVudCBlbGVtZW50IGluZm9ybWF0aW9uICovCgogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGNzOyAvKiBhIGxpc3Qgb2YgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbnMgKi8KCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlczsgLyogZmlyc3QgYWN0aXZlIHN0YXRlIG9iamVjdC4gKi8KICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHhwYXRoU3RhdGVQb29sOyAvKiBmaXJzdCBzdG9yZWQgc3RhdGUgb2JqZWN0LiAqLwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBpZGNNYXRjaGVyQ2FjaGU7IC8qIENhY2hlIGZvciBJREMgbWF0Y2hlciBvYmplY3RzLiAqLwoKICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICppZGNOb2RlczsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyovCiAgICBpbnQgbmJJZGNOb2RlczsKICAgIGludCBzaXplSWRjTm9kZXM7CgogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqaWRjS2V5czsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyAqLwogICAgaW50IG5iSWRjS2V5czsKICAgIGludCBzaXplSWRjS2V5czsKCiAgICBpbnQgZmxhZ3M7CgogICAgeG1sRGljdFB0ciBkaWN0OwoKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAogICAgeG1sVGV4dFJlYWRlclB0ciByZWFkZXI7CiNlbmRpZgoKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyICphdHRySW5mb3M7CiAgICBpbnQgbmJBdHRySW5mb3M7CiAgICBpbnQgc2l6ZUF0dHJJbmZvczsKCiAgICBpbnQgc2tpcERlcHRoOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbm9kZVFOYW1lczsKICAgIGludCBoYXNLZXlyZWZzOwogICAgaW50IGNyZWF0ZUlEQ05vZGVUYWJsZXM7CiAgICBpbnQgcHN2aUV4cG9zZUlEQ05vZGVUYWJsZXM7Cn07CgovKioKICogeG1sU2NoZW1hU3Vic3RHcm91cDoKICoKICoKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHhtbFNjaGVtYVN1YnN0R3JvdXA7CnR5cGVkZWYgeG1sU2NoZW1hU3Vic3RHcm91cCAqeG1sU2NoZW1hU3Vic3RHcm91cFB0cjsKc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIG1lbWJlcnM7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU29tZSBwcmVkZWNsYXJhdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hUGFyc2VSZWRlZmluZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBjdHh0KTsKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKTsKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCk7CnN0YXRpYyB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlCnhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCQkgaW50IHdpdGhQYXJ0aWNsZSk7CnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Q29tcG9uZW50VHlwZVN0cih4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlTGlua1B0cgp4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJbnRlcm5hbEVycih4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICAgICBjb25zdCBjaGFyICpmdW5jTmFtZSwKCQkgICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UpOwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCSAgICAgaW50IHN1YnNldCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBvbmVudExpc3RGcmVlKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpOwpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cFJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCXhtbE5vZGVQdHIgbm9kZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlIZWxwZXIgZnVuY3Rpb25zCQkJICAgICAgICAqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUl0ZW1UeXBlVG9TdHI6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hSXRlbVR5cGVUb1N0cih4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJICAgIHJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIHJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybihCQURfQ0FTVCAiZWxlbWVudCBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFX1VTRToKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSB1c2UiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCSAgICByZXR1cm4oQkFEX0NBU1QgIm5vdGF0aW9uIGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChzZXF1ZW5jZSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChjaG9pY2UpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCAoYWxsKSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJwYXJ0aWNsZSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRToKCSAgICByZXR1cm4oQkFEX0NBU1QgInVuaXF1ZSBpZGVudGl0eS1jb25zdHJhaW50Iik7CgkgICAgLyogcmV0dXJuKEJBRF9DQVNUICJJREMgKHVuaXF1ZSkiKTsgKi8KCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJrZXkgaWRlbnRpdHktY29uc3RyYWludCIpOwoJICAgIC8qIHJldHVybihCQURfQ0FTVCAiSURDIChrZXkpIik7ICovCgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJICAgIHJldHVybihCQURfQ0FTVCAia2V5cmVmIGlkZW50aXR5LWNvbnN0cmFpbnQiKTsKCSAgICAvKiByZXR1cm4oQkFEX0NBU1QgIklEQyAoa2V5cmVmKSIpOyAqLwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJICAgIHJldHVybihCQURfQ0FTVCAid2lsZGNhcmQgKGFueSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjoKCSAgICByZXR1cm4oQkFEX0NBU1QgIltoZWxwZXIgY29tcG9uZW50XSBRTmFtZSByZWZlcmVuY2UiKTsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUI6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJbaGVscGVyIGNvbXBvbmVudF0gYXR0cmlidXRlIHVzZSBwcm9oaWJpdGlvbiIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENvbXBvbmVudFR5cGVTdHI6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Q29tcG9uZW50VHlwZVN0cih4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSkKewogICAgc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKCSAgICBpZiAoV1hTX0lTX0NPTVBMRVgoV1hTX1RZUEVfQ0FTVCBpdGVtKSkKCQlyZXR1cm4oQkFEX0NBU1QgImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgkgICAgZWxzZQoJCXJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwkKCWRlZmF1bHQ6CgkgICAgcmV0dXJuKHhtbFNjaGVtYUl0ZW1UeXBlVG9TdHIoaXRlbS0+dHlwZSkpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hR2V0Q29tcG9uZW50Tm9kZToKICogQGl0ZW06IGEgc2NoZW1hIGNvbXBvbmVudAogKgogKiBSZXR1cm5zIG5vZGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzY2hlbWEgY29tcG9uZW50LgogKiBOT1RFIHRoYXQgc3VjaCBhIG5vZGUgbmVlZCBub3QgYmUgYXZhaWxhYmxlOyBwbHVzLCBhIGNvbXBvbmVudCdzCiAqIG5vZGUgbmVlZCBub3QgdG8gcmVmbGVjdCB0aGUgY29tcG9uZW50IGRpcmVjdGx5LCBzaW5jZSB0aGVyZSBpcyBubwogKiBvbmUtdG8tb25lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBYTUwgU2NoZW1hIHJlcHJlc2VudGF0aW9uIGFuZAogKiB0aGUgY29tcG9uZW50IHJlcHJlc2VudGF0aW9uLgogKi8Kc3RhdGljIHhtbE5vZGVQdHIKeG1sU2NoZW1hR2V0Q29tcG9uZW50Tm9kZSh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSkKewogICAgc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSktPm5vZGUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSktPm5vZGUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgaXRlbSktPm5vZGUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY6CgkgICAgcmV0dXJuKCgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0pLT5ub2RlKTsKCS8qIFRPRE86IFdoYXQgdG8gZG8gd2l0aCBOT1RBVElPTnM/CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hTm90YXRpb25QdHIpIGl0ZW0pLT5ub2RlKTsKCSovCgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIpIGl0ZW0pLT5ub2RlKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKI2lmIDAKLyoqCiAqIHhtbFNjaGVtYUdldE5leHRDb21wb25lbnQ6CiAqIEBpdGVtOiBhIHNjaGVtYSBjb21wb25lbnQKICoKICogUmV0dXJucyB0aGUgbmV4dCBzaWJsaW5nIG9mIHRoZSBzY2hlbWEgY29tcG9uZW50LgogKi8Kc3RhdGljIHhtbFNjaGVtYUJhc2ljSXRlbVB0cgp4bWxTY2hlbWFHZXROZXh0Q29tcG9uZW50KHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5uZXh0KTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpICgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtKS0+bmV4dCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIHJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKS0+bmV4dCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgoJICAgIHJldHVybiAoTlVMTCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpICgoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0pLT5uZXh0KTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJICAgIHJldHVybiAoTlVMTCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4gKE5VTEwpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSAoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtKS0+bmV4dCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUY6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSAoKHhtbFNjaGVtYUlEQ1B0cikgaXRlbSktPm5leHQpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gKE5VTEwpOwogICAgfQp9CiNlbmRpZgoKCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRRTmFtZToKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQG5hbWVzcGFjZU5hbWU6ICB0aGUgbmFtZXNwYWNlIG5hbWUKICogQGxvY2FsTmFtZTogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyB0aGUgZ2l2ZW4gUU5hbWUgaW4gdGhlIGZvcm1hdCAie25hbWVzcGFjZU5hbWV9bG9jYWxOYW1lIiBvcgogKiBqdXN0ICJsb2NhbE5hbWUiIGlmIEBuYW1lc3BhY2VOYW1lIGlzIE5VTEwuCiAqCiAqIFJldHVybnMgdGhlIGxvY2FsTmFtZSBpZiBAbmFtZXNwYWNlTmFtZSBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIqCnhtbFNjaGVtYUZvcm1hdFFOYW1lKHhtbENoYXIgKipidWYsCgkJICAgICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2VOYW1lLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lKQp7CiAgICBGUkVFX0FORF9OVUxMKCpidWYpCiAgICBpZiAobmFtZXNwYWNlTmFtZSAhPSBOVUxMKSB7CgkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Iik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIG5hbWVzcGFjZU5hbWUpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAifSIpOwogICAgfQogICAgaWYgKGxvY2FsTmFtZSAhPSBOVUxMKSB7CglpZiAobmFtZXNwYWNlTmFtZSA9PSBOVUxMKQoJICAgIHJldHVybihsb2NhbE5hbWUpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsb2NhbE5hbWUpOwogICAgfSBlbHNlIHsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIihOVUxMKSIpOwogICAgfSAgICAKICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXRRTmFtZU5zKHhtbENoYXIgKipidWYsIHhtbE5zUHRyIG5zLCBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWUpCnsKICAgIGlmIChucyAhPSBOVUxMKQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShidWYsIG5zLT5ocmVmLCBsb2NhbE5hbWUpKTsKICAgIGVsc2UKCXJldHVybiAoeG1sU2NoZW1hRm9ybWF0UU5hbWUoYnVmLCBOVUxMLCBsb2NhbE5hbWUpKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRDb21wb25lbnROYW1lKHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5uYW1lKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtKS0+bmFtZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0pLT5uYW1lKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSktPm5hbWUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGl0ZW0pLT5uYW1lKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+bmFtZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOgoJICAgIGlmIChXWFNfQVRUUlVTRV9ERUNMKGl0ZW0pICE9IE5VTEwpIHsKCQlyZXR1cm4oeG1sU2NoZW1hR2V0Q29tcG9uZW50TmFtZSgKCQkgICAgV1hTX0JBU0lDX0NBU1QgV1hTX0FUVFJVU0VfREVDTChpdGVtKSkpOwoJICAgIH0gZWxzZQoJCXJldHVybihOVUxMKTsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0pLT5uYW1lKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFOb3RhdGlvblB0cikgaXRlbSktPm5hbWUpOwoJZGVmYXVsdDoKCSAgICAvKgoJICAgICogT3RoZXIgY29tcG9uZW50cyBjYW5ub3QgaGF2ZSBuYW1lcy4KCSAgICAqLwoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKI2RlZmluZSB4bWxTY2hlbWFHZXRRTmFtZVJlZk5hbWUocikgKFdYU19RTkFNRV9DQVNUIChyKSktPm5hbWUKI2RlZmluZSB4bWxTY2hlbWFHZXRRTmFtZVJlZlRhcmdldE5zKHIpIChXWFNfUU5BTUVfQ0FTVCAocikpLT50YXJnZXROYW1lc3BhY2UKLyoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRRTmFtZVJlZk5hbWUodm9pZCAqcmVmKQp7CiAgICByZXR1cm4oKCh4bWxTY2hlbWFRTmFtZVJlZlB0cikgcmVmKS0+bmFtZSk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0UU5hbWVSZWZUYXJnZXROcyh2b2lkICpyZWYpCnsKICAgIHJldHVybigoKHhtbFNjaGVtYVFOYW1lUmVmUHRyKSByZWYpLT50YXJnZXROYW1lc3BhY2UpOwp9CiovCgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldENvbXBvbmVudFRhcmdldE5zKHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtKS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJICAgIHJldHVybiAoQkFEX0NBU1QgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSBpdGVtKS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURV9VU0U6CgkgICAgaWYgKFdYU19BVFRSVVNFX0RFQ0woaXRlbSkgIT0gTlVMTCkgewoJCXJldHVybih4bWxTY2hlbWFHZXRDb21wb25lbnRUYXJnZXROcygKCQkgICAgV1hTX0JBU0lDX0NBU1QgV1hTX0FUVFJVU0VfREVDTChpdGVtKSkpOwoJICAgIH0KCSAgICAvKiBUT0RPOiBXaWxsIHJldHVybmluZyBOVUxMIGJyZWFrIHNvbWV0aGluZz8gKi8KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSBpdGVtKS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWRlZmF1bHQ6CgkgICAgLyoKCSAgICAqIE90aGVyIGNvbXBvbmVudHMgY2Fubm90IGhhdmUgbmFtZXMuCgkgICAgKi8KCSAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyKgp4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSh4bWxDaGFyICoqYnVmLAoJCQkgICB2b2lkICppdGVtKQp7CiAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKGJ1ZiwKCXhtbFNjaGVtYUdldENvbXBvbmVudFRhcmdldE5zKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGl0ZW0pLAoJeG1sU2NoZW1hR2V0Q29tcG9uZW50TmFtZSgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBpdGVtKSkpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhcioKeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oeG1sQ2hhciAqKmJ1Ziwgdm9pZCAqaXRlbSkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIFdYU19JVEVNX1RZUEVfTkFNRShpdGVtKSk7CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwogICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLAoJKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgaXRlbSkpOwogICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpOwogICAgcmV0dXJuKCpidWYpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhcioKeG1sU2NoZW1hR2V0SURDRGVzaWduYXRpb24oeG1sQ2hhciAqKmJ1ZiwgeG1sU2NoZW1hSURDUHRyIGlkYykKewogICAgcmV0dXJuKHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKGJ1ZiwgaWRjKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmc6CiAqIEBwYzogdGhlIHR5cGUgb2YgcHJvY2Vzc0NvbnRlbnRzCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUgb2YKICogcHJvY2Vzc0NvbnRlbnRzLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmcoaW50IHBjKQp7CiAgICBzd2l0Y2ggKHBjKSB7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9TS0lQOgoJICAgIHJldHVybiAoQkFEX0NBU1QgInNraXAiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX0xBWDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJsYXgiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJzdHJpY3QiKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAiaW52YWxpZCBwcm9jZXNzIGNvbnRlbnRzIik7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDYW5vblZhbHVlV2h0c3BFeHQ6CiAqIEB2YWw6IHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKiBAcmV0VmFsdWU6IHRoZSByZXR1cm5lZCB2YWx1ZQogKiBAd3M6IHRoZSB3aGl0ZXNwYWNlIHR5cGUgb2YgdGhlIHZhbHVlCiAqCiAqIEdldCBhIHRoZSBjb25vbmljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlLgogKiBUaGUgY2FsbGVyIGhhcyB0byBmcmVlIHRoZSByZXR1cm5lZCByZXRWYWx1ZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBjb3VsZCBiZSBidWlsdCBhbmQgLTEgaW4gY2FzZSBvZgogKiAgICAgICAgIEFQSSBlcnJvcnMgb3IgaWYgdGhlIHZhbHVlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldENhbm9uVmFsdWVXaHRzcEV4dCh4bWxTY2hlbWFWYWxQdHIgdmFsLAoJCQkgICAgICAgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3cywKCQkJICAgICAgIHhtbENoYXIgKipyZXRWYWx1ZSkKewogICAgaW50IGxpc3Q7CiAgICB4bWxTY2hlbWFWYWxUeXBlIHZhbFR5cGU7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwgKnZhbHVlMiA9IE5VTEw7CiAgICAKCiAgICBpZiAoKHJldFZhbHVlID09IE5VTEwpIHx8ICh2YWwgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIGxpc3QgPSB4bWxTY2hlbWFWYWx1ZUdldE5leHQodmFsKSA/IDEgOiAwOwogICAgKnJldFZhbHVlID0gTlVMTDsKICAgIGRvIHsKCXZhbHVlID0gTlVMTDsJCgl2YWxUeXBlID0geG1sU2NoZW1hR2V0VmFsVHlwZSh2YWwpOyAgICAKCXN3aXRjaCAodmFsVHlwZSkgewkgICAgCgkgICAgY2FzZSBYTUxfU0NIRU1BU19TVFJJTkc6CgkgICAgY2FzZSBYTUxfU0NIRU1BU19OT1JNU1RSSU5HOgoJICAgIGNhc2UgWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRToKCQl2YWx1ZSA9IHhtbFNjaGVtYVZhbHVlR2V0QXNTdHJpbmcodmFsKTsKCQlpZiAodmFsdWUgIT0gTlVMTCkgewoJCSAgICBpZiAod3MgPT0gWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKQoJCQl2YWx1ZTIgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkJICAgIGVsc2UgaWYgKHdzID09IFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFKQoJCQl2YWx1ZTIgPSB4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSk7CgkJICAgIGlmICh2YWx1ZTIgIT0gTlVMTCkKCQkJdmFsdWUgPSB2YWx1ZTI7CgkJfQoJCWJyZWFrOwkgICAKCSAgICBkZWZhdWx0OgoJCWlmICh4bWxTY2hlbWFHZXRDYW5vblZhbHVlKHZhbCwgJnZhbHVlMikgPT0gLTEpIHsKCQkgICAgaWYgKHZhbHVlMiAhPSBOVUxMKQoJCQl4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlMik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXZhbHVlID0gdmFsdWUyOwoJfQoJaWYgKCpyZXRWYWx1ZSA9PSBOVUxMKQoJICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CgkJaWYgKCEgbGlzdCkKCQkgICAgKnJldFZhbHVlID0geG1sU3RyZHVwKEJBRF9DQVNUICIiKTsKCSAgICB9IGVsc2UKCQkqcmV0VmFsdWUgPSB4bWxTdHJkdXAodmFsdWUpOwoJZWxzZSBpZiAodmFsdWUgIT0gTlVMTCkgewoJICAgIC8qIExpc3QuICovCgkgICAgKnJldFZhbHVlID0geG1sU3RyY2F0KCh4bWxDaGFyICopICpyZXRWYWx1ZSwgQkFEX0NBU1QgIiAiKTsKCSAgICAqcmV0VmFsdWUgPSB4bWxTdHJjYXQoKHhtbENoYXIgKikgKnJldFZhbHVlLCB2YWx1ZSk7Cgl9CglGUkVFX0FORF9OVUxMKHZhbHVlMikKCXZhbCA9IHhtbFNjaGVtYVZhbHVlR2V0TmV4dCh2YWwpOwogICAgfSB3aGlsZSAodmFsICE9IE5VTEwpOwoKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKCpyZXRWYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZSgoeG1sQ2hhciAqKSAoKnJldFZhbHVlKSk7CiAgICBpZiAodmFsdWUyICE9IE5VTEwpCgl4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlMik7CiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQ6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGl0ZW0KICogQGl0ZW1OYW1lOiB0aGUgbmFtZSBvZiB0aGUgaXRlbQogKiBAaXRlbTogdGhlIGl0ZW0gYXMgYW4gb2JqZWN0IAogKiBAaXRlbU5vZGU6IHRoZSBub2RlIG9mIHRoZSBpdGVtCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICogQHBhcnNpbmc6IGlmIHRoZSBmdW5jdGlvbiBpcyB1c2VkIGR1cmluZyB0aGUgcGFyc2UKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBpdGVtIHVzZWQKICogZm9yIGVycm9yIHJlcG9ydHMuIAogKgogKiBUaGUgZm9sbG93aW5nIG9yZGVyIGlzIHVzZWQgdG8gYnVpbGQgdGhlIHJlc3VsdGluZyAKICogZGVzaWduYXRpb24gaWYgdGhlIGFyZ3VtZW50cyBhcmUgbm90IE5VTEw6CiAqIDFhLiBJZiBpdGVtRGVzIG5vdCBOVUxMIC0+IGl0ZW1EZXMKICogMWIuIElmIChpdGVtRGVzIG5vdCBOVUxMKSBhbmQgKGl0ZW1OYW1lIG5vdCBOVUxMKQogKiAgICAgLT4gaXRlbURlcyArIGl0ZW1OYW1lCiAqIDIuIElmIHRoZSBwcmVjZWRpbmcgd2FzIE5VTEwgYW5kIChpdGVtIG5vdCBOVUxMKSAtPiBpdGVtCiAqIDMuIElmIHRoZSBwcmVjZWRpbmcgd2FzIE5VTEwgYW5kIChpdGVtTm9kZSBub3QgTlVMTCkgLT4gaXRlbU5vZGUKICogCiAqIElmIHRoZSBpdGVtTm9kZSBpcyBhbiBhdHRyaWJ1dGUgbm9kZSwgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSByZXN1bHQuCiAqCiAqIFJldHVybnMgdGhlIGZvcm1hdHRlZCBzdHJpbmcgYW5kIHNldHMgQGJ1ZiB0byB0aGUgcmVzdWx0aW5nIHZhbHVlLgogKi8gIApzdGF0aWMgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCh4bWxDaGFyICoqYnVmLAkJICAgICAKCQkgICAgIGNvbnN0IHhtbENoYXIgKml0ZW1EZXMsCgkJICAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkgICAgIHhtbE5vZGVQdHIgaXRlbU5vZGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgbmFtZWQgPSAxOwoKICAgIGlmICgqYnVmICE9IE5VTEwpIHsKCXhtbEZyZWUoKmJ1Zik7CgkqYnVmID0gTlVMTDsKICAgIH0KICAgICAgICAgICAgCiAgICBpZiAoaXRlbURlcyAhPSBOVUxMKSB7CgkqYnVmID0geG1sU3RyZHVwKGl0ZW1EZXMpOwkKICAgIH0gZWxzZSBpZiAoaXRlbSAhPSBOVUxMKSB7Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOiB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlID0gV1hTX1RZUEVfQ0FTVCBpdGVtOwoKCSAgICBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJhdG9taWMgdHlwZSAneHM6Iik7CgkgICAgZWxzZSBpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAibGlzdCB0eXBlICd4czoiKTsKCSAgICBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAidW5pb24gdHlwZSAneHM6Iik7CgkgICAgZWxzZQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInNpbXBsZSB0eXBlICd4czoiKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHR5cGUtPm5hbWUpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6IHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSBXWFNfVFlQRV9DQVNUIGl0ZW07CgoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCIiKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImxvY2FsICIpOwoJICAgIH0KCSAgICBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJhdG9taWMgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGUpKQoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgImxpc3QgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFdYU19JU19VTklPTih0eXBlKSkKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJ1bmlvbiB0eXBlIik7CgkgICAgZWxzZQoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgInNpbXBsZSB0eXBlIik7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgdHlwZS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOiB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlID0gV1hTX1RZUEVfQ0FTVCBpdGVtOwoKCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICIiKTsKCSAgICBlbHNlCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAibG9jYWwgIik7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiY29tcGxleCB0eXBlIik7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgdHlwZS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOiB7CgkJeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIGF1c2U7CgkgICAgCgkJYXVzZSA9IFdYU19BVFRSX1VTRV9DQVNUIGl0ZW07CgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiYXR0cmlidXRlIHVzZSAiKTsKCQlpZiAoV1hTX0FUVFJVU0VfREVDTChhdXNlKSAhPSBOVUxMKSB7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBXWFNfQVRUUlVTRV9ERUNMKGF1c2UpKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkJfSBlbHNlIHsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiKHVua25vd24pIik7CgkJfQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTogewoJCXhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyOwoJICAgIAoJCWF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtOwoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImF0dHJpYnV0ZSBkZWNsLiIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBhdHRyLT50YXJnZXROYW1lc3BhY2UsIGF0dHItPm5hbWUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKGJ1ZiwgaXRlbSk7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOiB7CgkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtOwoKCQllbGVtID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW07CSAgICAKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJlbGVtZW50IGRlY2wuIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGVsZW0tPnRhcmdldE5hbWVzcGFjZSwgZWxlbS0+bmFtZSkpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUY6CQkKCSAgICBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJ1bmlxdWUgJyIpOwoJICAgIGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAia2V5ICciKTsKCSAgICBlbHNlCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAia2V5UmVmICciKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsICgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+bmFtZSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYVdpbGRjYXJkUENUb1N0cmluZygKCQkgICAgKCh4bWxTY2hlbWFXaWxkY2FyZFB0cikgaXRlbSktPnByb2Nlc3NDb250ZW50cykpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiB3aWxkY2FyZCIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiZmFjZXQgJyIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoaXRlbS0+dHlwZSkpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOiB7CgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAibW9kZWwgZ3JvdXAgZGVmLiIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBpdGVtKSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkgICAgKmJ1ZiA9IHhtbFN0cmR1cChXWFNfSVRFTV9UWVBFX05BTUUoaXRlbSkpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046IHsKCQkqYnVmID0geG1sU3RyZHVwKFdYU19JVEVNX1RZUEVfTkFNRShpdGVtKSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW0pKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgIH0KCWRlZmF1bHQ6CgkgICAgbmFtZWQgPSAwOwoJfQogICAgfSBlbHNlIAoJbmFtZWQgPSAwOwoKICAgIGlmICgobmFtZWQgPT0gMCkgJiYgKGl0ZW1Ob2RlICE9IE5VTEwpKSB7Cgl4bWxOb2RlUHRyIGVsZW07CgoJaWYgKGl0ZW1Ob2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCSAgICBlbGVtID0gaXRlbU5vZGUtPnBhcmVudDsKCWVsc2UgCgkgICAgZWxlbSA9IGl0ZW1Ob2RlOwoJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7CglpZiAoZWxlbS0+bnMgIT0gTlVMTCkgewoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBlbGVtLT5ucy0+aHJlZiwgZWxlbS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJfSBlbHNlCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5uYW1lKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQogICAgfQogICAgaWYgKChpdGVtTm9kZSAhPSBOVUxMKSAmJiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSkgewoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiLCBhdHRyaWJ1dGUgJyIpOwoJaWYgKGl0ZW1Ob2RlLT5ucyAhPSBOVUxMKSB7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCWl0ZW1Ob2RlLT5ucy0+aHJlZiwgaXRlbU5vZGUtPm5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCX0gZWxzZQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbU5vZGUtPm5hbWUpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChzdHIpCiAgICAKICAgIHJldHVybiAoKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQ6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEB0eXBlOiB0aGUgdHlwZSBob2xkaW5nIHRoZSBlbnVtZXJhdGlvbiBmYWNldHMKICoKICogQnVpbGRzIGEgc3RyaW5nIGNvbnNpc3Rpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKgogKiBSZXR1cm5zIGEgc3RyaW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgIHhtbENoYXIgKipidWYsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlIHdzOwogICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwogICAgaW50IHJlcywgZm91bmQgPSAwOwoKICAgIGlmICgqYnVmICE9IE5VTEwpCgl4bWxGcmVlKCpidWYpOyAgICAKICAgICpidWYgPSBOVUxMOwoKICAgIGRvIHsKCS8qCgkqIFVzZSB0aGUgd2hpdGVzcGFjZSB0eXBlIG9mIHRoZSBiYXNlIHR5cGUuCgkqLwkKCXdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZS0+YmFzZVR5cGUpOwoJZm9yIChmYWNldCA9IHR5cGUtPmZhY2V0czsgZmFjZXQgIT0gTlVMTDsgZmFjZXQgPSBmYWNldC0+bmV4dCkgewoJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKQoJCWNvbnRpbnVlOwoJICAgIGZvdW5kID0gMTsKCSAgICByZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlV2h0c3BFeHQoZmFjZXQtPnZhbCwKCQl3cywgJnZhbHVlKTsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hSW50ZXJuYWxFcnIoYWN0eHQsCgkJICAgICJ4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQiLAoJCSAgICAiY29tcHV0ZSB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24iKTsKCQlpZiAoKmJ1ZiAhPSBOVUxMKQoJCSAgICB4bWxGcmVlKCpidWYpOwoJCSpidWYgPSBOVUxMOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIGlmICgqYnVmID09IE5VTEwpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsICciKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUIHZhbHVlKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCQl4bWxGcmVlKCh4bWxDaGFyICopdmFsdWUpOwoJCXZhbHVlID0gTlVMTDsKCSAgICB9Cgl9CgkvKgoJKiBUaGUgZW51bWVyYXRpb24gZmFjZXQgb2YgYSB0eXBlIHJlc3RyaWN0cyB0aGUgZW51bWVyYXRpb24KCSogZmFjZXQgb2YgdGhlIGFuY2VzdG9yIHR5cGU7IGkuZS4sIHN1Y2ggcmVzdHJpY3RlZCBlbnVtZXJhdGlvbnMKCSogZG8gbm90IGJlbG9uZyB0byB0aGUgc2V0IG9mIHRoZSBnaXZlbiB0eXBlLiBUaHVzIHdlIGJyZWFrCgkqIG9uIHRoZSBmaXJzdCBmb3VuZCBlbnVtZXJhdGlvbi4KCSovCglpZiAoZm91bmQpCgkgICAgYnJlYWs7Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9IHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKTsKCiAgICByZXR1cm4gKChjb25zdCB4bWxDaGFyICopICpidWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlFcnJvciBmdW5jdGlvbnMJCQkJICAgICAgICAqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyTWVtb3J5KGNvbnN0IGNoYXIgKm1zZykKewogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIG1zZyk7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQU2ltcGxlRXJyKGNvbnN0IGNoYXIgKm1zZykKewogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyck1lbW9yeSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+ZXJyQ3R4dDsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyMjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQG5vZGU6IHRoZSBjdXJyZW50IGNoaWxkCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycjIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIGlmIChjaGlsZCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwogICAgZWxzZQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7Cn0KCgovKioKICogeG1sU2NoZW1hUEVyckV4dDoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQHN0ckRhdGExOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMjogZXh0cmEgZGF0YQogKiBAc3RyRGF0YTM6IGV4dHJhIGRhdGEKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMSwgY29uc3QgeG1sQ2hhciAqIHN0ckRhdGEyLCAKCQljb25zdCB4bWxDaGFyICogc3RyRGF0YTMsIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHIyLCBjb25zdCB4bWxDaGFyICogc3RyMywgY29uc3QgeG1sQ2hhciAqIHN0cjQsCgkJY29uc3QgeG1sQ2hhciAqIHN0cjUpCnsKCiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+ZXJyQ3R4dDsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMSwgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTIsIAoJCSAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMywgMCwgMCwgbXNnLCBzdHIxLCBzdHIyLCAKCQkgICAgc3RyMywgc3RyNCwgc3RyNSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCUFsbHJvdW5kIGVycm9yIGZ1bmN0aW9ucwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hVlR5cGVFcnJNZW1vcnk6CiAqIEBub2RlOiBhIGNvbnRleHQgbm9kZQogKiBAZXh0cmE6ICBleHRyYSBpbmZvcm1hdGlvbnMKICoKICogSGFuZGxlIGFuIG91dCBvZiBtZW1vcnkgY29uZGl0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyTWVtb3J5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGN0eHQtPmVyciA9IFhNTF9TQ0hFTUFWX0lOVEVSTkFMOwogICAgfQogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTViwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUFNpbXBsZUludGVybmFsRXJyKHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqc3RyKQp7CiAgICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIG5vZGUsCgkgbXNnLCAoY29uc3QgY2hhciAqKSBzdHIpOwp9CgojZGVmaW5lIFdYU19FUlJPUl9UWVBFX0VSUk9SIDEKI2RlZmluZSBXWFNfRVJST1JfVFlQRV9XQVJOSU5HIDIKLyoqCiAqIHhtbFNjaGVtYUVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVycjRMaW5lKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBjdHh0LAoJCSAgeG1sRXJyb3JMZXZlbCBlcnJvckxldmVsLAoJCSAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGludCBsaW5lLCBjb25zdCBjaGFyICptc2csCgkJICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7ICAgIAogICAgCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CglpZiAoY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SKSB7CgkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4dDsKCSAgICBjb25zdCBjaGFyICpmaWxlID0gTlVMTDsKCSAgICBpZiAoZXJyb3JMZXZlbCAhPSBYTUxfRVJSX1dBUk5JTkcpIHsKCQl2Y3R4dC0+bmJlcnJvcnMrKzsKCQl2Y3R4dC0+ZXJyID0gZXJyb3I7CgkJY2hhbm5lbCA9IHZjdHh0LT5lcnJvcjsJCQoJICAgIH0gZWxzZSB7CgkJY2hhbm5lbCA9IHZjdHh0LT53YXJuaW5nOwoJICAgIH0KCSAgICBzY2hhbm5lbCA9IHZjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHZjdHh0LT5lcnJDdHh0OwoKCSAgICAvKgoJICAgICogRXJyb3Igbm9kZS4gSWYgd2Ugc3BlY2lmeSBhIGxpbmUgbnVtYmVyLCB0aGVuCgkgICAgKiBkbyBub3QgY2hhbm5lbCBhbnkgbm9kZSB0byB0aGUgZXJyb3IgZnVuY3Rpb24uCgkgICAgKi8KCSAgICBpZiAobGluZSA9PSAwKSB7CgkJaWYgKChub2RlID09IE5VTEwpICYmCgkJICAgICh2Y3R4dC0+ZGVwdGggPj0gMCkgJiYKCQkgICAgKHZjdHh0LT5pbm9kZSAhPSBOVUxMKSkgewoJCSAgICBub2RlID0gdmN0eHQtPmlub2RlLT5ub2RlOwoJCX0KCQkvKgoJCSogR2V0IGZpbGVuYW1lIGFuZCBsaW5lIGlmIG5vIG5vZGUtdHJlZS4KCQkqLwoJCWlmICgobm9kZSA9PSBOVUxMKSAmJgoJCSAgICAodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkgJiYKCQkgICAgKHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dCAhPSBOVUxMKSkgewoJCSAgICBmaWxlID0gdmN0eHQtPnBhcnNlckN0eHQtPmlucHV0LT5maWxlbmFtZTsKCQkgICAgbGluZSA9IHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dC0+bGluZTsKCQl9CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogT3ZlcnJpZGUgdGhlIGdpdmVuIG5vZGUncyAoaWYgYW55KSBwb3NpdGlvbgoJCSogYW5kIGNoYW5uZWwgb25seSB0aGUgZ2l2ZW4gbGluZSBudW1iZXIuCgkJKi8KCQlub2RlID0gTlVMTDsKCQkvKgoJCSogR2V0IGZpbGVuYW1lLgoJCSovCgkJaWYgKHZjdHh0LT5kb2MgIT0gTlVMTCkKCQkgICAgZmlsZSA9IChjb25zdCBjaGFyICopIHZjdHh0LT5kb2MtPlVSTDsKCQllbHNlIGlmICgodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkgJiYKCQkgICAgKHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dCAhPSBOVUxMKSkKCQkgICAgZmlsZSA9IHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dC0+ZmlsZW5hbWU7CgkgICAgfQkgICAgICAgCgkgICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LAoJCW5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAoJCWVycm9yLCBlcnJvckxldmVsLCBmaWxlLCBsaW5lLAoJCShjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsCgkJKGNvbnN0IGNoYXIgKikgc3RyMywgMCwgMCwgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKCgl9IGVsc2UgaWYgKGN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikgewoJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgY3R4dDsKCSAgICBpZiAoZXJyb3JMZXZlbCAhPSBYTUxfRVJSX1dBUk5JTkcpIHsKCQlwY3R4dC0+bmJlcnJvcnMrKzsKCQlwY3R4dC0+ZXJyID0gZXJyb3I7CgkJY2hhbm5lbCA9IHBjdHh0LT5lcnJvcjsJCQoJICAgIH0gZWxzZSB7CgkJY2hhbm5lbCA9IHBjdHh0LT53YXJuaW5nOwoJICAgIH0KCSAgICBzY2hhbm5lbCA9IHBjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHBjdHh0LT5lcnJDdHh0OwoJICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwKCQlub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwgZXJyb3IsCgkJZXJyb3JMZXZlbCwgTlVMTCwgMCwKCQkoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLAoJCShjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgc3RyMywgc3RyNCk7Cgl9IGVsc2UgewoJICAgIFRPRE8KCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVycjMoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LCAgCgkgICAgICBpbnQgZXJyb3IsIHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbXNnLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMiwgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfRVJST1IsIGVycm9yLCBub2RlLCAwLAoJbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBOVUxMKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyNCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsICAKCSAgICAgIGludCBlcnJvciwgeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICptc2csCgkgICAgICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfRVJST1IsIGVycm9yLCBub2RlLCAwLAoJbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCSAgICAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm1zZywKCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sU2NoZW1hRXJyNChhY3R4dCwgZXJyb3IsIG5vZGUsIG1zZywgc3RyMSwgc3RyMiwgTlVMTCwgTlVMTCk7Cn0KCnN0YXRpYyB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKHhtbENoYXIgKiogbXNnLAoJCQkgICAgeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgICptc2cgPSBOVUxMOwogICAgaWYgKChub2RlICE9IE5VTEwpICYmCgkobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSAmJgoJKG5vZGUtPnR5cGUgIT0gWE1MX0FUVFJJQlVURV9OT0RFKSkKICAgIHsKCS8qIAoJKiBEb24ndCB0cnkgdG8gZm9ybWF0IG90aGVyIG5vZGVzIHRoYW4gZWxlbWVudCBhbmQKCSogYXR0cmlidXRlIG5vZGVzLgoJKiBQbGF5IHNhdmUgYW5kIHJldHVybiBhbiBlbXB0eSBzdHJpbmcuCgkqLwoJKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiIik7CglyZXR1cm4oKm1zZyk7CiAgICB9CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CgkvKgoJKiBXb3JrIG9uIHRyZWUgbm9kZXMuCgkqLwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CgkgICAgeG1sTm9kZVB0ciBlbGVtID0gbm9kZS0+cGFyZW50OwoJICAgIAoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJICAgIGlmIChlbGVtLT5ucyAhPSBOVUxMKQoJCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgZWxlbS0+bnMtPmhyZWYsIGVsZW0tPm5hbWUpKTsKCSAgICBlbHNlCgkJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBOVUxMLCBlbGVtLT5uYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIicsICIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgImF0dHJpYnV0ZSAnIik7CSAgICAKCX0gZWxzZSB7CgkgICAgKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7Cgl9CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgTlVMTCwgbm9kZS0+bmFtZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJzogIik7CiAgICB9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsKCXhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0OwoJLyoKCSogV29yayBvbiBub2RlIGluZm9zLgoJKi8JCglpZiAodmN0eHQtPmlub2RlLT5ub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbSA9CgkJdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwoKCSAgICAqbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJaWVsZW0tPm5zTmFtZSwgaWVsZW0tPmxvY2FsTmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICInLCAiKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICJhdHRyaWJ1dGUgJyIpOwkgICAgCgl9IGVsc2UgewoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJfQoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJICAgIHZjdHh0LT5pbm9kZS0+bnNOYW1lLCB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJzogIik7CiAgICB9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsKCS8qIAoJKiBIbW0sIG5vIG5vZGUgd2hpbGUgcGFyc2luZz8KCSogUmV0dXJuIGFuIGVtcHR5IHN0cmluZywgaW4gY2FzZSBOVUxMIHdpbGwgYnJlYWsgc29tZXRoaW5nLgoJKi8KCSptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiIpOwogICAgfSBlbHNlIHsKCVRPRE8KCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBWQUwgVE9ETzogVGhlIG91dHB1dCBvZiB0aGUgZ2l2ZW4gc2NoZW1hIGNvbXBvbmVudCBpcyBjdXJyZW50bHkKICAgICogZGlzYWJsZWQuCiAgICAqLwojaWYgMAogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpKSB7CgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICIgWyIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICJdIik7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuICgqbXNnKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hSW50ZXJuYWxFcnIyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgICBjb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMOwoKICAgIGlmIChhY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiSW50ZXJuYWwgZXJyb3I6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgZnVuY05hbWUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiwgIik7ICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CgogICAgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpCgl4bWxTY2hlbWFFcnIoYWN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBOVUxMLAoJICAgIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMik7CgogICAgZWxzZSBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikJCgl4bWxTY2hlbWFFcnIoYWN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBOVUxMLAoJICAgIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMik7CgogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUludGVybmFsRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sU2NoZW1hSW50ZXJuYWxFcnIyKGFjdHh0LCBmdW5jTmFtZSwgbWVzc2FnZSwgTlVMTCwgTlVMTCk7Cn0KCiNpZiAwCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbnRlcm5hbEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgY29uc3QgY2hhciAqZnVuY05hbWUsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbFNjaGVtYUludGVybmFsRXJyMihBQ1RYVF9DQVNUIHBjdHh0LCBmdW5jTmFtZSwgbWVzc2FnZSwKCXN0cjEsIHN0cjIpOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ3VzdG9tRXJyNCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgJiYgKGl0ZW0gIT0gTlVMTCkgJiYKCShhY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSKSkgewoJbm9kZSA9IFdYU19JVEVNX05PREUoaXRlbSk7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIGl0ZW0sIE5VTEwpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICB9IGVsc2UKCXhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCBhY3R4dCwgbm9kZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsgICAKICAgIHhtbFNjaGVtYUVycjQoYWN0eHQsIGVycm9yLCBub2RlLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDdXN0b21FcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbFNjaGVtYUN1c3RvbUVycjQoYWN0eHQsIGVycm9yLCBub2RlLCBpdGVtLAoJbWVzc2FnZSwgc3RyMSwgc3RyMiwgTlVMTCwgTlVMTCk7ICAgIAp9CgoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7IAogICAgCiAgICAvKiBVUkdFTlQgVE9ETzogU2V0IHRoZSBlcnJvciBjb2RlIHRvIHNvbWV0aGluZyBzYW5lLiAqLwogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfV0FSTklORywgZXJyb3IsIG5vZGUsIDAsCgkoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwoKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUtleXJlZkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGlkY05vZGUsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEwsICpxbmFtZSA9IE5VTEw7CiAgICAKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnJXMnOiAiKTsgICAgICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFFcnI0TGluZShBQ1RYVF9DQVNUIHZjdHh0LCBYTUxfRVJSX0VSUk9SLAoJZXJyb3IsIE5VTEwsIGlkY05vZGUtPm5vZGVMaW5lLCAoY29uc3QgY2hhciAqKSBtc2csCgl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmcW5hbWUsCgkgICAgdmN0eHQtPm5vZGVRTmFtZXMtPml0ZW1zW2lkY05vZGUtPm5vZGVRTmFtZUlEICsxXSwKCSAgICB2Y3R4dC0+bm9kZVFOYW1lcy0+aXRlbXNbaWRjTm9kZS0+bm9kZVFOYW1lSURdKSwgCglzdHIxLCBzdHIyLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwocW5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKQoJcmV0dXJuIChub2RlLT50eXBlKTsKICAgIGlmICgoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgJiYKCSgoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpLT5pbm9kZSAhPSBOVUxMKSkKCXJldHVybiAoICgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPmlub2RlLT5ub2RlVHlwZSk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJc0dsb2JhbEl0ZW0oeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgxKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIGlmICggKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJLyogTm90ZSB0aGF0IGF0dHJpYnV0ZSBncm91cHMgYXJlIGFsd2F5cyBnbG9iYWwuICovCglkZWZhdWx0OgoJICAgIHJldHVybigxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgaW50IGRpc3BsYXlWYWx1ZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwoKICAgIGlmIChkaXNwbGF5VmFsdWUgfHwgKHhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKGFjdHh0LCBub2RlKSA9PQoJICAgIFhNTF9BVFRSSUJVVEVfTk9ERSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyVzJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiAiKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGEgdmFsaWQgIgoJICAgICJ2YWx1ZSBvZiAiKTsKCiAgICBpZiAoISB4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSAiKTsKCiAgICBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJhdG9taWMgdHlwZSIpOwogICAgZWxzZSBpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAibGlzdCB0eXBlIik7CiAgICBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoKICAgIGlmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCWlmICh0eXBlLT5idWlsdEluVHlwZSAhPSAwKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInhzOiIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJfSBlbHNlIAoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLCB0eXBlLT5uYW1lKSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKGRpc3BsYXlWYWx1ZSB8fCAoeG1sU2NoZW1hRXZhbEVycm9yTm9kZVR5cGUoYWN0eHQsIG5vZGUpID09CgkgICAgWE1MX0FUVFJJQlVURV9OT0RFKSkKCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwogICAgZWxzZQoJeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKHhtbENoYXIgKiogc3RyLAoJCQkgICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBuaSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgTlVMTCwgbm9kZS0+bmFtZSkpOwogICAgfSBlbHNlIGlmIChuaSAhPSBOVUxMKQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShzdHIsIG5pLT5uc05hbWUsIG5pLT5sb2NhbE5hbWUpKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFBdHRySW5mb1B0ciBuaSwKCQkJeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCXhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKCZzdHIsICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgbmksIG5vZGUpLAoJTlVMTCk7ICAgICAgICAKICAgIEZSRUVfQU5EX05VTEwoc3RyKQogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWludCBuYnZhbCwKCQkJaW50IG5ibmVnLAoJCQl4bWxDaGFyICoqdmFsdWVzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbENoYXIgKmxvY2FsTmFtZSwgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGludCBpOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLiIpOwogICAgLyoKICAgICogTm90ZSB0aGF0IGlzIGRvZXMgbm90IG1ha2Ugc2Vuc2UgdG8gcmVwb3J0IHRoYXQgd2UgaGF2ZSBhCiAgICAqIHdpbGRjYXJkIGhlcmUsIHNpbmNlIHRoZSB3aWxkY2FyZCBtaWdodCBiZSB1bmZvbGRlZCBpbnRvCiAgICAqIG11bHRpcGxlIHRyYW5zaXRpb25zLgogICAgKi8KICAgIGlmIChuYnZhbCArIG5ibmVnID4gMCkgewoJaWYgKG5idmFsICsgbmJuZWcgPiAxKSB7CgkgICAgc3RyID0geG1sU3RyZHVwKEJBRF9DQVNUICIgRXhwZWN0ZWQgaXMgb25lIG9mICggIik7Cgl9IGVsc2UKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiBFeHBlY3RlZCBpcyAoICIpOwoJbnNOYW1lID0gTlVMTDsKICAgIAkgICAgCglmb3IgKGkgPSAwOyBpIDwgbmJ2YWwgKyBuYm5lZzsgaSsrKSB7CgkgICAgY3VyID0gdmFsdWVzW2ldOwoJICAgIGlmIChjdXIgPT0gTlVMTCkKCSAgICAgICAgY29udGludWU7CgkgICAgaWYgKChjdXJbMF0gPT0gJ24nKSAmJiAoY3VyWzFdID09ICdvJykgJiYgKGN1clsyXSA9PSAndCcpICYmCgkgICAgICAgIChjdXJbM10gPT0gJyAnKSkgewoJCWN1ciArPSA0OwoJCXN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUICIjI290aGVyIik7CgkgICAgfQoJICAgIC8qCgkgICAgKiBHZXQgdGhlIGxvY2FsIG5hbWUuCgkgICAgKi8KCSAgICBsb2NhbE5hbWUgPSBOVUxMOwoJICAgIAoJICAgIGVuZCA9IGN1cjsKCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQlsb2NhbE5hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIioiKTsKCQllbmQrKzsKCSAgICB9IGVsc2UgewoJCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoKmVuZCAhPSAnfCcpKQoJCSAgICBlbmQrKzsKCQlsb2NhbE5hbWUgPSB4bWxTdHJuY2F0KGxvY2FsTmFtZSwgQkFEX0NBU1QgY3VyLCBlbmQgLSBjdXIpOwoJICAgIH0JCQoJICAgIGlmICgqZW5kICE9IDApIHsJCSAgICAKCQllbmQrKzsKCQkvKgoJCSogU2tpcCAiKnwqIiBpZiB0aGV5IGNvbWUgd2l0aCBuZWdhdGVkIGV4cHJlc3Npb25zLCBzaW5jZQoJCSogdGhleSByZXByZXNlbnQgdGhlIHNhbWUgbmVnYXRlZCB3aWxkY2FyZC4KCQkqLwoJCWlmICgobmJuZWcgPT0gMCkgfHwgKCplbmQgIT0gJyonKSB8fCAoKmxvY2FsTmFtZSAhPSAnKicpKSB7CgkJICAgIC8qCgkJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCQkgICAgKi8KCQkgICAgY3VyID0gZW5kOwoJCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQkJbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Kn0iKTsKCQkgICAgfSBlbHNlIHsKCQkJd2hpbGUgKCplbmQgIT0gMCkKCQkJICAgIGVuZCsrOwoJCQkKCQkJaWYgKGkgPj0gbmJ2YWwpCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsjI290aGVyOiIpOwoJCQllbHNlCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsiKTsKCQkJCgkJCW5zTmFtZSA9IHhtbFN0cm5jYXQobnNOYW1lLCBCQURfQ0FTVCBjdXIsIGVuZCAtIGN1cik7CgkJCW5zTmFtZSA9IHhtbFN0cmNhdChuc05hbWUsIEJBRF9DQVNUICJ9Iik7CgkJICAgIH0KCQkgICAgc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgbnNOYW1lKTsKCQkgICAgRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJfSBlbHNlIHsKCQkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCSAgICBjb250aW51ZTsKCQl9CgkgICAgfQkgICAgICAgIAoJICAgIHN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUIGxvY2FsTmFtZSk7CgkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCQoJICAgIGlmIChpIDwgbmJ2YWwgKyBuYm5lZyAtMSkKCQlzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiLCAiKTsKCX0JCglzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiICkuXG4iKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIHN0cik7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0gZWxzZQogICAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZhY2V0RXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwKCQkgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSBmYWNldFR5cGU7CiAgICBpbnQgbm9kZVR5cGUgPSB4bWxTY2hlbWFFdmFsRXJyb3JOb2RlVHlwZShhY3R4dCwgbm9kZSk7CgogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIGlmIChlcnJvciA9PSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQpIHsKCWZhY2V0VHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CgkvKgoJKiBJZiBlbnVtZXJhdGlvbnMgYXJlIHZhbGlkYXRlZCwgb25lIG11c3Qgbm90IGV4cGVjdCB0aGUKCSogZmFjZXQgdG8gYmUgZ2l2ZW4uCgkqLwkKICAgIH0gZWxzZQkKCWZhY2V0VHlwZSA9IGZhY2V0LT50eXBlOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJmYWNldCAnIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldFR5cGUpKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInXSAiKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBhIGRlZmF1bHQgbWVzc2FnZS4KCSovCglpZiAoKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEgpKSB7CgoJICAgIGNoYXIgbGVuWzI1XSwgYWN0TGVuWzI1XTsKCgkgICAgLyogRklYTUUsIFRPRE86IFdoYXQgaXMgdGhlIG1heCBleHBlY3RlZCBzdHJpbmcgbGVuZ3RoIG9mIHRoZQoJICAgICogdGhpcyB2YWx1ZT8KCSAgICAqLwoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGhhcyBhIGxlbmd0aCBvZiAnJXMnOyAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgoJICAgIHNucHJpbnRmKGxlbiwgMjQsICIlbHUiLCB4bWxTY2hlbWFHZXRGYWNldFZhbHVlQXNVTG9uZyhmYWNldCkpOwoJICAgIHNucHJpbnRmKGFjdExlbiwgMjQsICIlbHUiLCBsZW5ndGgpOwoKCSAgICBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGRpZmZlcnMgZnJvbSB0aGUgYWxsb3dlZCBsZW5ndGggb2YgJyVzJy5cbiIpOyAgICAgCgkgICAgZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbWF4aW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyB1bmRlcnJ1bnMgdGhlIGFsbG93ZWQgbWluaW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIAoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJeG1sU2NoZW1hRXJyMyhhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgdmFsdWUsIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCSAgICBlbHNlIAoJCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4pOwoJCgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhbiBlbGVtZW50ICIKCQkib2YgdGhlIHNldCB7JXN9LlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgCgkJeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KGFjdHh0LCAmc3RyLCB0eXBlKSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFjY2VwdGVkICIKCQkiYnkgdGhlIHBhdHRlcm4gJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRSkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBsZXNzIHRoYW4gdGhlICIKCQkibWluaW11bSB2YWx1ZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIGdyZWF0ZXIgdGhhbiB0aGUgIgoJCSJtYXhpbXVtIHZhbHVlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBncmVhdGVyIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBsZXNzIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSAiCgkJImRpZ2l0cyB0aGFuIGFyZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSBmcmFjdGlvbmFsICIKCQkiZGlnaXRzIHRoYW4gYXJlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIqKSBtc2csIHZhbHVlLAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKG5vZGVUeXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewkJCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwkKCX0gZWxzZSB7CSAgICAKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7Cgl4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIpOwogICAgfSAgICAgICAgCiAgICBGUkVFX0FORF9OVUxMKHN0cikKICAgIHhtbEZyZWUobXNnKTsKfQoKI2RlZmluZSBWRVJST1IoZXJyLCB0eXBlLCBtc2cpIFwKICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LCBlcnIsIE5VTEwsIHR5cGUsIG1zZywgTlVMTCwgTlVMTCk7CgojZGVmaW5lIFZFUlJPUl9JTlQoZnVuYywgbXNnKSB4bWxTY2hlbWFJbnRlcm5hbEVycihBQ1RYVF9DQVNUIHZjdHh0LCBmdW5jLCBtc2cpOwoKI2RlZmluZSBQRVJST1JfSU5UKGZ1bmMsIG1zZykgeG1sU2NoZW1hSW50ZXJuYWxFcnIoQUNUWFRfQ0FTVCBwY3R4dCwgZnVuYywgbXNnKTsKI2RlZmluZSBQRVJST1JfSU5UMihmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKEFDVFhUX0NBU1QgY3R4dCwgZnVuYywgbXNnKTsKCiNkZWZpbmUgQUVSUk9SX0lOVChmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKGFjdHh0LCBmdW5jLCBtc2cpOwoKCi8qKgogKiB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lck5hbWU6IHRoZSBuYW1lIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5vZGU6IHRoZSBwYXJlbnQgZWxlbWVudCBub2RlIG9mIHRoZSBtaXNzaW5nIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwoKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsICIlczogJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLAoJICAgICIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nLlxuIiwKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgUU5hbWUKICogQHJlZk5hbWU6IHRoZSByZWZlcmVuY2VkIGxvY2FsIG5hbWUKICogQHJlZlVSSTogdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIFVSSQogKiBAbWVzc2FnZTogb3B0aW9uYWwgbWVzc2FnZQogKgogKiBVc2VkIHRvIHJlcG9ydCBRTmFtZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgZmFpbGVkIHRvIHJlc29sdmUKICogdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkgY29uc3QgY2hhciAqbmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZk5hbWUsCgkJCSBjb25zdCB4bWxDaGFyICpyZWZVUkksCgkJCSB4bWxTY2hlbWFUeXBlVHlwZSByZWZUeXBlLAoJCQkgY29uc3QgY2hhciAqcmVmVHlwZVN0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwogICAgaWYgKHJlZlR5cGVTdHIgPT0gTlVMTCkKCXJlZlR5cGVTdHIgPSAoY29uc3QgY2hhciAqKSB4bWxTY2hlbWFJdGVtVHlwZVRvU3RyKHJlZlR5cGUpOwoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBvd25lckVsZW0sIGVycm9yLAoJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIiVzLCBhdHRyaWJ1dGUgJyVzJzogVGhlIFFOYW1lIHZhbHVlICclcycgZG9lcyBub3QgcmVzb2x2ZSB0byBhKG4pICIKCSAgICAiJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUsCgkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ckEsIHJlZlVSSSwgcmVmTmFtZSksCgkgICAgQkFEX0NBU1QgcmVmVHlwZVN0ciwgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKGRlcykKICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlIGR1cmluZyB0aGUgcGFyc2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJeG1sQ2hhciAqKm93bmVyRGVzLAoJCQl4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQl4bWxBdHRyUHRyIGF0dHIsCgkJCWNvbnN0IGNoYXIgKm1zZykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBOVUxMLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsCgkgICAgQkFEX0NBU1QgZGVzLCAoY29uc3QgeG1sQ2hhciAqKSAiVW5rbm93biIsCgkgICAgKGNvbnN0IHhtbENoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsCgkgICAgQkFEX0NBU1QgZGVzLCBhdHRyLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgfQogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGF0dHJpYnV0ZSdzIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBhdHRyaWJ1dGUncyBvd25lciBpdGVtCiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlIGR1cmluZyB0aGUgcGFyc2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVyQ29tcCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgeG1sQXR0clB0ciBhdHRyKQp7CiAgICB4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmc3RyQSwgQUNUWFRfQ0FTVCBjdHh0LCBhdHRyLT5wYXJlbnQpOwogICAgeG1sU2NoZW1hRXJyNChBQ1RYVF9DQVNUIGN0eHQsIGVycm9yLCAoeG1sTm9kZVB0cikgYXR0ciwKCSIlc1RoZSBhdHRyaWJ1dGUgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsIEJBRF9DQVNUIHN0ckEsCgl4bWxTY2hlbWFGb3JtYXRRTmFtZU5zKCZzdHJCLCBhdHRyLT5ucywgYXR0ci0+bmFtZSksCglOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQSk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckIpOwp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIyOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjM6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICptc2cgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgaXRlbSwgaXRlbUVsZW0pOwogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlczogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIGlmICgoaXRlbUVsZW0gPT0gTlVMTCkgJiYgKGl0ZW0gIT0gTlVMTCkpCglpdGVtRWxlbSA9IFdYU19JVEVNX05PREUoaXRlbSk7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGl0ZW1FbGVtLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCShjb25zdCBjaGFyICopIG1zZywgQkFEX0NBU1QgZGVzLCBzdHIxLCBzdHIyLCBzdHIzLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsIGVycm9yLCBpdGVtLCBpdGVtRWxlbSwgbWVzc2FnZSwKCXN0cjEsIE5VTEwsIE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUEF0dHJVc2VFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIHR5cGUKICogQGl0ZW06IHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAYXR0cjogdGhlIGludmFsaWQgc2NoZW1hIGF0dHJpYnV0ZQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBhdHRyaWJ1dGUgdXNlIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEF0dHJVc2VFcnI0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJICAgIGNvbnN0IHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciBhdHRydXNlLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIzLGNvbnN0IHhtbENoYXIgKnN0cjQpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIG93bmVySXRlbSwgTlVMTCk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLCAiKTsgICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLAoJQkFEX0NBU1QgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLAoJV1hTX0JBU0lDX0NBU1QgYXR0cnVzZSwgTlVMTCkpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIHhtbFNjaGVtYUVycjQoQUNUWFRfQ0FTVCBjdHh0LCBlcnJvciwgbm9kZSwgCgkoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIsIHN0cjMsIHN0cjQpOwogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0VycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAdHlwZTogdGhlIHNjaGVtYSB0eXBlCiAqIEBiYXNlVHlwZTogdGhlIGJhc2UgdHlwZSBvZiB0eXBlCiAqIEBmYWNldDogdGhlIGlsbGVnYWwgZmFjZXQKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGZhY2V0IGZvciBhdG9taWMgc2ltcGxlIHR5cGVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0Vycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBXWFNfQkFTSUNfQ0FTVCB0eXBlLCB0eXBlLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgdHlwZS0+bm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXM6IFRoZSBmYWNldCAnJXMnIGlzIG5vdCBhbGxvd2VkIG9uIHR5cGVzIGRlcml2ZWQgZnJvbSB0aGUgIgoJInR5cGUgJXMuXG4iLAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJULCBOVUxMLCBXWFNfQkFTSUNfQ0FTVCBiYXNlVHlwZSwgTlVMTCksCglOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIDxsaXN0PiBhbmQgPHVuaW9uPi4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBXWFNfQkFTSUNfQ0FTVCB0eXBlLAoJdHlwZS0+bm9kZSk7CiAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIGVycm9yLAoJIiVzOiBUaGUgZmFjZXQgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsCglCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBlbGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50IG5vZGUKICogQGF0dHI6IHRoZSBiYWQgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJIHhtbEF0dHJQdHIgYXR0ciwKCQkJIGNvbnN0IGNoYXIgKm5hbWUxLAoJCQkgY29uc3QgY2hhciAqbmFtZTIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBXWFNfQkFTSUNfQ0FTVCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCk7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGF0dHJpYnV0ZXMgJyVzJyBhbmQgJyVzJyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLlxuIiwKCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZTEsIEJBRF9DQVNUIG5hbWUyLCBOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQHR5cGU6IHRoZSB0eXBlIHNwZWNpZmllcgogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3QgaWYgZXhpc3RlbnQgCiAqIEBub2RlOiB0aGUgdmFsaWRhdGVkIG5vZGUKICogQHZhbHVlOiB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqCiAqIFJlcG9ydHMgYSBzaW1wbGUgdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKiBUT0RPOiBTaG91bGQgdGhpcyByZXBvcnQgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgYXMgd2VsbD8KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSBBVFRSSUJVVEVfVU5VU0VELAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJY29uc3QgY2hhciAqZXhwZWN0ZWQsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQljb25zdCBjaGFyICptZXNzYWdlLAoJCQljb25zdCB4bWxDaGFyICpzdHIxLAoJCQljb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgQUNUWFRfQ0FTVCBjdHh0LCBub2RlKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBkZWZhdWx0IG1lc3NhZ2VzLgoJKi8JCglpZiAodHlwZSAhPSBOVUxMKSB7CgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInJXMnIGlzIG5vdCBhIHZhbGlkIHZhbHVlIG9mICIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCBhICIKCQkidmFsaWQgdmFsdWUgb2YgIik7CQoJICAgIGlmICghIHhtbFNjaGVtYUlzR2xvYmFsSXRlbSh0eXBlKSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlICIpOwoJICAgIAoJICAgIGlmIChXWFNfSVNfQVRPTUlDKHR5cGUpKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJhdG9taWMgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGUpKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJsaXN0IHR5cGUiKTsKCSAgICBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInVuaW9uIHR5cGUiKTsKCSAgICAKCSAgICBpZiAoeG1sU2NoZW1hSXNHbG9iYWxJdGVtKHR5cGUpKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCQlpZiAodHlwZS0+YnVpbHRJblR5cGUgIT0gMCkgewoJCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAieHM6Iik7CgkJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJCX0gZWxzZSAKCQkgICAgbXNnID0geG1sU3RyY2F0KG1zZywKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSwgdHlwZS0+bmFtZSkpOwoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInLiIpOwoJCUZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IHZhbGlkLiIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCAiCgkJInZhbGlkLiIpOwoJfQkKCWlmIChleHBlY3RlZCkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgRXhwZWN0ZWQgaXMgJyIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIGV4cGVjdGVkKTsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJy5cbiIpOwoJfSBlbHNlCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlxuIik7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgTlVMTCk7CgllbHNlCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBtZXNzYWdlKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKCXhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIChjb25zdCBjaGFyKikgbXNnLCBzdHIxLCBzdHIyLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIC8qIENsZWFudXAuICovICAgIAogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ29udGVudEVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb253ZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBpdGVtIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVyRWxlbTogdGhlIG5vZGUgb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAY2hpbGQ6IHRoZSBpbnZhbGlkIGNoaWxkIG5vZGUKICogQG1lc3NhZ2U6IHRoZSBvcHRpb25hbCBlcnJvciBtZXNzYWdlCiAqIEBjb250ZW50OiB0aGUgb3B0aW9uYWwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGNvcnJlY3QgY29udGVudAogKgogKiBSZXBvcnRzIGFuIGVycm9yIGNvbmNlcm5pbmcgdGhlIGNvbnRlbnQgb2YgYSBzY2hlbWEgZWxlbWVudC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDb250ZW50RXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkgICAgIHhtbE5vZGVQdHIgY2hpbGQsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgY2hhciAqY29udGVudCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtKTsKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCSAgICAiJXM6ICVzLlxuIiwKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZSB7CglpZiAoY29udGVudCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgb3duZXJFbGVtLCBjaGlsZCwgZXJyb3IsCgkJIiVzOiBUaGUgY29udGVudCBpcyBub3QgdmFsaWQuIEV4cGVjdGVkIGlzICVzLlxuIiwKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIGNvbnRlbnQpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIsCgkJQkFEX0NBU1QgZGVzLCBOVUxMKTsKCX0KICAgIH0KICAgIEZSRUVfQU5EX05VTEwoZGVzKQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU3RyZWFtYWJsZSBlcnJvciBmdW5jdGlvbnMgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJVmFsaWRhdGlvbiBoZWxwZXIgZnVuY3Rpb25zCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCUFsbG9jYXRpb24gZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYU5ld1NjaGVtYUZvclBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEFsbG9jYXRlIGEgbmV3IFNjaGVtYSBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hUHRyCnhtbFNjaGVtYU5ld1NjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWEpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgc2NoZW1hIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWEpKTsKICAgIHJldC0+ZGljdCA9IGN0eHQtPmRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKHJldC0+ZGljdCk7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RmFjZXQ6CiAqCiAqIEFsbG9jYXRlIGEgbmV3IEZhY2V0IHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnhtbFNjaGVtYUZhY2V0UHRyCnhtbFNjaGVtYU5ld0ZhY2V0KHZvaWQpCnsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hRmFjZXRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hRmFjZXQpKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdBbm5vdDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIG5vZGUKICoKICogQWxsb2NhdGUgYSBuZXcgYW5ub3RhdGlvbiBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQW5ub3RQdHIKeG1sU2NoZW1hTmV3QW5ub3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUFubm90UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hQW5ub3RQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQW5ub3QpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYW5ub3RhdGlvbiIsIG5vZGUpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQW5ub3QpKTsKICAgIHJldC0+Y29udGVudCA9IG5vZGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJdGVtTGlzdFB0cgp4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSh2b2lkKQp7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciByZXQ7CgogICAgcmV0ID0geG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJdGVtTGlzdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgYW4gaXRlbSBsaXN0IHN0cnVjdHVyZSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFJdGVtTGlzdCkpOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJdGVtTGlzdENsZWFyKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpCnsKICAgIGlmIChsaXN0LT5pdGVtcyAhPSBOVUxMKSB7Cgl4bWxGcmVlKGxpc3QtPml0ZW1zKTsKCWxpc3QtPml0ZW1zID0gTlVMTDsKICAgIH0KICAgIGxpc3QtPm5iSXRlbXMgPSAwOwogICAgbGlzdC0+c2l6ZUl0ZW1zID0gMDsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJdGVtTGlzdEFkZCh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LCB2b2lkICppdGVtKQp7CiAgICBpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIDIwICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIG5ldyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQoJbGlzdC0+c2l6ZUl0ZW1zID0gMjA7CiAgICB9IGVsc2UgaWYgKGxpc3QtPnNpemVJdGVtcyA8PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5zaXplSXRlbXMgKj0gMjsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MobGlzdC0+aXRlbXMsCgkgICAgbGlzdC0+c2l6ZUl0ZW1zICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJncm93aW5nIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIGxpc3QtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIGxpc3QtPml0ZW1zW2xpc3QtPm5iSXRlbXMrK10gPSBpdGVtOwogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUl0ZW1MaXN0QWRkU2l6ZSh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LAoJCQkgaW50IGluaXRpYWxTaXplLAoJCQkgdm9pZCAqaXRlbSkKewogICAgaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCWlmIChpbml0aWFsU2l6ZSA8PSAwKQoJICAgIGluaXRpYWxTaXplID0gMTsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbE1hbGxvYygKCSAgICBpbml0aWFsU2l6ZSAqIHNpemVvZih2b2lkICopKTsKCWlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBuZXcgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0KCWxpc3QtPnNpemVJdGVtcyA9IGluaXRpYWxTaXplOwogICAgfSBlbHNlIGlmIChsaXN0LT5zaXplSXRlbXMgPD0gbGlzdC0+bmJJdGVtcykgewoJbGlzdC0+c2l6ZUl0ZW1zICo9IDI7CglsaXN0LT5pdGVtcyA9ICh2b2lkICoqKSB4bWxSZWFsbG9jKGxpc3QtPml0ZW1zLAoJICAgIGxpc3QtPnNpemVJdGVtcyAqIHNpemVvZih2b2lkICopKTsKCWlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiZ3Jvd2luZyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICBsaXN0LT5zaXplSXRlbXMgPSAwOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9CiAgICBsaXN0LT5pdGVtc1tsaXN0LT5uYkl0ZW1zKytdID0gaXRlbTsKICAgIHJldHVybigwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJdGVtTGlzdEluc2VydCh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LCB2b2lkICppdGVtLCBpbnQgaWR4KQp7ICAgIAogICAgaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbE1hbGxvYygKCSAgICAyMCAqIHNpemVvZih2b2lkICopKTsKCWlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBuZXcgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0KCWxpc3QtPnNpemVJdGVtcyA9IDIwOwogICAgfSBlbHNlIGlmIChsaXN0LT5zaXplSXRlbXMgPD0gbGlzdC0+bmJJdGVtcykgewoJbGlzdC0+c2l6ZUl0ZW1zICo9IDI7CglsaXN0LT5pdGVtcyA9ICh2b2lkICoqKSB4bWxSZWFsbG9jKGxpc3QtPml0ZW1zLAoJICAgIGxpc3QtPnNpemVJdGVtcyAqIHNpemVvZih2b2lkICopKTsKCWlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiZ3Jvd2luZyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICBsaXN0LT5zaXplSXRlbXMgPSAwOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBKdXN0IGFwcGVuZCBpZiB0aGUgaW5kZXggaXMgZ3JlYXRlci9lcXVhbCB0aGFuIHRoZSBpdGVtIGNvdW50LgogICAgKi8KICAgIGlmIChpZHggPj0gbGlzdC0+bmJJdGVtcykgewoJbGlzdC0+aXRlbXNbbGlzdC0+bmJJdGVtcysrXSA9IGl0ZW07CiAgICB9IGVsc2UgewoJaW50IGk7Cglmb3IgKGkgPSBsaXN0LT5uYkl0ZW1zOyBpID4gaWR4OyBpLS0pCgkgICAgbGlzdC0+aXRlbXNbaV0gPSBsaXN0LT5pdGVtc1tpLTFdOwoJbGlzdC0+aXRlbXNbaWR4XSA9IGl0ZW07CglsaXN0LT5uYkl0ZW1zKys7CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCiNpZiAwIC8qIGVuYWJsZSBpZiBldmVyIG5lZWRlZCAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUl0ZW1MaXN0SW5zZXJ0U2l6ZSh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LAoJCQkgICAgaW50IGluaXRpYWxTaXplLAoJCQkgICAgdm9pZCAqaXRlbSwKCQkJICAgIGludCBpZHgpCnsgICAgCiAgICBpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJaWYgKGluaXRpYWxTaXplIDw9IDApCgkgICAgaW5pdGlhbFNpemUgPSAxOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIGluaXRpYWxTaXplICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIG5ldyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQoJbGlzdC0+c2l6ZUl0ZW1zID0gaW5pdGlhbFNpemU7CiAgICB9IGVsc2UgaWYgKGxpc3QtPnNpemVJdGVtcyA8PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5zaXplSXRlbXMgKj0gMjsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MobGlzdC0+aXRlbXMsCgkgICAgbGlzdC0+c2l6ZUl0ZW1zICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJncm93aW5nIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIGxpc3QtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIEp1c3QgYXBwZW5kIGlmIHRoZSBpbmRleCBpcyBncmVhdGVyL2VxdWFsIHRoYW4gdGhlIGl0ZW0gY291bnQuCiAgICAqLwogICAgaWYgKGlkeCA+PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5pdGVtc1tsaXN0LT5uYkl0ZW1zKytdID0gaXRlbTsKICAgIH0gZWxzZSB7CglpbnQgaTsKCWZvciAoaSA9IGxpc3QtPm5iSXRlbXM7IGkgPiBpZHg7IGktLSkKCSAgICBsaXN0LT5pdGVtc1tpXSA9IGxpc3QtPml0ZW1zW2ktMV07CglsaXN0LT5pdGVtc1tpZHhdID0gaXRlbTsKCWxpc3QtPm5iSXRlbXMrKzsKICAgIH0KICAgIHJldHVybigwKTsKfQojZW5kaWYKCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXRlbUxpc3RSZW1vdmUoeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCwgaW50IGlkeCkKewogICAgaW50IGk7CiAgICBpZiAoKGxpc3QtPml0ZW1zID09IE5VTEwpIHx8IChpZHggPj0gbGlzdC0+bmJJdGVtcykpIHsKCXhtbFNjaGVtYVBTaW1wbGVFcnIoIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZSwgIgoJICAgICJpbmRleCBlcnJvci5cbiIpOwoJcmV0dXJuKC0xKTsKICAgIH0KCiAgICBpZiAobGlzdC0+bmJJdGVtcyA9PSAxKSB7CgkvKiBUT0RPOiBSZWFsbHkgZnJlZSB0aGUgbGlzdD8gKi8KCXhtbEZyZWUobGlzdC0+aXRlbXMpOwoJbGlzdC0+aXRlbXMgPSBOVUxMOwoJbGlzdC0+bmJJdGVtcyA9IDA7CglsaXN0LT5zaXplSXRlbXMgPSAwOwogICAgfSBlbHNlIGlmIChsaXN0LT5uYkl0ZW1zIC0xID09IGlkeCkgewoJbGlzdC0+bmJJdGVtcy0tOwogICAgfSBlbHNlIHsJCglmb3IgKGkgPSBpZHg7IGkgPCBsaXN0LT5uYkl0ZW1zIC0xOyBpKyspCgkgICAgbGlzdC0+aXRlbXNbaV0gPSBsaXN0LT5pdGVtc1tpKzFdOwoJbGlzdC0+bmJJdGVtcy0tOwogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSXRlbUxpc3RGcmVlOgogKiBAYW5ub3Q6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgYW5ub3RhdGlvbiBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUl0ZW1MaXN0RnJlZSh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0KQp7CiAgICBpZiAobGlzdCA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGxpc3QtPml0ZW1zICE9IE5VTEwpCgl4bWxGcmVlKGxpc3QtPml0ZW1zKTsKICAgIHhtbEZyZWUobGlzdCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1Y2tldEZyZWUoeG1sU2NoZW1hQnVja2V0UHRyIGJ1Y2tldCkKewogICAgaWYgKGJ1Y2tldCA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGJ1Y2tldC0+Z2xvYmFscyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFDb21wb25lbnRMaXN0RnJlZShidWNrZXQtPmdsb2JhbHMpOwoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGJ1Y2tldC0+Z2xvYmFscyk7CiAgICB9CiAgICBpZiAoYnVja2V0LT5sb2NhbHMgIT0gTlVMTCkgewoJeG1sU2NoZW1hQ29tcG9uZW50TGlzdEZyZWUoYnVja2V0LT5sb2NhbHMpOwoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGJ1Y2tldC0+bG9jYWxzKTsJCiAgICB9CiAgICBpZiAoYnVja2V0LT5yZWxhdGlvbnMgIT0gTlVMTCkgewoJeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgcHJldiwgY3VyID0gYnVja2V0LT5yZWxhdGlvbnM7CglkbyB7CgkgICAgcHJldiA9IGN1cjsJICAgIAoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCSAgICB4bWxGcmVlKHByZXYpOwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKCghIGJ1Y2tldC0+cHJlc2VydmVEb2MpICYmIChidWNrZXQtPmRvYyAhPSBOVUxMKSkgewoJeG1sRnJlZURvYyhidWNrZXQtPmRvYyk7CiAgICB9IAogICAgaWYgKGJ1Y2tldC0+dHlwZSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQpIHsKCWlmIChXWFNfSU1QQlVDS0VUKGJ1Y2tldCktPnNjaGVtYSAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYUZyZWUoV1hTX0lNUEJVQ0tFVChidWNrZXQpLT5zY2hlbWEpOwogICAgfQogICAgeG1sRnJlZShidWNrZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hQnVja2V0UHRyCnhtbFNjaGVtYUJ1Y2tldENyZWF0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgaW50IHR5cGUsIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQnVja2V0UHRyIHJldDsKICAgIGludCBzaXplOwogICAgeG1sU2NoZW1hUHRyIG1haW5TY2hlbWE7CgogICAgaWYgKFdYU19DT05TVFJVQ1RPUihwY3R4dCktPm1haW5TY2hlbWEgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVja2V0Q3JlYXRlIiwKCSAgICAibm8gbWFpbiBzY2hlbWEgb24gY29uc3RydWN0b3IiKTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIG1haW5TY2hlbWEgPSBXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5tYWluU2NoZW1hOwogICAgLyogQ3JlYXRlIHRoZSBzY2hlbWEgYnVja2V0LiAqLwogICAgaWYgKFdYU19JU19CVUNLRVRfSU5DUkVERUYodHlwZSkpCglzaXplID0gc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpOwogICAgZWxzZQoJc2l6ZSA9IHNpemVvZih4bWxTY2hlbWFJbXBvcnQpOwogICAgcmV0ID0gKHhtbFNjaGVtYUJ1Y2tldFB0cikgeG1sTWFsbG9jKHNpemUpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBidWNrZXQiLCBOVUxMKTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemUpOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5nbG9iYWxzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIGlmIChyZXQtPmdsb2JhbHMgPT0gTlVMTCkgewoJeG1sRnJlZShyZXQpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgcmV0LT5sb2NhbHMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+bG9jYWxzID09IE5VTEwpIHsKCXhtbEZyZWUocmV0KTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIC8qIAogICAgKiBUaGUgZm9sbG93aW5nIHdpbGwgYXNzdXJlIHRoYXQgb25seSB0aGUgZmlyc3QgYnVja2V0IGlzIG1hcmtlZCBhcwogICAgKiBYTUxfU0NIRU1BX1NDSEVNQV9NQUlOIGFuZCBpdCBwb2ludHMgdG8gdGhlICptYWluKiBzY2hlbWEuCiAgICAqIEZvciBlYWNoIGZvbGxvd2luZyBpbXBvcnQgYnVja2V0cyBhbiB4bWxTY2hlbWEgd2lsbCBiZSBjcmVhdGVkLgogICAgKiBBbiB4bWxTY2hlbWEgd2lsbCBiZSBjcmVhdGVkIGZvciBldmVyeSBkaXN0aW5jdCB0YXJnZXROYW1lc3BhY2UuCiAgICAqIFdlIGFzc2lnbiB0aGUgdGFyZ2V0TmFtZXNwYWNlIHRvIHRoZSBzY2hlbWF0YSBoZXJlLgogICAgKi8KICAgIGlmICghIFdYU19IQVNfQlVDS0VUUyhwY3R4dCkpIHsKCWlmIChXWFNfSVNfQlVDS0VUX0lOQ1JFREVGKHR5cGUpKSB7CgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVja2V0Q3JlYXRlIiwKCQkiZmlyc3QgYnVja2V0IGJ1dCBpdCdzIGFuIGluY2x1ZGUgb3IgcmVkZWZpbmUiKTsKCSAgICB4bWxTY2hlbWFCdWNrZXRGcmVlKHJldCk7CgkgICAgcmV0dXJuKE5VTEwpOwoJfQoJLyogRm9yY2UgdGhlIHR5cGUgdG8gYmUgWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTi4gKi8gCglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1NDSEVNQV9NQUlOOwoJLyogUG9pbnQgdG8gdGhlICptYWluKiBzY2hlbWEuICovCglXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5tYWluQnVja2V0ID0gcmV0OwoJV1hTX0lNUEJVQ0tFVChyZXQpLT5zY2hlbWEgPSBtYWluU2NoZW1hOwoJLyoKCSogRW5zdXJlIHRoYXQgdGhlIG1haW4gc2NoZW1hIGdldHMgYSB0YXJnZXROYW1lc3BhY2UuCgkqLwoJbWFpblNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwogICAgfSBlbHNlIHsKCWlmICh0eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX01BSU4pIHsJICAgIAoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1Y2tldENyZWF0ZSIsCgkJIm1haW4gYnVja2V0IGJ1dCBpdCdzIG5vdCB0aGUgZmlyc3Qgb25lIik7CgkgICAgeG1sU2NoZW1hQnVja2V0RnJlZShyZXQpOwoJICAgIHJldHVybihOVUxMKTsKCX0gZWxzZSBpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQpIHsJICAgIAoJICAgIC8qCgkgICAgKiBDcmVhdGUgYSBzY2hlbWEgZm9yIGltcG9ydHMgYW5kIGFzc2lnbiB0aGUKCSAgICAqIHRhcmdldE5hbWVzcGFjZS4KCSAgICAqLwoJICAgIFdYU19JTVBCVUNLRVQocmV0KS0+c2NoZW1hID0geG1sU2NoZW1hTmV3U2NoZW1hKHBjdHh0KTsKCSAgICBpZiAoV1hTX0lNUEJVQ0tFVChyZXQpLT5zY2hlbWEgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUJ1Y2tldEZyZWUocmV0KTsKCQlyZXR1cm4oTlVMTCk7CgkgICAgfQoJICAgIFdYU19JTVBCVUNLRVQocmV0KS0+c2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7Cgl9CiAgICB9ICAgIAogICAgaWYgKFdYU19JU19CVUNLRVRfSU1QTUFJTih0eXBlKSkgewoJaW50IHJlczsKCS8qCgkqIEltcG9ydHMgZ28gaW50byB0aGUgInNjaGVtYXNJbXBvcnRzIiBzbG90IG9mIHRoZSBtYWluICpzY2hlbWEqLgoJKiBOb3RlIHRoYXQgd2UgY3JlYXRlIGFuIGltcG9ydCBlbnRyeSBmb3IgdGhlIG1haW4gc2NoZW1hIGFzIHdlbGw7IGkuZS4sCgkqIGV2ZW4gaWYgdGhlcmUncyBvbmx5IG9uZSBzY2hlbWEsIHdlJ2xsIGdldCBhbiBpbXBvcnQuCgkqLwoJaWYgKG1haW5TY2hlbWEtPnNjaGVtYXNJbXBvcnRzID09IE5VTEwpIHsKCSAgICBtYWluU2NoZW1hLT5zY2hlbWFzSW1wb3J0cyA9IHhtbEhhc2hDcmVhdGVEaWN0KDUsCgkJV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+ZGljdCk7CgkgICAgaWYgKG1haW5TY2hlbWEtPnNjaGVtYXNJbXBvcnRzID09IE5VTEwpIHsKCQl4bWxTY2hlbWFCdWNrZXRGcmVlKHJldCk7CgkJcmV0dXJuKE5VTEwpOwoJICAgIH0KCX0KCWlmICh0YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkKCSAgICByZXMgPSB4bWxIYXNoQWRkRW50cnkobWFpblNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCgkJWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFLCByZXQpOwoJZWxzZQoJICAgIHJlcyA9IHhtbEhhc2hBZGRFbnRyeShtYWluU2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKCQl0YXJnZXROYW1lc3BhY2UsIHJldCk7CglpZiAocmVzICE9IDApIHsKCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWNrZXRDcmVhdGUiLAoJCSJmYWlsZWQgdG8gYWRkIHRoZSBzY2hlbWEgYnVja2V0IHRvIHRoZSBoYXNoIik7CgkgICAgeG1sU2NoZW1hQnVja2V0RnJlZShyZXQpOwoJICAgIHJldHVybihOVUxMKTsKCX0KICAgIH0gZWxzZSB7CgkvKiBTZXQgdGhlIEBvd25lckltcG9ydCBvZiBhbiBpbmNsdWRlIGJ1Y2tldC4gKi8KCWlmIChXWFNfSVNfQlVDS0VUX0lNUE1BSU4oV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+YnVja2V0LT50eXBlKSkKCSAgICBXWFNfSU5DQlVDS0VUKHJldCktPm93bmVySW1wb3J0ID0KCQlXWFNfSU1QQlVDS0VUKFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCk7CgllbHNlCgkgICAgV1hTX0lOQ0JVQ0tFVChyZXQpLT5vd25lckltcG9ydCA9CgkJV1hTX0lOQ0JVQ0tFVChXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXQpLT5vd25lckltcG9ydDsKCgkvKiBJbmNsdWRlcyBnb3QgaW50byB0aGUgImluY2x1ZGVzIiBzbG90IG9mIHRoZSAqbWFpbiogc2NoZW1hLiAqLwoJaWYgKG1haW5TY2hlbWEtPmluY2x1ZGVzID09IE5VTEwpIHsKCSAgICBtYWluU2NoZW1hLT5pbmNsdWRlcyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkgICAgaWYgKG1haW5TY2hlbWEtPmluY2x1ZGVzID09IE5VTEwpIHsKCQl4bWxTY2hlbWFCdWNrZXRGcmVlKHJldCk7CgkJcmV0dXJuKE5VTEwpOwoJICAgIH0JICAgIAoJfQoJeG1sU2NoZW1hSXRlbUxpc3RBZGQobWFpblNjaGVtYS0+aW5jbHVkZXMsIHJldCk7CiAgICB9CiAgICAvKiAKICAgICogQWRkIHRvIGxpc3Qgb2YgYWxsIGJ1Y2tldHM7IHRoaXMgaXMgdXNlZCBmb3IgbG9va3VwCiAgICAqIGR1cmluZyBzY2hlbWEgY29uc3RydWN0aW9uIHRpbWUgb25seS4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hSXRlbUxpc3RBZGQoV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+YnVja2V0cywgcmV0KSA9PSAtMSkKCXJldHVybihOVUxMKTsKICAgIHJldHVybihyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZEl0ZW1TaXplKHhtbFNjaGVtYUl0ZW1MaXN0UHRyICpsaXN0LCBpbnQgaW5pdGlhbFNpemUsIHZvaWQgKml0ZW0pCnsKICAgIGlmICgqbGlzdCA9PSBOVUxMKSB7CgkqbGlzdCA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CglpZiAoKmxpc3QgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwogICAgfQogICAgeG1sU2NoZW1hSXRlbUxpc3RBZGRTaXplKCpsaXN0LCBpbml0aWFsU2l6ZSwgaXRlbSk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQW5ub3Q6CiAqIEBhbm5vdDogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBhbm5vdGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUFubm90KHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICBpZiAoYW5ub3QgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYW5ub3QtPm5leHQgPT0gTlVMTCkgewoJeG1sRnJlZShhbm5vdCk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hQW5ub3RQdHIgcHJldjsKCglkbyB7CgkgICAgcHJldiA9IGFubm90OwoJICAgIGFubm90ID0gYW5ub3QtPm5leHQ7CgkgICAgeG1sRnJlZShwcmV2KTsKCX0gd2hpbGUgKGFubm90ICE9IE5VTEwpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZU5vdGF0aW9uOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgbm90YXRpb24gc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgTm90YXRpb24gc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU5vdGF0aW9uKHhtbFNjaGVtYU5vdGF0aW9uUHRyIG5vdGEpCnsKICAgIGlmIChub3RhID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShub3RhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGU6CiAqIEBhdHRyOiAgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uCiAqCiAqIERlYWxsb2NhdGVzIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKQp7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIGlmIChhdHRyLT5kZWZWYWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShhdHRyLT5kZWZWYWwpOwogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2U6CiAqIEB1c2U6ICBhbiBhdHRyaWJ1dGUgdXNlCiAqCiAqIERlYWxsb2NhdGVzIGFuIGF0dHJpYnV0ZSB1c2Ugc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZSh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlKQp7CiAgICBpZiAodXNlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHVzZS0+YW5ub3QgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBbm5vdCh1c2UtPmFubm90KTsKICAgIGlmICh1c2UtPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKHVzZS0+ZGVmVmFsKTsKICAgIHhtbEZyZWUodXNlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VQcm9oaWI6CiAqIEBwcm9oaWI6ICBhbiBhdHRyaWJ1dGUgdXNlIHByb2hpYml0aW9uCiAqCiAqIERlYWxsb2NhdGVzIGFuIGF0dHJpYnV0ZSB1c2Ugc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZVByb2hpYih4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcHJvaGliKQp7CiAgICBpZiAocHJvaGliID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShwcm9oaWIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQ6CiAqIHNldDogIGEgc2NoZW1hIHdpbGRjYXJkIG5hbWVzcGFjZQogKgogKiBEZWFsbG9jYXRlcyBhIGxpc3Qgb2Ygd2lsZGNhcmQgY29uc3RyYWludCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzZXQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbmV4dDsKCiAgICB3aGlsZSAoc2V0ICE9IE5VTEwpIHsKCW5leHQgPSBzZXQtPm5leHQ7Cgl4bWxGcmVlKHNldCk7CglzZXQgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkOgogKiBAd2lsZGNhcmQ6ICBhIHdpbGRjYXJkIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlcyBhIHdpbGRjYXJkIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjYXJkKQp7CiAgICBpZiAod2lsZGNhcmQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAod2lsZGNhcmQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHdpbGRjYXJkLT5hbm5vdCk7CiAgICBpZiAod2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCh3aWxkY2FyZC0+bnNTZXQpOwogICAgaWYgKHdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sRnJlZSh3aWxkY2FyZC0+bmVnTnNTZXQpOwogICAgeG1sRnJlZSh3aWxkY2FyZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgZ3JvdXAgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIEdyb3VwIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyR3IpCnsKICAgIGlmIChhdHRyR3IgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ckdyLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChhdHRyR3ItPmFubm90KTsKICAgIGlmIChhdHRyR3ItPmF0dHJVc2VzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoV1hTX0xJU1RfQ0FTVCBhdHRyR3ItPmF0dHJVc2VzKTsKICAgIHhtbEZyZWUoYXR0ckdyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVRTmFtZVJlZjoKICogQGl0ZW06IGEgUU5hbWUgcmVmZXJlbmNlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlYSBhIFFOYW1lIHJlZmVyZW5jZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlUU5hbWVSZWYoeG1sU2NoZW1hUU5hbWVSZWZQdHIgaXRlbSkKewogICAgeG1sRnJlZShpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3Q6CiAqIEBhbGluazogYSB0eXBlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2YgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmspCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJbmV4dCA9IGxpbmstPm5leHQ7Cgl4bWxGcmVlKGxpbmspOwoJbGluayA9IG5leHQ7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QoeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBuZXh0OwogICAgd2hpbGUgKHN0byAhPSBOVUxMKSB7CgluZXh0ID0gc3RvLT5uZXh0OwoJaWYgKHN0by0+aGlzdG9yeSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoc3RvLT5oaXN0b3J5KTsKCWlmIChzdG8tPnhwYXRoQ3R4dCAhPSBOVUxMKQoJICAgIHhtbEZyZWVTdHJlYW1DdHh0KCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7Cgl4bWxGcmVlKHN0byk7CglzdG8gPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZUlEQzoKICogQGlkYzogYSBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24KICoKICogRGVhbGxvY2F0ZXMgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUlEQyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmKQp7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgY3VyLCBwcmV2OwoKICAgIGlmIChpZGNEZWYgPT0gTlVMTCkKCXJldHVybjsKICAgIGlmIChpZGNEZWYtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGlkY0RlZi0+YW5ub3QpOwogICAgLyogU2VsZWN0b3IgKi8KICAgIGlmIChpZGNEZWYtPnNlbGVjdG9yICE9IE5VTEwpIHsKCWlmIChpZGNEZWYtPnNlbGVjdG9yLT54cGF0aENvbXAgIT0gTlVMTCkKCSAgICB4bWxGcmVlUGF0dGVybigoeG1sUGF0dGVyblB0cikgaWRjRGVmLT5zZWxlY3Rvci0+eHBhdGhDb21wKTsKCXhtbEZyZWUoaWRjRGVmLT5zZWxlY3Rvcik7CiAgICB9CiAgICAvKiBGaWVsZHMgKi8KICAgIGlmIChpZGNEZWYtPmZpZWxkcyAhPSBOVUxMKSB7CgljdXIgPSBpZGNEZWYtPmZpZWxkczsKCWRvIHsKCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCSAgICBpZiAocHJldi0+eHBhdGhDb21wICE9IE5VTEwpCgkJeG1sRnJlZVBhdHRlcm4oKHhtbFBhdHRlcm5QdHIpIHByZXYtPnhwYXRoQ29tcCk7CgkgICAgeG1sRnJlZShwcmV2KTsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIHhtbEZyZWUoaWRjRGVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVFbGVtZW50OgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgZWxlbWVudCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBFbGVtZW50IHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVFbGVtZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoZWxlbS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoZWxlbS0+YW5ub3QpOwogICAgaWYgKGVsZW0tPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZWxlbS0+Y29udE1vZGVsKTsKICAgIGlmIChlbGVtLT5kZWZWYWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShlbGVtLT5kZWZWYWwpOwogICAgeG1sRnJlZShlbGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVGYWNldDoKICogQGZhY2V0OiAgYSBzY2hlbWEgZmFjZXQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRmFjZXQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIGlmIChmYWNldCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChmYWNldC0+dmFsICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGZhY2V0LT52YWwpOwogICAgaWYgKGZhY2V0LT5yZWdleHAgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGZhY2V0LT5yZWdleHApOwogICAgaWYgKGZhY2V0LT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChmYWNldC0+YW5ub3QpOwogICAgeG1sRnJlZShmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZToKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBuZXh0OwoKICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICBuZXh0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgICAgIGZhY2V0ID0gbmV4dDsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHlwZS0+YXR0clVzZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZSgoeG1sU2NoZW1hSXRlbUxpc3RQdHIpIHR5cGUtPmF0dHJVc2VzKTsKICAgIGlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdCh0eXBlLT5tZW1iZXJUeXBlcyk7CiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIG5leHQsIGxpbms7CgoJbGluayA9IHR5cGUtPmZhY2V0U2V0OwoJZG8gewoJICAgIG5leHQgPSBsaW5rLT5uZXh0OwoJICAgIHhtbEZyZWUobGluayk7CgkgICAgbGluayA9IG5leHQ7Cgl9IHdoaWxlIChsaW5rICE9IE5VTEwpOwogICAgfQogICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAodHlwZS0+Y29udE1vZGVsKTsKICAgIHhtbEZyZWUodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZjoKICogQGl0ZW06ICBhIHNjaGVtYSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqCiAqIERlYWxsb2NhdGVzIGEgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW0pCnsKICAgIGlmIChpdGVtLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGl0ZW0tPmFubm90KTsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cDoKICogQGl0ZW06ICBhIHNjaGVtYSBtb2RlbCBncm91cAogKgogKiBEZWFsbG9jYXRlcyBhIHNjaGVtYSBtb2RlbCBncm91cCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTW9kZWxHcm91cCh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW0pCnsKICAgIGlmIChpdGVtLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGl0ZW0tPmFubm90KTsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBvbmVudExpc3RGcmVlKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpCnsKICAgIGlmICgobGlzdCA9PSBOVUxMKSB8fCAobGlzdC0+bmJJdGVtcyA9PSAwKSkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGl0ZW07Cgl4bWxTY2hlbWFUcmVlSXRlbVB0ciAqaXRlbXMgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIgKikgbGlzdC0+aXRlbXM7CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgaXRlbSA9IGl0ZW1zW2ldOwoJICAgIGlmIChpdGVtID09IE5VTEwpCgkJY29udGludWU7CSAgICAKCSAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQkgICAgeG1sU2NoZW1hRnJlZVR5cGUoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURV9VU0U6CgkJICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2UoKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUI6CgkJICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VQcm9oaWIoCgkJCSh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCSAgICB4bWxTY2hlbWFGcmVlRWxlbWVudCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFOgoJCSAgICBpZiAoaXRlbS0+YW5ub3QgIT0gTlVMTCkKCQkJeG1sU2NoZW1hRnJlZUFubm90KGl0ZW0tPmFubm90KTsKCQkgICAgeG1sRnJlZShpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCQkgICAgeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXAoKHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKAoJCQkoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQkgICAgeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXBEZWYoCgkJCSh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSBpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZCgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCQkgICAgeG1sU2NoZW1hRnJlZUlEQygoeG1sU2NoZW1hSURDUHRyKSBpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkJICAgIHhtbFNjaGVtYUZyZWVOb3RhdGlvbigoeG1sU2NoZW1hTm90YXRpb25QdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY6CgkJICAgIHhtbFNjaGVtYUZyZWVRTmFtZVJlZigoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OiB7CgkJICAgIC8qIFRPRE86IFRoaXMgc2hvdWxkIG5ldmVyIGJlIGhpdC4gKi8KCQkgICAgeG1sU2NoZW1hUFNpbXBsZUludGVybmFsRXJyKE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ29tcG9uZW50TGlzdEZyZWUsICIKCQkJInVuZXhwZWN0ZWQgY29tcG9uZW50IHR5cGUgJyVzJ1xuIiwKCQkJKGNvbnN0IHhtbENoYXIgKikgV1hTX0lURU1fVFlQRV9OQU1FKGl0ZW0pKTsKCQkJIH0KCQkgICAgYnJlYWs7CgkgICAgfQoJfQoJbGlzdC0+bmJJdGVtcyA9IDA7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlKHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICAvKiBAdm9sYXRpbGVzIGlzIG5vdCB1c2VkIGFueW1vcmUgOi0vICovCiAgICBpZiAoc2NoZW1hLT52b2xhdGlsZXMgIT0gTlVMTCkKCVRPRE8KICAgIC8qCiAgICAqIE5vdGUgdGhhdCB0aG9zZSBzbG90cyBhcmUgbm90IHJlc3BvbnNpYmxlIGZvciBmcmVlaW5nCiAgICAqIHNjaGVtYSBjb21wb25lbnRzIGFueW1vcmU7IHRoaXMgd2lsbCBub3cgYmUgZG9uZSBieQogICAgKiB0aGUgc2NoZW1hIGJ1Y2tldHMuCiAgICAqLwogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPm5vdGFEZWNsLCBOVUxMKTsKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5hdHRyRGVjbCwgTlVMTCk7CiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+YXR0cmdycERlY2wsIE5VTEwpOwogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmVsZW1EZWNsLCBOVUxMKTsKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT50eXBlRGVjbCwgTlVMTCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmdyb3VwRGVjbCwgTlVMTCk7CiAgICBpZiAoc2NoZW1hLT5pZGNEZWYgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmlkY0RlZiwgTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgIT0gTlVMTCkKCXhtbEhhc2hGcmVlKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCgkJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUJ1Y2tldEZyZWUpOwogICAgaWYgKHNjaGVtYS0+aW5jbHVkZXMgIT0gTlVMTCkgewoJeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCA9ICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgc2NoZW1hLT5pbmNsdWRlczsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJICAgIHhtbFNjaGVtYUJ1Y2tldEZyZWUoKHhtbFNjaGVtYUJ1Y2tldFB0cikgbGlzdC0+aXRlbXNbaV0pOwkKCX0KCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShsaXN0KTsKICAgIH0KICAgIGlmIChzY2hlbWEtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHNjaGVtYS0+YW5ub3QpOwogICAgLyogTmV2ZXIgZnJlZSB0aGUgZG9jIGhlcmUsIHNpbmNlIHRoaXMgd2lsbCBiZSBkb25lIGJ5IHRoZSBidWNrZXRzLiAqLwoKICAgIHhtbERpY3RGcmVlKHNjaGVtYS0+ZGljdCk7CiAgICB4bWxGcmVlKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlEZWJ1ZyBmdW5jdGlvbnMJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmZGVmIExJQlhNTF9PVVRQVVRfRU5BQkxFRAoKc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUR1bXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBGSUxFICogb3V0cHV0KTsgLyogZm9yd2FyZCAqLwoKLyoqCiAqIHhtbFNjaGVtYUVsZW1lbnREdW1wOgogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKgogKiBEdW1wIHRoZSBlbGVtZW50CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFbGVtZW50RHVtcCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sIEZJTEUgKiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlIEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChlbGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKCiAgICBmcHJpbnRmKG91dHB1dCwgIkVsZW1lbnQiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKQoJZnByaW50ZihvdXRwdXQsICIgKGdsb2JhbCkiKTsKICAgIGZwcmludGYob3V0cHV0LCAiOiAnJXMnICIsIGVsZW0tPm5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihvdXRwdXQsICJucyAnJXMnIiwgbmFtZXNwYWNlKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKI2lmIDAKICAgIGlmICgoZWxlbS0+bWluT2NjdXJzICE9IDEpIHx8IChlbGVtLT5tYXhPY2N1cnMgIT0gMSkpIHsKCWZwcmludGYob3V0cHV0LCAiICBtaW4gJWQgIiwgZWxlbS0+bWluT2NjdXJzKTsKICAgICAgICBpZiAoZWxlbS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6IHVuYm91bmRlZFxuIik7CiAgICAgICAgZWxzZSBpZiAoZWxlbS0+bWF4T2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiAlZFxuIiwgZWxlbS0+bWF4T2NjdXJzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KI2VuZGlmCiAgICAvKgogICAgKiBNaXNjIG90aGVyIHByb3BlcnRpZXMuCiAgICAqLwogICAgaWYgKChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpIHx8CgkoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB8fAoJKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgfHwKCShlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fREVGQVVMVCkpIHsKCWZwcmludGYob3V0cHV0LCAiICBwcm9wczogIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2ZpeGVkXSAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fREVGQVVMVCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltkZWZhdWx0XSAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpCgkgICAgZnByaW50ZihvdXRwdXQsICJbYWJzdHJhY3RdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltuaWxsYWJsZV0gIik7CglmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICAvKgogICAgKiBEZWZhdWx0L2ZpeGVkIHZhbHVlLgogICAgKi8KICAgIGlmIChlbGVtLT52YWx1ZSAhPSBOVUxMKQoJZnByaW50ZihvdXRwdXQsICIgIHZhbHVlOiAnJXMnXG4iLCBlbGVtLT52YWx1ZSk7CiAgICAvKgogICAgKiBUeXBlLgogICAgKi8KICAgIGlmIChlbGVtLT5uYW1lZFR5cGUgIT0gTlVMTCkgewoJZnByaW50ZihvdXRwdXQsICIgIHR5cGU6ICclcycgIiwgZWxlbS0+bmFtZWRUeXBlKTsKCWlmIChlbGVtLT5uYW1lZFR5cGVOcyAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAibnMgJyVzJ1xuIiwgZWxlbS0+bmFtZWRUeXBlTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0gZWxzZSBpZiAoZWxlbS0+c3VidHlwZXMgIT0gTlVMTCkgewoJLyoKCSogRHVtcCBsb2NhbCB0eXBlcy4KCSovCgl4bWxTY2hlbWFUeXBlRHVtcChlbGVtLT5zdWJ0eXBlcywgb3V0cHV0KTsKICAgIH0KICAgIC8qCiAgICAqIFN1YnN0aXR1dGlvbiBncm91cC4KICAgICovCiAgICBpZiAoZWxlbS0+c3Vic3RHcm91cCAhPSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgc3Vic3RpdHV0aW9uR3JvdXA6ICclcycgIiwgZWxlbS0+c3Vic3RHcm91cCk7CglpZiAoZWxlbS0+c3Vic3RHcm91cE5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJucyAnJXMnXG4iLCBlbGVtLT5zdWJzdEdyb3VwTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUFubm90RHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAYW5ub3Q6ICBhIGFubm90YXRpb24KICoKICogRHVtcCB0aGUgYW5ub3RhdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQW5ub3REdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICB4bWxDaGFyICpjb250ZW50OwoKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBjb250ZW50ID0geG1sTm9kZUdldENvbnRlbnQoYW5ub3QtPmNvbnRlbnQpOwogICAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogJXNcbiIsIGNvbnRlbnQpOwogICAgICAgIHhtbEZyZWUoY29udGVudCk7CiAgICB9IGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgQW5ub3Q6IGVtcHR5XG4iKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXA6CiAqIEBwYXJ0aWNsZTogdGhlIHNjaGVtYSBwYXJ0aWNsZQogKiBAb3V0cHV0OiB0aGUgZmlsZSBvdXRwdXQKICogQGRlcHRoOiB0aGUgZGVwdGggdXNlZCBmb3IgaW50ZW50YXRpb24KICoKICogRHVtcCBhIFNjaGVtYVR5cGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlLCBGSUxFICogb3V0cHV0LCBpbnQgZGVwdGgpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciB0ZXJtOwogICAgY2hhciBzaGlmdFsxMDBdOwogICAgaW50IGk7CgogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCglyZXR1cm47CiAgICBmb3IgKGkgPSAwOygoaSA8IGRlcHRoKSAmJiAoaSA8IDI1KSk7aSsrKQogICAgICAgIHNoaWZ0WzIgKiBpXSA9IHNoaWZ0WzIgKiBpICsgMV0gPSAnICc7CiAgICBzaGlmdFsyICogaV0gPSBzaGlmdFsyICogaSArIDFdID0gMDsKICAgIGZwcmludGYob3V0cHV0LCBzaGlmdCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiTUlTU0lORyBwYXJ0aWNsZSB0ZXJtXG4iKTsKCXJldHVybjsKICAgIH0KICAgIHRlcm0gPSBwYXJ0aWNsZS0+Y2hpbGRyZW47CiAgICBpZiAodGVybSA9PSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIihOVUxMKSIpOwogICAgfSBlbHNlIHsKCXN3aXRjaCAodGVybS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJZnByaW50ZihvdXRwdXQsICJFTEVNICclcyciLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpdGVybSktPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgKCh4bWxTY2hlbWFFbGVtZW50UHRyKXRlcm0pLT5uYW1lKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJCWZwcmludGYob3V0cHV0LCAiU0VRVUVOQ0UiKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgkJZnByaW50ZihvdXRwdXQsICJDSE9JQ0UiKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkJZnByaW50ZihvdXRwdXQsICJBTEwiKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkJZnByaW50ZihvdXRwdXQsICJBTlkiKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWZwcmludGYob3V0cHV0LCAiVU5LTk9XTlxuIik7CgkJcmV0dXJuOwoJfQogICAgfQogICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgIT0gMSkKCWZwcmludGYob3V0cHV0LCAiIG1pbjogJWQiLCBwYXJ0aWNsZS0+bWluT2NjdXJzKTsKICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKCWZwcmludGYob3V0cHV0LCAiIG1heDogdW5ib3VuZGVkIik7CiAgICBlbHNlIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzICE9IDEpCglmcHJpbnRmKG91dHB1dCwgIiBtYXg6ICVkIiwgcGFydGljbGUtPm1heE9jY3Vycyk7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAodGVybSAmJgoJKCh0ZXJtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkgfHwKCSAodGVybS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSB8fAoJICh0ZXJtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpKSAmJgoJICh0ZXJtLT5jaGlsZHJlbiAhPSBOVUxMKSkgewoJeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHRlcm0tPmNoaWxkcmVuLAoJICAgIG91dHB1dCwgZGVwdGggKzEpOwogICAgfQogICAgaWYgKHBhcnRpY2xlLT5uZXh0ICE9IE5VTEwpCgl4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydGljbGUtPm5leHQsCgkJb3V0cHV0LCBkZXB0aCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyVXNlc0R1bXA6CiAqIEB1c2VzOiAgYXR0cmlidXRlIHVzZXMgbGlzdAogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0IAogKgogKiBEdW1wcyBhIGxpc3Qgb2YgYXR0cmlidXRlIHVzZSBjb21wb25lbnRzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0clVzZXNEdW1wKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHVzZXMsIEZJTEUgKiBvdXRwdXQpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2U7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcHJvaGliOwogICAgeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnRuczsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgaTsKCiAgICBpZiAoKHVzZXMgPT0gTlVMTCkgfHwgKHVzZXMtPm5iSXRlbXMgPT0gMCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGZwcmludGYob3V0cHV0LCAiICBhdHRyaWJ1dGVzOlxuIik7ICAgIAogICAgZm9yIChpID0gMDsgaSA8IHVzZXMtPm5iSXRlbXM7IGkrKykgewoJdXNlID0gdXNlcy0+aXRlbXNbaV07CglpZiAodXNlLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfQVRUUl9VU0VfUFJPSElCKSB7CgkgICAgZnByaW50ZihvdXRwdXQsICIgIFtwcm9oaWJpdGlvbl0gIik7CgkgICAgcHJvaGliID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cikgdXNlOwoJICAgIG5hbWUgPSBwcm9oaWItPm5hbWU7CgkgICAgdG5zID0gcHJvaGliLT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgaWYgKHVzZS0+dHlwZSA9PSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGKSB7CgkgICAgZnByaW50ZihvdXRwdXQsICIgIFtyZWZlcmVuY2VdICIpOwoJICAgIHJlZiA9ICh4bWxTY2hlbWFRTmFtZVJlZlB0cikgdXNlOwoJICAgIG5hbWUgPSByZWYtPm5hbWU7CgkgICAgdG5zID0gcmVmLT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgewoJICAgIGZwcmludGYob3V0cHV0LCAiICBbdXNlXSAiKTsKCSAgICBuYW1lID0gV1hTX0FUVFJVU0VfREVDTF9OQU1FKHVzZSk7CgkgICAgdG5zID0gV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKTsKCX0KCWZwcmludGYob3V0cHV0LCAiJyVzJ1xuIiwKCSAgICAoY29uc3QgY2hhciAqKSB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB0bnMsIG5hbWUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEB0eXBlOiAgYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEdW1wIGEgU2NoZW1hVHlwZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVEdW1wKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgRklMRSAqIG91dHB1dCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiVHlwZTogTlVMTFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiAiKTsKICAgIGlmICh0eXBlLT5uYW1lICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICInJXMnICIsIHR5cGUtPm5hbWUpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAiKG5vIG5hbWUpICIpOwogICAgaWYgKHR5cGUtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihvdXRwdXQsICJucyAnJXMnICIsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYmFzaWNdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3NpbXBsZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2NvbXBsZXhdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2VxdWVuY2VdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2Nob2ljZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYWxsXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3VyXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Jlc3RyaWN0aW9uXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltleHRlbnNpb25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlt1bmtub3duIHR5cGUgJWRdICIsIHR5cGUtPnR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiY29udGVudDogIik7CiAgICBzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbdW5rbm93bl0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltlbXB0eV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltlbGVtZW50XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW21peGVkXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CgkvKiBub3QgdXNlZC4gKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2Jhc2ljXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltzaW1wbGVdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9BTlk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2FueV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBiYXNlIHR5cGU6ICclcyciLCB0eXBlLT5iYXNlKTsKCWlmICh0eXBlLT5iYXNlTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIiBucyAnJXMnXG4iLCB0eXBlLT5iYXNlTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmICh0eXBlLT5hdHRyVXNlcyAhPSBOVUxMKQoJeG1sU2NoZW1hQXR0clVzZXNEdW1wKHR5cGUtPmF0dHJVc2VzLCBvdXRwdXQpOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hQW5ub3REdW1wKG91dHB1dCwgdHlwZS0+YW5ub3QpOwojaWZkZWYgRFVNUF9DT05URU5UX01PREVMCiAgICBpZiAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkpIHsKCXhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXAoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0eXBlLT5zdWJ0eXBlcywKCSAgICBvdXRwdXQsIDEpOwogICAgfQojZW5kaWYKfQoKLyoqCiAqIHhtbFNjaGVtYUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHNjaGVtYTogIGEgc2NoZW1hIHN0cnVjdHVyZQogKgogKiBEdW1wIGEgU2NoZW1hIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRHVtcChGSUxFICogb3V0cHV0LCB4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAob3V0cHV0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6ICIpOwogICAgaWYgKHNjaGVtYS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMsICIsIHNjaGVtYS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lLCAiKTsKICAgIGlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMiLCAoY29uc3QgY2hhciAqKSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyB0YXJnZXQgbmFtZXNwYWNlIik7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHNjaGVtYS0+YW5ub3QpOwogICAgeG1sSGFzaFNjYW4oc2NoZW1hLT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFUeXBlRHVtcCwKICAgICAgICAgICAgICAgIG91dHB1dCk7CiAgICB4bWxIYXNoU2NhbkZ1bGwoc2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFFbGVtZW50RHVtcCwgb3V0cHV0KTsKfQoKI2lmZGVmIERFQlVHX0lEQ19OT0RFX1RBQkxFCi8qKgogKiB4bWxTY2hlbWFEZWJ1Z0R1bXBJRENUYWJsZToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBEaXNwbGF5cyB0aGUgY3VycmVudCBJREMgdGFibGUgZm9yIGRlYnVnIHB1cnBvc2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRGVidWdEdW1wSURDVGFibGUoRklMRSAqIG91dHB1dCwKCQkJICAgY29uc3QgeG1sQ2hhciAqbmFtZXNwYWNlTmFtZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lLAoJCQkgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciB0YWI7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleTsKICAgIGludCBpLCBqLCByZXM7CgogICAgZnByaW50ZihvdXRwdXQsICJJREM6IFRBQkxFUyBvbiAnJXMnXG4iLAoJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgbmFtZXNwYWNlTmFtZSwgbG9jYWxOYW1lKSk7CiAgICBGUkVFX0FORF9OVUxMKHN0cikKCiAgICBpZiAoYmluZCA9PSBOVUxMKQoJcmV0dXJuOwogICAgZG8gewoJZnByaW50ZihvdXRwdXQsICJJREM6ICAgQklORElORyAnJXMnICglZClcbiIsCgkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgCgkJYmluZC0+ZGVmaW5pdGlvbiksIGJpbmQtPm5iTm9kZXMpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglmb3IgKGkgPSAwOyBpIDwgYmluZC0+bmJOb2RlczsgaSsrKSB7CgkgICAgdGFiID0gYmluZC0+bm9kZVRhYmxlW2ldOwoJICAgIGZwcmludGYob3V0cHV0LCAiICAgICAgICAgKCAiKTsKCSAgICBmb3IgKGogPSAwOyBqIDwgYmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGorKykgewoJCWtleSA9IHRhYi0+a2V5c1tqXTsKCQlpZiAoKGtleSAhPSBOVUxMKSAmJiAoa2V5LT52YWwgIT0gTlVMTCkpIHsKCQkgICAgcmVzID0geG1sU2NoZW1hR2V0Q2Fub25WYWx1ZShrZXktPnZhbCwgJnZhbHVlKTsKCQkgICAgaWYgKHJlcyA+PSAwKQoJCQlmcHJpbnRmKG91dHB1dCwgIiclcycgIiwgdmFsdWUpOwoJCSAgICBlbHNlCgkJCWZwcmludGYob3V0cHV0LCAiQ0FOT04tVkFMVUUtRkFJTEVEICIpOwoJCSAgICBpZiAocmVzID09IDApCgkJCUZSRUVfQU5EX05VTEwodmFsdWUpCgkJfSBlbHNlIGlmIChrZXkgIT0gTlVMTCkKCQkgICAgZnByaW50ZihvdXRwdXQsICIobm8gdmFsKSwgIik7CgkJZWxzZQoJCSAgICBmcHJpbnRmKG91dHB1dCwgIihrZXkgbWlzc2luZyksICIpOwoJICAgIH0KCSAgICBmcHJpbnRmKG91dHB1dCwgIilcbiIpOwoJfQoJaWYgKGJpbmQtPmR1cGxzICYmIGJpbmQtPmR1cGxzLT5uYkl0ZW1zKSB7CgkgICAgZnByaW50ZihvdXRwdXQsICJJREM6ICAgICBkdXBscyAoJWQpOlxuIiwgYmluZC0+ZHVwbHMtPm5iSXRlbXMpOwoJICAgIGZvciAoaSA9IDA7IGkgPCBiaW5kLT5kdXBscy0+bmJJdGVtczsgaSsrKSB7CgkJdGFiID0gYmluZC0+ZHVwbHMtPml0ZW1zW2ldOwoJCWZwcmludGYob3V0cHV0LCAiICAgICAgICAgKCAiKTsKCQlmb3IgKGogPSAwOyBqIDwgYmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGorKykgewoJCSAgICBrZXkgPSB0YWItPmtleXNbal07CgkJICAgIGlmICgoa2V5ICE9IE5VTEwpICYmIChrZXktPnZhbCAhPSBOVUxMKSkgewoJCQlyZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlKGtleS0+dmFsLCAmdmFsdWUpOwoJCQlpZiAocmVzID49IDApCgkJCSAgICBmcHJpbnRmKG91dHB1dCwgIiclcycgIiwgdmFsdWUpOwoJCQllbHNlCgkJCSAgICBmcHJpbnRmKG91dHB1dCwgIkNBTk9OLVZBTFVFLUZBSUxFRCAiKTsKCQkJaWYgKHJlcyA9PSAwKQoJCQkgICAgRlJFRV9BTkRfTlVMTCh2YWx1ZSkKCQkgICAgfSBlbHNlIGlmIChrZXkgIT0gTlVMTCkKCQkgICAgZnByaW50ZihvdXRwdXQsICIobm8gdmFsKSwgIik7CgkJCWVsc2UKCQkJICAgIGZwcmludGYob3V0cHV0LCAiKGtleSBtaXNzaW5nKSwgIik7CgkJfQoJCWZwcmludGYob3V0cHV0LCAiKVxuIik7CgkgICAgfQoJfQoJYmluZCA9IGJpbmQtPm5leHQ7CiAgICB9IHdoaWxlIChiaW5kICE9IE5VTEwpOwp9CiNlbmRpZiAvKiBERUJVR19JREMgKi8KI2VuZGlmIC8qIExJQlhNTF9PVVRQVVRfRU5BQkxFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJVXRpbGl0aWVzCQkJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3BOb2RlOgogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIG5hbWUgb2YgQG5hbWUgaW4KICogbm8gbmFtZXNwYWNlLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlKHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQXR0clB0ciBwcm9wOwoKICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKCXJldHVybihOVUxMKTsKICAgIHByb3AgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKHByb3AgIT0gTlVMTCkgewogICAgICAgIGlmICgocHJvcC0+bnMgPT0gTlVMTCkgJiYgeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgQkFEX0NBU1QgbmFtZSkpCgkgICAgcmV0dXJuKHByb3ApOwoJcHJvcCA9IHByb3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UHJvcE5vZGVOczoKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUKICogQHVyaTogdGhlIHVyaQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIGxvY2FsIG5hbWUgb2YgQG5hbWUgYW5kCiAqIGEgbmFtZXNwYWNlIFVSSSBvZiBAdXJpLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlTnMoeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICp1cmksIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbEF0dHJQdHIgcHJvcDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCglyZXR1cm4oTlVMTCk7ICAgIAogICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CglpZiAoKHByb3AtPm5zICE9IE5VTEwpICYmCgkgICAgeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgQkFEX0NBU1QgbmFtZSkgJiYKCSAgICB4bWxTdHJFcXVhbChwcm9wLT5ucy0+aHJlZiwgQkFEX0NBU1QgdXJpKSkKCSAgICByZXR1cm4ocHJvcCk7Cglwcm9wID0gcHJvcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKCXZhbCA9IHhtbFN0cmR1cCgoeG1sQ2hhciAqKSIiKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROb2RlQ29udGVudE5vRGljdCh4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHJldHVybigoY29uc3QgeG1sQ2hhciopIHhtbE5vZGVHZXRDb250ZW50KG5vZGUpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3A6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBub2RlCiAqIEBuYW1lOiB0aGUgcHJvcGVydHkgbmFtZQogKgogKiBSZWFkIGEgYXR0cmlidXRlIHZhbHVlIGFuZCBpbnRlcm5hbGl6ZSB0aGUgc3RyaW5nCiAqCiAqIFJldHVybnMgdGhlIHN0cmluZyBvciBOVUxMIGlmIG5vdCBwcmVzZW50LgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRQcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxHZXROb05zUHJvcChub2RlLCBCQURfQ0FTVCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwogICAgeG1sRnJlZSh2YWwpOwogICAgcmV0dXJuKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgV1hTX0ZJTkRfR0xPQkFMX0lURU0oc2xvdCkJCQlcCiAgICBpZiAoeG1sU3RyRXF1YWwobnNOYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpIHsgXAoJcmV0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNsb3QsIG5hbWUpOyBcCglpZiAocmV0ICE9IE5VTEwpIGdvdG8gZXhpdDsgXAogICAgfSBcCiAgICBpZiAoeG1sSGFzaFNpemUoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cykgPiAxKSB7IFwKCXhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7IFwKCWlmIChuc05hbWUgPT0gTlVMTCkgXAoJICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgXAoJCVhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7IFwKCWVsc2UgXAoJICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbnNOYW1lKTsgXAoJaWYgKGltcG9ydCA9PSBOVUxMKSBcCgkgICAgZ290byBleGl0OyBcCglyZXQgPSB4bWxIYXNoTG9va3VwKGltcG9ydC0+c2NoZW1hLT5zbG90LCBuYW1lKTsgXAogICAgfQoKLyoqCiAqIHhtbFNjaGVtYUdldEVsZW06CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGNvbnRleHQKICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCiAqIEBuczogIHRoZSBlbGVtZW50IG5hbWVzcGFjZQogKgogKiBMb29rdXAgYSBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbiBpbiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hR2V0RWxlbSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbnNOYW1lKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldCA9IE5VTEw7CiAgICAKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybihOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0oZWxlbURlY2wpCiAgICB9ICAgCmV4aXQ6CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZWxlbWVudCBkZWNsLiAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGVsZW1lbnQgZGVjbC4gJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5zTmFtZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0VHlwZToKICogQHNjaGVtYTogIHRoZSBtYWluIHNjaGVtYQogKiBAbmFtZTogIHRoZSB0eXBlJ3MgbmFtZQogKiBuc05hbWU6ICB0aGUgdHlwZSdzIG5hbWVzcGFjZQogKgogKiBMb29rdXAgYSB0eXBlIGluIHRoZSBzY2hlbWFzIG9yIHRoZSBwcmVkZWZpbmVkIHR5cGVzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRUeXBlKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuc05hbWUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7ICAgIAogICAgLyogRmlyc3QgdHJ5IHRoZSBidWlsdC1pbiB0eXBlcy4gKi8KICAgIGlmICgobnNOYW1lICE9IE5VTEwpICYmIHhtbFN0ckVxdWFsKG5zTmFtZSwgeG1sU2NoZW1hTnMpKSB7CQoJcmV0ID0geG1sU2NoZW1hR2V0UHJlZGVmaW5lZFR5cGUobmFtZSwgbnNOYW1lKTsKCWlmIChyZXQgIT0gTlVMTCkKCSAgICBnb3RvIGV4aXQ7CgkvKgoJKiBOb3RlIHRoYXQgd2UgdHJ5IHRoZSBwYXJzZWQgc2NoZW1hcyBhcyB3ZWxsIGhlcmUKCSogc2luY2Ugb25lIG1pZ2h0IGhhdmUgcGFyc2VkIHRoZSBTNFMsIHdoaWNoIGNvbnRhaW4gbW9yZQoJKiB0aGFuIHRoZSBidWlsdC1pbiB0eXBlcy4KCSogVE9ETzogQ2FuIHdlIG9wdGltaXplIHRoaXM/CgkqLwogICAgfQogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CglXWFNfRklORF9HTE9CQUxfSVRFTSh0eXBlRGVjbCkKICAgIH0gCmV4aXQ6CgojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuc05hbWUgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuc05hbWUpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2w6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuc05hbWUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKCVdYU19GSU5EX0dMT0JBTF9JVEVNKGF0dHJEZWNsKQogICAgfQpleGl0OgojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuc05hbWUgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbnNOYW1lKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbnNOYW1lKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKCVdYU19GSU5EX0dMT0JBTF9JVEVNKGF0dHJncnBEZWNsKQogICAgfQpleGl0OgogICAgLyogVE9ETzoKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPnJlZGVmICE9IE5VTEwpKSB7CgkqIFJldHVybiB0aGUgbGFzdCByZWRlZmluaXRpb24uICoKCXJldCA9IHJldC0+cmVkZWY7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuc05hbWUgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSBncm91cCAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbnNOYW1lKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwCiAqCiAqIExvb2t1cCBhIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIKeG1sU2NoZW1hR2V0R3JvdXAoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSkKewogICAgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKCVdYU19GSU5EX0dMT0JBTF9JVEVNKGdyb3VwRGVjbCkKICAgIH0KZXhpdDoKICAgIAojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuc05hbWUgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5zTmFtZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hTm90YXRpb25QdHIKeG1sU2NoZW1hR2V0Tm90YXRpb24oeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJICAgICBjb25zdCB4bWxDaGFyICpuc05hbWUpCnsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0obm90YURlY2wpCiAgICB9CmV4aXQ6CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJRENQdHIKeG1sU2NoZW1hR2V0SURDKHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJY29uc3QgeG1sQ2hhciAqbmFtZSwKCQljb25zdCB4bWxDaGFyICpuc05hbWUpCnsKICAgIHhtbFNjaGVtYUlEQ1B0ciByZXQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKCVdYU19GSU5EX0dMT0JBTF9JVEVNKGlkY0RlZikKICAgIH0KZXhpdDoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE5hbWVkQ29tcG9uZW50OgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgZ3JvdXAKICoKICogTG9va3VwIGEgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQmFzaWNJdGVtUHRyCnhtbFNjaGVtYUdldE5hbWVkQ29tcG9uZW50KHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgIHhtbFNjaGVtYVR5cGVUeXBlIGl0ZW1UeXBlLAoJCQkgICBjb25zdCB4bWxDaGFyICpuYW1lLAoJCQkgICBjb25zdCB4bWxDaGFyICp0YXJnZXROcykKewogICAgc3dpdGNoIChpdGVtVHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSB4bWxTY2hlbWFHZXRHcm91cChzY2hlbWEsCgkJbmFtZSwgdGFyZ2V0TnMpKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSB4bWxTY2hlbWFHZXRFbGVtKHNjaGVtYSwKCQluYW1lLCB0YXJnZXROcykpOwoJZGVmYXVsdDoKCSAgICBUT0RPCgkgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBJU19CTEFOS19OT0RFKG4pCQkJCQkJXAogICAgKCgobiktPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKHhtbFNjaGVtYUlzQmxhbmsoKG4pLT5jb250ZW50LCAtMSkpKQoKLyoqCiAqIHhtbFNjaGVtYUlzQmxhbms6CiAqIEBzdHI6ICBhIHN0cmluZwogKiBAbGVuOiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgb3IgLTEKICoKICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgaWdub3JhYmxlCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgc3RyaW5nIGlzIE5VTEwgb3IgbWFkZSBvZiBibGFua3MgY2hhcnMsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzQmxhbmsoeG1sQ2hhciAqIHN0ciwgaW50IGxlbikKewogICAgaWYgKHN0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoMSk7CiAgICBpZiAobGVuIDwgMCkgewoJd2hpbGUgKCpzdHIgIT0gMCkgewoJICAgIGlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKCQlyZXR1cm4gKDApOwoJICAgIHN0cisrOwoJfQogICAgfSBlbHNlIHdoaWxlICgoKnN0ciAhPSAwKSAmJiAobGVuICE9IDApKSB7CglpZiAoIShJU19CTEFOS19DSCgqc3RyKSkpCgkgICAgcmV0dXJuICgwKTsKCXN0cisrOwoJbGVuLS07CiAgICB9CiAgICAKICAgIHJldHVybiAoMSk7Cn0KCiNkZWZpbmUgV1hTX0NPTVBfTkFNRShjLCB0KSAoKHQpIChjKSktPm5hbWUKI2RlZmluZSBXWFNfQ09NUF9UTlMoYywgdCkgKCh0KSAoYykpLT50YXJnZXROYW1lc3BhY2UKLyoKKiB4bWxTY2hlbWFGaW5kUmVkZWZDb21wSW5HcmFwaDoKKiBBVFRFTlRJT04gVE9ETzogVGhpcyB1c2VzIHBvaW50ZXIgY29tcC4gZm9yIHN0cmluZ3MuCiovCnN0YXRpYyB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIKeG1sU2NoZW1hRmluZFJlZGVmQ29tcEluR3JhcGgoeG1sU2NoZW1hQnVja2V0UHRyIGJ1Y2tldCwKCQkJICAgICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSwKCQkJICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwKCQkJICAgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lKQp7CiAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgcmV0OwogICAgaW50IGk7CgogICAgaWYgKChidWNrZXQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCglyZXR1cm4oTlVMTCk7CiAgICBpZiAoKGJ1Y2tldC0+Z2xvYmFscyA9PSBOVUxMKSB8fAoJKGJ1Y2tldC0+Z2xvYmFscy0+bmJJdGVtcyA9PSAwKSkKCWdvdG8gc3Vic2NoZW1hczsKICAgIC8qCiAgICAqIFNlYXJjaCBpbiBnbG9iYWwgY29tcG9uZW50cy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgYnVja2V0LT5nbG9iYWxzLT5uYkl0ZW1zOyBpKyspIHsKCXJldCA9IGJ1Y2tldC0+Z2xvYmFscy0+aXRlbXNbaV07CglpZiAocmV0LT50eXBlID09IHR5cGUpIHsKCSAgICBzd2l0Y2ggKHR5cGUpIHsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQkgICAgaWYgKChXWFNfQ09NUF9OQU1FKHJldCwgeG1sU2NoZW1hVHlwZVB0cikgPT0gbmFtZSkgJiYKCQkJKFdYU19DT01QX1ROUyhyZXQsIHhtbFNjaGVtYVR5cGVQdHIpID09CgkJCW5zTmFtZSkpCgkJICAgIHsKCQkJcmV0dXJuKHJldCk7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJICAgIGlmICgoV1hTX0NPTVBfTkFNRShyZXQsCgkJCSAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSA9PSBuYW1lKSAmJgoJCQkoV1hTX0NPTVBfVE5TKHJldCwKCQkJICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpID09IG5zTmFtZSkpCgkJICAgIHsKCQkJcmV0dXJuKHJldCk7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJICAgIGlmICgoV1hTX0NPTVBfTkFNRShyZXQsCgkJCSAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgPT0gbmFtZSkgJiYKCQkJKFdYU19DT01QX1ROUyhyZXQsCgkJCSAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgPT0gbnNOYW1lKSkKCQkgICAgewoJCQlyZXR1cm4ocmV0KTsKCQkgICAgfQoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICAvKiBTaG91bGQgbm90IGJlIGhpdC4gKi8KCQkgICAgcmV0dXJuKE5VTEwpOwoJICAgIH0JCQoJfQogICAgfQpzdWJzY2hlbWFzOgogICAgLyoKICAgICogUHJvY2VzcyBpbXBvcnRlZC9pbmNsdWRlZCBzY2hlbWFzLgogICAgKi8KICAgIGlmIChidWNrZXQtPnJlbGF0aW9ucyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWwgPSBidWNrZXQtPnJlbGF0aW9uczsKCgkvKgoJKiBUT0RPOiBNYXJraW5nIHRoZSBidWNrZXQgd2lsbCBub3QgYXZvaWQgbXVsdGlwbGUgc2VhcmNoZXMKCSogaW4gdGhlIHNhbWUgc2NoZW1hLCBidXQgYXZvaWRzIGF0IGxlYXN0IGNpcmN1bGFyaXR5LgoJKi8KCWJ1Y2tldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9CVUNLRVRfTUFSS0VEOwoJZG8gewoJICAgIGlmICgocmVsLT5idWNrZXQgIT0gTlVMTCkgJiYKCQkoKHJlbC0+YnVja2V0LT5mbGFncyAmIFhNTF9TQ0hFTUFfQlVDS0VUX01BUktFRCkgPT0gMCkpIHsKCQlyZXQgPSB4bWxTY2hlbWFGaW5kUmVkZWZDb21wSW5HcmFwaChyZWwtPmJ1Y2tldCwKCQkgICAgdHlwZSwgbmFtZSwgbnNOYW1lKTsKCQlpZiAocmV0ICE9IE5VTEwpCgkJICAgIHJldHVybihyZXQpOwoJICAgIH0KCSAgICByZWwgPSByZWwtPm5leHQ7Cgl9IHdoaWxlIChyZWwgIT0gTlVMTCk7CgkgYnVja2V0LT5mbGFncyBePSBYTUxfU0NIRU1BX0JVQ0tFVF9NQVJLRUQ7CiAgICB9CiAgICByZXR1cm4oTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGROb3RhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgYW5ub3RhdGlvbiBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFBZGROb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkgICAgIHhtbE5vZGVQdHIgbm9kZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGQgYW5ub3RhdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5zTmFtZTsKICAgIC8qIFRPRE86IGRvIHdlIG5lZWQgdGhlIG5vZGUgdG8gYmUgc2V0PwogICAgKiByZXQtPm5vZGUgPSBub2RlOyovCiAgICBXWFNfQUREX0dMT0JBTChjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuc05hbWUsCgkJICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgcmV0LT5uYW1lID0gbmFtZTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbnNOYW1lOwoKICAgIGlmICh0b3BMZXZlbCkKCVdYU19BRERfR0xPQkFMKGN0eHQsIHJldCk7CiAgICBlbHNlCglXWFNfQUREX0xPQ0FMKGN0eHQsIHJldCk7CiAgICBXWFNfQUREX1BFTkRJTkcoY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZVVzZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlVXNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciByZXQgPSBOVUxMOwoKICAgIGlmIChwY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVVc2UpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkocGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlVXNlKSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFX1VTRTsKICAgIHJldC0+bm9kZSA9IG5vZGU7CgogICAgV1hTX0FERF9MT0NBTChwY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoKKiB4bWxTY2hlbWFBZGRSZWRlZjoKKgoqIEFkZHMgYSByZWRlZmluaXRpb24gaW5mb3JtYXRpb24uIFRoaXMgaXMgdXNlZCBhdCBhIGxhdGVyIHN0YWdlIHRvOgoqIHJlc29sdmUgcmVmZXJlbmNlcyB0byB0aGUgcmVkZWZpbmVkIGNvbXBvbmVudHMgYW5kIHRvIGNoZWNrIGNvbnN0cmFpbnRzLgoqLwpzdGF0aWMgeG1sU2NoZW1hUmVkZWZQdHIKeG1sU2NoZW1hQWRkUmVkZWYoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwJCSAgCgkJICB4bWxTY2hlbWFCdWNrZXRQdHIgdGFyZ2V0QnVja2V0LAoJCSAgdm9pZCAqaXRlbSwKCQkgIGNvbnN0IHhtbENoYXIgKnJlZk5hbWUsCgkJICBjb25zdCB4bWxDaGFyICpyZWZUYXJnZXROcykKewogICAgeG1sU2NoZW1hUmVkZWZQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFSZWRlZlB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUmVkZWYpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCSAgICAiYWxsb2NhdGluZyByZWRlZmluaXRpb24gaW5mbyIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFSZWRlZikpOwogICAgcmV0LT5pdGVtID0gaXRlbTsKICAgIHJldC0+dGFyZ2V0QnVja2V0ID0gdGFyZ2V0QnVja2V0OwogICAgcmV0LT5yZWZOYW1lID0gcmVmTmFtZTsKICAgIHJldC0+cmVmVGFyZ2V0TnMgPSByZWZUYXJnZXROczsKICAgIGlmIChXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5yZWRlZnMgPT0gTlVMTCkKCVdYU19DT05TVFJVQ1RPUihwY3R4dCktPnJlZGVmcyA9IHJldDsKICAgIGVsc2UKCVdYU19DT05TVFJVQ1RPUihwY3R4dCktPmxhc3RSZWRlZi0+bmV4dCA9IHJldDsKICAgIFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmxhc3RSZWRlZiA9IHJldDsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cERlZmluaXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuc05hbWU6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZQogKiBAbm9kZTogdGhlIGNvcnJlc3BvbmRpbmcgbm9kZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIEdyb3VwIGRlZmluaXRpb24uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cERlZmluaXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICBjb25zdCB4bWxDaGFyICpuYW1lLAoJCQkgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKQogICAgICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIGdyb3VwIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA7CiAgICByZXQtPm5hbWUgPSBuYW1lOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuc05hbWU7CiAgICByZXQtPm5vZGUgPSBub2RlOyAgIAoKICAgIC8qIFRPRE86IFJlbW92ZSB0aGUgZmxhZy4gKi8KICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTDsKICAgIGlmIChwY3R4dC0+aXNSZWRlZmluZSkgewoJcGN0eHQtPnJlZGVmID0geG1sU2NoZW1hQWRkUmVkZWYocGN0eHQsIHBjdHh0LT5yZWRlZmluZWQsCgkgICAgcmV0LCBuYW1lLCBuc05hbWUpOwoJaWYgKHBjdHh0LT5yZWRlZiA9PSBOVUxMKSB7CgkgICAgeG1sRnJlZShyZXQpOwoJICAgIHJldHVybihOVUxMKTsKCX0JICAgIAoJcGN0eHQtPnJlZGVmQ291bnRlciA9IDA7CiAgICB9CiAgICBXWFNfQUREX0dMT0JBTChwY3R4dCwgcmV0KTsKICAgIFdYU19BRERfUEVORElORyhwY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgdHlwZSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgRWxlbWVudCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUFkZEVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbnNOYW1lLAoJCSAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgZWxlbWVudCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ7CiAgICByZXQtPm5hbWUgPSBuYW1lOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuc05hbWU7CiAgICByZXQtPm5vZGUgPSBub2RlOwoKICAgIGlmICh0b3BMZXZlbCkKCVdYU19BRERfR0xPQkFMKGN0eHQsIHJldCk7CiAgICBlbHNlCglXWFNfQUREX0xPQ0FMKGN0eHQsIHJldCk7CiAgICBXWFNfQUREX1BFTkRJTkcoY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIGl0ZW0KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFBZGRUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSwKCQkgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgdHlwZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT50eXBlID0gdHlwZTsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5zTmFtZTsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICBpZiAodG9wTGV2ZWwpIHsKCWlmIChjdHh0LT5pc1JlZGVmaW5lKSB7CgkgICAgY3R4dC0+cmVkZWYgPSB4bWxTY2hlbWFBZGRSZWRlZihjdHh0LCBjdHh0LT5yZWRlZmluZWQsCgkJcmV0LCBuYW1lLCBuc05hbWUpOwoJICAgIGlmIChjdHh0LT5yZWRlZiA9PSBOVUxMKSB7CgkJeG1sRnJlZShyZXQpOwoJCXJldHVybihOVUxMKTsKCSAgICB9CSAgICAKCSAgICBjdHh0LT5yZWRlZkNvdW50ZXIgPSAwOwoJfQoJV1hTX0FERF9HTE9CQUwoY3R4dCwgcmV0KTsKICAgIH0gZWxzZQoJV1hTX0FERF9MT0NBTChjdHh0LCByZXQpOwogICAgV1hTX0FERF9QRU5ESU5HKGN0eHQsIHJldCk7ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hTmV3UU5hbWVSZWYoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJICAgICBjb25zdCB4bWxDaGFyICpyZWZOYW1lLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqcmVmTnMpCnsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVFOYW1lUmVmKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkocGN0eHQsCgkgICAgImFsbG9jYXRpbmcgUU5hbWUgcmVmZXJlbmNlIGl0ZW0iLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPm5vZGUgPSBOVUxMOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjsKICAgIHJldC0+bmFtZSA9IHJlZk5hbWU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHJlZk5zOwogICAgcmV0LT5pdGVtID0gTlVMTDsKICAgIHJldC0+aXRlbVR5cGUgPSByZWZUeXBlOwogICAgLyoKICAgICogU3RvcmUgdGhlIHJlZmVyZW5jZSBpdGVtIGluIHRoZSBzY2hlbWEuCiAgICAqLwogICAgV1hTX0FERF9MT0NBTChwY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGVVc2VQcm9oaWIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWIpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCSAgICAiYWxsb2NhdGluZyBhdHRyaWJ1dGUgdXNlIHByb2hpYml0aW9uIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYikpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUI7CiAgICBXWFNfQUREX0xPQ0FMKHBjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUFkZE1vZGVsR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQHR5cGU6IHRoZSAiY29tcG9zaXRvciIgdHlwZSBvZiB0aGUgbW9kZWwgZ3JvdXAKICogQG5vZGU6IHRoZSBub2RlIGluIHRoZSBzY2hlbWEgZG9jCiAqCiAqIEFkZHMgYSBzY2hlbWEgbW9kZWwgZ3JvdXAKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cFB0cgp4bWxTY2hlbWFBZGRNb2RlbEdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSwKCQkgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTW9kZWxHcm91cCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIG1vZGVsIGdyb3VwIGNvbXBvbmVudCIsCgkgICAgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYU1vZGVsR3JvdXApKTsKICAgIHJldC0+dHlwZSA9IHR5cGU7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgV1hTX0FERF9MT0NBTChjdHh0LCByZXQpOwogICAgaWYgKCh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkgfHwKCSh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpKQoJV1hTX0FERF9QRU5ESU5HKGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hQWRkUGFydGljbGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6IHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgaW4gdGhlIHNjaGVtYSBkb2MKICogQG1pbjogdGhlIG1pbk9jY3VycwogKiBAbWF4OiB0aGUgbWF4T2NjdXJzCiAqCiAqIEFkZHMgYW4gWE1MIHNjaGVtYSBwYXJ0aWNsZSBjb21wb25lbnQuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnRpY2xlUHRyCnhtbFNjaGVtYUFkZFBhcnRpY2xlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IG1pbiwgaW50IG1heCkKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcmV0ID0gTlVMTDsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgcGFydGljbGUgY29tcG9uZW50XG4iKTsKI2VuZGlmCiAgICByZXQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnRpY2xlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgcGFydGljbGUgY29tcG9uZW50IiwKCSAgICBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU7CiAgICByZXQtPmFubm90ID0gTlVMTDsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPm1pbk9jY3VycyA9IG1pbjsKICAgIHJldC0+bWF4T2NjdXJzID0gbWF4OwogICAgcmV0LT5uZXh0ID0gTlVMTDsKICAgIHJldC0+Y2hpbGRyZW4gPSBOVUxMOwoKICAgIFdYU19BRERfTE9DQUwoY3R4dCwgcmV0KTsKICAgIC8qIAogICAgKiBOb3RlIHRoYXQgYWRkaXRpb24gdG8gcGVuZGluZyBjb21wb25lbnRzIHdpbGwgYmUgZG9uZSBsb2NhbGx5CiAgICAqIHRvIHRoZSBzcGVjaWZpYyBwYXJzaW5nIGZ1bmN0aW9uLCBzaW5jZSB0aGUgbW9zdCBwYXJ0aWNsZXMKICAgICogbmVlZCBub3QgdG8gYmUgZml4ZWQgdXAgKGkuZS4gdGhlIHJlZmVyZW5jZSB0byBiZSByZXNvbHZlZCkuCiAgICAqIFJFTU9WRUQ6IFdYU19BRERfUEVORElORyhjdHh0LCByZXQpOwogICAgKi8KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE1vZGVsR3JvdXBEZWZpbml0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBncm91cCBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIKeG1sU2NoZW1hQWRkTW9kZWxHcm91cERlZmluaXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgY29uc3QgeG1sQ2hhciAqbmFtZSwKCQkJCSBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCQkgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTW9kZWxHcm91cERlZikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmKSk7CiAgICByZXQtPm5hbWUgPSBuYW1lOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0dST1VQOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbnNOYW1lOwoKICAgIGlmIChjdHh0LT5pc1JlZGVmaW5lKSB7CgljdHh0LT5yZWRlZiA9IHhtbFNjaGVtYUFkZFJlZGVmKGN0eHQsIGN0eHQtPnJlZGVmaW5lZCwKCSAgICByZXQsIG5hbWUsIG5zTmFtZSk7CglpZiAoY3R4dC0+cmVkZWYgPT0gTlVMTCkgewoJICAgIHhtbEZyZWUocmV0KTsKCSAgICByZXR1cm4oTlVMTCk7Cgl9CSAgICAKCWN0eHQtPnJlZGVmQ291bnRlciA9IDA7CiAgICB9CiAgICBXWFNfQUREX0dMT0JBTChjdHh0LCByZXQpOwogICAgV1hTX0FERF9QRU5ESU5HKGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmROc1B0cgp4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZE5zKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImNyZWF0aW5nIHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50IiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT52YWx1ZSA9IE5VTEw7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hSURDUHRyCnhtbFNjaGVtYUFkZElEQyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkgIGludCBjYXRlZ29yeSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFJRENQdHIgcmV0ID0gTlVMTDsgICAgCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hSURDUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LAoJICAgICJhbGxvY2F0aW5nIGFuIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hSURDKSk7CiAgICAvKiBUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgcGFyZW50IGVsZW1lbnQgZGVjbGFyYXRpb24uICovCiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5zTmFtZTsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnR5cGUgPSBjYXRlZ29yeTsKICAgIHJldC0+bm9kZSA9IG5vZGU7ICAgICAgICAKICAgIAogICAgV1hTX0FERF9HTE9CQUwoY3R4dCwgcmV0KTsKICAgIC8qCiAgICAqIE9ubHkga2V5cmVmcyBuZWVkIHRvIGJlIGZpeHVwIHVwLgogICAgKi8KICAgIGlmIChjYXRlZ29yeSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikKCVdYU19BRERfUEVORElORyhjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkV2lsZGNhcmQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6IGEgc2NoZW1hCiAqCiAqIEFkZHMgYSB3aWxkY2FyZC4KICogSXQgY29ycmVzcG9uZHMgdG8gYSB4c2Q6YW55QXR0cmlidXRlIGFuZCB4c2Q6YW55LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hQWRkV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSAgICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgd2lsZGNhcmQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5ub2RlID0gbm9kZTsgICAgCiAgICBXWFNfQUREX0xPQ0FMKGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVN1YnN0R3JvdXBGcmVlKHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIgZ3JvdXApCnsKICAgIGlmIChncm91cCA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGdyb3VwLT5tZW1iZXJzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoZ3JvdXAtPm1lbWJlcnMpOwogICAgeG1sRnJlZShncm91cCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFTdWJzdEdyb3VwUHRyCnhtbFNjaGVtYVN1YnN0R3JvdXBBZGQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkKQp7CiAgICB4bWxTY2hlbWFTdWJzdEdyb3VwUHRyIHJldDsKCiAgICAvKiBJbml0IHN1YnN0IGdyb3VwIGhhc2guICovCiAgICBpZiAoV1hTX1NVQlNUX0dST1VQUyhwY3R4dCkgPT0gTlVMTCkgewoJV1hTX1NVQlNUX0dST1VQUyhwY3R4dCkgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgcGN0eHQtPmRpY3QpOwoJaWYgKFdYU19TVUJTVF9HUk9VUFMocGN0eHQpID09IE5VTEwpCgkgICAgcmV0dXJuKE5VTEwpOwogICAgfQogICAgLyogQ3JlYXRlIGEgbmV3IHN1YnN0aXR1dGlvbiBncm91cC4gKi8KICAgIHJldCA9ICh4bWxTY2hlbWFTdWJzdEdyb3VwUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVN1YnN0R3JvdXApKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJICAgICJhbGxvY2F0aW5nIGEgc3Vic3RpdHV0aW9uIGdyb3VwIGNvbnRhaW5lciIsIE5VTEwpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVN1YnN0R3JvdXApKTsKICAgIHJldC0+aGVhZCA9IGhlYWQ7CiAgICAvKiBDcmVhdGUgbGlzdCBvZiBtZW1iZXJzLiAqLwogICAgcmV0LT5tZW1iZXJzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIGlmIChyZXQtPm1lbWJlcnMgPT0gTlVMTCkgewoJeG1sU2NoZW1hU3Vic3RHcm91cEZyZWUocmV0KTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIC8qIEFkZCBzdWJzdCBncm91cCB0byBoYXNoLiAqLwogICAgaWYgKHhtbEhhc2hBZGRFbnRyeTIoV1hTX1NVQlNUX0dST1VQUyhwY3R4dCksCgloZWFkLT5uYW1lLCBoZWFkLT50YXJnZXROYW1lc3BhY2UsIHJldCkgIT0gMCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hU3Vic3RHcm91cEFkZCIsCgkgICAgImZhaWxlZCB0byBhZGQgYSBuZXcgc3Vic3RpdHV0aW9uIGNvbnRhaW5lciIpOwoJeG1sU2NoZW1hU3Vic3RHcm91cEZyZWUocmV0KTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIHJldHVybihyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hU3Vic3RHcm91cFB0cgp4bWxTY2hlbWFTdWJzdEdyb3VwR2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZCkKeyAgIAogICAgaWYgKFdYU19TVUJTVF9HUk9VUFMocGN0eHQpID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXR1cm4oeG1sSGFzaExvb2t1cDIoV1hTX1NVQlNUX0dST1VQUyhwY3R4dCksCgloZWFkLT5uYW1lLCBoZWFkLT50YXJnZXROYW1lc3BhY2UpKTsKCn0KCi8qKgogKiB4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uTWVtYmVyOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAaGVhZDogIHRoZSBoZWFkIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKICogQG1lbWJlcjogdGhlIG5ldyBtZW1iZXIgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkRWxlbWVudFN1YnN0aXR1dGlvbk1lbWJlcih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkLAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBtZW1iZXIpCnsKICAgIHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIgc3Vic3RHcm91cCA9IE5VTEw7CgogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAoaGVhZCA9PSBOVUxMKSB8fCAobWVtYmVyID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CgogICAgc3Vic3RHcm91cCA9IHhtbFNjaGVtYVN1YnN0R3JvdXBHZXQocGN0eHQsIGhlYWQpOwogICAgaWYgKHN1YnN0R3JvdXAgPT0gTlVMTCkKCXN1YnN0R3JvdXAgPSB4bWxTY2hlbWFTdWJzdEdyb3VwQWRkKHBjdHh0LCBoZWFkKTsKICAgIGlmIChzdWJzdEdyb3VwID09IE5VTEwpCglyZXR1cm4oLTEpOwogICAgaWYgKHhtbFNjaGVtYUl0ZW1MaXN0QWRkKHN1YnN0R3JvdXAtPm1lbWJlcnMsIG1lbWJlcikgPT0gLTEpCglyZXR1cm4oLTEpOwogICAgcmV0dXJuKDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVV0aWxpdGllcyBmb3IgcGFyc2luZwkJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBwYXJlbnQgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEB2YWx1ZTogIHRoZSBRTmFtZSB2YWx1ZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyB0aGUgbG9jYWwgbmFtZSBhbmQgdGhlIFVSSSBvZiBhIFFOYW1lIHZhbHVlIGFuZCB2YWxpZGF0ZXMgaXQuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb24gYXR0cmlidXRlIHZhbHVlcyB0aGF0CiAqIHNob3VsZCByZXNvbHZlIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJCSAgICAgICB4bWxBdHRyUHRyIGF0dHIsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnByZWY7CiAgICB4bWxOc1B0ciBuczsKICAgIGludCBsZW4sIHJldDsKCiAgICAqdXJpID0gTlVMTDsKICAgICpsb2NhbCA9IE5VTEw7CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPiAwKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkgICAgTlVMTCwgdmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJKmxvY2FsID0gdmFsdWU7CglyZXR1cm4gKGN0eHQtPmVycik7CiAgICB9IGVsc2UgaWYgKHJldCA8IDApCglyZXR1cm4gKC0xKTsKCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWx1ZSwgJzonKSkgewoJbnMgPSB4bWxTZWFyY2hOcyhhdHRyLT5kb2MsIGF0dHItPnBhcmVudCwgTlVMTCk7CglpZiAobnMpCgkgICAgKnVyaSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKCWVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUykgewoJICAgIC8qIFRPRE86IG1vdmUgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMgdG8gdGhlCgkgICAgKiBwYXJzZXIgY29udGV4dC4gKi8KCSAgICAvKgoJICAgICogVGhpcyBvbmUgdGFrZXMgY2FyZSBvZiBpbmNsdWRlZCBzY2hlbWFzIHdpdGggbm8KCSAgICAqIHRhcmdldCBuYW1lc3BhY2UuCgkgICAgKi8KCSAgICAqdXJpID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJfQoJKmxvY2FsID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWx1ZSwgLTEpOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIEF0IHRoaXMgcG9pbnQgeG1sU3BsaXRRTmFtZTMgaGFzIHRvIHJldHVybiBhIGxvY2FsIG5hbWUuCiAgICAqLwogICAgKmxvY2FsID0geG1sU3BsaXRRTmFtZTModmFsdWUsICZsZW4pOwogICAgKmxvY2FsID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCAqbG9jYWwsIC0xKTsKICAgIHByZWYgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbHVlLCBsZW4pOwogICAgbnMgPSB4bWxTZWFyY2hOcyhhdHRyLT5kb2MsIGF0dHItPnBhcmVudCwgcHJlZik7CiAgICBpZiAobnMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCBOVUxMLCB2YWx1ZSwKCSAgICAiVGhlIHZhbHVlICclcycgb2Ygc2ltcGxlIHR5cGUgJ3hzOlFOYW1lJyBoYXMgbm8gIgoJICAgICJjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiBzY29wZSIsIHZhbHVlLCBOVUxMKTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKnVyaSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyIGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgbm9kZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIHRoZSBRTmFtZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb24gYXR0cmlidXRlIHZhbHVlcyB0aGF0CiAqIHNob3VsZCByZXNvbHZlIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKCiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZShjdHh0LCBzY2hlbWEsCglvd25lckl0ZW0sIGF0dHIsIHZhbHVlLCB1cmksIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0clFOYW1lOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIFFOYW1lIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0clFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQkJICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCQkgICBjb25zdCBjaGFyICpuYW1lLAoJCQkJICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKipsb2NhbCkKewogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJKmxvY2FsID0gTlVMTDsKCSp1cmkgPSBOVUxMOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJb3duZXJJdGVtLCBhdHRyLCB1cmksIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0cklEOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIElEIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBJRCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVJRCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbEF0dHJQdHIgYXR0cikKewogICAgaW50IHJldDsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIGlmIChhdHRyID09IE5VTEwpCglyZXR1cm4oMCk7CiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50Tm9EaWN0KCh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIHJldCA9IHhtbFZhbGlkYXRlTkNOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gMCkgewoJLyoKCSogTk9URTogdGhlIElEbmVzcyBtaWdodCBoYXZlIGFscmVhZHkgYmUgZGVjbGFyZWQgaW4gdGhlIERURAoJKi8KCWlmIChhdHRyLT5hdHlwZSAhPSBYTUxfQVRUUklCVVRFX0lEKSB7CgkgICAgeG1sSURQdHIgcmVzOwoJICAgIHhtbENoYXIgKnN0cmlwOwoKCSAgICAvKgoJICAgICogVE9ETzogVXNlIHhtbFNjaGVtYVN0cmlwIGhlcmU7IGl0J3Mgbm90IGV4cG9ydGVkIGF0IHRoaXMKCSAgICAqIG1vbWVudC4KCSAgICAqLwoJICAgIHN0cmlwID0geG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcodmFsdWUpOwoJICAgIGlmIChzdHJpcCAhPSBOVUxMKSB7CgkJeG1sRnJlZSgoeG1sQ2hhciAqKSB2YWx1ZSk7CgkJdmFsdWUgPSBzdHJpcDsKCSAgICB9CiAgICAJICAgIHJlcyA9IHhtbEFkZElEKE5VTEwsIGF0dHItPmRvYywgdmFsdWUsIGF0dHIpOwoJICAgIGlmIChyZXMgPT0gTlVMTCkgewoJCXJldCA9IFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUU7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0lEKSwKCQkgICAgTlVMTCwgTlVMTCwgIkR1cGxpY2F0ZSB2YWx1ZSAnJXMnIG9mIHNpbXBsZSAiCgkJICAgICJ0eXBlICd4czpJRCciLCB2YWx1ZSwgTlVMTCk7CgkgICAgfSBlbHNlCgkJYXR0ci0+YXR5cGUgPSBYTUxfQVRUUklCVVRFX0lEOwoJfQogICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CglyZXQgPSBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFOwoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0lEKSwKCSAgICBOVUxMLCBOVUxMLCAiVGhlIHZhbHVlICclcycgb2Ygc2ltcGxlIHR5cGUgJ3hzOklEJyBpcyAiCgkgICAgIm5vdCBhIHZhbGlkICd4czpOQ05hbWUnIiwKCSAgICB2YWx1ZSwgTlVMTCk7CiAgICB9CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUoKHhtbENoYXIgKil2YWx1ZSk7CgogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRySUQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkgICAgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIChjb25zdCBjaGFyICopIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybigwKTsKICAgIHJldHVybih4bWxTY2hlbWFQVmFsQXR0ck5vZGVJRChjdHh0LCBhdHRyKSk7Cgp9CgovKioKICogeG1sR2V0TWF4T2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWF4T2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWF4T2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAoJCWludCBtaW4sIGludCBtYXgsIGludCBkZWYsIGNvbnN0IGNoYXIgKmV4cGVjdGVkKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1heE9jY3VycyIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoZGVmKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCiAgICBpZiAoeG1sU3RyRXF1YWwodmFsLCAoY29uc3QgeG1sQ2hhciAqKSAidW5ib3VuZGVkIikpIHsKCWlmIChtYXggIT0gVU5CT1VOREVEKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCS8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCQl2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoZGVmKTsKCX0gZWxzZQoJICAgIHJldHVybiAoVU5CT1VOREVEKTsgIC8qIGVuY29kaW5nIGl0IHdpdGggLTEgbWlnaHQgYmUgYW5vdGhlciBvcHRpb24gKi8KICAgIH0KCiAgICBjdXIgPSB2YWw7CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICBpZiAoKmN1ciA9PSAwKSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbEdldE1pbk9jY3VyczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBHZXQgdGhlIG1pbk9jY3VycyBwcm9wZXJ0eQogKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGlmIG5vdCBmb3VuZCwgb3IgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50CnhtbEdldE1pbk9jY3Vycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKCQlpbnQgbWluLCBpbnQgbWF4LCBpbnQgZGVmLCBjb25zdCBjaGFyICpleHBlY3RlZCkKewogICAgY29uc3QgeG1sQ2hhciAqdmFsLCAqY3VyOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtaW5PY2N1cnMiKTsKICAgIGlmIChhdHRyID09IE5VTEwpCglyZXR1cm4gKGRlZik7CiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CiAgICBjdXIgPSB2YWw7CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICBpZiAoKmN1ciA9PSAwKSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHdoaWxlICgoKmN1ciA+PSAnMCcpICYmICgqY3VyIDw9ICc5JykpIHsKICAgICAgICByZXQgPSByZXQgKiAxMCArICgqY3VyIC0gJzAnKTsKICAgICAgICBjdXIrKzsKICAgIH0KICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIC8qCiAgICAqIFRPRE86IFJlc3RyaWN0IHRoZSBtYXhpbWFsIHZhbHVlIHRvIEludGVnZXIuCiAgICAqLwogICAgaWYgKCgqY3VyICE9IDApIHx8IChyZXQgPCBtaW4pIHx8ICgobWF4ICE9IC0xKSAmJiAocmV0ID4gbWF4KSkpIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICAvKiBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywgKi8KCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgZXhwZWN0ZWQsCgkgICAgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGRlZik7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG93bmVyRGVzOiAgb3duZXIgZGVzaWduYXRpb24KICogQG93bmVySXRlbTogIHRoZSBvd25lciBhcyBhIHNjaGVtYSBpdGVtCiAqIEBub2RlOiB0aGUgbm9kZSBob2xkaW5nIHRoZSB2YWx1ZQogKgogKiBDb252ZXJ0cyBhIGJvb2xlYW4gc3RyaW5nIHZhbHVlIGludG8gMSBvciAwLgogKgogKiBSZXR1cm5zIDAgb3IgMS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbHVlID0gTlVMTDsKICAgIGludCByZXMgPSAwOwoKICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CiAgICAvKgogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63CiAgICAqIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgbGVnYWwgbGl0ZXJhbHMge3RydWUsIGZhbHNlLCAxLCAwfS4KICAgICovCiAgICBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICJ0cnVlIikpCiAgICAgICAgcmVzID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICByZXMgPSAwOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICIxIikpCglyZXMgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICIwIikpCiAgICAgICAgcmVzID0gMDsKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9CT09MRUFOLAoJICAgIG93bmVySXRlbSwgbm9kZSwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwKCSAgICBOVUxMLCBCQURfQ0FTVCB2YWx1ZSwKCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJeG1sRnJlZSh2YWx1ZSk7CiAgICByZXR1cm4gKHJlcyk7Cn0KCi8qKgogKiB4bWxHZXRCb29sZWFuUHJvcDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKiBAZGVmOiAgdGhlIGRlZmF1bHQgdmFsdWUKICoKICogRXZhbHVhdGUgaWYgYSBib29sZWFuIHByb3BlcnR5IGlzIHNldAogKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGlmIG5vdCBmb3VuZCwgMCBpZiBmb3VuZCB0byBiZSBmYWxzZSwKICogMSBpZiBmb3VuZCB0byBiZSB0cnVlCiAqLwpzdGF0aWMgaW50CnhtbEdldEJvb2xlYW5Qcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSwgaW50IGRlZikKewogICAgY29uc3QgeG1sQ2hhciAqdmFsOwoKICAgIHZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgbmFtZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgLyoKICAgICogMy4yLjIuMSBMZXhpY2FsIHJlcHJlc2VudGF0aW9uCiAgICAqIEFuIGluc3RhbmNlIG9mIGEgZGF0YXR5cGUgdGhhdCBpcyBkZWZpbmVkIGFzILdib29sZWFutwogICAgKiBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGxlZ2FsIGxpdGVyYWxzIHt0cnVlLCBmYWxzZSwgMSwgMH0uCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMSIpKQoJZGVmID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgIjAiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0JPT0xFQU4sCgkgICAgTlVMTCwKCSAgICAoeG1sTm9kZVB0cikgeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgbmFtZSksCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQk9PTEVBTiksCgkgICAgTlVMTCwgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoZGVmKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqCQlTaGVtYSBleHRyYWN0aW9uIGZyb20gYW4gSW5mb3NldAkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCQkJIGludCB0b3BMZXZlbCk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCQkJICB4bWxTY2hlbWFUeXBlVHlwZSBwYXJlbnRUeXBlKTsKc3RhdGljIHhtbFNjaGVtYUJhc2ljSXRlbVB0cgp4bWxTY2hlbWFQYXJzZUxvY2FsQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgdXNlcywKCQkJICAgICBpbnQgcGFyZW50VHlwZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKTsKCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZToKICoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3Qgb3duZXIgaWYgZXhpc3RlbnQKICogQGF0dHI6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBub2RlIGJlaW5nIHZhbGlkYXRlZAogKiBAdmFsdWU6IHRoZSB2YWx1ZQogKiBAdHlwZTogdGhlIGJ1aWx0LWluIHR5cGUgdG8gYmUgdmFsaWRhdGVkIGFnYWluc3QKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJICAgeG1sQXR0clB0ciBhdHRyLAoJCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CgogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICogTk9URTogU2hvdWxkIHdlIG1vdmUgdGhpcyB0byB4bWxzY2hlbWF0eXBlcy5jPyBIbW0sIGJ1dCB0aGlzCiAgICAqIG9uZSBpcyByZWFsbHkgbWVhbnQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5LCBzbyBiZXR0ZXIgbm90LgogICAgKi8KICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkgfHwgKGF0dHIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUiLAoJICAgICJ0aGUgZ2l2ZW4gdHlwZSBpcyBub3QgYSBidWlsdC1pbiB0eXBlIik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHN3aXRjaCAodHlwZS0+YnVpbHRJblR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQVNfTkNOQU1FOgoJY2FzZSBYTUxfU0NIRU1BU19RTkFNRToKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZVVJJOgoJY2FzZSBYTUxfU0NIRU1BU19UT0tFTjoKCWNhc2UgWE1MX1NDSEVNQVNfTEFOR1VBR0U6CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGUodHlwZSwgdmFsdWUsIE5VTEwsCgkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDogewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlIiwKCQkidmFsaWRhdGlvbiB1c2luZyB0aGUgZ2l2ZW4gdHlwZSBpcyBub3Qgc3VwcG9ydGVkIHdoaWxlICIKCQkicGFyc2luZyBhIHNjaGVtYSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgLyoKICAgICogVE9ETzogU2hvdWxkIHdlIHVzZSB0aGUgUzRTIGVycm9yIGNvZGVzIGluc3RlYWQ/CiAgICAqLwogICAgaWYgKHJldCA8IDApIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlIiwKCSAgICAiZmFpbGVkIHRvIHZhbGlkYXRlIGEgc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZSIpOwoJcmV0dXJuICgtMSk7CiAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCWlmIChXWFNfSVNfTElTVCh0eXBlKSkKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgllbHNlCgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsIAoJICAgIHJldCwgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB0eXBlLCBOVUxMLCB2YWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGU6CiAqCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZSBiZWluZyB2YWxpZGF0ZWQKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqIEB2YWx1ZTogdGhlIHJlc3VsdGluZyB2YWx1ZSBpZiBhbnkKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCSAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICBjb25zdCB4bWxDaGFyICoqdmFsdWUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkgfHwgKGF0dHIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCSp2YWx1ZSA9IHZhbDsKCiAgICByZXR1cm4gKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIG93bmVySXRlbSwgYXR0ciwKCXZhbCwgdHlwZSkpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHI6CiAqCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3Qgb3duZXIgaWYgZXhpc3RlbnQKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqIEB2YWx1ZTogdGhlIHJlc3VsdGluZyB2YWx1ZSBpZiBhbnkKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwJCSAgICAgICAKCQkgICAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkgICAgICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlKQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICAqdmFsdWUgPSBOVUxMOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBWYWxBdHRyLCB0aGUgZ2l2ZW4gIgoJICAgICJ0eXBlICclcycgaXMgbm90IGEgYnVpbHQtaW4gdHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgKnZhbHVlID0gTlVMTDsKCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBvd25lckl0ZW0sIGF0dHIsCgl0eXBlLCB2YWx1ZSkpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJICB4bWxTY2hlbWFQdHIgc2NoZW1hIEFUVFJJQlVURV9VTlVTRUQsCgkJICB4bWxOb2RlUHRyIG5vZGUsCgkJICB4bWxBdHRyUHRyIGF0dHIsCgkJICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2VOYW1lKQp7CiAgICAvKiBUT0RPOiBQb2ludGVyIGNvbXBhcmlzb24gaW5zdGVhZD8gKi8KICAgIGlmICh4bWxTdHJFcXVhbChwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBuYW1lc3BhY2VOYW1lKSkKCXJldHVybiAoMCk7CiAgICBpZiAoeG1sU3RyRXF1YWwoeG1sU2NoZW1hTnMsIG5hbWVzcGFjZU5hbWUpKQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIENoZWNrIGlmIHRoZSByZWZlcmVuY2VkIG5hbWVzcGFjZSB3YXMgPGltcG9ydD5lZC4KICAgICovCiAgICBpZiAoV1hTX0JVQ0tFVChwY3R4dCktPnJlbGF0aW9ucyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWw7CgoJcmVsID0gV1hTX0JVQ0tFVChwY3R4dCktPnJlbGF0aW9uczsKCWRvIHsKCSAgICBpZiAoV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHJlbC0+dHlwZSkgJiYKCQl4bWxTdHJFcXVhbChuYW1lc3BhY2VOYW1lLCByZWwtPmltcG9ydE5hbWVzcGFjZSkpCgkJcmV0dXJuICgwKTsKCSAgICByZWwgPSByZWwtPm5leHQ7Cgl9IHdoaWxlIChyZWwgIT0gTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBObyBtYXRjaGluZyA8aW1wb3J0PmVkIG5hbWVzcGFjZSBmb3VuZC4KICAgICovCiAgICB7Cgl4bWxOb2RlUHRyIG4gPSAoYXR0ciAhPSBOVUxMKSA/ICh4bWxOb2RlUHRyKSBhdHRyIDogbm9kZTsKCglpZiAobmFtZXNwYWNlTmFtZSA9PSBOVUxMKQoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCBuLCBOVUxMLAoJCSJSZWZlcmVuY2VzIGZyb20gdGhpcyBzY2hlbWEgdG8gY29tcG9uZW50cyBpbiBubyAiCgkJIm5hbWVzcGFjZSBhcmUgbm90IGFsbG93ZWQsIHNpbmNlIG5vdCBpbmRpY2F0ZWQgYnkgYW4gIgoJCSJpbXBvcnQgc3RhdGVtZW50IiwgTlVMTCwgTlVMTCk7CgllbHNlCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIG4sIE5VTEwsCgkJIlJlZmVyZW5jZXMgZnJvbSB0aGlzIHNjaGVtYSB0byBjb21wb25lbnRzIGluIHRoZSAiCgkJIm5hbWVzcGFjZSAnJXMnIGFyZSBub3QgYWxsb3dlZCwgc2luY2Ugbm90IGluZGljYXRlZCBieSBhbiAiCgkJImltcG9ydCBzdGF0ZW1lbnQiLCBuYW1lc3BhY2VOYW1lLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMb2NhbEF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHR5cGU6ICB0aGUgaG9zdGluZyB0eXBlIHdoZXJlIHRoZSBhdHRyaWJ1dGVzIHdpbGwgYmUgYW5jaG9yZWQKICoKICogUGFyc2VzIGF0dHJpYnV0ZSB1c2VzIGFuZCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGFuZAogKiBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcy4gCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGVzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciAqY2hpbGQsIHhtbFNjaGVtYUl0ZW1MaXN0UHRyICpsaXN0LAoJCQlpbnQgcGFyZW50VHlwZSwgaW50ICpoYXNSZWZzKQp7CiAgICB2b2lkICppdGVtOwoKICAgIHdoaWxlICgoSVNfU0NIRU1BKCgqY2hpbGQpLCAiYXR0cmlidXRlIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQSgoKmNoaWxkKSwgImF0dHJpYnV0ZUdyb3VwIikpKSB7CiAgICAgICAgaWYgKElTX1NDSEVNQSgoKmNoaWxkKSwgImF0dHJpYnV0ZSIpKSB7CgkgICAgaXRlbSA9IHhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCAqY2hpbGQsCgkJKmxpc3QsIHBhcmVudFR5cGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGl0ZW0gPSB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwUmVmKGN0eHQsIHNjaGVtYSwgKmNoaWxkKTsKCSAgICBpZiAoKGl0ZW0gIT0gTlVMTCkgJiYgKGhhc1JlZnMgIT0gTlVMTCkpCgkJKmhhc1JlZnMgPSAxOwogICAgICAgIH0KCWlmIChpdGVtICE9IE5VTEwpIHsKCSAgICBpZiAoKmxpc3QgPT0gTlVMTCkgewoJCS8qIFRPRE86IEN1c3RvbWl6ZSBncm93IGZhY3Rvci4gKi8KCQkqbGlzdCA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkJaWYgKCpsaXN0ID09IE5VTEwpCgkJICAgIHJldHVybigtMSk7CgkgICAgfQoJICAgIGlmICh4bWxTY2hlbWFJdGVtTGlzdEFkZFNpemUoKmxpc3QsIDIsIGl0ZW0pID09IC0xKQoJCXJldHVybigtMSk7Cgl9CiAgICAgICAgKmNoaWxkID0gKCpjaGlsZCktPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBuZWVkZWQpCnsKICAgIHhtbFNjaGVtYUFubm90UHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IGJhcmtlZCA9IDA7CgogICAgLyoKICAgICogSU5GTzogUzRTIGNvbXBsZXRlZC4KICAgICovCiAgICAvKgogICAgKiBpZCA9IElECiAgICAqIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KICAgICogQ29udGVudDogKGFwcGluZm8gfCBkb2N1bWVudGF0aW9uKSoKICAgICovCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChuZWVkZWQpCglyZXQgPSB4bWxTY2hlbWFOZXdBbm5vdChjdHh0LCBub2RlKTsKICAgIGVsc2UKCXJldCA9IE5VTEw7CiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmICgoKGF0dHItPm5zID09IE5VTEwpICYmCgkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIHx8CgkgICAgKChhdHRyLT5ucyAhPSBOVUxMKSAmJgoJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKSB7CgoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFwcGluZm8iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJhcHBpbmZvIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJgoJCSAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic291cmNlIikpKSB8fAoJCSAgICAgKChhdHRyLT5ucyAhPSBOVUxMKSAmJgoJCSAgICAgIHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKSB7CgoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCX0KCQlhdHRyID0gYXR0ci0+bmV4dDsKCSAgICB9CgkgICAgeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgY2hpbGQsICJzb3VyY2UiLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImRvY3VtZW50YXRpb24iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJkb2N1bWVudGF0aW9uIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzb3VyY2UiKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpIHx8CgkJCSh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibGFuZyIpICYmCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIFhNTF9YTUxfTkFNRVNQQUNFKSkpKSB7CgoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCQkgICAgfQoJCX0KCQlhdHRyID0gYXR0ci0+bmV4dDsKCSAgICB9CgkgICAgLyoKCSAgICAqIEF0dHJpYnV0ZSAieG1sOmxhbmciLgoJICAgICovCgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlTnMoY2hpbGQsIChjb25zdCBjaGFyICopIFhNTF9YTUxfTkFNRVNQQUNFLCAibGFuZyIpOwoJICAgIGlmIChhdHRyICE9IE5VTEwpCgkJeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIGF0dHIsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTEFOR1VBR0UpLCBOVUxMKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIHsKCSAgICBpZiAoIWJhcmtlZCkKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsICIoYXBwaW5mbyB8IGRvY3VtZW50YXRpb24pKiIpOwoJICAgIGJhcmtlZCA9IDE7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUZhY2V0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBGYWNldCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyB0eXBlIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFGYWNldFB0cgp4bWxTY2hlbWFQYXJzZUZhY2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGZhY2V0ID0geG1sU2NoZW1hTmV3RmFjZXQoKTsKICAgIGlmIChmYWNldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBmYWNldCIsIG5vZGUpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBmYWNldC0+bm9kZSA9IG5vZGU7CiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInZhbHVlIik7CiAgICBpZiAodmFsdWUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9GQUNFVF9OT19WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAiRmFjZXQgJXMgaGFzIG5vIHZhbHVlXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5JbmNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWluRXhjbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtYXhFeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAidG90YWxEaWdpdHMiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJmcmFjdGlvbkRpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgInBhdHRlcm4iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImVudW1lcmF0aW9uIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAid2hpdGVTcGFjZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heExlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5MZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg7CiAgICB9IGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gZmFjZXQgdHlwZSAlc1xuIiwgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGZhY2V0LT52YWx1ZSA9IHZhbHVlOwogICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsKCWNvbnN0IHhtbENoYXIgKmZpeGVkOwoKCWZpeGVkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKCWlmIChmaXhlZCAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGZpeGVkLCBCQURfQ0FTVCAidHJ1ZSIpKQoJCWZhY2V0LT5maXhlZCA9IDE7Cgl9CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwoKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICBmYWNldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgdW5leHBlY3RlZCBjaGlsZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHdpbGRjOiAgdGhlIHdpbGRjYXJkLCBhbHJlYWR5IGNyZWF0ZWQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgdGhlIGF0dHJpYnV0ZSAicHJvY2Vzc0NvbnRlbnRzIiBhbmQgIm5hbWVzcGFjZSIKICogb2YgYSB4c2Q6YW55QXR0cmlidXRlIGFuZCB4c2Q6YW55LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgMCBpZiBldmVyeXRoaW5nIGdvZXMgZmluZSwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIHNvbWV0aGluZyBpcyBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFNjaGVtYVB0ciBzY2hlbWEgQVRUUklCVVRFX1VOVVNFRCwKCQkJIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjLAoJCQkgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpwYywgKm5zLCAqZGljdG5zSXRlbTsKICAgIGludCByZXQgPSAwOwogICAgeG1sQ2hhciAqbnNJdGVtOwogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciB0bXAsIGxhc3ROcyA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgcGMgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJwcm9jZXNzQ29udGVudHMiKTsKICAgIGlmICgocGMgPT0gTlVMTCkKICAgICAgICB8fCAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJzdHJpY3QiKSkpIHsKICAgICAgICB3aWxkYy0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJza2lwIikpIHsKICAgICAgICB3aWxkYy0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX1NLSVA7CiAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKHBjLCAoY29uc3QgeG1sQ2hhciAqKSAibGF4IikpIHsKICAgICAgICB3aWxkYy0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX0xBWDsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgTlVMTCwgIihzdHJpY3QgfCBza2lwIHwgbGF4KSIsIHBjLAoJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOwoJcmV0ID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKICAgIH0KICAgIC8qCiAgICAgKiBCdWlsZCB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzLgogICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWVzcGFjZSIpOwogICAgbnMgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CiAgICBpZiAoKGF0dHIgPT0gTlVMTCkgfHwgKHhtbFN0ckVxdWFsKG5zLCBCQURfQ0FTVCAiIyNhbnkiKSkpCgl3aWxkYy0+YW55ID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKG5zLCBCQURfQ0FTVCAiIyNvdGhlciIpKSB7Cgl3aWxkYy0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICh3aWxkYy0+bmVnTnNTZXQgPT0gTlVMTCkgewoJICAgIHJldHVybiAoLTEpOwoJfQoJd2lsZGMtPm5lZ05zU2V0LT52YWx1ZSA9IGN0eHQtPnRhcmdldE5hbWVzcGFjZTsKICAgIH0gZWxzZSB7Cgljb25zdCB4bWxDaGFyICplbmQsICpjdXI7CgoJY3VyID0gbnM7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBuc0l0ZW0gPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBpZiAoKHhtbFN0ckVxdWFsKG5zSXRlbSwgQkFEX0NBU1QgIiMjb3RoZXIiKSkgfHwKCQkgICAgKHhtbFN0ckVxdWFsKG5zSXRlbSwgQkFEX0NBU1QgIiMjYW55IikpKSB7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfV0lMRENBUkRfSU5WQUxJRF9OU19NRU1CRVIsCgkJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJCSAgICBOVUxMLAoJCSAgICAiKCgjI2FueSB8ICMjb3RoZXIpIHwgTGlzdCBvZiAoeHM6YW55VVJJIHwgIgoJCSAgICAiKCMjdGFyZ2V0TmFtZXNwYWNlIHwgIyNsb2NhbCkpKSIsCgkJICAgIG5zSXRlbSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJcmV0ID0gWE1MX1NDSEVNQVBfV0lMRENBUkRfSU5WQUxJRF9OU19NRU1CRVI7CgkgICAgfSBlbHNlIHsKCQlpZiAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyN0YXJnZXROYW1lc3BhY2UiKSkgewoJCSAgICBkaWN0bnNJdGVtID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNsb2NhbCIpKSB7CgkJICAgIGRpY3Ruc0l0ZW0gPSBOVUxMOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogVmFsaWRhdGUgdGhlIGl0ZW0gKGFueVVSSSkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIE5VTEwsIGF0dHIsCgkJCW5zSXRlbSwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSk7CgkJICAgIGRpY3Ruc0l0ZW0gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zSXRlbSwgLTEpOwoJCX0KCQkvKgoJCSogQXZvaWQgZHVibGljYXRlIG5hbWVzcGFjZXMuCgkJKi8KCQl0bXAgPSB3aWxkYy0+bnNTZXQ7CgkJd2hpbGUgKHRtcCAhPSBOVUxMKSB7CgkJICAgIGlmIChkaWN0bnNJdGVtID09IHRtcC0+dmFsdWUpCgkJCWJyZWFrOwoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJCXhtbEZyZWUobnNJdGVtKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdG1wLT52YWx1ZSA9IGRpY3Ruc0l0ZW07CgkJICAgIHRtcC0+bmV4dCA9IE5VTEw7CgkJICAgIGlmICh3aWxkYy0+bnNTZXQgPT0gTlVMTCkKCQkJd2lsZGMtPm5zU2V0ID0gdG1wOwoJCSAgICBlbHNlCgkJCWxhc3ROcy0+bmV4dCA9IHRtcDsKCQkgICAgbGFzdE5zID0gdG1wOwoJCX0KCgkgICAgfQoJICAgIHhtbEZyZWUobnNJdGVtKTsKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtIEFUVFJJQlVURV9VTlVTRUQsCgkJCQkgeG1sTm9kZVB0ciBub2RlLAoJCQkJIGludCBtaW5PY2N1cnMsCgkJCQkgaW50IG1heE9jY3VycykgewoKICAgIGlmICgobWF4T2NjdXJzID09IDApICYmICggbWluT2NjdXJzID09IDApKQoJcmV0dXJuICgwKTsKICAgIGlmIChtYXhPY2N1cnMgIT0gVU5CT1VOREVEKSB7CgkvKgoJKiBUT0RPOiBNYXliZSB3ZSBzaG91bGQgYmV0dGVyIG5vdCBjcmVhdGUgdGhlIHBhcnRpY2xlLAoJKiBpZiBtaW4vbWF4IGlzIGludmFsaWQsIHNpbmNlIGl0IGNvdWxkIGNvbmZ1c2UgdGhlIGJ1aWxkIG9mIHRoZQoJKiBjb250ZW50IG1vZGVsLgoJKi8KCS8qCgkqIDMuOS42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogUGFydGljbGUgQ29ycmVjdAoJKgoJKi8KCWlmIChtYXhPY2N1cnMgPCAxKSB7CgkgICAgLyoKCSAgICAqIDIuMiB7bWF4IG9jY3Vyc30gbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMiwKCQlOVUxMLCBOVUxMLAoJCXhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtYXhPY2N1cnMiKSwKCQkiVGhlIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEiKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzIpOwoJfSBlbHNlIGlmIChtaW5PY2N1cnMgPiBtYXhPY2N1cnMpIHsKCSAgICAvKgoJICAgICogMi4xIHttaW4gb2NjdXJzfSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4ge21heCBvY2N1cnN9LgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9QX1BST1BTX0NPUlJFQ1RfMl8xLAoJCU5VTEwsIE5VTEwsCgkJeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1pbk9jY3VycyIpLAoJCSJUaGUgdmFsdWUgbXVzdCBub3QgYmUgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiAnbWF4T2NjdXJzJyIpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbnk6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VhIGEgWE1MIHNjaGVtYSA8YW55PiBlbGVtZW50LiBBIHBhcnRpY2xlIGFuZCB3aWxkY2FyZAogKiB3aWxsIGJlIGNyZWF0ZWQgKGV4Y2VwdCBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MCwgaW4gdGhpcyBjYXNlCiAqIG5vdGhpbmcgd2lsbCBiZSBjcmVhdGVkKS4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBwYXJ0aWNsZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3Igb3IgaWYgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJ0aWNsZVB0cgp4bWxTY2hlbWFQYXJzZUFueSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQ7CiAgICBpbnQgbWluLCBtYXg7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJwcm9jZXNzQ29udGVudHMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIG1pbk9jY3Vycy9tYXhPY2N1cnMuCiAgICAqLwogICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwKCSIoeHM6bm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLAoJInhzOm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgTlVMTCwgbm9kZSwgbWluLCBtYXgpOwogICAgLyoKICAgICogQ3JlYXRlICYgcGFyc2UgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIHdpbGQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0LCBzY2hlbWEsIFhNTF9TQ0hFTUFfVFlQRV9BTlksIG5vZGUpOwogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICB4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnMoY3R4dCwgc2NoZW1hLCB3aWxkLCBub2RlKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgLyoKICAgICogTm8gY29tcG9uZW50IGlmIG1pbk9jY3Vycz09bWF4T2NjdXJzPT0wLgogICAgKi8KICAgIGlmICgobWluID09IDApICYmIChtYXggPT0gMCkpIHsKCS8qIERvbid0IGZyZWUgdGhlIHdpbGRjYXJkLCBzaW5jZSBpdCdzIGFscmVhZHkgb24gdGhlIGxpc3QuICovCglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgLyoKICAgICogQ3JlYXRlIHRoZSBwYXJ0aWNsZS4KICAgICovCiAgICBwYXJ0aWNsZSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKGN0eHQsIG5vZGUsIG1pbiwgbWF4KTsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBwYXJ0aWNsZS0+YW5ub3QgPSBhbm5vdDsKICAgIHBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgd2lsZDsKCiAgICByZXR1cm4gKHBhcnRpY2xlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIE5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm90YXRpb25QdHIKeG1sU2NoZW1hUGFyc2VOb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgeG1sU2NoZW1hTm90YXRpb25QdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX05PVEFUSU9OX05PX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIk5vdGF0aW9uIGhhcyBubyBuYW1lXG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hQWRkTm90YXRpb24oY3R4dCwgc2NoZW1hLCBuYW1lLAoJY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKICAgIGlmIChyZXQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/KSIpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBbnlBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyBhIHdpbGRjYXJkIG9yIE5VTEwuCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCwgc2NoZW1hLCBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURSwKCW5vZGUpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJwcm9jZXNzQ29udGVudHMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIFBhcnNlIHRoZSBuYW1lc3BhY2UgbGlzdC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zKGN0eHQsIHNjaGVtYSwgcmV0LCBub2RlKSAhPSAwKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUJhc2ljSXRlbVB0cgp4bWxTY2hlbWFQYXJzZUxvY2FsQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgdXNlcywKCQkJICAgICBpbnQgcGFyZW50VHlwZSkKewogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlLCAqbmFtZSA9IE5VTEwsICpucyA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlID0gTlVMTDsgICAgCiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKnRtcE5zID0gTlVMTCwgKnRtcE5hbWUgPSBOVUxMLCAqZGVmVmFsdWUgPSBOVUxMOwogICAgaW50IGlzUmVmID0gMCwgb2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CiAgICBpbnQJbmJlcnJvcnMsIGhhc0Zvcm0gPSAwLCBkZWZWYWx1ZVR5cGUgPSAwOwoKI2RlZmluZSBXWFNfQVRUUl9ERUZfVkFMX0RFRkFVTFQgMQojZGVmaW5lIFdYU19BVFRSX0RFRl9WQUxfRklYRUQgMgoKICAgIC8qCiAgICAgKiAzLjIuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEF0dHJpYnV0ZSBEZWNsYXJhdGlvbnMKICAgICAqLwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShwY3R4dCwgc2NoZW1hLAoJICAgIE5VTEwsIGF0dHIsICZ0bXBOcywgJnRtcE5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaWYgKHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKHBjdHh0LCBzY2hlbWEsIG5vZGUsIGF0dHIsIHRtcE5zKSAhPSAwKQoJICAgIHJldHVybihOVUxMKTsKCWlzUmVmID0gMTsKICAgIH0KICAgIG5iZXJyb3JzID0gcGN0eHQtPm5iZXJyb3JzOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKGlzUmVmKSB7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZUlEKHBjdHh0LCBhdHRyKTsKCQkgICAgZ290byBhdHRyX25leHQ7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpIHsKCQkgICAgZ290byBhdHRyX25leHQ7CgkJfQoJICAgIH0gZWxzZSB7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpIHsKCQkgICAgZ290byBhdHRyX25leHQ7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVJRChwY3R4dCwgYXR0cik7CgkJICAgIGdvdG8gYXR0cl9uZXh0OwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkgewoJCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShwY3R4dCwgc2NoZW1hLCBOVUxMLAoJCQlhdHRyLCAmdG1wTnMsICZ0bXBOYW1lKTsKCQkgICAgZ290byBhdHRyX25leHQ7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSB7CgkJICAgIC8qCgkJICAgICogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UKCQkgICAgKi8KCQkgICAgaGFzRm9ybSA9IDE7CQkgICAgCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KHBjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CgkJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCQlucyA9IHBjdHh0LT50YXJnZXROYW1lc3BhY2U7CgkJICAgIH0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpCgkJICAgIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJCSAgICBOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsCgkJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCSAgICB9CgkJICAgIGdvdG8gYXR0cl9uZXh0OwoJCX0KCSAgICB9CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ1c2UiKSkgewoKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChwY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCS8qIFRPRE86IE1heWJlIHdlIG5lZWQgdG8gbm9ybWFsaXplIHRoZSB2YWx1ZSBiZWZvcmVoYW5kLiAqLwoJCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJvcHRpb25hbCIpKQoJCSAgICBvY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTDsKCQllbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJwcm9oaWJpdGVkIikpCgkJICAgIG9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQ7CgkJZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicmVxdWlyZWQiKSkKCQkgICAgb2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQ7CgkJZWxzZSB7CgkJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfVVNFLAoJCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkJTlVMTCwgIihvcHRpb25hbCB8IHByb2hpYml0ZWQgfCByZXF1aXJlZCkiLAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0KCQlnb3RvIGF0dHJfbmV4dDsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJkZWZhdWx0IikpIHsKCQkvKgoJCSogMy4yLjMgOiAxCgkJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuCgkJKi8KCQlpZiAoZGVmVmFsdWUpIHsKCQkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzEsCgkJCU5VTEwsIGF0dHIsICJkZWZhdWx0IiwgImZpeGVkIik7CgkJfSBlbHNlIHsKCQkgICAgZGVmVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChwY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBkZWZWYWx1ZVR5cGUgPSBXWFNfQVRUUl9ERUZfVkFMX0RFRkFVTFQ7CgkJfQoJCWdvdG8gYXR0cl9uZXh0OwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpeGVkIikpIHsKCQkvKgoJCSogMy4yLjMgOiAxCgkJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuCgkJKi8KCQlpZiAoZGVmVmFsdWUpIHsKCQkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzEsCgkJCU5VTEwsIGF0dHIsICJkZWZhdWx0IiwgImZpeGVkIik7CgkJfSBlbHNlIHsKCQkgICAgZGVmVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChwY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBkZWZWYWx1ZVR5cGUgPSBXWFNfQVRUUl9ERUZfVkFMX0ZJWEVEOwoJCX0KCQlnb3RvIGF0dHJfbmV4dDsKCSAgICB9Cgl9IGVsc2UgaWYgKCEgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkKCSAgICBnb3RvIGF0dHJfbmV4dDsKCgl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoKYXR0cl9uZXh0OgoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9ICAgICAgICAKICAgIC8qCiAgICAqIDMuMi4zIDogMgogICAgKiBJZiBkZWZhdWx0IGFuZCB1c2UgYXJlIGJvdGggcHJlc2VudCwgdXNlIG11c3QgaGF2ZQogICAgKiB0aGUgYWN0dWFsIHZhbHVlIG9wdGlvbmFsLgogICAgKi8KICAgIGlmICgoZGVmVmFsdWVUeXBlID09IFdYU19BVFRSX0RFRl9WQUxfREVGQVVMVCkgJiYKCShvY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzIsCgkgICAgTlVMTCwgbm9kZSwgTlVMTCwKCSAgICAiKG9wdGlvbmFsIHwgcHJvaGliaXRlZCB8IHJlcXVpcmVkKSIsIE5VTEwsCgkgICAgIlRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICd1c2UnIG11c3QgYmUgJ29wdGlvbmFsJyAiCgkgICAgImlmIHRoZSBhdHRyaWJ1dGUgJ2RlZmF1bHQnIGlzIHByZXNlbnQiLAoJICAgIE5VTEwsIE5VTEwpOwogICAgfQogICAgLyoKICAgICogV2Ugd2FudCBjb3JyZWN0IGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKG5iZXJyb3JzICE9IHBjdHh0LT5uYmVycm9ycykKCXJldHVybihOVUxMKTsKICAgIGlmICghIGlzUmVmKSB7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2w7CgoJLyogVE9ETzogbW92ZSBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUiB0byB0aGUgcGFyc2VyLiAqLwoJaWYgKCghIGhhc0Zvcm0pICYmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpKQoJICAgIG5zID0gcGN0eHQtPnRhcmdldE5hbWVzcGFjZTsJCQoJLyoKCSogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4c2k6IE5vdCBBbGxvd2VkCgkqIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgY29tcG9uZW50IGxheWVyLgoJKi8KCWlmICh4bWxTdHJFcXVhbChucywgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9OT19YU0ksCgkJbm9kZSwgTlVMTCwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgbXVzdCBub3QgbWF0Y2ggJyVzJyIsCgkJeG1sU2NoZW1hSW5zdGFuY2VOcywgTlVMTCk7Cgl9CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwgIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShwY3R4dCwgTlVMTCwgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgkvKgoJKiAzLjIuNiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IHhtbG5zIE5vdCBBbGxvd2VkCgkqIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgY29tcG9uZW50IGxheWVyLgoJKi8KCWlmICh4bWxTdHJFcXVhbChuYW1lLCBCQURfQ0FTVCAieG1sbnMiKSkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX05PX1hNTE5TLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksIE5VTEwsIE5VTEwsCgkJIlRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIG11c3Qgbm90IG1hdGNoICd4bWxucyciLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglpZiAob2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpCgkgICAgZ290byBjaGVja19jaGlsZHJlbjsKCS8qCgkqIENyZWF0ZSB0aGUgYXR0cmlidXRlIHVzZSBjb21wb25lbnQuCgkqLwoJdXNlID0geG1sU2NoZW1hQWRkQXR0cmlidXRlVXNlKHBjdHh0LCBub2RlKTsKCWlmICh1c2UgPT0gTlVMTCkKCSAgICByZXR1cm4oTlVMTCk7Cgl1c2UtPm9jY3VycyA9IG9jY3VyczsKCS8qCgkqIENyZWF0ZSB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8KCWF0dHJEZWNsID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKHBjdHh0LCBzY2hlbWEsIG5hbWUsIG5zLCBub2RlLCAwKTsKCWlmIChhdHRyRGVjbCA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglpZiAodG1wTmFtZSAhPSBOVUxMKSB7CgkgICAgYXR0ckRlY2wtPnR5cGVOYW1lID0gdG1wTmFtZTsKCSAgICBhdHRyRGVjbC0+dHlwZU5zID0gdG1wTnM7Cgl9Cgl1c2UtPmF0dHJEZWNsID0gYXR0ckRlY2w7CgkvKgoJKiBWYWx1ZSBjb25zdHJhaW50LgoJKi8JCglpZiAoZGVmVmFsdWUgIT0gTlVMTCkgewoJICAgIGF0dHJEZWNsLT5kZWZWYWx1ZSA9IGRlZlZhbHVlOwoJICAgIGlmIChkZWZWYWx1ZVR5cGUgPT0gV1hTX0FUVFJfREVGX1ZBTF9GSVhFRCkKCQlhdHRyRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9GSVhFRDsKCX0KICAgIH0gZWxzZSBpZiAob2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCXhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKCgkvKgoJKiBDcmVhdGUgdGhlIGF0dHJpYnV0ZSB1c2UgY29tcG9uZW50LgoJKi8KCXVzZSA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZVVzZShwY3R4dCwgbm9kZSk7CglpZiAodXNlID09IE5VTEwpCgkgICAgcmV0dXJuKE5VTEwpOwoJLyoKCSogV2UgbmVlZCB0byByZXNvbHZlIHRoZSByZWZlcmVuY2UgYXQgbGF0ZXIgc3RhZ2UuCgkqLwoJV1hTX0FERF9QRU5ESU5HKHBjdHh0LCB1c2UpOwoJdXNlLT5vY2N1cnMgPSBvY2N1cnM7CgkvKgoJKiBDcmVhdGUgYSBRTmFtZSByZWZlcmVuY2UgdG8gdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KCSovCglyZWYgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihwY3R4dCwgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSwKCSAgICB0bXBOYW1lLCB0bXBOcyk7CglpZiAocmVmID09IE5VTEwpCgkgICAgcmV0dXJuKE5VTEwpOwoJLyoKCSogQXNzaWduIHRoZSByZWZlcmVuY2UuIFRoaXMgd2lsbCBiZSBzdWJzdGl0dXRlZCBmb3IgdGhlCgkqIHJlZmVyZW5jZWQgYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdoZW4gdGhlIFFOYW1lIGlzIHJlc29sdmVkLgoJKi8KCXVzZS0+YXR0ckRlY2wgPSBXWFNfQVRUUl9DQVNUIHJlZjsKCS8qCgkqIFZhbHVlIGNvbnN0cmFpbnQuCgkqLwoJaWYgKGRlZlZhbHVlICE9IE5VTEwpCgkgICAgdXNlLT5kZWZWYWx1ZSA9IGRlZlZhbHVlOwoJICAgIGlmIChkZWZWYWx1ZVR5cGUgPT0gV1hTX0FUVFJfREVGX1ZBTF9GSVhFRCkKCQl1c2UtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfQVRUUl9VU0VfRklYRUQ7CiAgICB9CiAgICAKY2hlY2tfY2hpbGRyZW46CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKG9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcHJvaGliOwkKCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKHBjdHh0LCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPykiKTsKCX0KCS8qCgkqIENoZWNrIGZvciBwb2ludGxlc3NuZXNzIG9mIGF0dHJpYnV0ZSBwcm9oaWJpdGlvbnMuCgkqLwoJaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CQkKCSAgICB4bWxTY2hlbWFDdXN0b21XYXJuaW5nKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfV0FSTl9BVFRSX1BPSU5UTEVTU19QUk9ILAoJCW5vZGUsIE5VTEwsCgkJIlNraXBwaW5nIGF0dHJpYnV0ZSB1c2UgcHJvaGliaXRpb24sIHNpbmNlIGl0IGlzICIKCQkicG9pbnRsZXNzIGluc2lkZSBhbiA8YXR0cmlidXRlR3JvdXA+IiwKCQlOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oTlVMTCk7Cgl9IGVsc2UgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTikgewoJICAgIHhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9XQVJOX0FUVFJfUE9JTlRMRVNTX1BST0gsCgkJbm9kZSwgTlVMTCwKCQkiU2tpcHBpbmcgYXR0cmlidXRlIHVzZSBwcm9oaWJpdGlvbiwgc2luY2UgaXQgaXMgIgoJCSJwb2ludGxlc3Mgd2hlbiBleHRlbmRpbmcgYSB0eXBlIiwKCQlOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oTlVMTCk7Cgl9CglpZiAoISBpc1JlZikgewoJICAgIHRtcE5hbWUgPSBuYW1lOyAKCSAgICB0bXBOcyA9IG5zOwoJfQoJLyoKCSogQ2hlY2sgZm9yIGR1cGxpY2F0ZSBhdHRyaWJ1dGUgcHJvaGliaXRpb25zLgoJKi8KCWlmICh1c2VzKSB7CgkgICAgaW50IGk7CgkgICAgCgkgICAgZm9yIChpID0gMDsgaSA8IHVzZXMtPm5iSXRlbXM7IGkrKykgewoJCXVzZSA9IHVzZXMtPml0ZW1zW2ldOwoJCWlmICgodXNlLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfQVRUUl9VU0VfUFJPSElCKSAmJgoJCSAgICAodG1wTmFtZSA9PSAoV1hTX0FUVFJfUFJPSElCX0NBU1QgdXNlKS0+bmFtZSkgJiYKCQkgICAgKHRtcE5zID09IChXWFNfQVRUUl9QUk9ISUJfQ0FTVCB1c2UpLT50YXJnZXROYW1lc3BhY2UpKQoJCXsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkgICAgCgkJICAgIHhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJWE1MX1NDSEVNQVBfV0FSTl9BVFRSX1BPSU5UTEVTU19QUk9ILAoJCQlub2RlLCBOVUxMLAoJCQkiU2tpcHBpbmcgZHVwbGljYXRlIGF0dHJpYnV0ZSB1c2UgcHJvaGliaXRpb24gJyVzJyIsCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHRtcE5zLCB0bXBOYW1lKSwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQkJCQoJCSAgICByZXR1cm4oTlVMTCk7CgkJfQkKCSAgICB9Cgl9CgkvKgoJKiBDcmVhdGUgdGhlIGF0dHJpYnV0ZSBwcm9oaWJpdGlvbiBoZWxwZXIgY29tcG9uZW50LgoJKi8KCXByb2hpYiA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZVVzZVByb2hpYihwY3R4dCk7CglpZiAocHJvaGliID09IE5VTEwpCgkgICAgcmV0dXJuKE5VTEwpOwoJcHJvaGliLT5ub2RlID0gbm9kZTsKCXByb2hpYi0+bmFtZSA9IHRtcE5hbWU7Cglwcm9oaWItPnRhcmdldE5hbWVzcGFjZSA9IHRtcE5zOwoJaWYgKGlzUmVmKSB7CgkgICAgLyoKCSAgICAqIFdlIG5lZWQgYXQgbGVhc3QgdG8gcmVzb2x2ZSB0byB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJICAgICovCgkgICAgV1hTX0FERF9QRU5ESU5HKHBjdHh0LCBwcm9oaWIpOwoJfQoJcmV0dXJuKFdYU19CQVNJQ19DQVNUIHByb2hpYik7CiAgICB9IGVsc2UgeyAgICAgICAgCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFNob3VsZCB0aGlzIGdvIGludG8gdGhlIGF0dHIgZGVjbD8KCSAgICAqLwoJICAgIHVzZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24ocGN0eHQsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGlzUmVmKSB7CgkgICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCQlpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKQoJCSAgICAvKgoJCSAgICAqIDMuMi4zIDogMy4yCgkJICAgICogSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxzaW1wbGVUeXBlPiwKCQkgICAgKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8zXzIsCgkJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCQkiKGFubm90YXRpb24/KSIpOwoJCWVsc2UKCQkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkJIihhbm5vdGF0aW9uPykiKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCQlpZiAoV1hTX0FUVFJVU0VfREVDTCh1c2UpLT50eXBlTmFtZSAhPSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogMy4yLjMgOiA0CgkJICAgICogdHlwZSBhbmQgPHNpbXBsZVR5cGU+IG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfNCwKCQkJTlVMTCwgbm9kZSwgY2hpbGQsCgkJCSJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJCSJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkJfSBlbHNlCgkJICAgIFdYU19BVFRSVVNFX1RZUEVERUYodXNlKSA9CgkJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShwY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkJY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGNoaWxkICE9IE5VTEwpCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGU/KSIpOwoJfQogICAgfSAgIAogICAgcmV0dXJuIChXWFNfQkFTSUNfQ0FTVCB1c2UpOwp9CgoKc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFQYXJzZUdsb2JhbEF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICAvKgogICAgICogTm90ZSB0aGF0IHRoZSB3M2Mgc3BlYyBhc3N1bWVzIHRoZSBzY2hlbWEgdG8gYmUgdmFsaWRhdGVkIHdpdGggc2NoZW1hCiAgICAgKiBmb3Igc2NoZW1hcyBiZWZvcmVoYW5kLgogICAgICoKICAgICAqIDMuMi4zIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgQXR0cmlidXRlIERlY2xhcmF0aW9ucwogICAgICovCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsgICAgICAgIAogICAgLyoKICAgICogMy4yLjMgOiAzLjEKICAgICogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgIm5hbWUiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKHBjdHh0LCBOVUxMLCBhdHRyLAoJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJmF0dHJWYWx1ZSkgIT0gMCkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeG1sbnMgTm90IEFsbG93ZWQKICAgICogVE9ETzogTW92ZSB0aGlzIHRvIHRoZSBjb21wb25lbnQgbGF5ZXIuCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInhtbG5zIikpIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PX1hNTE5TLAoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksIE5VTEwsIE5VTEwsCgkgICAgIlRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlIG11c3Qgbm90IG1hdGNoICd4bWxucyciLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeHNpOiBOb3QgQWxsb3dlZAogICAgKiBUT0RPOiBNb3ZlIHRoaXMgdG8gdGhlIGNvbXBvbmVudCBsYXllci4KICAgICogICAgICAgT3IgYmV0dGVyIGxlYXZlIGl0IGhlcmUgYW5kIGFkZCBpdCB0byB0aGUgY29tcG9uZW50IGxheWVyCiAgICAqICAgICAgIGlmIHdlIGhhdmUgYSBzY2hlbWEgY29uc3RydWN0aW9uIEFQSS4KICAgICovCiAgICBpZiAoeG1sU3RyRXF1YWwocGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PX1hTSSwgbm9kZSwgTlVMTCwKCSAgICAiVGhlIHRhcmdldCBuYW1lc3BhY2UgbXVzdCBub3QgbWF0Y2ggJyVzJyIsCgkgICAgeG1sU2NoZW1hSW5zdGFuY2VOcywgTlVMTCk7CiAgICB9CgogICAgcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKHBjdHh0LCBzY2hlbWEsIGF0dHJWYWx1ZSwKCXBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUsIDEpOwogICAgaWYgKHJldCA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUw7CgkKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ0eXBlIikpKQoJICAgIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsJCQoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRyUU5hbWUocGN0eHQsIHNjaGVtYSwgTlVMTCwKCW5vZGUsICJ0eXBlIiwgJnJldC0+dHlwZU5zLCAmcmV0LT50eXBlTmFtZSk7CiAgICAKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQocGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlICJmaXhlZCIuCiAgICAqLwogICAgcmV0LT5kZWZWYWx1ZSA9IHhtbFNjaGVtYUdldFByb3AocGN0eHQsIG5vZGUsICJmaXhlZCIpOwogICAgaWYgKHJldC0+ZGVmVmFsdWUgIT0gTlVMTCkKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9GSVhFRDsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAiZGVmYXVsdCIuCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJkZWZhdWx0Iik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CgkvKgoJKiAzLjIuMyA6IDEKCSogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgoJKi8KCWlmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgewoJICAgIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihwY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8xLAoJCVdYU19CQVNJQ19DQVNUIHJldCwgYXR0ciwgImRlZmF1bHQiLCAiZml4ZWQiKTsKCX0gZWxzZQoJICAgIHJldC0+ZGVmVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChwY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKHBjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCWlmIChyZXQtPnR5cGVOYW1lICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogMy4yLjMgOiA0CgkgICAgKiB0eXBlIGFuZCA8c2ltcGxlVHlwZT4gbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgoJICAgICovCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfNCwKCQlOVUxMLCBub2RlLCBjaGlsZCwKCQkiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7Cgl9IGVsc2UKCSAgICByZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHBjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkKCXhtbFNjaGVtYVBDb250ZW50RXJyKHBjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlPykiKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwUmVmOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHJlZmVyZW5jZS4KICogTm90ZSB0aGF0IGEgcmVmZXJlbmNlIHRvIGFuIGF0dHJpYnV0ZSBncm91cCBkb2VzIG5vdAogKiBjb3JyZXNwb25kIHRvIGFueSBjb21wb25lbnQgYXQgYWxsLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cFJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCXhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMOwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCAicmVmIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQkKICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKHBjdHh0LCBzY2hlbWEsCglOVUxMLCBhdHRyLCAmcmVmTnMsICZyZWYpOwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKHBjdHh0LCBzY2hlbWEsIG5vZGUsIGF0dHIsIHJlZk5zKSAhPSAwKQoJcmV0dXJuKE5VTEwpOwogICAKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWYiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyogQXR0cmlidXRlIElEICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKHBjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogVE9ETzogV2UgZG8gbm90IGhhdmUgYSBwbGFjZSB0byBzdG9yZSB0aGUgYW5ub3RhdGlvbiwgZG8gd2U/CgkqLwogICAgICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihwY3R4dCwgY2hpbGQsIDApOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KCiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlIGdyb3VwIHJlZGVmaW5pdGlvbnMuCiAgICAqLwogICAgaWYgKHBjdHh0LT5pc1JlZGVmaW5lICYmIHBjdHh0LT5yZWRlZiAmJgoJKHBjdHh0LT5yZWRlZi0+aXRlbS0+dHlwZSA9PQoJICAgIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgJiYKCShyZWYgPT0gcGN0eHQtPnJlZGVmLT5yZWZOYW1lKSAmJgoJKHJlZk5zID09IHBjdHh0LT5yZWRlZi0+cmVmVGFyZ2V0TnMpKQogICAgewoJLyoKCSogU1BFQyBzcmMtcmVkZWZpbmU6CgkqICg3LjEpICJJZiBpdCBoYXMgYW4gPGF0dHJpYnV0ZUdyb3VwPiBhbW9uZyBpdHMgY29udGVudHMKCSogdGhlILdhY3R1YWwgdmFsdWW3IG9mIHdob3NlIHJlZiBbYXR0cmlidXRlXSBpcyB0aGUgc2FtZQoJKiBhcyB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgaXRzIG93biBuYW1lIGF0dHJpYnV0ZSBwbHVzCgkqIHRhcmdldCBuYW1lc3BhY2UsIHRoZW4gaXQgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHN1Y2ggZ3JvdXAuIgoJKi8KCWlmIChwY3R4dC0+cmVkZWZDb3VudGVyICE9IDApIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIAoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwgbm9kZSwgTlVMTCwKCQkiVGhlIHJlZGVmaW5pbmcgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gIgoJCSInJXMnIG11c3Qgbm90IGNvbnRhaW4gbW9yZSB0aGFuIG9uZSAiCgkJInJlZmVyZW5jZSB0byB0aGUgcmVkZWZpbmVkIGRlZmluaXRpb24iLAoJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHJlZk5zLCByZWYpLCBOVUxMKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgcmV0dXJuKE5VTEwpOwoJfQoJcGN0eHQtPnJlZGVmQ291bnRlcisrOwoJLyoKCSogVVJHRU5UIFRPRE86IEhvdyB0byBlbnN1cmUgdGhhdCB0aGUgcmVmZXJlbmNlIHdpbGwgbm90IGJlCgkqIGhhbmRsZWQgYnkgdGhlIG5vcm1hbCBjb21wb25lbnQgcmVzb2x1dGlvbiBtZWNoYW5pc20/CgkqLwoJcmV0ID0geG1sU2NoZW1hTmV3UU5hbWVSZWYocGN0eHQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQLCByZWYsIHJlZk5zKTsKCWlmIChyZXQgPT0gTlVMTCkKCSAgICByZXR1cm4oTlVMTCk7CglyZXQtPm5vZGUgPSBub2RlOwoJcGN0eHQtPnJlZGVmLT5yZWZlcmVuY2UgPSBXWFNfQkFTSUNfQ0FTVCByZXQ7CiAgICB9IGVsc2UgewoJLyoKCSogQ3JlYXRlIGEgUU5hbWUtcmVmZXJlbmNlIGhlbHBlciBjb21wb25lbnQuIFdlIHdpbGwgc3Vic3RpdHV0ZSB0aGlzCgkqIGNvbXBvbmVudCBmb3IgdGhlIGF0dHJpYnV0ZSB1c2VzIG9mIHRoZSByZWZlcmVuY2VkIGF0dHJpYnV0ZSBncm91cAoJKiBkZWZpbml0aW9uLgoJKi8KCXJldCA9IHhtbFNjaGVtYU5ld1FOYW1lUmVmKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCwgcmVmLCByZWZOcyk7CglpZiAocmV0ID09IE5VTEwpCgkgICAgcmV0dXJuKE5VTEwpOwoJcmV0LT5ub2RlID0gbm9kZTsKCS8qIEFkZCB0byBwZW5kaW5nIGl0ZW1zLCB0byBiZSBhYmxlIHRvIHJlc29sdmUgdGhlIHJlZmVyZW5jZS4gKi8KCVdYU19BRERfUEVORElORyhwY3R4dCwgcmV0KTsKICAgIH0gICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbjoKICogQHBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgaGFzUmVmcyA9IDA7CgogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCAibmFtZSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIFRoZSBuYW1lIGlzIGNydWNpYWwsIGV4aXQgaWYgaW52YWxpZC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKHBjdHh0LAoJTlVMTCwgYXR0ciwKCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uKHBjdHh0LCBzY2hlbWEsCgluYW1lLCBwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKICAgIGlmIChyZXQgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CQogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyogQXR0cmlidXRlIElEICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKHBjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihwY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBQYXJzZSBjb250YWluZWQgYXR0cmlidXRlIGRlY2xzL3JlZnMuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGVzKHBjdHh0LCBzY2hlbWEsICZjaGlsZCwKCSh4bWxTY2hlbWFJdGVtTGlzdFB0ciAqKSAmKHJldC0+YXR0clVzZXMpLAoJWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQLCAmaGFzUmVmcykgPT0gLTEpCglyZXR1cm4oTlVMTCk7CiAgICBpZiAoaGFzUmVmcykKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX0hBU19SRUZTOwogICAgLyoKICAgICogUGFyc2UgdGhlIGF0dHJpYnV0ZSB3aWxkY2FyZC4KICAgICovCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCXJldC0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShwY3R4dCwKCSAgICBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQ6CiAqIEB2YWx1ZTogIHRoZSB2YWx1ZQogKiBAZmxhZ3M6IHRoZSBmbGFncyB0byBiZSBtb2RpZmllZAogKiBAZmxhZ1F1YWxpZmllZDogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJxdWFsaWZpZWQiCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIDEgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0KGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgIGludCAqZmxhZ3MsCgkJCSAgICAgaW50IGZsYWdRdWFsaWZpZWQpCnsKICAgIGlmICh4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CglpZiAgKCgqZmxhZ3MgJiBmbGFnUXVhbGlmaWVkKSA9PSAwKQoJICAgICpmbGFncyB8PSBmbGFnUXVhbGlmaWVkOwogICAgfSBlbHNlIGlmICgheG1sU3RyRXF1YWwodmFsdWUsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKQoJcmV0dXJuICgxKTsKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsOgogKiBAdmFsdWU6ICB0aGUgdmFsdWUKICogQGZsYWdzOiB0aGUgZmxhZ3MgdG8gYmUgbW9kaWZpZWQKICogQGZsYWdBbGw6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiI2FsbCIKICogQGZsYWdFeHRlbnNpb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiZXh0ZW5zaW9uIgogKiBAZmxhZ1Jlc3RyaWN0aW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInJlc3RyaWN0aW9uIgogKiBAZmxhZ1N1YnN0aXR1dGlvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJzdWJzdGl0dXRpb24iCiAqIEBmbGFnTGlzdDogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJsaXN0IgogKiBAZmxhZ1VuaW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInVuaW9uIgogKgogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgImZpbmFsIiBhbmQgImJsb2NrIi4gVGhlIHZhbHVlCiAqIGlzIGNvbnZlcnRlZCBpbnRvIHRoZSBzcGVjaWZpZWQgZmxhZyB2YWx1ZXMgYW5kIHJldHVybmVkIGluIEBmbGFncy4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgMSBvdGhlcndpc2UuCiAqLwoKc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICBpbnQgKmZsYWdzLAoJCQkgICAgaW50IGZsYWdBbGwsCgkJCSAgICBpbnQgZmxhZ0V4dGVuc2lvbiwKCQkJICAgIGludCBmbGFnUmVzdHJpY3Rpb24sCgkJCSAgICBpbnQgZmxhZ1N1YnN0aXR1dGlvbiwKCQkJICAgIGludCBmbGFnTGlzdCwKCQkJICAgIGludCBmbGFnVW5pb24pCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIFRPRE86IFRoaXMgZG9lcyBub3QgY2hlY2sgZm9yIGR1YmxpY2F0ZSBlbnRyaWVzLgogICAgKi8KICAgIGlmICgoZmxhZ3MgPT0gTlVMTCkgfHwgKHZhbHVlID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CiAgICBpZiAodmFsdWVbMF0gPT0gMCkKCXJldHVybiAoMCk7CiAgICBpZiAoeG1sU3RyRXF1YWwodmFsdWUsIEJBRF9DQVNUICIjYWxsIikpIHsKCWlmIChmbGFnQWxsICE9IC0xKQoJICAgICpmbGFncyB8PSBmbGFnQWxsOwoJZWxzZSB7CgkgICAgaWYgKGZsYWdFeHRlbnNpb24gIT0gLTEpCgkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247CgkgICAgaWYgKGZsYWdSZXN0cmljdGlvbiAhPSAtMSkKCQkqZmxhZ3MgfD0gZmxhZ1Jlc3RyaWN0aW9uOwoJICAgIGlmIChmbGFnU3Vic3RpdHV0aW9uICE9IC0xKQoJCSpmbGFncyB8PSBmbGFnU3Vic3RpdHV0aW9uOwoJICAgIGlmIChmbGFnTGlzdCAhPSAtMSkKCQkqZmxhZ3MgfD0gZmxhZ0xpc3Q7CgkgICAgaWYgKGZsYWdVbmlvbiAhPSAtMSkKCQkqZmxhZ3MgfD0gZmxhZ1VuaW9uOwoJfQogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKmVuZCwgKmN1ciA9IHZhbHVlOwoJeG1sQ2hhciAqaXRlbTsKCglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBpdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJleHRlbnNpb24iKSkgewoJCWlmIChmbGFnRXh0ZW5zaW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ0V4dGVuc2lvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247CgkJfSBlbHNlCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAicmVzdHJpY3Rpb24iKSkgewoJCWlmIChmbGFnUmVzdHJpY3Rpb24gIT0gLTEpIHsKCQkgICAgaWYgKCgqZmxhZ3MgJiBmbGFnUmVzdHJpY3Rpb24pID09IDApCgkJCSpmbGFncyB8PSBmbGFnUmVzdHJpY3Rpb247CgkJfSBlbHNlCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uIikpIHsKCQlpZiAoZmxhZ1N1YnN0aXR1dGlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdTdWJzdGl0dXRpb24pID09IDApCgkJCSpmbGFncyB8PSBmbGFnU3Vic3RpdHV0aW9uOwoJCX0gZWxzZQoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImxpc3QiKSkgewoJCWlmIChmbGFnTGlzdCAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdMaXN0KSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ0xpc3Q7CgkJfSBlbHNlCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAidW5pb24iKSkgewoJCWlmIChmbGFnVW5pb24gIT0gLTEpIHsKCQkgICAgaWYgKCgqZmxhZ3MgJiBmbGFnVW5pb24pID09IDApCgkJCSpmbGFncyB8PSBmbGFnVW5pb247CgkJfSBlbHNlCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlCgkJcmV0ID0gMTsKCSAgICBpZiAoaXRlbSAhPSBOVUxMKQoJCXhtbEZyZWUoaXRlbSk7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKHJldCA9PSAwKSAmJiAoKmN1ciAhPSAwKSk7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1NlbGVjdG9yWFBhdGgoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbGVjdG9yLAoJCQkgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJICAgICBpbnQgaXNGaWVsZCkKewogICAgeG1sTm9kZVB0ciBub2RlOwoKICAgIC8qCiAgICAqIGMtc2VsZWN0b3IteHBhdGg6CiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2VsZWN0b3IgVmFsdWUgT0sKICAgICoKICAgICogVE9ETzogMSBUaGUge3NlbGVjdG9yfSBtdXN0IGJlIGEgdmFsaWQgWFBhdGggZXhwcmVzc2lvbiwgYXMgZGVmaW5lZAogICAgKiBpbiBbWFBhdGhdLgogICAgKi8KICAgIGlmIChzZWxlY3RvciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIGlkYy0+bm9kZSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ1NlbGVjdG9yWFBhdGgsICIKCSAgICAidGhlIHNlbGVjdG9yIGlzIG5vdCBzcGVjaWZpZWQuXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKGF0dHIgPT0gTlVMTCkKCW5vZGUgPSBpZGMtPm5vZGU7CiAgICBlbHNlCglub2RlID0gKHhtbE5vZGVQdHIpIGF0dHI7CiAgICBpZiAoc2VsZWN0b3ItPnhwYXRoID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICAvKiBUT0RPOiBBZGp1c3QgZXJyb3IgY29kZS4gKi8KCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBYUGF0aCBleHByZXNzaW9uIG9mIHRoZSBzZWxlY3RvciBpcyBub3QgdmFsaWQiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSk7CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqKm5zQXJyYXkgPSBOVUxMOwoJeG1sTnNQdHIgKm5zTGlzdCA9IE5VTEw7CgkvKgoJKiBDb21waWxlIHRoZSBYUGF0aCBleHByZXNzaW9uLgoJKi8KCS8qCgkqIFRPRE86IFdlIG5lZWQgdGhlIGFycmF5IG9mIGluLXNjb3BlIG5hbWVzcGFjZXMgZm9yIGNvbXBpbGF0aW9uLgoJKiBUT0RPOiBDYWxsIHhtbFBhdHRlcm5jb21waWxlIHdpdGggZGlmZmVyZW50IG9wdGlvbnMgZm9yIHNlbGVjdG9yLwoJKiBmaWVsZC4KCSovCglpZiAoYXR0ciA9PSBOVUxMKQoJICAgIG5zTGlzdCA9IE5VTEw7CgllbHNlCgkgICAgbnNMaXN0ID0geG1sR2V0TnNMaXN0KGF0dHItPmRvYywgYXR0ci0+cGFyZW50KTsKCS8qCgkqIEJ1aWxkIGFuIGFycmF5IG9mIHByZWZpeGVzIGFuZCBuYW1lc3BhY2VzLgoJKi8KCWlmIChuc0xpc3QgIT0gTlVMTCkgewoJICAgIGludCBpLCBjb3VudCA9IDA7CgoJICAgIGZvciAoaSA9IDA7IG5zTGlzdFtpXSAhPSBOVUxMOyBpKyspCgkJY291bnQrKzsKCgkgICAgbnNBcnJheSA9IChjb25zdCB4bWxDaGFyICoqKSB4bWxNYWxsb2MoCgkJKGNvdW50ICogMiArIDEpICogc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJICAgIGlmIChuc0FycmF5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgbmFtZXNwYWNlIGFycmF5IiwKCQkgICAgTlVMTCk7CgkJeG1sRnJlZShuc0xpc3QpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCW5zQXJyYXlbMiAqIGldID0gbnNMaXN0W2ldLT5ocmVmOwoJCW5zQXJyYXlbMiAqIGkgKyAxXSA9IG5zTGlzdFtpXS0+cHJlZml4OwoJICAgIH0KCSAgICBuc0FycmF5W2NvdW50ICogMl0gPSBOVUxMOwoJICAgIHhtbEZyZWUobnNMaXN0KTsKCX0KCS8qCgkqIFRPRE86IERpZmZlcmVudGlhdGUgYmV0d2VlbiAic2VsZWN0b3IiIGFuZCAiZmllbGQiLgoJKi8KCWlmIChpc0ZpZWxkKQoJICAgIHNlbGVjdG9yLT54cGF0aENvbXAgPSAodm9pZCAqKSB4bWxQYXR0ZXJuY29tcGlsZShzZWxlY3Rvci0+eHBhdGgsCgkJTlVMTCwgWE1MX1BBVFRFUk5fWFNGSUVMRCwgbnNBcnJheSk7CgllbHNlCgkgICAgc2VsZWN0b3ItPnhwYXRoQ29tcCA9ICh2b2lkICopIHhtbFBhdHRlcm5jb21waWxlKHNlbGVjdG9yLT54cGF0aCwKCQlOVUxMLCBYTUxfUEFUVEVSTl9YU1NFTCwgbnNBcnJheSk7CglpZiAobnNBcnJheSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHhtbENoYXIgKiopIG5zQXJyYXkpOwoKCWlmIChzZWxlY3Rvci0+eHBhdGhDb21wID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJLyogVE9ETzogQWRqdXN0IGVycm9yIGNvZGU/ICovCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQlOVUxMLCBub2RlLAoJCSJUaGUgWFBhdGggZXhwcmVzc2lvbiAnJXMnIGNvdWxkIG5vdCBiZSAiCgkJImNvbXBpbGVkIiwgc2VsZWN0b3ItPnhwYXRoKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUpOwoJfQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKI2RlZmluZSBBRERfQU5OT1RBVElPTihhbm5vdCkgICBcCiAgICB4bWxTY2hlbWFBbm5vdFB0ciBjdXIgPSBpdGVtLT5hbm5vdDsgXAogICAgaWYgKGl0ZW0tPmFubm90ID09IE5VTEwpIHsgIFwKCWl0ZW0tPmFubm90ID0gYW5ub3Q7ICAgIFwKCXJldHVybiAoYW5ub3QpOyAgICAgICAgIFwKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBjdXIgPSBpdGVtLT5hbm5vdDsgICAgICAgICAgXAogICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7ICAgIFwKCWN1ciA9IGN1ci0+bmV4dDsJXAogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGN1ci0+bmV4dCA9IGFubm90OwoKLyoqCiAqIHhtbFNjaGVtYUFzc2lnbkFubm90YXRpb246CiAqIEBpdGVtOiB0aGUgc2NoZW1hIGNvbXBvbmVudAogKiBAYW5ub3Q6IHRoZSBhbm5vdGF0aW9uCiAqCiAqIEFkZHMgdGhlIGFubm90YXRpb24gdG8gdGhlIGdpdmVuIHNjaGVtYSBjb21wb25lbnQuCiAqCiAqIFJldHVybnMgdGhlIGdpdmVuIGFubm90YWlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKHhtbFNjaGVtYUFubm90SXRlbVB0ciBhbm5JdGVtLAoJCSAgICAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCkKewogICAgaWYgKChhbm5JdGVtID09IE5VTEwpIHx8IChhbm5vdCA9PSBOVUxMKSkKCXJldHVybiAoTlVMTCk7CiAgICBzd2l0Y2ggKGFubkl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6IHsKCQl4bWxTY2hlbWFFbGVtZW50UHRyIGl0ZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6IHsKCQl4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogewoJCXhtbFNjaGVtYVdpbGRjYXJkUHRyIGl0ZW0gPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6IHsKCQl4bWxTY2hlbWFBbm5vdEl0ZW1QdHIgaXRlbSA9ICh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6IHsKCQl4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBpdGVtID0KCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOiB7CgkJeG1sU2NoZW1hTm90YXRpb25QdHIgaXRlbSA9ICh4bWxTY2hlbWFOb3RhdGlvblB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDogewoJCXhtbFNjaGVtYUZhY2V0UHRyIGl0ZW0gPSAoeG1sU2NoZW1hRmFjZXRQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDogewoJCXhtbFNjaGVtYVR5cGVQdHIgaXRlbSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOiB7CgkJeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtID0gKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6IHsKCQl4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW0gPSAoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKE5VTEwsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJTlVMTCwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEFubm90YXRpb24sICIKCQkiVGhlIGl0ZW0gaXMgbm90IGEgYW5ub3RhdGVkIHNjaGVtYSBjb21wb25lbnQiLCBOVUxMKTsKCSAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKGFubm90KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgU2NoZW1hIGlkZW50aXR5LWNvbnRyYWludCBkZWZpbml0aW9uJ3MKICogPHNlbGVjdG9yPiBhbmQgPGZpZWxkPiBlbGVtZW50cy4KICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFJRENTZWxlY3RQdHIKeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwJCQkgIAoJCQkgIHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgeG1sTm9kZVB0ciBub2RlLAoJCQkgIGludCBpc0ZpZWxkKQp7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgaXRlbTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInhwYXRoIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIENyZWF0ZSB0aGUgaXRlbS4KICAgICovCiAgICBpdGVtID0gKHhtbFNjaGVtYUlEQ1NlbGVjdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENTZWxlY3QpKTsKICAgIGlmIChpdGVtID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsCgkgICAgImFsbG9jYXRpbmcgYSAnc2VsZWN0b3InIG9mIGFuIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbiIsCgkgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChpdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDU2VsZWN0KSk7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgInhwYXRoIiAobWFuZGF0b3J5KS4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInhwYXRoIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLAoJICAgICJuYW1lIiwgTlVMTCk7CiAgICB9IGVsc2UgewoJaXRlbS0+eHBhdGggPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkvKgoJKiBVUkdFTlQgVE9ETzogImZpZWxkInMgaGF2ZSBhbiBvdGhlciBzeW50YXggdGhhbiAic2VsZWN0b3Iicy4KCSovCgoJaWYgKHhtbFNjaGVtYUNoZWNrQ1NlbGVjdG9yWFBhdGgoY3R4dCwgaWRjLCBpdGVtLCBhdHRyLAoJICAgIGlzRmllbGQpID09IC0xKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LAoJCSh4bWxOb2RlUHRyKSBhdHRyLAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkLCAiCgkJInZhbGlkYXRpbmcgdGhlIFhQYXRoIGV4cHJlc3Npb24gb2YgYSBJREMgc2VsZWN0b3IuXG4iLAoJCU5VTEwsIE5VTEwpOwoJfQoKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBwYXJlbnQgSURDLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgaWRjLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSkpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgcmV0dXJuIChpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSURDOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyBhIFhNTCBTY2hlbWEgaWRlbnRpdHktY29udHJhaW50IGRlZmluaXRpb24uCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlZCBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hSURDUHRyCnhtbFNjaGVtYVBhcnNlSURDKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICB4bWxOb2RlUHRyIG5vZGUsCgkJICB4bWxTY2hlbWFUeXBlVHlwZSBpZGNDYXRlZ29yeSwKCQkgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hSURDUHRyIGl0ZW0gPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBmaWVsZCA9IE5VTEwsIGxhc3RGaWVsZCA9IE5VTEw7CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSgoaWRjQ2F0ZWdvcnkgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHx8CgkJICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZmVyIikpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgIm5hbWUiIChtYW5kYXRvcnkpLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLAoJICAgICJuYW1lIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCU5VTEwsIGF0dHIsCgl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qIENyZWF0ZSB0aGUgY29tcG9uZW50LiAqLwogICAgaXRlbSA9IHhtbFNjaGVtYUFkZElEQyhjdHh0LCBzY2hlbWEsIG5hbWUsIHRhcmdldE5hbWVzcGFjZSwKCWlkY0NhdGVnb3J5LCBub2RlKTsKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGlmIChpZGNDYXRlZ29yeSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJLyoKCSogQXR0cmlidXRlICJyZWZlciIgKG1hbmRhdG9yeSkuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWZlciIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwKCQkicmVmZXIiLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIENyZWF0ZSBhIHJlZmVyZW5jZSBpdGVtLgoJICAgICovCgkgICAgaXRlbS0+cmVmID0geG1sU2NoZW1hTmV3UU5hbWVSZWYoY3R4dCwgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVksCgkJTlVMTCwgTlVMTCk7CgkgICAgaWYgKGl0ZW0tPnJlZiA9PSBOVUxMKQoJCXJldHVybiAoTlVMTCk7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJCU5VTEwsIGF0dHIsCgkJJihpdGVtLT5yZWYtPnRhcmdldE5hbWVzcGFjZSksCgkJJihpdGVtLT5yZWYtPm5hbWUpKTsKCSAgICB4bWxTY2hlbWFDaGVja1JlZmVyZW5jZShjdHh0LCBzY2hlbWEsIG5vZGUsIGF0dHIsCgkJaXRlbS0+cmVmLT50YXJnZXROYW1lc3BhY2UpOwoJfQogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsIGNoaWxkLAoJCSJBIGNoaWxkIGVsZW1lbnQgaXMgbWlzc2luZyIsCgkJIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwogICAgfQogICAgLyoKICAgICogQ2hpbGQgZWxlbWVudCA8c2VsZWN0b3I+LgogICAgKi8KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZWxlY3RvciIpKSB7CglpdGVtLT5zZWxlY3RvciA9IHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZChjdHh0LAoJICAgIGl0ZW0sIGNoaWxkLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkvKgoJKiBDaGlsZCBlbGVtZW50cyA8ZmllbGQ+LgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJmaWVsZCIpKSB7CgkgICAgZG8gewoJCWZpZWxkID0geG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKGN0eHQsCgkJICAgIGl0ZW0sIGNoaWxkLCAxKTsKCQlpZiAoZmllbGQgIT0gTlVMTCkgewoJCSAgICBmaWVsZC0+aW5kZXggPSBpdGVtLT5uYkZpZWxkczsKCQkgICAgaXRlbS0+bmJGaWVsZHMrKzsKCQkgICAgaWYgKGxhc3RGaWVsZCAhPSBOVUxMKQoJCQlsYXN0RmllbGQtPm5leHQgPSBmaWVsZDsKCQkgICAgZWxzZQoJCQlpdGVtLT5maWVsZHMgPSBmaWVsZDsKCQkgICAgbGFzdEZpZWxkID0gZmllbGQ7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgfSB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiZmllbGQiKSk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwogICAgfQoKICAgIHJldHVybiAoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHRvcExldmVsOiBpbmRpY2F0ZXMgaWYgdGhpcyBpcyBnbG9iYWwgZGVjbGFyYXRpb24KICoKICogUGFyc2VzIGEgWE1MIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgYSBwYXJ0aWNsZTsgTlVMTCBpbiBjYXNlCiAqIG9mIGFuIGVycm9yIG9yIGlmIHRoZSBwYXJ0aWNsZSBoYXMgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQmFzaWNJdGVtUHRyCnhtbFNjaGVtYVBhcnNlRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCAqaXNFbGVtUmVmLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCA9IE5VTEw7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CiAgICBpbnQgbWluLCBtYXgsIGlzUmVmID0gMDsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgLyogMy4zLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBFbGVtZW50IERlY2xhcmF0aW9ucyAqLwogICAgLyogVE9ETzogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgMy4zLjYgKi8KCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChpc0VsZW1SZWYgIT0gTlVMTCkKCSppc0VsZW1SZWYgPSAwOwogICAgLyoKICAgICogSWYgd2UgZ2V0IGEgInJlZiIgYXR0cmlidXRlIG9uIGEgbG9jYWwgPGVsZW1lbnQ+IHdlIHdpbGwgYXNzdW1lIGl0J3MKICAgICogYSByZWZlcmVuY2UgLSBldmVuIGlmIHRoZXJlJ3MgYSAibmFtZSIgYXR0cmlidXRlOyB0aGlzIHNlZW1zIHRvIGJlIG1vcmUKICAgICogcm9idXN0LgogICAgKi8KICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZQoJaXNSZWYgPSAxOwoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIFNraXAgcGFydGljbGUgcGFydCBpZiBhIGdsb2JhbCBkZWNsYXJhdGlvbi4KICAgICovCiAgICBpZiAodG9wTGV2ZWwpCglnb3RvIGRlY2xhcmF0aW9uX3BhcnQ7CiAgICAvKgogICAgKiBUaGUgcGFydGljbGUgcGFydCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgKi8KICAgIG1pbiA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgInhzOm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCBOVUxMLCBub2RlLCBtaW4sIG1heCk7CiAgICBwYXJ0aWNsZSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKGN0eHQsIG5vZGUsIG1pbiwgbWF4KTsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJZ290byByZXR1cm5fbnVsbDsKCiAgICAvKiByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fUkVGOyAqLwoKICAgIGlmIChpc1JlZikgewoJY29uc3QgeG1sQ2hhciAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTDsKCXhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZmVyID0gTlVMTDsKCS8qCgkqIFRoZSByZWZlcmVuY2UgcGFydCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCSovCglpZiAoaXNFbGVtUmVmICE9IE5VTEwpCgkgICAgKmlzRWxlbVJlZiA9IDE7CgoJeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgIE5VTEwsIGF0dHIsICZyZWZOcywgJnJlZik7Cgl4bWxTY2hlbWFDaGVja1JlZmVyZW5jZShjdHh0LCBzY2hlbWEsIG5vZGUsIGF0dHIsIHJlZk5zKTsKCS8qCgkqIFNQRUMgKDMuMy4zIDogMi4xKSAiT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIgoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8xLCBOVUxMLCBuYW1lQXR0ciwgInJlZiIsICJuYW1lIik7Cgl9CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWYiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpCgkJewoJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgLyogU1BFQyAoMy4zLjMgOiAyLjIpICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzJfMiwKCQkJTlVMTCwgTlVMTCwgYXR0ciwKCQkJIk9ubHkgdGhlIGF0dHJpYnV0ZXMgJ21pbk9jY3VycycsICdtYXhPY2N1cnMnIGFuZCAiCgkJCSInaWQnIGFyZSBhbGxvd2VkIGluIGFkZGl0aW9uIHRvICdyZWYnIik7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIE5vIGNoaWxkcmVuIGV4Y2VwdCA8YW5ub3RhdGlvbj4gZXhwZWN0ZWQuCgkqLwoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKCX0KCWlmICgobWluID09IDApICYmIChtYXggPT0gMCkpCgkgICAgZ290byByZXR1cm5fbnVsbDsKCS8qCgkqIENyZWF0ZSB0aGUgcmVmZXJlbmNlIGl0ZW0gYW5kIGF0dGFjaCBpdCB0byB0aGUgcGFydGljbGUuCgkqLwoJcmVmZXIgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihjdHh0LCBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCwKCSAgICByZWYsIHJlZk5zKTsKCWlmIChyZWZlciA9PSBOVUxMKQoJICAgIGdvdG8gcmV0dXJuX251bGw7CglwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHJlZmVyOwoJcGFydGljbGUtPmFubm90ID0gYW5ub3Q7CgkvKgoJKiBBZGQgdGhlIHBhcnRpY2xlIHRvIHBlbmRpbmcgY29tcG9uZW50cywgc2luY2UgdGhlIHJlZmVyZW5jZQoJKiBuZWVkIHRvIGJlIHJlc29sdmVkLgoJKi8KCVdYU19BRERfUEVORElORyhjdHh0LCBwYXJ0aWNsZSk7CglyZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHBhcnRpY2xlKTsKICAgIH0KICAgIC8qCiAgICAqIFRoZSBkZWNsYXJhdGlvbiBwYXJ0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAqLwpkZWNsYXJhdGlvbl9wYXJ0OgogICAgewoJY29uc3QgeG1sQ2hhciAqbnMgPSBOVUxMLCAqZml4ZWQsICpuYW1lLCAqYXR0clZhbHVlOwoJeG1sU2NoZW1hSURDUHRyIGN1cklEQyA9IE5VTEwsIGxhc3RJREMgPSBOVUxMOwoKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgbmFtZUF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApCgkgICAgZ290byByZXR1cm5fbnVsbDsKCS8qCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KCWlmICh0b3BMZXZlbCkgewoJICAgIG5zID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJfSBlbHNlIHsKCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZvcm0iKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCSAgICBucyA9IGN0eHQtPnRhcmdldE5hbWVzcGFjZTsKCQl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKQoJCW5zID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJfQoJZGVjbCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgbmFtZSwgbnMsIG5vZGUsIHRvcExldmVsKTsKCWlmIChkZWNsID09IE5VTEwpIHsKCSAgICBnb3RvIHJldHVybl9udWxsOwoJfQoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWxsYWJsZSIpKSkKCQl7CgkJICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CgkJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSkKCQkJewoJCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJCX0KCQkgICAgfSBlbHNlIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSAmJgoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJhYnN0cmFjdCIpKSAmJgoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzdWJzdGl0dXRpb25Hcm91cCIpKSkgewoKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJICAgIH0KCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQoJLyoKCSogRXh0cmFjdC92YWxpZGF0ZSBhdHRyaWJ1dGVzLgoJKi8KCWlmICh0b3BMZXZlbCkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIHRvcCBhdHRyaWJ1dGVzIG9mIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9ucyBoZXJlLgoJICAgICovCgkgICAgZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUw7CgkgICAgZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9UT1BMRVZFTDsKCSAgICB4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwKCQlOVUxMLCBub2RlLCAic3Vic3RpdHV0aW9uR3JvdXAiLAoJCSYoZGVjbC0+c3Vic3RHcm91cE5zKSwgJihkZWNsLT5zdWJzdEdyb3VwKSk7CgkgICAgaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIG5vZGUsICJhYnN0cmFjdCIsIDApKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1Q7CgkgICAgLyoKCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJICAgICovCgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbCIpOwoJICAgIGlmIChhdHRyID09IE5VTEwpIHsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OKQoJCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTjsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT047CgkgICAgfSBlbHNlIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYoZGVjbC0+ZmxhZ3MpLAoJCSAgICAtMSwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9FWFRFTlNJT04sCgkJICAgIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04sIC0xLCAtMSwgLTEpICE9IDApIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJCU5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0KCSAgICB9Cgl9CgkvKgoJKiBBdHRyaWJ1dGUgImJsb2NrIi4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImJsb2NrIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEFwcGx5IGRlZmF1bHQgImJsb2NrIiB2YWx1ZXMuCgkgICAgKi8KCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTjsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OOwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04pCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT047Cgl9IGVsc2UgewoJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihkZWNsLT5mbGFncyksCgkJLTEsCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04sCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTiwKCQlYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTiwgLTEsIC0xKSAhPSAwKSB7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8ICIKCQkgICAgInJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkiLCBhdHRyVmFsdWUsCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0KCX0KCWlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBub2RlLCAibmlsbGFibGUiLCAwKSkKCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFOwoKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidHlwZSIpOwoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwKCQlOVUxMLCBhdHRyLAoJCSYoZGVjbC0+bmFtZWRUeXBlTnMpLCAmKGRlY2wtPm5hbWVkVHlwZSkpOwoJICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwKCQlhdHRyLCBkZWNsLT5uYW1lZFR5cGVOcyk7Cgl9CglkZWNsLT52YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImRlZmF1bHQiKTsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZml4ZWQiKTsKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICBmaXhlZCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAoZGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJCS8qCgkJKiAzLjMuMyA6IDEKCQkqIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KCQkqLwoJCXhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8xLAoJCSAgICBOVUxMLCBhdHRyLCAiZGVmYXVsdCIsICJmaXhlZCIpOwoJICAgIH0gZWxzZSB7CgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9GSVhFRDsKCQlkZWNsLT52YWx1ZSA9IGZpeGVkOwoJICAgIH0KCX0KCS8qCgkqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgLyoKCSAgICAqIDMuMy4zIDogMwoJICAgICogInR5cGUiIGFuZCBlaXRoZXIgPHNpbXBsZVR5cGU+IG9yIDxjb21wbGV4VHlwZT4gYXJlIG11dHVhbGx5CgkgICAgKiBleGNsdXNpdmUKCSAgICAqLwoJICAgIGlmIChkZWNsLT5uYW1lZFR5cGUgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzMsCgkJICAgIE5VTEwsIG5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8Y29tcGxleFR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlXWFNfRUxFTV9UWVBFREVGKGRlY2wpID0geG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICAvKgoJICAgICogMy4zLjMgOiAzCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUKCSAgICAqIG11dHVhbGx5IGV4Y2x1c2l2ZQoJICAgICovCgkgICAgaWYgKGRlY2wtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlCgkJV1hTX0VMRU1fVFlQRURFRihkZWNsKSA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJ1bmlxdWUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHx8IChJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkpIHsKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAidW5pcXVlIikpIHsKCQljdXJJREMgPSB4bWxTY2hlbWFQYXJzZUlEQyhjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRSwgZGVjbC0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImtleSIpKSB7CgkJY3VySURDID0geG1sU2NoZW1hUGFyc2VJREMoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVksIGRlY2wtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGLCBkZWNsLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIH0KCSAgICBpZiAobGFzdElEQyAhPSBOVUxMKQoJCWxhc3RJREMtPm5leHQgPSBjdXJJREM7CgkgICAgZWxzZQoJCWRlY2wtPmlkY3MgPSAodm9pZCAqKSBjdXJJREM7CgkgICAgbGFzdElEQyA9IGN1cklEQzsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIG5vZGUsIGNoaWxkLAoJCU5VTEwsICIoYW5ub3RhdGlvbj8sICgoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlKT8sICIKCQkiKHVuaXF1ZSB8IGtleSB8IGtleXJlZikqKSkiKTsKCX0KCWRlY2wtPmFubm90ID0gYW5ub3Q7CiAgICB9CiAgICAvKgogICAgKiBOT1RFOiBFbGVtZW50IERlY2xhcmF0aW9uIFJlcHJlc2VudGF0aW9uIE9LIDQuIHdpbGwgYmUgY2hlY2tlZCBhdCBhCiAgICAqIGRpZmZlcmVudCBsYXllci4KICAgICovCiAgICBGUkVFX0FORF9OVUxMKGRlcykKICAgIGlmICh0b3BMZXZlbCkKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgZGVjbCk7CiAgICBlbHNlIHsKCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgZGVjbDsKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcGFydGljbGUpOwogICAgfQoKcmV0dXJuX251bGw6CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBpZiAoYW5ub3QgIT0gTlVMTCkgewoJaWYgKHBhcnRpY2xlICE9IE5VTEwpCgkgICAgcGFydGljbGUtPmFubm90ID0gTlVMTDsKCWlmIChkZWNsICE9IE5VTEwpCgkgICAgZGVjbC0+YW5ub3QgPSBOVUxMOwoJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVVuaW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBVbmlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGludGVybmFsIGVycm9yLCAwIGluIGNhc2Ugb2Ygc3VjY2VzcyBhbmQgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VVbmlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIC8qCiAgICAqIE1hcmsgdGhlIHNpbXBsZSB0eXBlIGFzIGJlaW5nIG9mIHZhcmlldHkgInVuaW9uIi4KICAgICovCiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CiAgICAvKgogICAgKiBTUEVDIChCYXNlIHR5cGUpICgyKSAiSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKICAgICogdGhlbiB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LiIKICAgICovCiAgICB0eXBlLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWVtYmVyVHlwZXMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAibWVtYmVyVHlwZXMiLiBUaGlzIGlzIGEgbGlzdCBvZiBRTmFtZXMuCiAgICAqIFRPRE86IENoZWNrIHRoZSB2YWx1ZSB0byBjb250YWluIGFueXRoaW5nLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWVtYmVyVHlwZXMiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCWNvbnN0IHhtbENoYXIgKmVuZDsKCXhtbENoYXIgKnRtcDsKCWNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSwgKm5zTmFtZTsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rID0gTlVMTDsKCXhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKCgljdXIgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7Cgl0eXBlLT5iYXNlID0gY3VyOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWUoY3R4dCwgc2NoZW1hLAoJCU5VTEwsIGF0dHIsIEJBRF9DQVNUIHRtcCwgJm5zTmFtZSwgJmxvY2FsTmFtZSkgPT0gMCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIG1lbWJlciB0eXBlIGxpbmsuCgkJKi8KCQlsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKQoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CgkJaWYgKGxpbmsgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJ4bWxTY2hlbWFQYXJzZVVuaW9uLCAiCgkJCSJhbGxvY2F0aW5nIGEgdHlwZSBsaW5rIiwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlsaW5rLT50eXBlID0gTlVMTDsKCQlsaW5rLT5uZXh0ID0gTlVMTDsKCQlpZiAobGFzdExpbmsgPT0gTlVMTCkKCQkgICAgdHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rOwoJCWVsc2UKCQkgICAgbGFzdExpbmstPm5leHQgPSBsaW5rOwoJCWxhc3RMaW5rID0gbGluazsKCQkvKgoJCSogQ3JlYXRlIGEgcmVmZXJlbmNlIGl0ZW0uCgkJKi8KCQlyZWYgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihjdHh0LCBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLAoJCSAgICBsb2NhbE5hbWUsIG5zTmFtZSk7CgkJaWYgKHJlZiA9PSBOVUxMKSB7CgkJICAgIEZSRUVfQU5EX05VTEwodG1wKQoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJLyoKCQkqIEFzc2lnbiB0aGUgcmVmZXJlbmNlIHRvIHRoZSBsaW5rLCBpdCB3aWxsIGJlIHJlc29sdmVkCgkJKiBsYXRlciBkdXJpbmcgZml4dXAgb2YgdGhlIHVuaW9uIHNpbXBsZSB0eXBlLgoJCSovCgkJbGluay0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSByZWY7CgkgICAgfQoJICAgIEZSRUVfQU5EX05VTEwodG1wKQoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CgogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIEFkZCB0aGUgYW5ub3RhdGlvbiB0byB0aGUgc2ltcGxlIHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwoKCS8qCgkqIEFuY2hvciB0aGUgbWVtYmVyIHR5cGVzIGluIHRoZSAic3VidHlwZXMiIGZpZWxkIG9mIHRoZQoJKiBzaW1wbGUgdHlwZS4KCSovCgl3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CgkJaWYgKGxhc3QgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CgkJICAgIGxhc3QgPSBzdWJ0eXBlOwoJCX0gZWxzZSB7CgkJICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwoJCSAgICBsYXN0ID0gc3VidHlwZTsKCQl9CgkJbGFzdC0+bmV4dCA9IE5VTEw7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZSopIik7CiAgICB9CiAgICBpZiAoKGF0dHIgPT0gTlVMTCkgJiYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpKSB7CgkgLyoKCSogc3JjLXVuaW9uLW1lbWJlclR5cGVzLW9yLXNpbXBsZVR5cGVzCgkqIEVpdGhlciB0aGUgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0gb2YgdGhlIDx1bmlvbj4gZWxlbWVudCBtdXN0CgkqIGJlIG5vbi1lbXB0eSBvciB0aGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSBzaW1wbGVUeXBlIFtjaGlsZF0uCgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19VTklPTl9NRU1CRVJUWVBFU19PUl9TSU1QTEVUWVBFUywKCSAgICBOVUxMLCBub2RlLAoJICAgICJFaXRoZXIgdGhlIGF0dHJpYnV0ZSAnbWVtYmVyVHlwZXMnIG9yICIKCSAgICAiYXQgbGVhc3Qgb25lIDxzaW1wbGVUeXBlPiBjaGlsZCBtdXN0IGJlIHByZXNlbnQiLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxpc3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIExpc3QgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICAvKgogICAgKiBNYXJrIHRoZSB0eXBlIGFzIGJlaW5nIG9mIHZhcmlldHkgImxpc3QiLgogICAgKi8KICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUOwogICAgLyoKICAgICogU1BFQyAoQmFzZSB0eXBlKSAoMikgIklmIHRoZSA8bGlzdD4gb3IgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sCiAgICAqIHRoZW4gdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4iCiAgICAqLwogICAgdHlwZS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIml0ZW1UeXBlIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAiaXRlbVR5cGUiLiBOT1RFIHRoYXQgd2Ugd2lsbCB1c2UgdGhlICJyZWYiIGFuZCAicmVmTnMiCiAgICAqIGZpZWxkcyBmb3IgaG9sZGluZyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBpdGVtVHlwZS4KICAgICoKICAgICogUkVWQU1QIFRPRE86IFVzZSB0aGUgImJhc2UiIGFuZCAiYmFzZU5zIiBmaWVsZHMsIHNpbmNlIHdlIHdpbGwgcmVtb3ZlCiAgICAqIHRoZSAicmVmIiBmaWVsZHMuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsCglub2RlLCAiaXRlbVR5cGUiLCAmKHR5cGUtPmJhc2VOcyksICYodHlwZS0+YmFzZSkpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJLyoKCSogc3JjLWxpc3QtaXRlbVR5cGUtb3Itc2ltcGxlVHlwZQoJKiBFaXRoZXIgdGhlIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIHRoZSA8c2ltcGxlVHlwZT4gW2NoaWxkXSBvZgoJKiB0aGUgPGxpc3Q+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguCgkqLwoJaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMSwKCQlOVUxMLCBub2RlLAoJCSJUaGUgYXR0cmlidXRlICdpdGVtVHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIHR5cGUtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdpdGVtVHlwZScgb3IgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgIm11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsICIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGU/KSIpOwogICAgfQogICAgaWYgKCh0eXBlLT5iYXNlID09IE5VTEwpICYmCgkodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCSh4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiaXRlbVR5cGUiKSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdpdGVtVHlwZScgb3IgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgIm11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlIFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIG9sZEN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICphdHRyVmFsdWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IGhhc1Jlc3RyaWN0aW9uID0gMDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmICh0b3BMZXZlbCkgewoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LAoJCU5VTEwsIGF0dHIsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJmF0dHJWYWx1ZSkgIT0gMCkKCQlyZXR1cm4gKE5VTEwpOwoJICAgIC8qCgkgICAgKiBTa2lwIGJ1aWx0LWluIHR5cGVzLgoJICAgICovCgkgICAgaWYgKGN0eHQtPmlzUzRTKSB7CgkJeG1sU2NoZW1hVHlwZVB0ciBiaVR5cGU7CgoJCWlmIChjdHh0LT5pc1JlZGVmaW5lKSB7CgkJICAgIC8qCgkJICAgICogUkVERUZJTkU6IERpc2FsbG93IHJlZGVmaW5pdGlvbiBvZiBidWlsdC1pbi10eXBlcy4KCQkgICAgKiBUT0RPOiBJdCBzZWVtcyB0aGF0IHRoZSBzcGVjIGRvZXMgbm90IHNheSBhbnl0aGluZwoJCSAgICAqIGFib3V0IHRoaXMgY2FzZS4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsCgkJCU5VTEwsIG5vZGUsCgkJCSJSZWRlZmluaXRpb24gb2YgYnVpbHQtaW4gc2ltcGxlIHR5cGVzIGlzIG5vdCAiCgkJCSJzdXBwb3J0ZWQiLCBOVUxMKTsKCQkgICAgcmV0dXJuKE5VTEwpOwoJCX0KCQliaVR5cGUgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShhdHRyVmFsdWUsIHhtbFNjaGVtYU5zKTsKCQlpZiAoYmlUeXBlICE9IE5VTEwpCgkJICAgIHJldHVybiAoYmlUeXBlKTsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBUYXJnZXROYW1lc3BhY2U6CiAgICAqIFNQRUMgIlRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdCiAgICAqIG9mIHRoZSA8c2NoZW1hPiBhbmNlc3RvciBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaWYgcHJlc2VudCwKICAgICogb3RoZXJ3aXNlILdhYnNlbnS3LgogICAgKi8KICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CiNpZmRlZiBFTkFCTEVfTkFNRURfTE9DQUxTCiAgICAgICAgY2hhciBidWZbNDBdOwojZW5kaWYKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwojaWZkZWYgRU5BQkxFX05BTUVEX0xPQ0FMUwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjU1QlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsCgkgICAgeG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgLTEpLAoJICAgIGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMCk7CiNlbHNlCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwKCSAgICBOVUxMLCBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUsIDApOwojZW5kaWYKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsgCgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSoKCSogTm90ZSB0aGF0IGF0dHJWYWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAibmFtZSIgaGVyZS4KCSovCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsCgkgICAgYXR0clZhbHVlLCBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUsIDEpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7Cgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIEF0dHJpYnV0ZSAiZmluYWwiLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVCkKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1Q7CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT047Cgl9IGVsc2UgewoJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZpbmFsIik7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYodHlwZS0+ZmxhZ3MpLAoJCS0xLCAtMSwgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTiwgLTEsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNULAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT04pICE9IDApIHsKCgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGxpc3QgfCB1bmlvbiB8IHJlc3RyaWN0aW9uKSIsCgkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQogICAgfQogICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZEN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICAKICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGxpc3QgfCB1bmlvbikpIik7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsJCiAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpOwkKCWhhc1Jlc3RyaWN0aW9uID0gMTsJCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibGlzdCIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VMaXN0KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInVuaW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZVVuaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiKTsKICAgIH0KICAgIC8qCiAgICAqIFJFREVGSU5FOiBTUEVDIHNyYy1yZWRlZmluZSAoNSkKICAgICogIldpdGhpbiB0aGUgW2NoaWxkcmVuXSwgZWFjaCA8c2ltcGxlVHlwZT4gbXVzdCBoYXZlIGEKICAgICogPHJlc3RyaWN0aW9uPiBhbW9uZyBpdHMgW2NoaWxkcmVuXSAuLi4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHdob3NlCiAgICAqIGJhc2UgW2F0dHJpYnV0ZV0gbXVzdCBiZSB0aGUgc2FtZSBhcyB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgaXRzIG93bgogICAgKiBuYW1lIGF0dHJpYnV0ZSBwbHVzIHRhcmdldCBuYW1lc3BhY2U7IgogICAgKi8KICAgIGlmICh0b3BMZXZlbCAmJiBjdHh0LT5pc1JlZGVmaW5lICYmICghIGhhc1Jlc3RyaWN0aW9uKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsCgkgICAgTlVMTCwgbm9kZSwgIlRoaXMgaXMgYSByZWRlZmluaXRpb24sIHRodXMgdGhlICIKCSAgICAiPHNpbXBsZVR5cGU+IG11c3QgaGF2ZSBhIDxyZXN0cmljdGlvbj4gY2hpbGQiLCBOVUxMKTsKICAgIH0KICAgIAogICAgY3R4dC0+Y3R4dFR5cGUgPSBvbGRDdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWY6CiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICB0aGUgbm9kZQogKgogKiBQYXJzZXMgYSByZWZlcmVuY2UgdG8gYSBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogKgogKiBXZSB3aWxsIHJldHVybiBhIHBhcnRpY2xlIGNvbXBvbmVudCB3aXRoIGEgcW5hbWUtY29tcG9uZW50IG9yCiAqIE5VTEwgaW4gY2FzZSBvZiBhbiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqcmVmID0gTlVMTCwgKnJlZk5zID0gTlVMTDsKICAgIGludCBtaW4sIG1heDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsICJyZWYiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwgTlVMTCwKCWF0dHIsICZyZWZOcywgJnJlZikgIT0gMCkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgYXR0ciwgcmVmTnMpOwogICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLAoJIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGl0ZW0gPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShjdHh0LCBub2RlLCBtaW4sIG1heCk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsgICAgCiAgICAvKgogICAgKiBDcmVhdGUgYSBxbmFtZS1yZWZlcmVuY2UgYW5kIHNldCBhcyB0aGUgdGVybTsgaXQgd2lsbCBiZSBzdWJzdGl0dXRlZAogICAgKiBmb3IgdGhlIG1vZGVsIGdyb3VwIGFmdGVyIHRoZSByZWZlcmVuY2UgaGFzIGJlZW4gcmVzb2x2ZWQuCiAgICAqLwogICAgaXRlbS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgl4bWxTY2hlbWFOZXdRTmFtZVJlZihjdHh0LCBYTUxfU0NIRU1BX1RZUEVfR1JPVVAsIHJlZiwgcmVmTnMpOyAgICAKICAgIHhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIGl0ZW0sIG5vZGUsIG1pbiwgbWF4KTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICAvKiBUT0RPOiBJcyBhbm5vdGF0aW9uIGV2ZW4gYWxsb3dlZCBmb3IgYSBtb2RlbCBncm91cCByZWZlcmVuY2U/ICovCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBUT0RPOiBXaGF0IHRvIGRvIGV4YWN0bHkgd2l0aCB0aGUgYW5ub3RhdGlvbj8KCSovCglpdGVtLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIC8qCiAgICAqIENvcnJlc3BvbmRzIHRvIG5vIGNvbXBvbmVudCBhdCBhbGwgaWYgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAuCiAgICAqLwogICAgaWYgKChtaW4gPT0gMCkgJiYgKG1heCA9PSAwKSkKCXJldHVybiAoTlVMTCk7CgogICAgcmV0dXJuICgoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmaW5pdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAqCiAqIE5vdGUgdGhhdCB0aGUgY29udHJhaW50IHNyYy1yZWRlZmluZSAoNi4yKSBjYW4ndCBiZSBhcHBsaWVkIHVudGlsCiAqIHJlZmVyZW5jZXMgaGF2ZSBiZWVuIHJlc29sdmVkLiBTbyB3ZSB3aWxsIGRvIHRoaXMgYXQgdGhlCiAqIGNvbXBvbmVudCBmaXh1cCBsZXZlbC4KICogICAgCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZmluaXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIm5hbWUiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBhdHRyLAoJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpdGVtID0geG1sU2NoZW1hQWRkTW9kZWxHcm91cERlZmluaXRpb24oY3R4dCwgc2NoZW1hLCBuYW1lLAoJY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKCWl0ZW0tPmNoaWxkcmVuID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCwgMCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewoJaXRlbS0+Y2hpbGRyZW4gPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCWl0ZW0tPmNoaWxkcmVuID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CgogICAKCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAoYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpPykiKTsKICAgIH0KICAgIHJldHVybiAoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhbnVwRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSByb290IG9mIHRoZSBkb2N1bWVudC4KICoKICogcmVtb3ZlcyB1bndhbnRlZCBub2RlcyBpbiBhIHNjaGVtYXMgZG9jdW1lbnQgdHJlZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYW51cERvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgcm9vdCkKewogICAgeG1sTm9kZVB0ciBkZWxldGUsIGN1cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHJvb3QgPT0gTlVMTCkpIHJldHVybjsKCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICBkZWxldGUgPSBOVUxMOwogICAgY3VyID0gcm9vdDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgewogICAgICAgICAgICBpZiAoSVNfQkxBTktfTk9ERShjdXIpKSB7CiAgICAgICAgICAgICAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIGRlbGV0ZSA9IGN1cjsKICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBTa2lwIHRvIG5leHQgbm9kZQogICAgICAgICAqLwogICAgICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfUkVGX05PREUpICYmCiAgICAgICAgICAgICAgICAoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX05PREUpKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIHNraXBfY2hpbGRyZW46CiAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBkbyB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+cGFyZW50OwogICAgICAgICAgICBpZiAoY3VyID09IE5VTEwpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgaWYgKGN1ciA9PSByb290KSB7CiAgICAgICAgICAgICAgICBjdXIgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICB4bWxGcmVlTm9kZShkZWxldGUpOwogICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICB9Cn0KCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1QpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVDsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsKCiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlU2NoZW1hRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKICAgIGludCByZXMgPSAwLCBvbGRFcnJzID0gY3R4dC0+bmJlcnJvcnM7CgogICAgLyoKICAgICogVGhvc2UgZmxhZ3Mgc2hvdWxkIGJlIG1vdmVkIHRvIHRoZSBwYXJzZXIgY29udGV4dCBmbGFncywKICAgICogc2luY2UgdGhleSBhcmUgbm90IHZpc2libGUgYXQgdGhlIGNvbXBvbmVudCBsZXZlbC4gSS5lLgogICAgKiB0aGV5IGFyZSB1c2VkIGlmIHByb2Nlc3Npbmcgc2NoZW1hICpkb2N1bWVudHMqIG9ubHkuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIEhGQUlMVVJFOwoKICAgIC8qCiAgICAqIFNpbmNlIHRoZSB2ZXJzaW9uIGlzIG9mIHR5cGUgeHM6dG9rZW4sIHdlIHdvbid0IGJvdGhlciB0bwogICAgKiBjaGVjayBpdC4KICAgICovCiAgICAvKiBSRU1PVkVEOgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ2ZXJzaW9uIik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CglyZXMgPSB4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgTlVMTCwgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19UT0tFTiksICZ2YWwpOyAgICAKCUhGQUlMVVJFOwogICAgfQogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidGFyZ2V0TmFtZXNwYWNlIik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CglyZXMgPSB4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCBOVUxMKTsKCUhGQUlMVVJFOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgY3R4dC0+c3RvcCA9IFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUU7CgkgICAgZ290byBleGl0OwoJfQogICAgfQogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJlbGVtZW50Rm9ybURlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQodmFsLCAmc2NoZW1hLT5mbGFncywKCSAgICBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSk7CglIRkFJTFVSRTsKCWlmIChyZXMgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfRUxFTUZPUk1ERUZBVUxUX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYXR0cmlidXRlRm9ybURlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQodmFsLCAmc2NoZW1hLT5mbGFncywKCSAgICBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUik7CglIRkFJTFVSRTsKCWlmIChyZXMgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQVRUUkZPUk1ERUZBVUxUX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWxEZWZhdWx0Iik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgl2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CglyZXMgPSB4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwodmFsLCAmKHNjaGVtYS0+ZmxhZ3MpLCAtMSwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTiwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OLAoJICAgIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVCwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OKTsKCUhGQUlMVVJFOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImJsb2NrRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbCh2YWwsICYoc2NoZW1hLT5mbGFncyksIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04sCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04sIC0xLCAtMSk7CglIRkFJTFVSRTsKCWlmIChyZXMgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbiB8IHN1YnN0aXR1dGlvbikpIiwKCQl2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQogICAgfQoKZXhpdDoKICAgIGlmIChvbGRFcnJzICE9IGN0eHQtPm5iZXJyb3JzKQoJcmVzID0gY3R4dC0+ZXJyOwogICAgcmV0dXJuKHJlcyk7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMKICogQG5vZGVzOiAgdGhlIGxpc3Qgb2YgdG9wIGxldmVsIG5vZGVzCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZXMpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIGludCByZXMgPSAwLCBvbGRFcnJzLCB0bXBPbGRFcnJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlcyA9PSBOVUxMKSkKICAgICAgICByZXR1cm4oLTEpOwoKICAgIG9sZEVycnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGNoaWxkID0gbm9kZXM7CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJpbXBvcnQiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJyZWRlZmluZSIpKSB8fAoJICAgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImltcG9ydCIpKSB7CgkgICAgdG1wT2xkRXJycyA9IGN0eHQtPm5iZXJyb3JzOwoJICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW1wb3J0KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIEhGQUlMVVJFOwoJICAgIEhTVE9QKGN0eHQpOwoJICAgIGlmICh0bXBPbGRFcnJzICE9IGN0eHQtPm5iZXJyb3JzKQoJCWdvdG8gZXhpdDsJICAgIAoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJpbmNsdWRlIikpIHsKCSAgICB0bXBPbGRFcnJzID0gY3R4dC0+bmJlcnJvcnM7CgkgICAgcmVzID0geG1sU2NoZW1hUGFyc2VJbmNsdWRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIEhGQUlMVVJFOwoJICAgIEhTVE9QKGN0eHQpOwoJICAgIGlmICh0bXBPbGRFcnJzICE9IGN0eHQtPm5iZXJyb3JzKQoJCWdvdG8gZXhpdDsJICAgIAoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZWRlZmluZSIpKSB7CgkgICAgdG1wT2xkRXJycyA9IGN0eHQtPm5iZXJyb3JzOwoJICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlUmVkZWZpbmUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgSEZBSUxVUkU7CgkgICAgSFNUT1AoY3R4dCk7CgkgICAgaWYgKHRtcE9sZEVycnMgIT0gY3R4dC0+bmJlcnJvcnMpCgkJZ290byBleGl0OwoJfQoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIFVSR0VOVCBUT0RPOiBDaGFuZ2UgdGhlIGZ1bmN0aW9ucyB0byByZXR1cm4gaW50IHJlc3VsdHMuCiAgICAqIFdlIG5lZWQgZXNwZWNpYWxseSB0byBjYXRjaCBpbnRlcm5hbCBlcnJvcnMuCiAgICAqLwogICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIE5VTEwsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VHbG9iYWxBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXBEZWZpbml0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgIm5vdGF0aW9uIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZU5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgY2hpbGQtPnBhcmVudCwgY2hpbGQsCgkJTlVMTCwgIigoaW5jbHVkZSB8IGltcG9ydCB8IHJlZGVmaW5lIHwgYW5ub3RhdGlvbikqLCAiCgkJIigoKHNpbXBsZVR5cGUgfCBjb21wbGV4VHlwZSB8IGdyb3VwIHwgYXR0cmlidXRlR3JvdXApICIKCQkifCBlbGVtZW50IHwgYXR0cmlidXRlIHwgbm90YXRpb24pLCBhbm5vdGF0aW9uKikqKSIpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9Cgl3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFdlIHNob3VsZCBhZGQgYWxsIGFubm90YXRpb25zLgoJICAgICovCgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwoJICAgIGlmIChzY2hlbWEtPmFubm90ID09IE5VTEwpCgkJc2NoZW1hLT5hbm5vdCA9IGFubm90OwoJICAgIGVsc2UKCQl4bWxTY2hlbWFGcmVlQW5ub3QoYW5ub3QpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CmV4aXQ6CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CiAgICBpZiAob2xkRXJycyAhPSBjdHh0LT5uYmVycm9ycykKCXJlcyA9IGN0eHQtPmVycjsKICAgIHJldHVybihyZXMpOwpleGl0X2ZhaWx1cmU6CiAgICByZXR1cm4oLTEpOwp9CgpzdGF0aWMgeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIKeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25DcmVhdGUodm9pZCkKewogICAgeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hU2NoZW1hUmVsYXRpb24pKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcmVsYXRpb24iLCBOVUxMKTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbikpOwogICAgcmV0dXJuKHJldCk7Cn0KCiNpZiAwCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uRnJlZSh4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWwpCnsKICAgIHhtbEZyZWUocmVsKTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVJlZGVmTGlzdEZyZWUoeG1sU2NoZW1hUmVkZWZQdHIgcmVkZWYpCnsKICAgIHhtbFNjaGVtYVJlZGVmUHRyIHByZXY7CgogICAgd2hpbGUgKHJlZGVmICE9IE5VTEwpIHsKCXByZXYgPSByZWRlZjsKCXJlZGVmID0gcmVkZWYtPm5leHQ7Cgl4bWxGcmVlKHByZXYpOwogICAgfQp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0RnJlZSh4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0UHRyIGNvbikKewogICAgLyoKICAgICogQWZ0ZXIgdGhlIGNvbnN0cnVjdGlvbiBjb250ZXh0IGhhcyBiZWVuIGZyZWVkLCB0aGVyZSB3aWxsIGJlCiAgICAqIG5vIHNjaGVtYSBncmFwaCBhdmFpbGFibGUgYW55IG1vcmUuIE9ubHkgdGhlIHNjaGVtYSBidWNrZXRzCiAgICAqIHdpbGwgc3RheSBhbGl2ZSwgd2hpY2ggYXJlIHB1dCBpbnRvIHRoZSAic2NoZW1hc0ltcG9ydHMiIGFuZAogICAgKiAiaW5jbHVkZXMiIHNsb3RzIG9mIHRoZSB4bWxTY2hlbWEuCiAgICAqLwogICAgaWYgKGNvbi0+YnVja2V0cyAhPSBOVUxMKQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGNvbi0+YnVja2V0cyk7CiAgICBpZiAoY29uLT5wZW5kaW5nICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoY29uLT5wZW5kaW5nKTsKICAgIGlmIChjb24tPnN1YnN0R3JvdXBzICE9IE5VTEwpCgl4bWxIYXNoRnJlZShjb24tPnN1YnN0R3JvdXBzLAoJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYVN1YnN0R3JvdXBGcmVlKTsKICAgIGlmIChjb24tPnJlZGVmcyAhPSBOVUxMKQoJeG1sU2NoZW1hUmVkZWZMaXN0RnJlZShjb24tPnJlZGVmcyk7CiAgICBpZiAoY29uLT5kaWN0ICE9IE5VTEwpCgl4bWxEaWN0RnJlZShjb24tPmRpY3QpOwogICAgeG1sRnJlZShjb24pOwp9CgpzdGF0aWMgeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dFB0ciAKeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dENyZWF0ZSh4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0UHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgc2NoZW1hIGNvbnN0cnVjdGlvbiBjb250ZXh0IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0KSk7CgogICAgcmV0LT5idWNrZXRzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIGlmIChyZXQtPmJ1Y2tldHMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJICAgICJhbGxvY2F0aW5nIGxpc3Qgb2Ygc2NoZW1hIGJ1Y2tldHMiLCBOVUxMKTsKCXhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5wZW5kaW5nID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIGlmIChyZXQtPnBlbmRpbmcgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJICAgICJhbGxvY2F0aW5nIGxpc3Qgb2YgcGVuZGluZyBnbG9iYWwgY29tcG9uZW50cyIsIE5VTEwpOwoJeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5kaWN0ID0gZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UoZGljdCk7CiAgICByZXR1cm4ocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSh2b2lkKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVI7CiAgICByZXQtPmF0dHJQcm9oaWJzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIGlmIChyZXQtPmF0dHJQcm9oaWJzID09IE5VTEwpIHsKCXhtbEZyZWUocmV0KTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIHJldHVybihyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3Q6CiAqIEBVUkw6ICB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKiBAZGljdDogdGhlIGRpY3Rpb25hcnkgdG8gYmUgdXNlZAogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBmaWxlL3Jlc291cmNlIGV4cGVjdGVkCiAqIHRvIGNvbnRhaW4gYW4gWE1MIFNjaGVtYXMgZmlsZS4KICoKICogUmV0dXJucyB0aGUgcGFyc2VyIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdChjb25zdCBjaGFyICpVUkwsIHhtbERpY3RQdHIgZGljdCkKewogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciByZXQ7CgogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSgpOwogICAgaWYgKHJldCA9PSBOVUxMKSAgICAgICAgCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldC0+ZGljdCA9IGRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKGRpY3QpOyAgICAKICAgIGlmIChVUkwgIT0gTlVMTCkKCXJldC0+VVJMID0geG1sRGljdExvb2t1cChkaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKICAgICAgICBpZiAodmN0eHQtPnNjaGVtYSAhPSBOVUxMKQoJICAgIHZjdHh0LT5wY3R4dCA9CgkJeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoIioiLCB2Y3R4dC0+c2NoZW1hLT5kaWN0KTsKCWVsc2UKCSAgICB2Y3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7CglpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQiLAoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qIFRPRE86IFBhc3MgdXNlciBkYXRhLiAqLwoJeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHZjdHh0LT5wY3R4dCwgdmN0eHQtPmVycm9yLAoJICAgIHZjdHh0LT53YXJuaW5nLCB2Y3R4dC0+ZXJyQ3R4dCk7Cgl4bWxTY2hlbWFTZXRQYXJzZXJTdHJ1Y3R1cmVkRXJyb3JzKHZjdHh0LT5wY3R4dCwgdmN0eHQtPnNlcnJvciwKCSAgICB2Y3R4dC0+ZXJyQ3R4dCk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hR2V0U2NoZW1hQnVja2V0OgogKiBAcGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYUxvY2F0aW9uOiB0aGUgVVJJIG9mIHRoZSBzY2hlbWEgZG9jdW1lbnQKICoKICogUmV0dXJucyBhIHNjaGVtYSBidWNrZXQgaWYgaXQgd2FzIGFscmVhZHkgcGFyc2VkLgogKgogKiBSZXR1cm5zIGEgc2NoZW1hIGJ1Y2tldCBpZiBpdCB3YXMgYWxyZWFkeSBwYXJzZWQgZnJvbQogKiAgICAgICAgIEBzY2hlbWFMb2NhdGlvbiwgTlVMTCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQnVja2V0UHRyCnhtbFNjaGVtYUdldFNjaGVtYUJ1Y2tldCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24pCnsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBjdXI7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0OwoKICAgIGxpc3QgPSBwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldHM7CiAgICBpZiAobGlzdC0+bmJJdGVtcyA9PSAwKQoJcmV0dXJuKE5VTEwpOwogICAgZWxzZSB7CglpbnQgaTsKCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5uYkl0ZW1zOyBpKyspIHsKCSAgICBjdXIgPSAoeG1sU2NoZW1hQnVja2V0UHRyKSBsaXN0LT5pdGVtc1tpXTsKCSAgICAvKiBQb2ludGVyIGNvbXBhcmlzb24hICovCgkgICAgaWYgKGN1ci0+c2NoZW1hTG9jYXRpb24gPT0gc2NoZW1hTG9jYXRpb24pCgkJcmV0dXJuKGN1cik7Cgl9CiAgICB9CiAgICByZXR1cm4oTlVMTCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFCdWNrZXRQdHIKeG1sU2NoZW1hR2V0Q2hhbWVsZW9uU2NoZW1hQnVja2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uLAoJCQkJICAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBjdXI7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0OwoKICAgIGxpc3QgPSBwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldHM7CiAgICBpZiAobGlzdC0+bmJJdGVtcyA9PSAwKQoJcmV0dXJuKE5VTEwpOwogICAgZWxzZSB7CglpbnQgaTsKCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5uYkl0ZW1zOyBpKyspIHsKCSAgICBjdXIgPSAoeG1sU2NoZW1hQnVja2V0UHRyKSBsaXN0LT5pdGVtc1tpXTsKCSAgICAvKiBQb2ludGVyIGNvbXBhcmlzb24hICovCgkgICAgaWYgKChjdXItPm9yaWdUYXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgJiYKCQkoY3VyLT5zY2hlbWFMb2NhdGlvbiA9PSBzY2hlbWFMb2NhdGlvbikgJiYKCQkoY3VyLT50YXJnZXROYW1lc3BhY2UgPT0gdGFyZ2V0TmFtZXNwYWNlKSkKCQlyZXR1cm4oY3VyKTsKCX0KICAgIH0KICAgIHJldHVybihOVUxMKTsKfQoKCiNkZWZpbmUgSVNfQkFEX1NDSEVNQV9ET0MoYikgXAogICAgKCgoYiktPmRvYyA9PSBOVUxMKSAmJiAoKGIpLT5zY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSkKCnN0YXRpYyB4bWxTY2hlbWFCdWNrZXRQdHIKeG1sU2NoZW1hR2V0U2NoZW1hQnVja2V0QnlUTlMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UsCgkJCQkgaW50IGltcG9ydGVkKQp7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgY3VyOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdDsKCiAgICBsaXN0ID0gcGN0eHQtPmNvbnN0cnVjdG9yLT5idWNrZXRzOwogICAgaWYgKGxpc3QtPm5iSXRlbXMgPT0gMCkKCXJldHVybihOVUxMKTsKICAgIGVsc2UgewoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgY3VyID0gKHhtbFNjaGVtYUJ1Y2tldFB0cikgbGlzdC0+aXRlbXNbaV07CgkgICAgaWYgKCghIElTX0JBRF9TQ0hFTUFfRE9DKGN1cikpICYmCgkJKGN1ci0+b3JpZ1RhcmdldE5hbWVzcGFjZSA9PSB0YXJnZXROYW1lc3BhY2UpICYmCgkJKChpbXBvcnRlZCAmJiBjdXItPmltcG9ydGVkKSB8fAoJCSAoKCFpbXBvcnRlZCkgJiYgKCFjdXItPmltcG9ydGVkKSkpKQoJCXJldHVybihjdXIpOwoJfQogICAgfQogICAgcmV0dXJuKE5VTEwpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlTmV3RG9jV2l0aENvbnRleHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0KQp7CiAgICBpbnQgb2xkRmxhZ3M7CiAgICB4bWxEb2NQdHIgb2xkRG9jOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IHJldCwgb2xkRXJyczsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBvbGRidWNrZXQgPSBwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldDsKICAgIAogICAgLyogCiAgICAqIFNhdmUgb2xkIHZhbHVlczsgcmVzZXQgdGhlICptYWluKiBzY2hlbWEuCiAgICAqIFVSR0VOVCBUT0RPOiBUaGlzIGlzIG5vdCBnb29kOyBtb3ZlIHRoZSBwZXItZG9jdW1lbnQgaW5mb3JtYXRpb24KICAgICogdG8gdGhlIHBhcnNlci4gR2V0IHJpZCBvZiBwYXNzaW5nIHRoZSBtYWluIHNjaGVtYSB0byB0aGUKICAgICogcGFyc2luZyBmdW5jdGlvbnMuCiAgICAqLwogICAgb2xkRmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwogICAgb2xkRG9jID0gc2NoZW1hLT5kb2M7CiAgICBpZiAoc2NoZW1hLT5mbGFncyAhPSAwKQoJeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyhzY2hlbWEpOwogICAgc2NoZW1hLT5kb2MgPSBidWNrZXQtPmRvYzsgICAgCiAgICBwY3R4dC0+c2NoZW1hID0gc2NoZW1hOwogICAgLyogCiAgICAqIEtlZXAgdGhlIGN1cnJlbnQgdGFyZ2V0IG5hbWVzcGFjZSBvbiB0aGUgcGFyc2VyICpub3QqIG9uIHRoZQogICAgKiBtYWluIHNjaGVtYS4KICAgICovCiAgICBwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlID0gYnVja2V0LT50YXJnZXROYW1lc3BhY2U7CiAgICBXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXQgPSBidWNrZXQ7CgogICAgaWYgKChidWNrZXQtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSAmJgoJeG1sU3RyRXF1YWwoYnVja2V0LT50YXJnZXROYW1lc3BhY2UsIHhtbFNjaGVtYU5zKSkgewoJLyoKCSogV2UgYXJlIHBhcnNpbmcgdGhlIHNjaGVtYSBmb3Igc2NoZW1hcyEKCSovCglwY3R4dC0+aXNTNFMgPSAxOwogICAgfSAgICAKICAgIC8qIE1hcmsgaXQgYXMgcGFyc2VkLCBldmVuIGlmIHBhcnNpbmcgZmFpbHMuICovCiAgICBidWNrZXQtPnBhcnNlZCsrOwogICAgLyogQ29tcGlsZSB0aGUgc2NoZW1hIGRvYy4gKi8KICAgIG5vZGUgPSB4bWxEb2NHZXRSb290RWxlbWVudChidWNrZXQtPmRvYyk7CiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZVNjaGVtYUVsZW1lbnQocGN0eHQsIHNjaGVtYSwgbm9kZSk7CiAgICBpZiAocmV0ICE9IDApCglnb3RvIGV4aXQ7CiAgICAvKiBBbiBlbXB0eSBzY2hlbWE7IGp1c3QgZ2V0IG91dC4gKi8KICAgIGlmIChub2RlLT5jaGlsZHJlbiA9PSBOVUxMKQoJZ290byBleGl0OwogICAgb2xkRXJycyA9IHBjdHh0LT5uYmVycm9yczsKICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwocGN0eHQsIHNjaGVtYSwgbm9kZS0+Y2hpbGRyZW4pOwogICAgaWYgKHJldCAhPSAwKQoJZ290byBleGl0OwogICAgLyoKICAgICogVE9ETzogTm90IG5pY2UsIGJ1dCBJJ20gbm90IDEwMCUgc3VyZSB3ZSB3aWxsIGdldCBhbHdheXMgYW4gZXJyb3IKICAgICogYXMgYSByZXN1bHQgb2YgdGhlIG9ib3ZlIGZ1bmN0aW9uczsgc28gYmV0dGVyIHJlbHkgb24gcGN0eHQtPmVycgogICAgKiBhcyB3ZWxsLgogICAgKi8KICAgIGlmICgocmV0ID09IDApICYmIChvbGRFcnJzICE9IHBjdHh0LT5uYmVycm9ycykpIHsKCXJldCA9IHBjdHh0LT5lcnI7Cglnb3RvIGV4aXQ7CiAgICB9CiAgICAKZXhpdDoKICAgIFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCA9IG9sZGJ1Y2tldDsKICAgIC8qIFJlc3RvcmUgc2NoZW1hIHZhbHVlcy4gKi8KICAgIHNjaGVtYS0+ZG9jID0gb2xkRG9jOwogICAgc2NoZW1hLT5mbGFncyA9IG9sZEZsYWdzOwogICAgcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VOZXdEb2MoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0KQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIG5ld3BjdHh0OwogICAgaW50IHJlcyA9IDA7CgogICAgaWYgKGJ1Y2tldCA9PSBOVUxMKQoJcmV0dXJuKDApOwogICAgaWYgKGJ1Y2tldC0+cGFyc2VkKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFQYXJzZU5ld0RvYyIsCgkgICAgInJlcGFyc2luZyBhIHNjaGVtYSBkb2MiKTsKCXJldHVybigtMSk7CiAgICB9CiAgICBpZiAoYnVja2V0LT5kb2MgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hUGFyc2VOZXdEb2MiLAoJICAgICJwYXJzaW5nIGEgc2NoZW1hIGRvYywgYnV0IHRoZXJlJ3Mgbm8gZG9jIik7CglyZXR1cm4oLTEpOwogICAgfQogICAgaWYgKHBjdHh0LT5jb25zdHJ1Y3RvciA9PSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFQYXJzZU5ld0RvYyIsCgkgICAgIm5vIGNvbnN0cnVjdG9yIik7CglyZXR1cm4oLTEpOwogICAgfSAgICAKICAgIC8qIENyZWF0ZSBhbmQgaW5pdCB0aGUgdGVtcG9yYXJ5IHBhcnNlciBjb250ZXh0LiAqLwogICAgbmV3cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdCgKCShjb25zdCBjaGFyICopIGJ1Y2tldC0+c2NoZW1hTG9jYXRpb24sIHBjdHh0LT5kaWN0KTsKICAgIGlmIChuZXdwY3R4dCA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKICAgIG5ld3BjdHh0LT5jb25zdHJ1Y3RvciA9IHBjdHh0LT5jb25zdHJ1Y3RvcjsKICAgIC8qCiAgICAqIFRPRE86IENhbiB3ZSBhdm9pZCB0aGF0IHRoZSBwYXJzZXIga25vd3MgYWJvdXQgdGhlIG1haW4gc2NoZW1hPyAKICAgICogSXQgd291bGQgYmUgYmV0dGVyIGlmIGhlIGtub3dzIGFib3V0IHRoZSBjdXJyZW50IHNjaGVtYSBidWNrZXQKICAgICogb25seS4KICAgICovCiAgICBuZXdwY3R4dC0+c2NoZW1hID0gc2NoZW1hOwogICAgeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKG5ld3BjdHh0LCBwY3R4dC0+ZXJyb3IsIHBjdHh0LT53YXJuaW5nLAoJcGN0eHQtPmVyckN0eHQpOwogICAgeG1sU2NoZW1hU2V0UGFyc2VyU3RydWN0dXJlZEVycm9ycyhuZXdwY3R4dCwgcGN0eHQtPnNlcnJvciwKCXBjdHh0LT5lcnJDdHh0KTsKICAgIG5ld3BjdHh0LT5jb3VudGVyID0gcGN0eHQtPmNvdW50ZXI7CiAgICAKCiAgICByZXMgPSB4bWxTY2hlbWFQYXJzZU5ld0RvY1dpdGhDb250ZXh0KG5ld3BjdHh0LCBzY2hlbWEsIGJ1Y2tldCk7CiAgICAKICAgIC8qIENoYW5uZWwgYmFjayBlcnJvcnMgYW5kIGNsZWFudXAgdGhlIHRlbXBvcmFyeSBwYXJzZXIgY29udGV4dC4gKi8KICAgIGlmIChyZXMgIT0gMCkKCXBjdHh0LT5lcnIgPSByZXM7CiAgICBwY3R4dC0+bmJlcnJvcnMgKz0gbmV3cGN0eHQtPm5iZXJyb3JzOwogICAgcGN0eHQtPmNvdW50ZXIgPSBuZXdwY3R4dC0+Y291bnRlcjsKICAgIG5ld3BjdHh0LT5jb25zdHJ1Y3RvciA9IE5VTEw7ICAgIAogICAgLyogRnJlZSB0aGUgcGFyc2VyIGNvbnRleHQuICovCiAgICB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChuZXdwY3R4dCk7CiAgICByZXR1cm4ocmVzKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25BZGRDaGlsZCh4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0LAoJCQkJeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgcmVsKQp7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciBjdXIgPSBidWNrZXQtPnJlbGF0aW9uczsKCiAgICBpZiAoY3VyID09IE5VTEwpIHsKCWJ1Y2tldC0+cmVsYXRpb25zID0gcmVsOwoJcmV0dXJuOwogICAgfQogICAgd2hpbGUgKGN1ci0+bmV4dCAhPSBOVUxMKQoJY3VyID0gY3VyLT5uZXh0OwogICAgY3VyLT5uZXh0ID0gcmVsOwp9CgoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFCdWlsZEFic29sdXRlVVJJKHhtbERpY3RQdHIgZGljdCwgY29uc3QgeG1sQ2hhciogbG9jYXRpb24sCgkJCSAgeG1sTm9kZVB0ciBjdHh0Tm9kZSkKeyAgICAKICAgIC8qCiAgICAqIEJ1aWxkIGFuIGFic29sdWUgbG9jYXRpb24gVVJJLgogICAgKi8KICAgIGlmIChsb2NhdGlvbiAhPSBOVUxMKSB7CQoJaWYgKGN0eHROb2RlID09IE5VTEwpCgkgICAgcmV0dXJuKGxvY2F0aW9uKTsKCWVsc2UgewoJICAgIHhtbENoYXIgKmJhc2UsICpVUkk7CgkgICAgY29uc3QgeG1sQ2hhciAqcmV0ID0gTlVMTDsKCgkgICAgYmFzZSA9IHhtbE5vZGVHZXRCYXNlKGN0eHROb2RlLT5kb2MsIGN0eHROb2RlKTsKCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIGN0eHROb2RlLT5kb2MtPlVSTCk7CgkgICAgfSBlbHNlIHsKCQlVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgYmFzZSk7CgkJeG1sRnJlZShiYXNlKTsKCSAgICB9CgkgICAgaWYgKFVSSSAhPSBOVUxMKSB7CgkJcmV0ID0geG1sRGljdExvb2t1cChkaWN0LCBVUkksIC0xKTsKCQl4bWxGcmVlKFVSSSk7CgkJcmV0dXJuKHJldCk7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuKE5VTEwpOwp9CiAgICAKCgovKioKICogeG1sU2NoZW1hQWRkU2NoZW1hRG9jOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZSBhbiBpbmNsdWRlZCAoYW5kIHRvLWJlLXJlZGVmaW5lZCkgWE1MIHNjaGVtYSBkb2N1bWVudC4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBlcnJvcnMgYW5kCiAqICAgICAgICAgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwoKc3RhdGljIGludAp4bWxTY2hlbWFBZGRTY2hlbWFEb2MoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQlpbnQgdHlwZSwgLyogaW1wb3J0IG9yIGluY2x1ZGUgb3IgcmVkZWZpbmUgKi8KCQljb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiwKCQl4bWxEb2NQdHIgc2NoZW1hRG9jLAoJCWNvbnN0IGNoYXIgKnNjaGVtYUJ1ZmZlciwKCQlpbnQgc2NoZW1hQnVmZmVyTGVuLAoJCXhtbE5vZGVQdHIgaW52b2tpbmdOb2RlLAoJCWNvbnN0IHhtbENoYXIgKnNvdXJjZVRhcmdldE5hbWVzcGFjZSwJCQoJCWNvbnN0IHhtbENoYXIgKmltcG9ydE5hbWVzcGFjZSwJCgkJeG1sU2NoZW1hQnVja2V0UHRyICpidWNrZXQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWxhdGlvbiA9IE5VTEw7CiAgICB4bWxEb2NQdHIgZG9jID0gTlVMTDsKICAgIGludCByZXMgPSAwLCBlcnIgPSAwLCBsb2NhdGVkID0gMCwgcHJlc2VydmVEb2MgPSAwOwogICAgeG1sU2NoZW1hQnVja2V0UHRyIGJrdCA9IE5VTEw7CgogICAgaWYgKGJ1Y2tldCAhPSBOVUxMKQoJKmJ1Y2tldCA9IE5VTEw7CiAgICAKICAgIHN3aXRjaCAodHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQ6CgljYXNlIFhNTF9TQ0hFTUFfU0NIRU1BX01BSU46CgkgICAgZXJyID0gWE1MX1NDSEVNQVBfU1JDX0lNUE9SVDsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9TQ0hFTUFfSU5DTFVERToKCSAgICBlcnIgPSBYTUxfU0NIRU1BUF9TUkNfSU5DTFVERTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkU6CgkgICAgZXJyID0gWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FOwoJICAgIGJyZWFrOwogICAgfSAgICAKICAgICAgIAoKICAgIC8qIFNwZWNpYWwgaGFuZGxpbmcgZm9yIHRoZSBtYWluIHNjaGVtYToKICAgICogc2tpcCB0aGUgbG9jYXRpb24gYW5kIHJlbGF0aW9uIGxvZ2ljIGFuZCBqdXN0IHBhcnNlIHRoZSBkb2MuCiAgICAqIFdlIG5lZWQganVzdCBhIGJ1Y2tldCB0byBiZSByZXR1cm5lZCBpbiB0aGlzIGNhc2UuCiAgICAqLyAgICAKICAgIGlmICgodHlwZSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9NQUlOKSB8fCAoISBXWFNfSEFTX0JVQ0tFVFMocGN0eHQpKSkKCWdvdG8gZG9jX2xvYWQ7CQoKICAgIC8qIE5vdGUgdGhhdCB3ZSBleHBlY3QgdGhlIGxvY2F0aW9uIHRvIGJlIGFuIGFic3VsdXRlIFVSSS4gKi8gCiAgICBpZiAoc2NoZW1hTG9jYXRpb24gIT0gTlVMTCkgewoJYmt0ID0geG1sU2NoZW1hR2V0U2NoZW1hQnVja2V0KHBjdHh0LCBzY2hlbWFMb2NhdGlvbik7CglpZiAoKGJrdCAhPSBOVUxMKSAmJgoJICAgIChwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldCA9PSBia3QpKSB7CgkgICAgLyogUmVwb3J0IHNlbGYtaW1wb3J0cy9pbmNsdXNpb25zL3JlZGVmaW5pdGlvbnMuICovCgkgICAgCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIGVyciwKCQlpbnZva2luZ05vZGUsIE5VTEwsCgkJIlRoZSBzY2hlbWEgbXVzdCBub3QgaW1wb3J0L2luY2x1ZGUvcmVkZWZpbmUgaXRzZWxmIiwKCQlOVUxMLCBOVUxMKTsKCSAgICBnb3RvIGV4aXQ7Cgl9CiAgICB9CiAgICAvKgogICAgKiBDcmVhdGUgYSByZWxhdGlvbiBmb3IgdGhlIGdyYXBoIG9mIHNjaGVtYXMuCiAgICAqLwogICAgcmVsYXRpb24gPSB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbkNyZWF0ZSgpOwogICAgaWYgKHJlbGF0aW9uID09IE5VTEwpCglyZXR1cm4oLTEpOyAgICAKICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uQWRkQ2hpbGQocGN0eHQtPmNvbnN0cnVjdG9yLT5idWNrZXQsCglyZWxhdGlvbik7CiAgICByZWxhdGlvbi0+dHlwZSA9IHR5cGU7CgogICAgLyoKICAgICogU2F2ZSB0aGUgbmFtZXNwYWNlIGltcG9ydCBpbmZvcm1hdGlvbi4KICAgICovCiAgICBpZiAoV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHR5cGUpKSB7CglyZWxhdGlvbi0+aW1wb3J0TmFtZXNwYWNlID0gaW1wb3J0TmFtZXNwYWNlOwkKCWlmIChzY2hlbWFMb2NhdGlvbiA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIE5vIGxvY2F0aW9uOyB0aGlzIGlzIGp1c3QgYW4gaW1wb3J0IG9mIHRoZSBuYW1lc3BhY2UuCgkgICAgKiBOb3RlIHRoYXQgd2UgZG9uJ3QgYXNzaWduIGEgYnVja2V0IHRvIHRoZSByZWxhdGlvbgoJICAgICogaW4gdGhpcyBjYXNlLgoJICAgICovCgkgICAgZ290byBleGl0OwoJfQoJdGFyZ2V0TmFtZXNwYWNlID0gaW1wb3J0TmFtZXNwYWNlOwogICAgfQoKICAgIC8qIERpZCB3ZSBhbHJlYWR5IGZldGNoIHRoZSBkb2M/ICovCiAgICBpZiAoYmt0ICE9IE5VTEwpIHsJCQoJLyogVE9ETzogVGhlIGZvbGxvd2luZyBuYXN0eSBjYXNlcyB3aWxsIHByb2R1Y2UgYW4gZXJyb3IuICovCglpZiAoKFdYU19JU19CVUNLRVRfSU1QTUFJTih0eXBlKSkgJiYgKCEgYmt0LT5pbXBvcnRlZCkpIHsKCSAgICAvKiBXZSBpbmNsdWRlZC9yZWRlZmluZWQgYW5kIHRoZW4gdHJ5IHRvIGltcG9ydCBhIHNjaGVtYS4gKi8KCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgZXJyLAoJCWludm9raW5nTm9kZSwgTlVMTCwKCQkiVGhlIHNjaGVtYSBkb2N1bWVudCAnJXMnIGNhbm5vdCBiZSBpbXBvcnRlZCwgc2luY2UgIgoJCSJpdCB3YXMgYWxyZWFkeSBpbmNsdWRlZCBvciByZWRlZmluZWQiLAoJCXNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCSAgICBnb3RvIGV4aXQ7Cgl9IGVsc2UgaWYgKCghIFdYU19JU19CVUNLRVRfSU1QTUFJTih0eXBlKSkgJiYgKGJrdC0+aW1wb3J0ZWQpKSB7CgkgICAgLyogV2UgaW1wb3J0ZWQgYW5kIHRoZW4gdHJ5IHRvIGluY2x1ZGUvcmVkZWZpbmUgYSBzY2hlbWEuICovCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIGVyciwKCQlpbnZva2luZ05vZGUsIE5VTEwsCgkJIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgYmUgaW5jbHVkZWQgb3IgIgoJCSJyZWRlZmluZWQsIHNpbmNlIGl0IHdhcyBhbHJlYWR5IGltcG9ydGVkIiwKCQlzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CgkgICAgZ290byBleGl0OwoJfQkKICAgIH0KICAgIAkKICAgIGlmIChXWFNfSVNfQlVDS0VUX0lNUE1BSU4odHlwZSkpIHsKCS8qCgkqIEdpdmVuIHRoYXQgdGhlIHNjaGVtYUxvY2F0aW9uIFthdHRyaWJ1dGVdIGlzIG9ubHkgYSBoaW50LCBpdCBpcyBvcGVuCgkqIHRvIGFwcGxpY2F0aW9ucyB0byBpZ25vcmUgYWxsIGJ1dCB0aGUgZmlyc3QgPGltcG9ydD4gZm9yIGEgZ2l2ZW4KCSogbmFtZXNwYWNlLCByZWdhcmRsZXNzIG9mIHRoZSC3YWN0dWFsIHZhbHVltyBvZiBzY2hlbWFMb2NhdGlvbiwgYnV0CgkqIHN1Y2ggYSBzdHJhdGVneSByaXNrcyBtaXNzaW5nIHVzZWZ1bCBpbmZvcm1hdGlvbiB3aGVuIG5ldwoJKiBzY2hlbWFMb2NhdGlvbnMgYXJlIG9mZmVyZWQuCgkqCgkqIFdlIHdpbGwgdXNlIHRoZSBmaXJzdCA8aW1wb3J0PiB0aGF0IGNvbWVzIHdpdGggYSBsb2NhdGlvbi4KCSogRnVydGhlciA8aW1wb3J0PnMgKndpdGgqIGEgbG9jYXRpb24sIHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLgoJKiBUT0RPOiBCZXR0ZXIgd291bGQgYmUgdG8ganVzdCByZXBvcnQgYSB3YXJuaW5nIGhlcmUsIGJ1dAoJKiB3ZSdsbCB0cnkgaXQgdGhpcyB3YXkgdW50aWwgc29tZW9uZSBjb21wbGFpbnMuCgkqCgkqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneToKCSogMyBCYXNlZCBvbiB0aGUgbmFtZXNwYWNlIG5hbWUsIGlkZW50aWZ5IGFuIGV4aXN0aW5nIHNjaGVtYSBkb2N1bWVudCwKCSogZWl0aGVyIGFzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gWE1MIGRvY3VtZW50IG9yIGEgPHNjaGVtYT4gZWxlbWVudAoJKiBpbmZvcm1hdGlvbiBpdGVtLCBpbiBzb21lIGxvY2FsIHNjaGVtYSByZXBvc2l0b3J5OwoJKiA1IEF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgbmFtZXNwYWNlIG5hbWUgdG8gbG9jYXRlIHN1Y2ggYSByZXNvdXJjZS4KCSoKCSogTk9URTogKDMpIGFuZCAoNSkgYXJlIG5vdCBzdXBwb3J0ZWQuCgkqLwkKCWlmIChia3QgIT0gTlVMTCkgewoJICAgIHJlbGF0aW9uLT5idWNrZXQgPSBia3Q7CgkgICAgZ290byBleGl0OwoJfQoJYmt0ID0geG1sU2NoZW1hR2V0U2NoZW1hQnVja2V0QnlUTlMocGN0eHQsCgkgICAgaW1wb3J0TmFtZXNwYWNlLCAxKTsKCglpZiAoYmt0ICE9IE5VTEwpIHsJICAgIAoJICAgIHJlbGF0aW9uLT5idWNrZXQgPSBia3Q7CgkgICAgaWYgKGJrdC0+c2NoZW1hTG9jYXRpb24gPT0gTlVMTCkgewoJCS8qIEZpcnN0IGdpdmVuIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWE7IGxvYWQgdGhlIGRvYy4gKi8KCQlia3QtPnNjaGVtYUxvY2F0aW9uID0gc2NoZW1hTG9jYXRpb247CgkgICAgfSBlbHNlIHsKCQlpZiAoIXhtbFN0ckVxdWFsKHNjaGVtYUxvY2F0aW9uLAoJCSAgICBia3QtPnNjaGVtYUxvY2F0aW9uKSkgewoJCSAgICAvKgoJCSAgICAqIEFkZGl0aW9uYWwgbG9jYXRpb24gZ2l2ZW47IGp1c3Qgc2tpcCBpdC4KCQkgICAgKiBVUkdFTlQgVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhIHdhcm5pbmcgaGVyZS4KCQkgICAgKiByZXMgPSBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUOwoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21XYXJuaW5nKEFDVFhUX0NBU1QgcGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1dBUk5fU0tJUF9TQ0hFTUEsCgkJCWludm9raW5nTm9kZSwgTlVMTCwKCQkJIlNraXBwaW5nIGltcG9ydCBvZiBzY2hlbWEgbG9jYXRlZCBhdCAnJXMnIGZvciB0aGUgIgoJCQkibmFtZXNwYWNlICclcycsIHNpbmNlIHRoaXMgbmFtZXNwYWNlIHdhcyBhbHJlYWR5ICIKCQkJImltcG9ydGVkIHdpdGggdGhlIHNjaGVtYSBsb2NhdGVkIGF0ICclcyciLAoJCQlzY2hlbWFMb2NhdGlvbiwgaW1wb3J0TmFtZXNwYWNlLCBia3QtPnNjaGVtYUxvY2F0aW9uKTsKCQl9CgkJZ290byBleGl0OwoJICAgIH0KCX0JCgkvKiAKCSogTm8gYnVja2V0ICsgZmlyc3QgbG9jYXRpb246IGxvYWQgdGhlIGRvYyBhbmQgY3JlYXRlIGEKCSogYnVja2V0LgoJKi8KICAgIH0gZWxzZSB7CgkvKiA8aW5jbHVkZT4gYW5kIDxyZWRlZmluZT4gKi8KCWlmIChia3QgIT0gTlVMTCkgewoJICAgIAkgICAgCgkgICAgaWYgKChia3QtPm9yaWdUYXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgJiYKCQkoYmt0LT50YXJnZXROYW1lc3BhY2UgIT0gc291cmNlVGFyZ2V0TmFtZXNwYWNlKSkgewoJCXhtbFNjaGVtYUJ1Y2tldFB0ciBjaGFtZWw7CgkJCgkJLyoKCQkqIENoYW1lbGVvbiBpbmNsdWRlL3JlZGVmaW5lOiBza2lwIGxvYWRpbmcgb25seSBpZiBpdCB3YXMKCQkqIGFsZWFkeSBidWlsZCBmb3IgdGhlIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgaW5jbHVkaW5nCgkJKiBzY2hlbWEuCgkJKi8KCQkvKgoJCSogVVJHRU5UIFRPRE86IElmIHRoZSBzY2hlbWEgaXMgYSBjaGFtZWxlb24taW5jbHVkZSB0aGVuIGNvcHkKCQkqIHRoZSBjb21wb25lbnRzIGludG8gdGhlIGluY2x1ZGluZyBzY2hlbWEgYW5kIG1vZGlmeSB0aGUKCQkqIHRhcmdldE5hbWVzcGFjZSBvZiB0aG9zZSBjb21wb25lbnRzLCBkbyBub3RoaW5nIG90aGVyd2lzZS4KCQkqIE5PVEU6IFRoaXMgaXMgY3VycmVudGx5IHdvcmtlZC1hcm91bmQgYnkgY29tcGlsaW5nIHRoZQoJCSogY2hhbWVsZW9uIGZvciBldmVyeSBkZXN0aW5jdCBpbmNsdWRpbmcgdGFyZ2V0TmFtZXNwYWNlOyB0aHVzCgkJKiBub3QgcGVyZm9ybWFudCBhdCB0aGUgbW9tZW50LgoJCSogVE9ETzogQ2hlY2sgd2hlbiB0aGUgbmFtZXNwYWNlIGluIHdpbGRjYXJkcyBmb3IgY2hhbWVsZW9ucwoJCSogbmVlZHMgdG8gYmUgY29udmVydGVkOiBiZWZvcmUgd2UgYnVpbHQgd2lsZGNhcmQgaW50ZXJzZWN0aW9ucwoJCSogb3IgYWZ0ZXIuCgkJKiAgIEFuc3dlcjogYWZ0ZXIhCgkJKi8KCQljaGFtZWwgPSB4bWxTY2hlbWFHZXRDaGFtZWxlb25TY2hlbWFCdWNrZXQocGN0eHQsCgkJICAgIHNjaGVtYUxvY2F0aW9uLCBzb3VyY2VUYXJnZXROYW1lc3BhY2UpOwoJCWlmIChjaGFtZWwgIT0gTlVMTCkgewoJCSAgICAvKiBBIGZpdHRpbmcgY2hhbWVsZW9uIHdhcyBhbHJlYWR5IHBhcnNlZDsgTk9QLiAqLwoJCSAgICByZWxhdGlvbi0+YnVja2V0ID0gY2hhbWVsOwoJCSAgICBnb3RvIGV4aXQ7CgkJfQoJCS8qIAoJCSogV2UgbmVlZCB0byBwYXJzZSB0aGUgY2hhbWVsZW9uIGFnYWluIGZvciBhIGRpZmZlcmVudAoJCSogdGFyZ2V0TmFtZXNwYWNlLgoJCSogQ0hBTUVMRU9OIFRPRE86IE9wdGltaXplIHRoaXMgYnkgb25seSBwYXJzaW5nIHRoZQoJCSogY2hhbWVsZW9uIG9uY2UsIGFuZCB0aGVuIGNvcHlpbmcgdGhlIGNvbXBvbmVudHMgdG8KCQkqIHRoZSBuZXcgdGFyZ2V0TmFtZXNwYWNlLgoJCSovCgkJYmt0ID0gTlVMTDsKCSAgICB9IGVsc2UgewoJCXJlbGF0aW9uLT5idWNrZXQgPSBia3Q7CgkJZ290byBleGl0OwoJICAgIH0JICAgIAoJfQogICAgfQogICAgaWYgKChia3QgIT0gTlVMTCkgJiYgKGJrdC0+ZG9jICE9IE5VTEwpKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFBZGRTY2hlbWFEb2MiLAoJICAgICJ0cnlpbmcgdG8gbG9hZCBhIHNjaGVtYSBkb2MsIGJ1dCBhIGRvYyBpcyBhbHJlYWR5ICIKCSAgICAiYXNzaWduZWQgdG8gdGhlIHNjaGVtYSBidWNrZXQiKTsKCWdvdG8gZXhpdF9mYWlsdXJlOwogICAgfQoKZG9jX2xvYWQ6CiAgICAvKgogICAgKiBMb2FkIHRoZSBkb2N1bWVudC4KICAgICovCiAgICBpZiAoc2NoZW1hRG9jICE9IE5VTEwpIHsKCWRvYyA9IHNjaGVtYURvYzsKCS8qIERvbicgZnJlZSB0aGlzIG9uZSwgc2luY2UgaXQgd2FzIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIuICovCglwcmVzZXJ2ZURvYyA9IDE7CgkvKiBUT0RPOiBEb2VzIHRoZSBjb250ZXh0IG9yIHRoZSBkb2MgaG9sZCB0aGUgbG9jYXRpb24/ICovCglpZiAoc2NoZW1hRG9jLT5VUkwgIT0gTlVMTCkKCSAgICBzY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAocGN0eHQtPmRpY3QsCgkJc2NoZW1hRG9jLT5VUkwsIC0xKTsKCiAgICB9IGVsc2UgaWYgKChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB8fCAoc2NoZW1hQnVmZmVyICE9IE5VTEwpKSB7Cgl4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CgoJcGFyc2VyQ3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKCWlmIChwYXJzZXJDdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJ4bWxTY2hlbWFHZXREb2MsICIKCQkiYWxsb2NhdGluZyBhIHBhcnNlciBjb250ZXh0IiwgTlVMTCk7CgkgICAgZ290byBleGl0X2ZhaWx1cmU7Cgl9CglpZiAoKHBjdHh0LT5kaWN0ICE9IE5VTEwpICYmIChwYXJzZXJDdHh0LT5kaWN0ICE9IE5VTEwpKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IERvIHdlIGhhdmUgdG8gYnVyZGVuIHRoZSBzY2hlbWEgcGFyc2VyIGRpY3Qgd2l0aCBhbGwKCSAgICAqIHRoZSBjb250ZW50IG9mIHRoZSBzY2hlbWEgZG9jPwoJICAgICovCgkgICAgeG1sRGljdEZyZWUocGFyc2VyQ3R4dC0+ZGljdCk7CgkgICAgcGFyc2VyQ3R4dC0+ZGljdCA9IHBjdHh0LT5kaWN0OwoJICAgIHhtbERpY3RSZWZlcmVuY2UocGFyc2VyQ3R4dC0+ZGljdCk7Cgl9CglpZiAoc2NoZW1hTG9jYXRpb24gIT0gTlVMTCkgewoJICAgIC8qIFBhcnNlIGZyb20gZmlsZS4gKi8KCSAgICBkb2MgPSB4bWxDdHh0UmVhZEZpbGUocGFyc2VyQ3R4dCwgKGNvbnN0IGNoYXIgKikgc2NoZW1hTG9jYXRpb24sCgkJTlVMTCwgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKCX0gZWxzZSBpZiAoc2NoZW1hQnVmZmVyICE9IE5VTEwpIHsKCSAgICAvKiBQYXJzZSBmcm9tIG1lbW9yeSBidWZmZXIuICovCgkgICAgZG9jID0geG1sQ3R4dFJlYWRNZW1vcnkocGFyc2VyQ3R4dCwgc2NoZW1hQnVmZmVyLCBzY2hlbWFCdWZmZXJMZW4sCgkJTlVMTCwgTlVMTCwgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKCSAgICBzY2hlbWFMb2NhdGlvbiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIpOwoJICAgIGlmIChkb2MgIT0gTlVMTCkKCQlkb2MtPlVSTCA9IHNjaGVtYUxvY2F0aW9uOwkgICAgCgl9CgkvKgoJKiBGb3IgPGltcG9ydD46CgkqIDIuMSBUaGUgcmVmZXJlbnQgaXMgKGEgZnJhZ21lbnQgb2YpIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4KCSogWE1MIGRvY3VtZW50IChzZWUgY2xhdXNlIDEuMSksIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8KCSogYSA8c2NoZW1hPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaW4gYSB3ZWxsLWZvcm1lZCBpbmZvcm1hdGlvbgoJKiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8gYSB2YWxpZCBzY2hlbWEuCgkqIFRPRE86ICgyLjEpIGZyYWdtZW50cyBvZiBYTUwgZG9jdW1lbnRzIGFyZSBub3Qgc3VwcG9ydGVkLgoJKgoJKiAyLjIgVGhlIHJlZmVyZW50IGlzIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluCgkqIGEgd2VsbC1mb3JtZWQgaW5mb3JtYXRpb24gc2V0LCB3aGljaCBpbiB0dXJuIGNvcnJlc3BvbmRzCgkqIHRvIGEgdmFsaWQgc2NoZW1hLgoJKiBUT0RPOiAoMi4yKSBpcyBub3Qgc3VwcG9ydGVkLgoJKi8KCWlmIChkb2MgPT0gTlVMTCkgewoJICAgIHhtbEVycm9yUHRyIGxlcnI7CgkgICAgbGVyciA9IHhtbEdldExhc3RFcnJvcigpOwoJICAgIC8qCgkgICAgKiBDaGVjayBpZiB0aGlzIGEgcGFyc2VyIGVycm9yLCBvciBpZiB0aGUgZG9jdW1lbnQgY291bGQKCSAgICAqIGp1c3Qgbm90IGJlIGxvY2F0ZWQuCgkgICAgKiBUT0RPOiBUcnkgdG8gZmluZCBzcGVjaWZpYyBlcnJvciBjb2RlcyB0byByZWFjdCBvbmx5IG9uCgkgICAgKiBsb2NhbGlzYXRpb24gZmFpbHVyZXMuCgkgICAgKi8KCSAgICBpZiAoKGxlcnIgPT0gTlVMTCkgfHwgKGxlcnItPmRvbWFpbiAhPSBYTUxfRlJPTV9JTykpIHsKCQkvKgoJCSogV2UgYXNzdW1lIGEgcGFyc2VyIGVycm9yIGhlcmUuCgkJKi8KCQlsb2NhdGVkID0gMTsKCQkvKiBUT0RPOiBFcnJvciBjb2RlID8/ICovCgkJcmVzID0gWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzE7CgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIHJlcywKCQkgICAgaW52b2tpbmdOb2RlLCBOVUxMLAoJCSAgICAiRmFpbGVkIHRvIHBhcnNlIHRoZSBYTUwgcmVzb3VyY2UgJyVzJyIsCgkJICAgIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsJCQoJICAgIH0KCX0KCXhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwoJaWYgKChkb2MgPT0gTlVMTCkgJiYgbG9jYXRlZCkKCSAgICBnb3RvIGV4aXRfZXJyb3I7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgTlVMTCwKCSAgICBYTUxfU0NIRU1BUF9OT1RISU5HX1RPX1BBUlNFLAoJICAgICJObyBpbmZvcm1hdGlvbiBmb3IgcGFyc2luZyB3YXMgcHJvdmlkZWQgd2l0aCB0aGUgIgoJICAgICJnaXZlbiBzY2hlbWEgcGFyc2VyIGNvbnRleHQuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJZ290byBleGl0X2ZhaWx1cmU7CiAgICB9CiAgICAvKgogICAgKiBQcmVwcm9jZXNzIHRoZSBkb2N1bWVudC4KICAgICovCiAgICBpZiAoZG9jICE9IE5VTEwpIHsKCXhtbE5vZGVQdHIgZG9jRWxlbSA9IE5VTEw7CgoJbG9jYXRlZCA9IDE7CQoJZG9jRWxlbSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CglpZiAoZG9jRWxlbSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQlpbnZva2luZ05vZGUsIE5VTEwsIAoJCSJUaGUgZG9jdW1lbnQgJyVzJyBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudCIsCgkJc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoJICAgIGdvdG8gZXhpdF9lcnJvcjsKCX0KCS8qCgkqIFJlbW92ZSBhbGwgdGhlIGJsYW5rIHRleHQgbm9kZXMuCgkqLwoJeG1sU2NoZW1hQ2xlYW51cERvYyhwY3R4dCwgZG9jRWxlbSk7CgkvKgoJKiBDaGVjayB0aGUgc2NoZW1hJ3MgdG9wIGxldmVsIGVsZW1lbnQuCgkqLwoJaWYgKCFJU19TQ0hFTUEoZG9jRWxlbSwgInNjaGVtYSIpKSB7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJaW52b2tpbmdOb2RlLCBOVUxMLAoJCSJUaGUgWE1MIGRvY3VtZW50ICclcycgaXMgbm90IGEgc2NoZW1hIGRvY3VtZW50IiwKCQlzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CgkgICAgZ290byBleGl0X2Vycm9yOwoJfQoJLyogCgkqIE5vdGUgdGhhdCB3ZSBkb24ndCBhcHBseSBhIHR5cGUgY2hlY2sgZm9yIHRoZQoJKiB0YXJnZXROYW1lc3BhY2UgdmFsdWUgaGVyZS4KCSovCgl0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKHBjdHh0LCBkb2NFbGVtLAoJICAgICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIH0KICAgIAovKiBhZnRlcl9kb2NfbG9hZGluZzogKi8KICAgIGlmICgoYmt0ID09IE5VTEwpICYmIGxvY2F0ZWQpIHsKCS8qIE9ubHkgY3JlYXRlIGEgYnVja2V0IGlmIHRoZSBzY2hlbWEgd2FzIGxvY2F0ZWQuICovCiAgICAgICAgYmt0ID0geG1sU2NoZW1hQnVja2V0Q3JlYXRlKHBjdHh0LCB0eXBlLAoJICAgIHRhcmdldE5hbWVzcGFjZSk7CglpZiAoYmt0ID09IE5VTEwpCgkgICAgZ290byBleGl0X2ZhaWx1cmU7CiAgICB9CiAgICBpZiAoYmt0ICE9IE5VTEwpIHsKCWJrdC0+c2NoZW1hTG9jYXRpb24gPSBzY2hlbWFMb2NhdGlvbjsKCWJrdC0+bG9jYXRlZCA9IGxvY2F0ZWQ7CglpZiAoZG9jICE9IE5VTEwpIHsKCSAgICBia3QtPmRvYyA9IGRvYzsKCSAgICBia3QtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKCSAgICBia3QtPm9yaWdUYXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7CgkgICAgaWYgKHByZXNlcnZlRG9jKQoJCWJrdC0+cHJlc2VydmVEb2MgPSAxOwoJfQoJaWYgKFdYU19JU19CVUNLRVRfSU1QTUFJTih0eXBlKSkKCSAgICBia3QtPmltcG9ydGVkKys7CgkgICAgLyoKCSAgICAqIEFkZCBpdCB0byB0aGUgZ3JhcGggb2Ygc2NoZW1hcy4KCSAgICAqLwoJaWYgKHJlbGF0aW9uICE9IE5VTEwpCgkgICAgcmVsYXRpb24tPmJ1Y2tldCA9IGJrdDsKICAgIH0KICAKZXhpdDoKICAgIC8qCiAgICAqIFJldHVybiB0aGUgYnVja2V0IGV4cGxpY2l0ZWx5OyB0aGlzIGlzIG5lZWRlZCBmb3IgdGhlCiAgICAqIG1haW4gc2NoZW1hLgogICAgKi8KICAgIGlmIChidWNrZXQgIT0gTlVMTCkKCSpidWNrZXQgPSBia3Q7ICAgIAogICAgcmV0dXJuICgwKTsKCmV4aXRfZXJyb3I6CiAgICBpZiAoKGRvYyAhPSBOVUxMKSAmJiAoISBwcmVzZXJ2ZURvYykpIHsKCXhtbEZyZWVEb2MoZG9jKTsKCWlmIChia3QgIT0gTlVMTCkKCSAgICBia3QtPmRvYyA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4ocGN0eHQtPmVycik7CgpleGl0X2ZhaWx1cmU6CiAgICBpZiAoKGRvYyAhPSBOVUxMKSAmJiAoISBwcmVzZXJ2ZURvYykpIHsKCXhtbEZyZWVEb2MoZG9jKTsKCWlmIChia3QgIT0gTlVMTCkKCSAgICBia3QtPmRvYyA9IE5VTEw7CiAgICB9ICAgIAogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUltcG9ydDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW1wb3J0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYKICogbm90IHZhbGlkIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2VOYW1lID0gTlVMTCwgKnNjaGVtYUxvY2F0aW9uID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnRoaXNUYXJnZXROYW1lc3BhY2U7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQgPSBOVUxMOwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyKHBjdHh0LCBOVUxMLCBub2RlLAoJIm5hbWVzcGFjZSIsIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkmbmFtZXNwYWNlTmFtZSkgIT0gMCkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBOVUxMLCBub2RlLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkgICAgTlVMTCwgbmFtZXNwYWNlTmFtZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKHBjdHh0LT5lcnIpOwogICAgfQoKICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0cihwY3R4dCwgTlVMTCwgbm9kZSwKCSJzY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkmc2NoZW1hTG9jYXRpb24pICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgbm9kZSwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLAoJICAgIE5VTEwsIG5hbWVzcGFjZU5hbWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChwY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbiBoZXJlIGlzIHNpbXBseSBkaXNjYXJkZWQgLi4uCgkgKiBUT0RPOiByZWFsbHk/CiAgICAgICAgICovCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgLyoKICAgICogQXBwbHkgYWRkaXRpb25hbCBjb25zdHJhaW50cy4KICAgICoKICAgICogTm90ZSB0aGF0IGl0IGlzIGltcG9ydGFudCB0byB1c2UgdGhlIG9yaWdpbmFsIEB0YXJnZXROYW1lc3BhY2UKICAgICogKG9yIG5vbmUgYXQgYWxsKSwgdG8gcnVsZSBvdXQgaW1wb3J0cyBvZiBzY2hlbWFzIF93aXRoXyBhCiAgICAqIEB0YXJnZXROYW1lc3BhY2UgaWYgdGhlIGltcG9ydGluZyBzY2hlbWEgaXMgYSBjaGFtZWxlb24gc2NoZW1hCiAgICAqICh3aXRoIG5vIEB0YXJnZXROYW1lc3BhY2UpLgogICAgKi8KICAgIHRoaXNUYXJnZXROYW1lc3BhY2UgPSBXWFNfQlVDS0VUKHBjdHh0KS0+b3JpZ1RhcmdldE5hbWVzcGFjZTsKICAgIGlmIChuYW1lc3BhY2VOYW1lICE9IE5VTEwpIHsKCS8qCgkqIDEuMSBJZiB0aGUgbmFtZXNwYWNlIFthdHRyaWJ1dGVdIGlzIHByZXNlbnQsIHRoZW4gaXRzILdhY3R1YWwgdmFsdWW3CgkqIG11c3Qgbm90IG1hdGNoIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgZW5jbG9zaW5nIDxzY2hlbWE+J3MKCSogdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmICh4bWxTdHJFcXVhbCh0aGlzVGFyZ2V0TmFtZXNwYWNlLCBuYW1lc3BhY2VOYW1lKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzEsCgkJTlVMTCwgbm9kZSwKCQkiVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBub3QgbWF0Y2ggIgoJCSJ0aGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbXBvcnRpbmcgc2NoZW1hIiwKCQl0aGlzVGFyZ2V0TmFtZXNwYWNlKTsKCSAgICByZXR1cm4gKHBjdHh0LT5lcnIpOwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIDEuMiBJZiB0aGUgbmFtZXNwYWNlIFthdHRyaWJ1dGVdIGlzIG5vdCBwcmVzZW50LCB0aGVuIHRoZSBlbmNsb3NpbmcKCSogPHNjaGVtYT4gbXVzdCBoYXZlIGEgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmICh0aGlzVGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMV8yLAoJCU5VTEwsIG5vZGUsCgkJIlRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBiZSBleGlzdGVudCBpZiAiCgkJInRoZSBpbXBvcnRpbmcgc2NoZW1hIGhhcyBubyB0YXJnZXQgbmFtZXNwYWNlIiwKCQlOVUxMKTsKCSAgICByZXR1cm4gKHBjdHh0LT5lcnIpOwoJfQogICAgfQogICAgLyoKICAgICogTG9jYXRlIGFuZCBhY3F1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgaWYgKHNjaGVtYUxvY2F0aW9uICE9IE5VTEwpCglzY2hlbWFMb2NhdGlvbiA9IHhtbFNjaGVtYUJ1aWxkQWJzb2x1dGVVUkkocGN0eHQtPmRpY3QsCgkgICAgc2NoZW1hTG9jYXRpb24sIG5vZGUpOwogICAgcmV0ID0geG1sU2NoZW1hQWRkU2NoZW1hRG9jKHBjdHh0LCBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQsCglzY2hlbWFMb2NhdGlvbiwgTlVMTCwgTlVMTCwgMCwgbm9kZSwgdGhpc1RhcmdldE5hbWVzcGFjZSwKCW5hbWVzcGFjZU5hbWUsICZidWNrZXQpOwoKICAgIGlmIChyZXQgIT0gMCkKCXJldHVybihyZXQpOwoKICAgIC8qCiAgICAqIEZvciA8aW1wb3J0PjogIkl0IGlzICpub3QqIGFuIGVycm9yIGZvciB0aGUgYXBwbGljYXRpb24KICAgICogc2NoZW1hIHJlZmVyZW5jZSBzdHJhdGVneSB0byBmYWlsLiIKICAgICogU28ganVzdCBkb24ndCBwYXJzZSBpZiBubyBzY2hlbWEgZG9jdW1lbnQgd2FzIGZvdW5kLgogICAgKiBOb3RlIHRoYXQgd2Ugd2lsbCBnZXQgbm8gYnVja2V0IGlmIHRoZSBzY2hlbWEgY291bGQgbm90IGJlCiAgICAqIGxvY2F0ZWQgb3IgaWYgdGhlcmUgd2FzIG5vIHNjaGVtYUxvY2F0aW9uLgogICAgKi8KICAgIGlmICgoYnVja2V0ID09IE5VTEwpICYmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSkgewoJeG1sU2NoZW1hQ3VzdG9tV2FybmluZyhBQ1RYVF9DQVNUIHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1dBUk5fVU5MT0NBVEVEX1NDSEVNQSwKCSAgICBub2RlLCBOVUxMLAoJICAgICJGYWlsZWQgdG8gbG9jYXRlIGEgc2NoZW1hIGF0IGxvY2F0aW9uICclcycuICIKCSAgICAiU2tpcHBpbmcgdGhlIGltcG9ydCIsIHNjaGVtYUxvY2F0aW9uLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIAogICAgaWYgKChidWNrZXQgIT0gTlVMTCkgJiYgQ0FOX1BBUlNFX1NDSEVNQShidWNrZXQpKSB7CQoJcmV0ID0geG1sU2NoZW1hUGFyc2VOZXdEb2MocGN0eHQsIHNjaGVtYSwgYnVja2V0KTsKICAgIH0KICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmVBdHRycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkgICAgIHhtbENoYXIgKipzY2hlbWFMb2NhdGlvbiwKCQkJCSAgICAgaW50IHR5cGUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwKCShzY2hlbWFMb2NhdGlvbiA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAqc2NoZW1hTG9jYXRpb24gPSBOVUxMOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICogQXBwbGllcyBmb3IgYm90aCA8aW5jbHVkZT4gYW5kIDxyZWRlZmluZT4uCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChwY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBQcmVsaW1pbmFyeSBzdGVwLCBleHRyYWN0IHRoZSBVUkktUmVmZXJlbmNlIGFuZCBtYWtlIGFuIFVSSQogICAgKiBmcm9tIHRoZSBiYXNlLgogICAgKi8KICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAic2NoZW1hTG9jYXRpb24iIGlzIG1hbmRhdG9yeS4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInNjaGVtYUxvY2F0aW9uIik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CiAgICAgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEw7CiAgICAgICAgeG1sQ2hhciAqdXJpID0gTlVMTDsKCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKHBjdHh0LCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkgICAgKGNvbnN0IHhtbENoYXIgKiopIHNjaGVtYUxvY2F0aW9uKSAhPSAwKQoJICAgIGdvdG8gZXhpdF9lcnJvcjsKCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKCpzY2hlbWFMb2NhdGlvbiwgbm9kZS0+ZG9jLT5VUkwpOwoJfSBlbHNlIHsKCSAgICB1cmkgPSB4bWxCdWlsZFVSSSgqc2NoZW1hTG9jYXRpb24sIGJhc2UpOwoJICAgIHhtbEZyZWUoYmFzZSk7Cgl9CglpZiAodXJpID09IE5VTEwpIHsKCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFQYXJzZUluY2x1ZGVPclJlZGVmaW5lIiwKCQkiY291bGQgbm90IGJ1aWxkIGFuIFVSSSBmcm9tIHRoZSBzY2hlbWFMb2NhdGlvbiIpCgkgICAgZ290byBleGl0X2ZhaWx1cmU7Cgl9CgkoKnNjaGVtYUxvY2F0aW9uKSA9ICh4bWxDaGFyICopIHhtbERpY3RMb29rdXAocGN0eHQtPmRpY3QsIHVyaSwgLTEpOwoJeG1sRnJlZSh1cmkpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsICJzY2hlbWFMb2NhdGlvbiIsIE5VTEwpOwoJZ290byBleGl0X2Vycm9yOwogICAgfQogICAgLyoKICAgICogUmVwb3J0IHNlbGYtaW5jbHVzaW9uIGFuZCBzZWxmLXJlZGVmaW5pdGlvbi4KICAgICovCiAgICBpZiAoeG1sU3RyRXF1YWwoKnNjaGVtYUxvY2F0aW9uLCBwY3R4dC0+VVJMKSkgewoJaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCQlOVUxMLCBub2RlLAoJCSJUaGUgc2NoZW1hIGRvY3VtZW50ICclcycgY2Fubm90IHJlZGVmaW5lIGl0c2VsZi4iLAoJCSpzY2hlbWFMb2NhdGlvbik7CSAgICAKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU5DTFVERSwKCQlOVUxMLCBub2RlLAoJCSJUaGUgc2NoZW1hIGRvY3VtZW50ICclcycgY2Fubm90IGluY2x1ZGUgaXRzZWxmLiIsCgkJKnNjaGVtYUxvY2F0aW9uKTsKCX0KCWdvdG8gZXhpdF9lcnJvcjsKICAgIH0KICAgIAogICAgcmV0dXJuKDApOwpleGl0X2Vycm9yOgogICAgcmV0dXJuKHBjdHh0LT5lcnIpOwpleGl0X2ZhaWx1cmU6CiAgICByZXR1cm4oLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCXhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCQlpbnQgdHlwZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiA9IE5VTEw7CiAgICBpbnQgcmVzID0gMDsgLyogaGFzUmVkZWZpbml0aW9ucyA9IDAgKi8KICAgIGludCBpc0NoYW1lbGVvbiA9IDAsIHdhc0NoYW1lbGVvbiA9IDA7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0ID0gTlVMTDsKCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgLyoKICAgICogUGFyc2UgYXR0cmlidXRlcy4gTm90ZSB0aGF0IHRoZSByZXR1cm5lZCBzY2hlbWFMb2NhdGlvbiB3aWxsCiAgICAqIGJlIGFscmVhZHkgY29udmVydGVkIHRvIGFuIGFic29sdXRlIFVSSS4KICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFQYXJzZUluY2x1ZGVPclJlZGVmaW5lQXR0cnMocGN0eHQsIHNjaGVtYSwKCW5vZGUsICh4bWxDaGFyICoqKSAoJnNjaGVtYUxvY2F0aW9uKSwgdHlwZSk7CiAgICBpZiAocmVzICE9IDApCglyZXR1cm4ocmVzKTsgICAgCSAgIAogICAgLyoKICAgICogTG9hZCBhbmQgYWRkIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQWRkU2NoZW1hRG9jKHBjdHh0LCB0eXBlLCBzY2hlbWFMb2NhdGlvbiwgTlVMTCwKCU5VTEwsIDAsIG5vZGUsIHBjdHh0LT50YXJnZXROYW1lc3BhY2UsIE5VTEwsICZidWNrZXQpOwogICAgaWYgKHJlcyAhPSAwKQoJcmV0dXJuKHJlcyk7ICAgIAogICAgLyoKICAgICogSWYgd2UgZ2V0IG5vIHNjaGVtYSBidWNrZXQgYmFjaywgdGhlbiB0aGlzIG1lYW5zIHRoYXQgdGhlIHNjaGVtYQogICAgKiBkb2N1bWVudCBjb3VsZCBub3QgYmUgbG9jYXRlZCBvciB3YXMgYnJva2VuIFhNTCBvciB3YXMgbm90CiAgICAqIGEgc2NoZW1hIGRvY3VtZW50LgogICAgKi8gICAgCiAgICBpZiAoKGJ1Y2tldCA9PSBOVUxMKSB8fCAoYnVja2V0LT5kb2MgPT0gTlVMTCkpIHsKCWlmICh0eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX0lOQ0xVREUpIHsKCSAgICAvKgoJICAgICogV0FSTklORyBmb3IgPGluY2x1ZGU+OgoJICAgICogV2Ugd2lsbCByYWlzZSBhbiBlcnJvciBpZiB0aGUgc2NoZW1hIGNhbm5vdCBiZSBsb2NhdGVkCgkgICAgKiBmb3IgaW5jbHVzaW9ucywgc2luY2UgdGhlIHRoYXQgd2FzIHRoZSBmZWVkYmFjayBmcm9tIHRoZQoJICAgICogc2NoZW1hIHBlb3BsZS4gSS5lLiB0aGUgZm9sbG93aW5nIHNwZWMgcGllY2Ugd2lsbCAqbm90KiBiZQoJICAgICogc2F0aXNmaWVkOgoJICAgICogU1BFQyBzcmMtaW5jbHVkZTogIkl0IGlzIG5vdCBhbiBlcnJvciBmb3IgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZQoJICAgICogc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gdG8gZmFpbCB0byByZXNvbHZlIGl0IGFsbCwgaW4gd2hpY2gKCSAgICAqIGNhc2Ugbm8gY29ycmVzcG9uZGluZyBpbmNsdXNpb24gaXMgcGVyZm9ybWVkLgoJICAgICogU28gZG8gd2UgbmVlZCBhIHdhcm5pbmcgcmVwb3J0IGhlcmU/IgoJICAgICovCgkgICAgcmVzID0gWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREU7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIHJlcywKCQlub2RlLCBOVUxMLAoJCSJGYWlsZWQgdG8gbG9hZCB0aGUgZG9jdW1lbnQgJyVzJyBmb3IgaW5jbHVzaW9uIiwKCQlzY2hlbWFMb2NhdGlvbiwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGlzIHdhcyBjaGFuZ2VkIHRvIHJhaXNlIGFuIGVycm9yIGV2ZW4gaWYgbm8gcmVkZWZpbml0aW9ucwoJICAgICogYXJlIHNwZWNpZmllZC4KCSAgICAqCgkgICAgKiBTUEVDIHNyYy1yZWRlZmluZSAoMSkKCSAgICAqICJJZiB0aGVyZSBhcmUgYW55IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbXMgYW1vbmcgdGhlIFtjaGlsZHJlbl0KCSAgICAqIG90aGVyIHRoYW4gPGFubm90YXRpb24+IHRoZW4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZQoJICAgICogc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gbXVzdCBzdWNjZXNzZnVsbHkgcmVzb2x2ZS4iCgkgICAgKiBUT0RPOiBBc2sgdGhlIFdHIGlmIGEgdGhlIGxvY2F0aW9uIGhhcyBhbHdheXMgdG8gcmVzb2x2ZQoJICAgICogaGVyZSBhcyB3ZWxsIQoJICAgICovCgkgICAgcmVzID0gWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FOwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LCByZXMsCgkJbm9kZSwgTlVMTCwKCQkiRmFpbGVkIHRvIGxvYWQgdGhlIGRvY3VtZW50ICclcycgZm9yIHJlZGVmaW5pdGlvbiIsCgkJc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIENoZWNrIHRhcmdldE5hbWVzcGFjZSBzYW5pdHkgYmVmb3JlIHBhcnNpbmcgdGhlIG5ldyBzY2hlbWEuCgkqIFRPRE86IE5vdGUgdGhhdCB3ZSB3b24ndCBjaGVjayBmdXJ0aGVyIGNvbnRlbnQgaWYgdGhlCgkqIHRhcmdldE5hbWVzcGFjZSB3YXMgYmFkLgoJKi8gICAgCglpZiAoYnVja2V0LT5vcmlnVGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsJICAgIAoJICAgIC8qCgkgICAgKiBTUEVDIHNyYy1pbmNsdWRlICgyLjEpCgkgICAgKiAiU0lJIGhhcyBhIHRhcmdldE5hbWVzcGFjZSBbYXR0cmlidXRlXSwgYW5kIGl0cyC3YWN0dWFsCgkgICAgKiB2YWx1ZbcgaXMgaWRlbnRpY2FsIHRvIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdGFyZ2V0TmFtZXNwYWNlCgkgICAgKiBbYXR0cmlidXRlXSBvZiBTSUmSICh3aGljaCBtdXN0IGhhdmUgc3VjaCBhbiBbYXR0cmlidXRlXSkuIgoJICAgICovCgkgICAgaWYgKHBjdHh0LT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfSU5DTFVERSwKCQkgICAgbm9kZSwgTlVMTCwKCQkgICAgIlRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRlZC9yZWRlZmluZWQgc2NoZW1hICIKCQkgICAgIiclcycgaGFzIHRvIGJlIGFic2VudCwgc2luY2UgdGhlIGluY2x1ZGluZy9yZWRlZmluaW5nICIKCQkgICAgInNjaGVtYSBoYXMgbm8gdGFyZ2V0IG5hbWVzcGFjZSIsCgkJICAgIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCQlnb3RvIGV4aXRfZXJyb3I7CgkgICAgfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoYnVja2V0LT5vcmlnVGFyZ2V0TmFtZXNwYWNlLAoJCXBjdHh0LT50YXJnZXROYW1lc3BhY2UpKSB7CgkJLyogVE9ETzogQ2hhbmdlIGVycm9yIGZ1bmN0aW9uLiAqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCSAgICBOVUxMLCBub2RlLAoJCSAgICAiVGhlIHRhcmdldCBuYW1lc3BhY2UgJyVzJyBvZiB0aGUgaW5jbHVkZWQvcmVkZWZpbmVkICIKCQkgICAgInNjaGVtYSAnJXMnIGRpZmZlcnMgZnJvbSAnJXMnIG9mIHRoZSAiCgkJICAgICJpbmNsdWRpbmcvcmVkZWZpbmluZyBzY2hlbWEiLAoJCSAgICBidWNrZXQtPm9yaWdUYXJnZXROYW1lc3BhY2UsIHNjaGVtYUxvY2F0aW9uLAoJCSAgICBwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlKTsKCQlnb3RvIGV4aXRfZXJyb3I7CgkgICAgfQoJfSBlbHNlIGlmIChwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsJICAgIAoJICAgIC8qCgkgICAgKiBDaGFtZWxlb25zOiB0aGUgb3JpZ2luYWwgdGFyZ2V0IG5hbWVzcGFjZSB3aWxsCgkgICAgKiBkaWZmZXIgZnJvbSB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZS4KCSAgICAqLwoJICAgIGlzQ2hhbWVsZW9uID0gMTsKCSAgICBpZiAoYnVja2V0LT5wYXJzZWQgJiYKCQkoYnVja2V0LT50YXJnZXROYW1lc3BhY2UgIT0gcGN0eHQtPnRhcmdldE5hbWVzcGFjZSkpIHsKCQkvKgoJCSogVGhpcyBpcyBhIHNhbml0eSBjaGVjaywgSSBkdW5ubyB5ZXQgaWYgdGhpcyBjYW4gaGFwcGVuLgoJCSovCgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZSIsCgkJICAgICJ0cnlpbmcgdG8gdXNlIGFuIGFscmVhZHkgcGFyc2VkIHNjaGVtYSBmb3IgYSAiCgkJICAgICJkaWZmZXJlbnQgdGFyZ2V0TmFtZXNwYWNlIik7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgYnVja2V0LT50YXJnZXROYW1lc3BhY2UgPSBwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJfQogICAgfSAgICAKICAgIC8qCiAgICAqIFBhcnNlIHRoZSBzY2hlbWEuCiAgICAqLyAgIAogICAgaWYgKGJ1Y2tldCAmJiAoIWJ1Y2tldC0+cGFyc2VkKSAmJiAoYnVja2V0LT5kb2MgIT0gTlVMTCkpIHsKCWlmIChpc0NoYW1lbGVvbikgewoJICAgIC8qIFRPRE86IEdldCByaWQgb2YgdGhpcyBmbGFnIG9uIHRoZSBzY2hlbWEgaXRzZWxmLiAqLwoJICAgIGlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSA9PSAwKSB7CgkJc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsKCSAgICB9IGVsc2UKCQl3YXNDaGFtZWxlb24gPSAxOwoJfQoJeG1sU2NoZW1hUGFyc2VOZXdEb2MocGN0eHQsIHNjaGVtYSwgYnVja2V0KTsKCS8qIFJlc3RvcmUgY2hhbWVsZW9uIGZsYWcuICovCglpZiAoaXNDaGFtZWxlb24gJiYgKCF3YXNDaGFtZWxlb24pKQoJICAgIHNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlM7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOyAgICAKICAgIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX1JFREVGSU5FKSB7CQoJLyoKCSogUGFyc2UgKHNpbXBsZVR5cGUgfCBjb21wbGV4VHlwZSB8IGdyb3VwIHwgYXR0cmlidXRlR3JvdXApKSoKCSovCglwY3R4dC0+cmVkZWZpbmVkID0gYnVja2V0OwoJLyoKCSogSG93IHRvIHByb2NlZWQgaWYgdGhlIHJlZGVmaW5lZCBzY2hlbWEgd2FzIG5vdCBsb2NhdGVkPwoJKi8KCXBjdHh0LT5pc1JlZGVmaW5lID0gMTsKCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikgfHwKCSAgICBJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikgfHwKCSAgICBJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpIHx8CgkgICAgSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSB8fAoJICAgIElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpIHsKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkJLyoKCQkqIFRPRE86IGRpc2NhcmQgb3Igbm90PwoJCSovCgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUocGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleFR5cGUiKSkgewoJCXhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUocGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJCS8qIGhhc1JlZGVmaW5pdGlvbnMgPSAxOyAqLwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewkJCgkJLyogaGFzUmVkZWZpbml0aW9ucyA9IDE7ICovCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmaW5pdGlvbihwY3R4dCwKCQkgICAgc2NoZW1hLCBjaGlsZCk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CgkJLyogaGFzUmVkZWZpbml0aW9ucyA9IDE7ICovCgkJeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cERlZmluaXRpb24ocGN0eHQsIHNjaGVtYSwKCQkgICAgY2hpbGQpOwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJcGN0eHQtPnJlZGVmaW5lZCA9IE5VTEw7CglwY3R4dC0+aXNSZWRlZmluZSA9IDA7CiAgICB9IGVsc2UgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBkaXNjYXJkIG9yIG5vdD8KCSAgICAqLwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9ICAgIAogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXJlcyA9IFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VEOwoJaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihwY3R4dCwgcmVzLAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbiB8IChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUgfCBncm91cCB8IGF0dHJpYnV0ZUdyb3VwKSkqIik7Cgl9IGVsc2UgewoJICAgICB4bWxTY2hlbWFQQ29udGVudEVycihwY3R4dCwgcmVzLAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8pIik7Cgl9CQogICAgfSAgICAgICAKICAgIHJldHVybihyZXMpOwoKZXhpdF9lcnJvcjoKICAgIHJldHVybihwY3R4dC0+ZXJyKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVJlZGVmaW5lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmVzOwojaWZuZGVmIEVOQUJMRV9SRURFRklORQogICAgVE9ETwogICAgcmV0dXJuKDApOwojZW5kaWYKICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUocGN0eHQsIHNjaGVtYSwgbm9kZSwKCVhNTF9TQ0hFTUFfU0NIRU1BX1JFREVGSU5FKTsKICAgIGlmIChyZXMgIT0gMCkKCXJldHVybihyZXMpOwogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaW50IHJlczsKCiAgICByZXMgPSB4bWxTY2hlbWFQYXJzZUluY2x1ZGVPclJlZGVmaW5lKHBjdHh0LCBzY2hlbWEsIG5vZGUsCglYTUxfU0NIRU1BX1NDSEVNQV9JTkNMVURFKTsKICAgIGlmIChyZXMgIT0gMCkKCXJldHVybihyZXMpOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqIEB0eXBlOiB0aGUgImNvbXBvc2l0b3IiIHR5cGUKICogQHBhcnRpY2xlTmVlZGVkOiBpZiBhIGEgbW9kZWwgZ3JvdXAgd2l0aCBhIHBhcnRpY2xlCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTZXF1ZW5jZSBkZWZpbml0aW9uLgogKiBBcHBsaWVzIHBhcnRzIG9mOgogKiAgIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OgogKiAgICAgUmVkZWZpbml0aW9uIENvbnN0cmFpbnRzIGFuZCBTZW1hbnRpY3MgKHNyYy1yZWRlZmluZSkKICogICAgICg2LjEpLCAoNi4xLjEpLCAoNi4xLjIpCiAqCiAqICAgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiAKICogICAgIEFsbCBHcm91cCBMaW1pdGVkIChjb3MtYWxsLWxpbWl0ZWQpICgyKQogKiAgICAgVE9ETzogQWN0dWFsbHkgdGhpcyBzaG91bGQgZ28gdG8gY29tcG9uZW50LWxldmVsIGNoZWNrcywKICogICAgIGJ1dCBpcyBkb25lIGhlcmUgZHVlIHRvIHBlcmZvcm1hbmNlLiBNb3ZlIGl0IHRvIGFuIG90aGVyIGxheWVyCiAqICAgICBpcyBzY2hlbWEgY29uc3RydWN0aW9uIHZpYSBhbiBBUEkgaXMgaW1wbGVtZW50ZWQuCiAqCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCQkgaW50IHdpdGhQYXJ0aWNsZSkKewogICAgeG1sU2NoZW1hTW9kZWxHcm91cFB0ciBpdGVtOwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgbWluID0gMSwgbWF4ID0gMSwgaXNFbGVtUmVmLCBoYXNSZWZzID0gMDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogQ3JlYXRlIGEgbW9kZWwgZ3JvdXAgd2l0aCB0aGUgZ2l2ZW4gY29tcG9zaXRvci4KICAgICovCiAgICBpdGVtID0geG1sU2NoZW1hQWRkTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIHR5cGUsIG5vZGUpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CgogICAgaWYgKHdpdGhQYXJ0aWNsZSkgewoJaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgewoJICAgIG1pbiA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAxLCAxLCAiKDAgfCAxKSIpOwoJICAgIG1heCA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAxLCAxLCAxLCAiMSIpOwoJfSBlbHNlIHsKCSAgICAvKiBjaG9pY2UgKyBzZXF1ZW5jZSAqLwoJICAgIG1pbiA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgInhzOm5vbk5lZ2F0aXZlSW50ZWdlciIpOwoJICAgIG1heCA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsCgkJIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7Cgl9Cgl4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCBOVUxMLCBub2RlLCBtaW4sIG1heCk7CgkvKgoJKiBDcmVhdGUgYSBwYXJ0aWNsZQoJKi8KCXBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUoY3R4dCwgbm9kZSwgbWluLCBtYXgpOwoJaWYgKHBhcnRpY2xlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0KCiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIGl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgewoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCwgbGFzdCA9IE5VTEw7CgoJd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LAoJCXNjaGVtYSwgY2hpbGQsICZpc0VsZW1SZWYsIDApOwoJICAgIC8qCgkgICAgKiBTUEVDIGNvcy1hbGwtbGltaXRlZCAoMikKCSAgICAqICJUaGUge21heCBvY2N1cnN9IG9mIGFsbCB0aGUgcGFydGljbGVzIGluIHRoZSB7cGFydGljbGVzfQoJICAgICogb2YgdGhlICgnYWxsJykgZ3JvdXAgbXVzdCBiZSAwIG9yIDEuCgkgICAgKi8KCSAgICBpZiAocGFydCAhPSBOVUxMKSB7CgkJaWYgKGlzRWxlbVJlZikKCQkgICAgaGFzUmVmcysrOwoJCWlmIChwYXJ0LT5taW5PY2N1cnMgPiAxKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX0FMTF9MSU1JVEVELAoJCQlOVUxMLCBjaGlsZCwKCQkJIkludmFsaWQgdmFsdWUgZm9yIG1pbk9jY3VycyAobXVzdCBiZSAwIG9yIDEpIiwKCQkJTlVMTCk7CgkJICAgIC8qIFJlc2V0IHRvIDEuICovCgkJICAgIHBhcnQtPm1pbk9jY3VycyA9IDE7CgkJfQoJCWlmIChwYXJ0LT5tYXhPY2N1cnMgPiAxKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX0FMTF9MSU1JVEVELAoJCQlOVUxMLCBjaGlsZCwKCQkJIkludmFsaWQgdmFsdWUgZm9yIG1heE9jY3VycyAobXVzdCBiZSAwIG9yIDEpIiwKCQkJTlVMTCk7CgkJICAgIC8qIFJlc2V0IHRvIDEuICovCgkJICAgIHBhcnQtPm1heE9jY3VycyA9IDE7CgkJfQoJCWlmIChsYXN0ID09IE5VTEwpCgkJICAgIGl0ZW0tPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0OwoJCWVsc2UKCQkgICAgbGFzdC0+bmV4dCA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcGFydDsKCQlsYXN0ID0gcGFydDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoYW5ub3RhdGlvbj8sIGVsZW1lbnQqKSIpOwoJfQogICAgfSBlbHNlIHsKCS8qIGNob2ljZSArIHNlcXVlbmNlICovCgl4bWxTY2hlbWFUcmVlSXRlbVB0ciBwYXJ0ID0gTlVMTCwgbGFzdCA9IE5VTEw7CgoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKCgkgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewoJCXBhcnQgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAmaXNFbGVtUmVmLCAwKTsKCQlpZiAocGFydCAmJiBpc0VsZW1SZWYpCgkJICAgIGhhc1JlZnMrKzsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCQlwYXJ0ID0KCQkgICAgeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmUmVmKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJCWlmIChwYXJ0ICE9IE5VTEwpCgkJICAgIGhhc1JlZnMrKzsKCQkvKgoJCSogSGFuZGxlIHJlZGVmaW5pdGlvbnMuCgkJKi8KCQlpZiAoY3R4dC0+aXNSZWRlZmluZSAmJiBjdHh0LT5yZWRlZiAmJgoJCSAgICAoY3R4dC0+cmVkZWYtPml0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSAmJgoJCSAgICBwYXJ0ICYmIHBhcnQtPmNoaWxkcmVuKQoJCXsKCQkgICAgaWYgKCh4bWxTY2hlbWFHZXRRTmFtZVJlZk5hbWUocGFydC0+Y2hpbGRyZW4pID09CgkJCSAgICBjdHh0LT5yZWRlZi0+cmVmTmFtZSkgJiYKCQkJKHhtbFNjaGVtYUdldFFOYW1lUmVmVGFyZ2V0TnMocGFydC0+Y2hpbGRyZW4pID09CgkJCSAgICBjdHh0LT5yZWRlZi0+cmVmVGFyZ2V0TnMpKQoJCSAgICB7CgkJCS8qCgkJCSogU1BFQyBzcmMtcmVkZWZpbmU6CgkJCSogKDYuMSkgIklmIGl0IGhhcyBhIDxncm91cD4gYW1vbmcgaXRzIGNvbnRlbnRzIGF0CgkJCSogc29tZSBsZXZlbCB0aGUgt2FjdHVhbCB2YWx1Zbcgb2Ygd2hvc2UgcmVmCgkJCSogW2F0dHJpYnV0ZV0gaXMgdGhlIHNhbWUgYXMgdGhlILdhY3R1YWwgdmFsdWW3IG9mCgkJCSogaXRzIG93biBuYW1lIGF0dHJpYnV0ZSBwbHVzIHRhcmdldCBuYW1lc3BhY2UsIHRoZW4KCQkJKiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJCQkqICg2LjEuMSkgIkl0IG11c3QgaGF2ZSBleGFjdGx5IG9uZSBzdWNoIGdyb3VwLiIKCQkJKi8KCQkJaWYgKGN0eHQtPnJlZGVmQ291bnRlciAhPSAwKSB7CgkJCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKCQkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsIGNoaWxkLCBOVUxMLAoJCQkJIlRoZSByZWRlZmluaW5nIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gIgoJCQkJIiclcycgbXVzdCBub3QgY29udGFpbiBtb3JlIHRoYW4gb25lICIKCQkJCSJyZWZlcmVuY2UgdG8gdGhlIHJlZGVmaW5lZCBkZWZpbml0aW9uIiwKCQkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCQkgICAgY3R4dC0+cmVkZWYtPnJlZlRhcmdldE5zLAoJCQkJICAgIGN0eHQtPnJlZGVmLT5yZWZOYW1lKSwKCQkJCU5VTEwpOwoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCSAgICBwYXJ0ID0gTlVMTDsKCQkJfSBlbHNlIGlmICgoKFdYU19QQVJUSUNMRShwYXJ0KSktPm1pbk9jY3VycyAhPSAxKSB8fAoJCQkgICAgKChXWFNfUEFSVElDTEUocGFydCkpLT5tYXhPY2N1cnMgIT0gMSkpCgkJCXsKCQkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJCSAgICAvKgoJCQkgICAgKiBTUEVDIHNyYy1yZWRlZmluZToKCQkJICAgICogKDYuMS4yKSAiVGhlILdhY3R1YWwgdmFsdWW3IG9mIGJvdGggdGhhdAoJCQkgICAgKiBncm91cCdzIG1pbk9jY3VycyBhbmQgbWF4T2NjdXJzIFthdHRyaWJ1dGVdCgkJCSAgICAqIG11c3QgYmUgMSAob3Igt2Fic2VudLcpLgoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsIGNoaWxkLCBOVUxMLAoJCQkJIlRoZSByZWRlZmluaW5nIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gIgoJCQkJIiclcycgbXVzdCBub3QgY29udGFpbiBhIHJlZmVyZW5jZSB0byB0aGUgIgoJCQkJInJlZGVmaW5lZCBkZWZpbml0aW9uIHdpdGggYSAiCgkJCQkibWF4T2NjdXJzL21pbk9jY3VycyBvdGhlciB0aGFuIDEiLAoJCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJCSAgICBjdHh0LT5yZWRlZi0+cmVmVGFyZ2V0TnMsCgkJCQkgICAgY3R4dC0+cmVkZWYtPnJlZk5hbWUpLAoJCQkJTlVMTCk7CgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJICAgIHBhcnQgPSBOVUxMOwoJCQl9CgkJCWN0eHQtPnJlZGVmLT5yZWZlcmVuY2UgPSBXWFNfQkFTSUNfQ0FTVCBwYXJ0OwoJCQljdHh0LT5yZWRlZkNvdW50ZXIrKzsKCQkgICAgfQkJICAgICAgICAJCSAgIAoJCX0KCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB7CgkJcGFydCA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCQkgICAgeG1sU2NoZW1hUGFyc2VBbnkoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewoJCXBhcnQgPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgMSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CgkJcGFydCA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDEpOwoJICAgIH0KCSAgICBpZiAocGFydCAhPSBOVUxMKSB7CgkJaWYgKGxhc3QgPT0gTlVMTCkKCQkgICAgaXRlbS0+Y2hpbGRyZW4gPSBwYXJ0OwoJCWVsc2UKCQkgICAgbGFzdC0+bmV4dCA9IHBhcnQ7CgkJbGFzdCA9IHBhcnQ7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIik7Cgl9CiAgICB9CiAgICBpZiAoKG1heCA9PSAwKSAmJiAobWluID09IDApKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmIChoYXNSZWZzKSB7CgkvKgoJKiBXZSBuZWVkIHRvIHJlc29sdmUgcmVmZXJlbmNlcy4KCSovCglXWFNfQUREX1BFTkRJTkcoY3R4dCwgaXRlbSk7CiAgICB9CiAgICBpZiAod2l0aFBhcnRpY2xlKQoJcmV0dXJuICgoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHBhcnRpY2xlKTsJCiAgICBlbHNlCglyZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBSZXN0cmljdGlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSBwYXJlbnRUeXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJhc2UiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlIAogICAgKi8KICAgIC8qCiAgICAqIEV4dHJhY3QgdGhlIGJhc2UgdHlwZS4gVGhlICJiYXNlIiBhdHRyaWJ1dGUgaXMgbWFuZGF0b3J5IGlmIGluc2lkZQogICAgKiBhIGNvbXBsZXggdHlwZSBvciBpZiByZWRlZmluaW5nLgogICAgKgogICAgKiBTUEVDICgxLjIpICIuLi5vdGhlcndpc2UgKDxyZXN0cmljdGlvbj4gaGFzIG5vIDxzaW1wbGVUeXBlPiAiCiAgICAqIGFtb25nIGl0cyBbY2hpbGRyZW5dKSwgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gd2hpY2ggaXMKICAgICogdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieQogICAgKiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCBOVUxMLCBub2RlLCAiYmFzZSIsCgkmKHR5cGUtPmJhc2VOcyksICYodHlwZS0+YmFzZSkpID09IDApCiAgICB7CglpZiAoKHR5cGUtPmJhc2UgPT0gTlVMTCkgJiYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLCAiYmFzZSIsIE5VTEwpOwoJfSBlbHNlIGlmICgoY3R4dC0+aXNSZWRlZmluZSkgJiYKCSAgICAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkpCgl7CgkgICAgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCSAgICBOVUxMLCBub2RlLCAiYmFzZSIsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAoKCEgeG1sU3RyRXF1YWwodHlwZS0+YmFzZSwgdHlwZS0+bmFtZSkpIHx8CgkJKCEgeG1sU3RyRXF1YWwodHlwZS0+YmFzZU5zLCB0eXBlLT50YXJnZXROYW1lc3BhY2UpKSkKCSAgICB7CgkJeG1sQ2hhciAqc3RyMSA9IE5VTEwsICpzdHIyID0gTlVMTDsKCQkvKgoJCSogUkVERUZJTkU6IFNQRUMgc3JjLXJlZGVmaW5lICg1KQoJCSogIldpdGhpbiB0aGUgW2NoaWxkcmVuXSwgZWFjaCA8c2ltcGxlVHlwZT4gbXVzdCBoYXZlIGEKCQkqIDxyZXN0cmljdGlvbj4gYW1vbmcgaXRzIFtjaGlsZHJlbl0gLi4uIHRoZSC3YWN0dWFsIHZhbHVltyBvZgoJCSogd2hvc2UgYmFzZSBbYXR0cmlidXRlXSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSC3YWN0dWFsIHZhbHVltwoJCSogb2YgaXRzIG93biBuYW1lIGF0dHJpYnV0ZSBwbHVzIHRhcmdldCBuYW1lc3BhY2U7IgoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsCgkJICAgIE5VTEwsIG5vZGUsICJUaGlzIGlzIGEgcmVkZWZpbml0aW9uLCBidXQgdGhlIFFOYW1lICIKCQkgICAgInZhbHVlICclcycgb2YgdGhlICdiYXNlJyBhdHRyaWJ1dGUgZG9lcyBub3QgbWF0Y2ggdGhlICIKCQkgICAgInR5cGUncyBkZXNpZ25hdGlvbiAnJXMnIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0cjEsIHR5cGUtPmJhc2VOcywgdHlwZS0+YmFzZSksCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIyLCB0eXBlLT50YXJnZXROYW1lc3BhY2UsCgkJCXR5cGUtPm5hbWUpLCBOVUxMKTsKCQlGUkVFX0FORF9OVUxMKHN0cjEpOwoJCUZSRUVfQU5EX05VTEwoc3RyMik7CgkJLyogQXZvaWQgY29uZnVzaW9uIGFuZCBlcmFzZSB0aGUgdmFsdWVzLiAqLwoJCXR5cGUtPmJhc2UgPSBOVUxMOwoJCXR5cGUtPmJhc2VOcyA9IE5VTEw7CgkgICAgfQoJfQkJCiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBzaW1wbGUgdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbj48c2ltcGxlVHlwZT4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCQkvKgoJCSogc3JjLXJlc3RyaWN0aW9uLWJhc2Utb3Itc2ltcGxlVHlwZQoJCSogRWl0aGVyIHRoZSBiYXNlIFthdHRyaWJ1dGVdIG9yIHRoZSBzaW1wbGVUeXBlIFtjaGlsZF0gb2YgdGhlCgkJKiA8cmVzdHJpY3Rpb24+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfUkVTVFJJQ1RJT05fQkFTRV9PUl9TSU1QTEVUWVBFLAoJCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ2Jhc2UnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCXR5cGUtPmJhc2VUeXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAodHlwZS0+YmFzZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTVFJJQ1RJT05fQkFTRV9PUl9TSU1QTEVUWVBFLAoJCU5VTEwsIG5vZGUsIGNoaWxkLAoJCSJFaXRoZXIgdGhlIGF0dHJpYnV0ZSAnYmFzZScgb3IgYSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJtdXN0IGJlIHByZXNlbnQiLCBOVUxMKTsKCX0KICAgIH0gZWxzZSBpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8Y29tcGxleFR5cGU+PGNvbXBsZXhDb250ZW50PjxyZXN0cmljdGlvbj4uLi4KCSogZm9sbG93ZWQgYnk6CgkqCgkqIE1vZGVsIGdyb3VwcyA8YWxsPiwgPGNob2ljZT4gYW5kIDxzZXF1ZW5jZT4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LAoJCSAgICBzY2hlbWEsIGNoaWxkLCBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJLyoKCSogTW9kZWwgZ3JvdXAgcmVmZXJlbmNlIDxncm91cD4uCgkqLwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CSAgICAKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICAvKgoJICAgICogTm90ZSB0aGF0IHRoZSByZWZlcmVuY2Ugd2lsbCBiZSByZXNvbHZlZCBpbgoJICAgICogeG1sU2NoZW1hUmVzb2x2ZVR5cGVSZWZlcmVuY2VzKCk7CgkgICAgKi8KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfSBlbHNlIGlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgewoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50PjxyZXN0cmljdGlvbj4uLi4KCSoKCSogIjEuMSB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4KCSogYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPHJlc3RyaWN0aW9uPiBpZiB0aGVyZSBpcyBvbmU7IgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICAvKgoJICAgICogV2Ugd2lsbCBzdG9yZSB0aGUgdG8tYmUtcmVzdHJpY3RlZCBzaW1wbGUgdHlwZSBpbgoJICAgICogdHlwZS0+Y29udGVudFR5cGVEZWYgKnRlbXBvcmFyaWx5Ki4KCSAgICAqLwoJICAgIHR5cGUtPmNvbnRlbnRUeXBlRGVmID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGlmICggdHlwZS0+Y29udGVudFR5cGVEZWYgPT0gTlVMTCkKCQlyZXR1cm4gKE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CgogICAgaWYgKChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgbGFzdGZhY2V0ID0gTlVMTDsKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxjb21wbGV4VHlwZT48c2ltcGxlQ29udGVudD48cmVzdHJpY3Rpb24+Li4uCgkqIDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbj4uLi4KCSovCgoJLyoKCSogQWRkIHRoZSBmYWNldHMgdG8gdGhlIHNpbXBsZSB0eXBlIGFuY2VzdG9yLgoJKi8KCS8qCgkqIFRPRE86IERhdGF0eXBlczogNC4xLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9uIG9mCgkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6CgkqICpTaW5nbGUgRmFjZXQgVmFsdWUqCgkqLwoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJtaW5JbmNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWluRXhjbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heEluY2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtYXhFeGNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAidG90YWxEaWdpdHMiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZnJhY3Rpb25EaWdpdHMiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAicGF0dGVybiIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJlbnVtZXJhdGlvbiIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJ3aGl0ZVNwYWNlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImxlbmd0aCIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtYXhMZW5ndGgiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWluTGVuZ3RoIikpKSB7CgkgICAgZmFjZXQgPSB4bWxTY2hlbWFQYXJzZUZhY2V0KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGlmIChmYWNldCAhPSBOVUxMKSB7CgkJaWYgKGxhc3RmYWNldCA9PSBOVUxMKQoJCSAgICB0eXBlLT5mYWNldHMgPSBmYWNldDsKCQllbHNlCgkJICAgIGxhc3RmYWNldC0+bmV4dCA9IGZhY2V0OwoJCWxhc3RmYWNldCA9IGZhY2V0OwoJCWxhc3RmYWNldC0+bmV4dCA9IE5VTEw7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CgkvKgoJKiBDcmVhdGUgbGlua3MgZm9yIGRlcml2YXRpb24gYW5kIHZhbGlkYXRpb24uCgkqLwoJaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluaywgbGFzdEZhY2V0TGluayA9IE5VTEw7CgoJICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJICAgIGRvIHsKCQlmYWNldExpbmsgPSAoeG1sU2NoZW1hRmFjZXRMaW5rUHRyKQoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0TGluaykpOwoJCWlmIChmYWNldExpbmsgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgZmFjZXQgbGluayIsIE5VTEwpOwoJCSAgICB4bWxGcmVlKGZhY2V0TGluayk7CgkJICAgIHJldHVybiAoTlVMTCk7CgkJfQoJCWZhY2V0TGluay0+ZmFjZXQgPSBmYWNldDsKCQlmYWNldExpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0RmFjZXRMaW5rID09IE5VTEwpCgkJICAgIHR5cGUtPmZhY2V0U2V0ID0gZmFjZXRMaW5rOwoJCWVsc2UKCQkgICAgbGFzdEZhY2V0TGluay0+bmV4dCA9IGZhY2V0TGluazsKCQlsYXN0RmFjZXRMaW5rID0gZmFjZXRMaW5rOwoJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7Cgl9CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJLyoKCSogQXR0cmlidXRlIHVzZXMvZGVjbGFyYXRpb25zLgoJKi8KCWlmICh4bWxTY2hlbWFQYXJzZUxvY2FsQXR0cmlidXRlcyhjdHh0LCBzY2hlbWEsICZjaGlsZCwKCSAgICAoeG1sU2NoZW1hSXRlbUxpc3RQdHIgKikgJih0eXBlLT5hdHRyVXNlcyksCgkgICAgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OLCBOVUxMKSA9PSAtMSkKCSAgICByZXR1cm4oTlVMTCk7CgkvKgoJKiBBdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPQoJCXhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJImFubm90YXRpb24/LCAoZ3JvdXAgfCBhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSk/LCAiCgkJIigoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpIik7Cgl9IGVsc2UgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CgkgICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKHNpbXBsZVR5cGU/LCAobWluRXhjbHVzaXZlIHwgbWluSW5jbHVzaXZlIHwgIgoJCSJtYXhFeGNsdXNpdmUgfCBtYXhJbmNsdXNpdmUgfCB0b3RhbERpZ2l0cyB8IGZyYWN0aW9uRGlnaXRzIHwgIgoJCSJsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCAiCgkJInBhdHRlcm4pKik/LCAoKGF0dHJpYnV0ZSB8IGF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSIpOwoJfSBlbHNlIHsKCSAgICAvKiBTaW1wbGUgdHlwZSAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKHNpbXBsZVR5cGU/LCAobWluRXhjbHVzaXZlIHwgbWluSW5jbHVzaXZlIHwgIgoJCSJtYXhFeGNsdXNpdmUgfCBtYXhJbmNsdXNpdmUgfCB0b3RhbERpZ2l0cyB8IGZyYWN0aW9uRGlnaXRzIHwgIgoJCSJsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCAiCgkJInBhdHRlcm4pKikpIik7Cgl9CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VFeHRlbnNpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VzIGFuIDxleHRlbnNpb24+LCB3aGljaCBpcyBmb3VuZCBpbnNpZGUgYQogKiA8c2ltcGxlQ29udGVudD4gb3IgPGNvbXBsZXhDb250ZW50Pi4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZS4KICoKICogVE9ETzogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHBhcmVudFR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJhc2UiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogQXR0cmlidXRlICJiYXNlIiAtIG1hbmRhdG9yeS4KICAgICovCiAgICBpZiAoKHhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCBOVUxMLCBub2RlLAoJImJhc2UiLCAmKHR5cGUtPmJhc2VOcyksICYodHlwZS0+YmFzZSkpID09IDApICYmCgkodHlwZS0+YmFzZSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCAiYmFzZSIsIE5VTEwpOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIEFkZCB0aGUgYW5ub3RhdGlvbiB0byB0aGUgdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxjb21wbGV4VHlwZT48Y29tcGxleENvbnRlbnQ+PGV4dGVuc2lvbj4uLi4gYW5kOgoJKgoJKiBNb2RlbCBncm91cHMgPGFsbD4sIDxjaG9pY2U+LCA8c2VxdWVuY2U+IGFuZCA8Z3JvdXA+LgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwKCQkgICAgY2hpbGQsIFhNTF9TQ0hFTUFfVFlQRV9BTEwsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLAoJCSAgICBjaGlsZCwgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwKCQljaGlsZCwgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgLyoKCSAgICAqIE5vdGUgdGhhdCB0aGUgcmVmZXJlbmNlIHdpbGwgYmUgcmVzb2x2ZWQgaW4KCSAgICAqIHhtbFNjaGVtYVJlc29sdmVUeXBlUmVmZXJlbmNlcygpOwoJICAgICovCgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkvKgoJKiBBdHRyaWJ1dGUgdXNlcy9kZWNsYXJhdGlvbnMuCgkqLwoJaWYgKHhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGVzKGN0eHQsIHNjaGVtYSwgJmNoaWxkLAoJICAgICh4bWxTY2hlbWFJdGVtTGlzdFB0ciAqKSAmKHR5cGUtPmF0dHJVc2VzKSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OLCBOVUxMKSA9PSAtMSkKCSAgICByZXR1cm4oTlVMTCk7CgkvKgoJKiBBdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgY3R4dC0+Y3R4dFR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0KCQl4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCSAgICAvKiBDb21wbGV4IGNvbnRlbnQgZXh0ZW5zaW9uLiAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpIik7Cgl9IGVsc2UgewoJICAgIC8qIFNpbXBsZSBjb250ZW50IGV4dGVuc2lvbi4gKi8KCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgIgoJCSJhbnlBdHRyaWJ1dGU/KSkiKTsKCX0KICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZUNvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgIGludCAqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwKCShoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPSAwOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIEFkZCB0aGUgYW5ub3RhdGlvbiB0byB0aGUgY29tcGxleCB0eXBlIGFuY2VzdG9yLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCBOVUxMLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CQogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCBOVUxMLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CQogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImV4dGVuc2lvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpOwoJKCpoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKSA9IDE7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIGludCAqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwKCShoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPSAwOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaXhlZCIpKSkKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgIC8qCiAgICAqIFNldCB0aGUgJ21peGVkJyBvbiB0aGUgY29tcGxleCB0eXBlIGFuY2VzdG9yLgogICAgKi8KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBub2RlLCAibWl4ZWQiLCAwKSkgIHsKCWlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSA9PSAwKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsIE5VTEwsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgTlVMTCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCk7CgkoKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pID0gMTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCk7CgkoKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pID0gMTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4IFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZTsKI2lmZGVmIEVOQUJMRV9OQU1FRF9MT0NBTFMKICAgIGNoYXIgYnVmWzQwXTsKI2VuZGlmCiAgICBpbnQgZmluYWwgPSAwLCBibG9jayA9IDAsIGhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPSAwOwoKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CgogICAgaWYgKHRvcExldmVsKSB7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCBOVUxMLCBub2RlLCAibmFtZSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCiAgICB9CgogICAgaWYgKHRvcExldmVsID09IDApIHsKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgoJKi8KI2lmZGVmIEVOQUJMRV9OQU1FRF9MT0NBTFMKICAgICAgICBzbnByaW50ZihidWYsIDM5LCAiI0NUJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCwKCSAgICB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIChjb25zdCB4bWxDaGFyICopYnVmLCAtMSksCgkgICAgY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlLCAwKTsKI2Vsc2UKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCwKCSAgICBOVUxMLCBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUsIDApOwojZW5kaWYKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCW5hbWUgPSB0eXBlLT5uYW1lOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7CgkvKgoJKiBUT0RPOiBXZSBuZWVkIHRoZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KICAgIH0gZWxzZSB7CgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYLAoJICAgIG5hbWUsIGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgfQogICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgImlkIi4KCQkqLwoJCXhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgIm1peGVkIi4KCQkqLwoJCWlmICh4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZShjdHh0LAoJCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0cikpCgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CgkgICAgfSBlbHNlIGlmICh0b3BMZXZlbCkgewoJCS8qCgkJKiBBdHRyaWJ1dGVzIG9mIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbnMuCgkJKi8KCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgewoJCSAgICAvKiBQYXNzLiAqLwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImFic3RyYWN0Ii4KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsCgkJCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0cikpCgkJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1Q7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJCSAgICAqLwoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CgkJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLAoJCQkmKHR5cGUtPmZsYWdzKSwKCQkJLTEsCgkJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OLAoJCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OLAoJCQktMSwgLTEsIC0xKSAhPSAwKQoJCSAgICB7CgkJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpIiwKCQkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIH0gZWxzZSAKCQkJZmluYWwgPSAxOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJsb2NrIikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImJsb2NrIi4KCQkgICAgKi8KCQkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwKCQkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJih0eXBlLT5mbGFncyksCgkJCS0xLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTiwKCQkJWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTiwKCQkJLTEsIC0xLCAtMSkgIT0gMCkgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCQkgICAgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKSAiLAoJCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkgICAgfSBlbHNlIAoJCQlibG9jayA9IDE7CgkJfSBlbHNlIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICBpZiAoISBibG9jaykgewoJLyoKCSogQXBwbHkgZGVmYXVsdCAiYmxvY2siIHZhbHVlcy4KCSovCglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT047CiAgICB9CiAgICBpZiAoISBmaW5hbCkgewoJLyoKCSogQXBwbHkgZGVmYXVsdCAiYmxvY2siIHZhbHVlcy4KCSovCglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjsKCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT047CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZUNvbnRlbnQiKSkgewoJLyoKCSogPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50Pi4uLgoJKiAzLjQuMyA6IDIuMgoJKiBTcGVjaWZ5aW5nIG1peGVkPSd0cnVlJyB3aGVuIHRoZSA8c2ltcGxlQ29udGVudD4KCSogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuIGhhcyBubyBlZmZlY3QKCSovCglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJICAgIHR5cGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgJmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhDb250ZW50IikpIHsKCS8qCgkqIDxjb21wbGV4VHlwZT48Y29tcGxleENvbnRlbnQ+Li4uCgkqLwoJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgICZoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIHsKCS8qCgkqIEUuZyA8Y29tcGxleFR5cGU+PHNlcXVlbmNlPi4uLiBvciA8Y29tcGxleFR5cGU+PGF0dHJpYnV0ZT4uLi4gZXRjLgoJKgoJKiBTUEVDCgkqICIuLi50aGUgdGhpcmQgYWx0ZXJuYXRpdmUgKG5laXRoZXIgPHNpbXBsZUNvbnRlbnQ+IG5vcgoJKiA8Y29tcGxleENvbnRlbnQ+KSBpcyBjaG9zZW4uIFRoaXMgY2FzZSBpcyB1bmRlcnN0b29kIGFzIHNob3J0aGFuZAoJKiBmb3IgY29tcGxleCBjb250ZW50IHJlc3RyaWN0aW5nIHRoZSC3dXItdHlwZSBkZWZpbml0aW9utywgYW5kIHRoZQoJKiBkZXRhaWxzIG9mIHRoZSBtYXBwaW5ncyBzaG91bGQgYmUgbW9kaWZpZWQgYXMgbmVjZXNzYXJ5LgoJKi8KCXR5cGUtPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoJLyoKCSogUGFyc2UgbW9kZWwgZ3JvdXBzLgoJKi8KICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCwgMSk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgLyoKCSAgICAqIE5vdGUgdGhhdCB0aGUgcmVmZXJlbmNlIHdpbGwgYmUgcmVzb2x2ZWQgaW4KCSAgICAqIHhtbFNjaGVtYVJlc29sdmVUeXBlUmVmZXJlbmNlcygpOwoJICAgICovCiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfQoJLyoKCSogUGFyc2UgYXR0cmlidXRlIGRlY2xzL3JlZnMuCgkqLwogICAgICAgIGlmICh4bWxTY2hlbWFQYXJzZUxvY2FsQXR0cmlidXRlcyhjdHh0LCBzY2hlbWEsICZjaGlsZCwKCSAgICAoeG1sU2NoZW1hSXRlbUxpc3RQdHIgKikgJih0eXBlLT5hdHRyVXNlcyksCgkgICAgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OLCBOVUxMKSA9PSAtMSkKCSAgICByZXR1cm4oTlVMTCk7CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNpbXBsZUNvbnRlbnQgfCBjb21wbGV4Q29udGVudCB8ICIKCSAgICAiKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICgoYXR0cmlidXRlIHwgIgoJICAgICJhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpKSIpOwogICAgfQogICAgLyoKICAgICogUkVERUZJTkU6IFNQRUMgc3JjLXJlZGVmaW5lICg1KQogICAgKi8KICAgIGlmICh0b3BMZXZlbCAmJiBjdHh0LT5pc1JlZGVmaW5lICYmICghIGhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCSAgICBOVUxMLCBub2RlLCAiVGhpcyBpcyBhIHJlZGVmaW5pdGlvbiwgdGh1cyB0aGUgIgoJICAgICI8Y29tcGxleFR5cGU+IG11c3QgaGF2ZSBhIDxyZXN0cmljdGlvbj4gb3IgPGV4dGVuc2lvbj4gIgoJICAgICJncmFuZC1jaGlsZCIsIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW5nIHVzaW5nIFNjaGVtYXMJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlSZWFkaW5nL1dyaXRpbmcgU2NoZW1hcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZiAwIC8qIFdpbGwgYmUgZW5hYmxlZCBpZiBpdCBpcyBjbGVhciB3aGF0IG9wdGlvbnMgYXJlIG5lZWRlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVBhcnNlckN0eHRTZXRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG9wdGlvbnM6IGEgY29tYmluYXRpb24gb2YgeG1sU2NoZW1hUGFyc2VyT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHBhcnNlLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICBpbnQgb3B0aW9ucykKCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFQYXJzZU9wdGlvbi4KICAgICovCiAgICBmb3IgKGkgPSAxOyBpIDwgKGludCkgc2l6ZW9mKGludCkgKiA4OyBpKyspIHsKICAgICAgICBpZiAob3B0aW9ucyAmIDE8PGkpIHsKCSAgICByZXR1cm4gKC0xKTsKICAgICAgICB9CiAgICB9CiAgICBjdHh0LT5vcHRpb25zID0gb3B0aW9uczsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHRHZXRPcHRpb25zOgogKiBAY3R4dDogYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9mIHRoZSBwYXJzZXIgY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQoKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZQoJcmV0dXJuIChjdHh0LT5vcHRpb25zKTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KGNvbnN0IGNoYXIgKlVSTCkKewogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciByZXQ7CgogICAgaWYgKFVSTCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSgpOwogICAgaWYgKHJldCA9PSBOVUxMKQoJcmV0dXJuKE5VTEwpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0OgogKiBAYnVmZmVyOiAgYSBwb2ludGVyIHRvIGEgY2hhciBhcnJheSBjb250YWluaW5nIHRoZSBzY2hlbWFzCiAqIEBzaXplOiAgdGhlIHNpemUgb2YgdGhlIGFycmF5CiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IG1lbW9yeSBidWZmZXIgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3TWVtUGFyc2VyQ3R4dChjb25zdCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoKGJ1ZmZlciA9PSBOVUxMKSB8fCAoc2l6ZSA8PSAwKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSgpOwogICAgaWYgKHJldCA9PSBOVUxMKQoJcmV0dXJuKE5VTEwpOwogICAgcmV0LT5idWZmZXIgPSBidWZmZXI7CiAgICByZXQtPnNpemUgPSBzaXplOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOyAgICAKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0RvY1BhcnNlckN0eHQ6CiAqIEBkb2M6ICBhIHByZXBhcnNlZCBkb2N1bWVudCB0cmVlCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGRvY3VtZW50LgogKiBOQi4gVGhlIGRvY3VtZW50IG1heSBiZSBtb2RpZmllZCBkdXJpbmcgdGhlIHBhcnNpbmcgcHJvY2Vzcy4KICoKICogUmV0dXJucyB0aGUgcGFyc2VyIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld0RvY1BhcnNlckN0eHQoeG1sRG9jUHRyIGRvYykKewogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciByZXQ7CgogICAgaWYgKGRvYyA9PSBOVUxMKQogICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSgpOwogICAgaWYgKHJldCA9PSBOVUxMKQoJcmV0dXJuKE5VTEwpOwogICAgcmV0LT5kb2MgPSBkb2M7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICAvKiBUaGUgYXBwbGljYXRpb24gaGFzIHJlc3BvbnNpYmlsaXR5IGZvciB0aGUgZG9jdW1lbnQgKi8KICAgIHJldC0+cHJlc2VydmUgPSAxOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGN0eHQtPmRvYyAhPSBOVUxMICYmICFjdHh0LT5wcmVzZXJ2ZSkKICAgICAgICB4bWxGcmVlRG9jKGN0eHQtPmRvYyk7ICAgIAogICAgaWYgKGN0eHQtPnZjdHh0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWxpZEN0eHQoY3R4dC0+dmN0eHQpOwogICAgfQogICAgaWYgKGN0eHQtPm93bnNDb25zdHJ1Y3RvciAmJiAoY3R4dC0+Y29uc3RydWN0b3IgIT0gTlVMTCkpIHsKCXhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRGcmVlKGN0eHQtPmNvbnN0cnVjdG9yKTsKCWN0eHQtPmNvbnN0cnVjdG9yID0gTlVMTDsKCWN0eHQtPm93bnNDb25zdHJ1Y3RvciA9IDA7CiAgICB9CiAgICBpZiAoY3R4dC0+YXR0clByb2hpYnMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjdHh0LT5hdHRyUHJvaGlicyk7CiAgICB4bWxEaWN0RnJlZShjdHh0LT5kaWN0KTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqCQkJQnVpbGRpbmcgdGhlIGNvbnRlbnQgbW9kZWxzCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUsIGludCBjb3VudGVyLCB4bWxBdXRvbWF0YVN0YXRlUHRyIGVuZCkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgdG1wOwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwgbWVtYmVyOwogICAgeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBzdWJzdEdyb3VwOwogICAgaW50IGk7CgogICAgZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwogICAgLyoKICAgICogV3JhcCB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwIHdpdGggYSBDSE9JQ0UuCiAgICAqLwogICAgc3RhcnQgPSBwY3R4dC0+c3RhdGU7CiAgICBpZiAoZW5kID09IE5VTEwpCgllbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CiAgICBzdWJzdEdyb3VwID0geG1sU2NoZW1hU3Vic3RHcm91cEdldChwY3R4dCwgZWxlbURlY2wpOwogICAgaWYgKHN1YnN0R3JvdXAgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgV1hTX0lURU1fTk9ERShwYXJ0aWNsZSksCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAsICIKCSAgICAiZGVjbGFyYXRpb24gaXMgbWFya2VkIGhhdmluZyBhIHN1YnN0LiBncm91cCBidXQgbm9uZSAiCgkgICAgImF2YWlsYWJsZS5cbiIsIGVsZW1EZWNsLT5uYW1lLCBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIGlmIChjb3VudGVyID49IDApIHsKCS8qCgkqIE5PVEUgdGhhdCB3ZSBwdXQgdGhlIGRlY2xhcmF0aW9uIGluLCBldmVuIGlmIGl0J3MgYWJzdHJhY3QuCgkqIEhvd2V2ZXIsIGFuIGVycm9yIHdpbGwgYmUgcmFpc2VkIGR1cmluZyAqdmFsaWRhdGlvbiogaWYgYW4gZWxlbWVudAoJKiBpbmZvcm1hdGlvbiBpdGVtIHNoYWxsIGJlIHZhbGlkYXRlZCBhZ2FpbnN0IGFuIGFic3RyYWN0IGVsZW1lbnQKCSogZGVjbGFyYXRpb24uCgkqLwoJdG1wID0geG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLCBzdGFydCwgTlVMTCwgY291bnRlcik7CiAgICAgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sIHRtcCwgZW5kLAoJICAgICAgICAgICAgZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsKCS8qCgkqIEFkZCBzdWJzdC4gZ3JvdXAgbWVtYmVycy4KCSovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwogICAgICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwgdG1wLCBlbmQsCgkJICAgICAgICAgICAgICAgbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwgbWVtYmVyKTsKCX0KICAgIH0gZWxzZSBpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkvKgoJKiBOT1RFIHRoYXQgd2UgcHV0IHRoZSBkZWNsYXJhdGlvbiBpbiwgZXZlbiBpZiBpdCdzIGFic3RyYWN0LAoJKi8KCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkgICAgc3RhcnQsIE5VTEwsCgkgICAgZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKSwgZW5kKTsKCS8qCgkqIEFkZCBzdWJzdC4gZ3JvdXAgbWVtYmVycy4KCSovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGlzIGZpeGVzIGJ1ZyAjMzQxMTUwLiB4bWxBdXRvbWF0YU5ld09uY2VUcmFuczIoKQoJICAgICogIHdhcyBpbmNvcnJlY3RseSB1c2VkIGluc3RlYWQgb2YgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMigpCgkgICAgKiAgKHNlZW1zIGxpa2UgYSBjb3B5JnBhc3RlIGJ1ZyBmcm9tIHRoZSBYTUxfU0NIRU1BX1RZUEVfQUxMCgkgICAgKiAgc2VjdGlvbiBpbiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoKSApLgoJICAgICogVE9ETzogQ2hlY2sgaWYgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKCkgd2FzIGluc3RlYWQgCgkgICAgKiAgaW50ZW5kZWQgZm9yIHRoZSBhYm92ZSAiY291bnRlciIgc2VjdGlvbiBvcmlnaW5hbGx5LiBJLmUuLAoJICAgICogIGNoZWNrIHhzOmFsbCB3aXRoIHN1YnN0LWdyb3Vwcy4KCSAgICAqCgkgICAgKiB0bXAgPSB4bWxBdXRvbWF0YU5ld09uY2VUcmFuczIocGN0eHQtPmFtLCBzdGFydCwgTlVMTCwKCSAgICAqCSAgICAgICAgICAgICAgIG1lbWJlci0+bmFtZSwgbWVtYmVyLT50YXJnZXROYW1lc3BhY2UsCgkgICAgKgkJICAgICAgIDEsIDEsIG1lbWJlcik7CgkgICAgKi8KCSAgICB0bXAgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwgbWVtYmVyKTsJICAgIAoJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHRtcCwgZW5kKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKCWludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CgkgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CglpbnQgbWluT2NjdXJzID0gcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJY291bnRlciA9CgkgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwgbWluT2NjdXJzLAoJICAgIG1heE9jY3Vycyk7Cglob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCSAgICBzdGFydCwgTlVMTCwKCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpLAoJICAgIGhvcCk7CgkvKgoJICogQWRkIHN1YnN0LiBncm91cCBtZW1iZXJzLgoJICovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwoJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkJc3RhcnQsIE5VTEwsCgkJbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwgbWVtYmVyKSwKCQlob3ApOwoJfQoJeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLCBob3AsIHN0YXJ0LCBjb3VudGVyKTsKCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKHBjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwogICAgfQogICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkKCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgcGN0eHQtPnN0YXRlID0gZW5kOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvckVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuKS0+ZmxhZ3MgJgoJWE1MX1NDSEVNQVNfRUxFTV9TVUJTVF9HUk9VUF9IRUFEKSB7CgkvKgoJKiBTdWJzdGl0dXRpb24gZ3JvdXBzLgoJKi8KCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cChjdHh0LCBwYXJ0aWNsZSwgLTEsIE5VTEwpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoKCWVsZW1EZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbjsKCglpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKCSAgICByZXR1cm47CglpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwoJfSBlbHNlIGlmICgocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpICYmCgkgICAgICAgICAgIChwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMikpIHsKCSAgICAvKiBTcGVjaWFsIGNhc2UuICovCgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsJICAgIAoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsJICAgIAoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGN0eHQtPnN0YXRlLAoJCWVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCk7CSAgICAKCX0gZWxzZSB7CgkgICAgaW50IGNvdW50ZXI7CgkgICAgaW50IG1heE9jY3VycyA9IHBhcnRpY2xlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KCQkJICAgIFVOQk9VTkRFRCA6IHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxOwoJICAgIGludCBtaW5PY2N1cnMgPSBwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMSA/CgkJCSAgICAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJICAgIHN0YXJ0ID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgTlVMTCk7CgkgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOwoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsKCSAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIHN0YXJ0LCBjb3VudGVyKTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKCQlOVUxMLCBjb3VudGVyKTsKCX0KCWlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApCgkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBzdGFydCwgY3R4dC0+c3RhdGUpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHBhcnRpY2xlOiAgdGhlIHBhcnRpY2xlIGNvbXBvbmVudAogKiBAbmFtZTogIHRoZSBjb21wbGV4IHR5cGUncyBuYW1lIHdob3NlIGNvbnRlbnQgaXMgYmVpbmcgYnVpbHQKICoKICogQ3JlYXRlIHRoZSBhdXRvbWF0b24gZm9yIHRoZSB7Y29udGVudCB0eXBlfSBvZiBhIGNvbXBsZXggdHlwZS4KICoKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwiLCAicGFydGljbGUgaXMgTlVMTCIpOwkgICAgCglyZXR1cm47CiAgICB9CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHsKCS8qCgkqIEp1c3QgcmV0dXJuIGluIHRoaXMgY2FzZS4gQSBtaXNzaW5nICJ0ZXJtIiBvZiB0aGUgcGFydGljbGUKCSogbWlnaHQgYXJpc2UgZHVlIHRvIGFuIGludmFsaWQgInRlcm0iIGNvbXBvbmVudC4KCSovCglyZXR1cm47CiAgICB9CgogICAgc3dpdGNoIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogewoJICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkOwoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbnM7CgoJICAgIHdpbGQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbjsKCgkgICAgc3RhcnQgPSBwY3R4dC0+c3RhdGU7CgkgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwoKCSAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkJaWYgKHdpbGQtPmFueSA9PSAxKSB7CgkJICAgIC8qCgkJICAgICogV2UgbmVlZCB0byBhZGQgYm90aCB0cmFuc2l0aW9uczoKCQkgICAgKgoJCSAgICAqIDEuIHRoZSB7IioiLCAiKiJ9IGZvciBlbGVtZW50cyBpbiBhIG5hbWVzcGFjZS4KCQkgICAgKi8KCQkgICAgcGN0eHQtPnN0YXRlID0KCQkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIEJBRF9DQVNUICIqIiwgd2lsZCk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkgICAgLyoKCQkgICAgKiAyLiB0aGUgeyIqIn0gZm9yIGVsZW1lbnRzIGluIG5vIG5hbWVzcGFjZS4KCQkgICAgKi8KCQkgICAgcGN0eHQtPnN0YXRlID0KCQkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIE5VTEwsIHdpbGQpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGVuZCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCXBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoJCQlwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJICAgIHBjdHh0LT5zdGF0ZSwgTlVMTCwgQkFEX0NBU1QgIioiLCBucy0+dmFsdWUsIHdpbGQpOwoJCQl4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGVuZCk7CgkJCW5zID0gbnMtPm5leHQ7CgkJICAgIH0gd2hpbGUgKG5zICE9IE5VTEwpOwoKCQl9IGVsc2UgaWYgKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgcGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdOZWdUcmFucyhwY3R4dC0+YW0sCgkJCXN0YXJ0LCBlbmQsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLAoJCQl3aWxkKTsKCQl9CgkgICAgfSBlbHNlIHsKCQlpbnQgY291bnRlcjsKCQl4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKCQlpbnQgbWF4T2NjdXJzID0KCQkgICAgcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPyBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKCQlpbnQgbWluT2NjdXJzID0KCQkgICAgcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJCWNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIocGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CgkJaG9wID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwoJCWlmICh3aWxkLT5hbnkgPT0gMSkgewoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBob3ApOwoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgTlVMTCwgd2lsZCk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgaG9wKTsKCQl9IGVsc2UgaWYgKHdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgbnMgPSB3aWxkLT5uc1NldDsKCQkgICAgZG8gewoJCQlwY3R4dC0+c3RhdGUgPQoJCQkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBucy0+dmFsdWUsIHdpbGQpOwoJCQl4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGhvcCk7CgkJCW5zID0gbnMtPm5leHQ7CgkJICAgIH0gd2hpbGUgKG5zICE9IE5VTEwpOwoKCQl9IGVsc2UgaWYgKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgcGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdOZWdUcmFucyhwY3R4dC0+YW0sCgkJCXN0YXJ0LCBob3AsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLAoJCQl3aWxkKTsKCQl9CgkJeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLCBob3AsIHN0YXJ0LCBjb3VudGVyKTsKCQl4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIGhvcCwgZW5kLCBjb3VudGVyKTsKCSAgICB9CgkgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewoJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwoJICAgIH0KCSAgICBwY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWxGb3JFbGVtZW50KHBjdHh0LCBwYXJ0aWNsZSk7CgkgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgc3ViOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJZiBtYXggYW5kIG1pbiBvY2N1cmFuY2VzIGFyZSBkZWZhdWx0ICgxKSB0aGVuCiAgICAgICAgICAgICAgICAgKiBzaW1wbHkgaXRlcmF0ZSBvdmVyIHRoZSBwYXJ0aWNsZXMgb2YgdGhlIDxzZXF1ZW5jZT4uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgocGFydGljbGUtPm1pbk9jY3VycyA9PSAxKSAmJiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBvbGRzdGF0ZSA9IHBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBwY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sCgkJCQlwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwgVU5CT1VOREVEKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBwY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMocGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQkJCW9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gcGN0eHQtPnN0YXRlOwoKCQkJICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSk7CgkJCSAgICAvKgoJCQkgICAgICogZXBzaWxvbiBuZWVkZWQgdG8gYmxvY2sgcHJldmlvdXMgdHJhbnMgZnJvbQoJCQkgICAgICogYmVpbmcgYWxsb3dlZCB0byBlbnRlciBiYWNrIGZyb20gYW5vdGhlcgoJCQkgICAgICogY29uc3RydWN0CgkJCSAgICAgKi8KCQkJICAgIHBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJCQkJCXBjdHh0LT5zdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQkJCSAgICBvbGRzdGF0ZSwgcGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHBhcnRpY2xlLT5tYXhPY2N1cnMgPiAxKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHBhcnRpY2xlLT5taW5PY2N1cnMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkgICAgb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IHBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIocGN0eHQtPmFtLAoJCQkgICAgcGFydGljbGUtPm1pbk9jY3VycyAtIDEsCgkJCSAgICBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMSk7CgogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJCSh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBwY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwKCQkJICAgIHRtcCwgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMocGN0eHQtPmFtLCB0bXAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQkJCW9sZHN0YXRlLCBwY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIHN1YjsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCiAgICAgICAgICAgICAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIGVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUocGN0eHQtPmFtKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaXRlcmF0ZSBvdmVyIHRoZSBzdWJ0eXBlcyBhbmQgcmVtZXJnZSB0aGUgZW5kIHdpdGggYW4KICAgICAgICAgICAgICAgICAqIGVwc2lsb24gdHJhbnNpdGlvbgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkJICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yik7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBob3AsIGJhc2U7CiAgICAgICAgICAgICAgICAgICAgaW50IG1heE9jY3VycyA9IHBhcnRpY2xlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KICAgICAgICAgICAgICAgICAgICAgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CiAgICAgICAgICAgICAgICAgICAgaW50IG1pbk9jY3VycyA9CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlLT5taW5PY2N1cnMgPCAxID8gMCA6IHBhcnRpY2xlLT5taW5PY2N1cnMgLSAxOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHVzZSBhIGNvdW50ZXIgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHRyYW5zdGlvbnMKICAgICAgICAgICAgICAgICAgICAgKiB3aGljaCB3ZW50IHRocm91Z2ggdGhlIGNob2ljZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOwogICAgICAgICAgICAgICAgICAgIGhvcCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUocGN0eHQtPmFtKTsKICAgICAgICAgICAgICAgICAgICBiYXNlID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwoKCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0gYmFzZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGhvcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgc3RhcnQsIGJhc2UpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIGhvcCwgYmFzZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMocGN0eHQtPmFtLCBob3AsIGVuZCwgY291bnRlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDp7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoJCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHN1YjsKCQl4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOwogICAgICAgICAgICAgICAgaW50IGxheDsKCgkJc3ViID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgaWYgKHN1YiA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgc3RhcnQgPSBwY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSBzdGFydDsKCgkJICAgIGVsZW1EZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1Yi0+Y2hpbGRyZW47CgkJICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCIsCgkJCSAgICAiPGVsZW1lbnQ+IHBhcnRpY2xlIGhhcyBubyB0ZXJtIik7CgkJCXJldHVybjsKCQkgICAgfTsKCQkgICAgLyoKCQkgICAgKiBOT1RFOiBUaGUge21heCBvY2N1cnN9IG9mIGFsbCB0aGUgcGFydGljbGVzIGluIHRoZQoJCSAgICAqIHtwYXJ0aWNsZXN9IG9mIHRoZSBncm91cCBtdXN0IGJlIDAgb3IgMTsgdGhpcyBpcwoJCSAgICAqIGFscmVhZHkgZW5zdXJlZCBkdXJpbmcgdGhlIHBhcnNlIG9mIHRoZSBjb250ZW50IG9mCgkJICAgICogPGFsbD4uCgkJICAgICovCgkJICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1NVQlNUX0dST1VQX0hFQUQpIHsKCQkJaW50IGNvdW50ZXI7CgoJCSAgICAgICAgLyoKCQkJICogVGhpcyBpcyBhbiBhYnN0cmFjdCBncm91cCwgd2UgbmVlZCB0byBzaGFyZQoJCQkgKiB0aGUgc2FtZSBjb3VudGVyIGZvciBhbGwgdGhlIGVsZW1lbnQgdHJhbnNpdGlvbnMKCQkJICogZGVyaXZlZCBmcm9tIHRoZSBncm91cAoJCQkgKi8KCQkJY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sCgkJCSAgICAgICAgICAgICAgICAgICBzdWItPm1pbk9jY3Vycywgc3ViLT5tYXhPY2N1cnMpOwoJCQl4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAocGN0eHQsCgkJCQkJICAgc3ViLCBjb3VudGVyLCBwY3R4dC0+c3RhdGUpOwoJCSAgICB9IGVsc2UgewoJCQlpZiAoKHN1Yi0+bWluT2NjdXJzID09IDEpICYmCgkJCSAgICAoc3ViLT5tYXhPY2N1cnMgPT0gMSkpIHsKCQkJICAgIHhtbEF1dG9tYXRhTmV3T25jZVRyYW5zMihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwKCQkJCQkJICAgIHBjdHh0LT5zdGF0ZSwKCQkJCQkJICAgIGVsZW1EZWNsLT5uYW1lLAoJCQkJCQkgICAgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJCQkJICAgIDEsIDEsIGVsZW1EZWNsKTsKCQkJfSBlbHNlIGlmICgoc3ViLT5taW5PY2N1cnMgPT0gMCkgJiYKCQkJICAgIChzdWItPm1heE9jY3VycyA9PSAxKSkgewoKCQkJICAgIHhtbEF1dG9tYXRhTmV3Q291bnRUcmFuczIocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsCgkJCQkJCSAgICAgcGN0eHQtPnN0YXRlLAoJCQkJCQkgICAgIGVsZW1EZWNsLT5uYW1lLAoJCQkJCQkgICAgIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJCQkJCSAgICAgMCwKCQkJCQkJICAgICAxLAoJCQkJCQkgICAgIGVsZW1EZWNsKTsKCQkJfQoJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgc3ViID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYXggPSBwYXJ0aWNsZS0+bWluT2NjdXJzID09IDA7CiAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3QWxsVHJhbnMocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIE5VTEwsIGxheCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgLyoKCSAgICAqIElmIHdlIGhpdCBhIG1vZGVsIGdyb3VwIGRlZmluaXRpb24sIHRoZW4gdGhpcyBtZWFucyB0aGF0CgkgICAgKiBpdCB3YXMgZW1wdHksIHRodXMgd2FzIG5vdCBzdWJzdGl0dXRlZCBmb3IgdGhlIGNvbnRhaW5pbmcKCSAgICAqIG1vZGVsIGdyb3VwLiBKdXN0IGRvIG5vdGhpbmcgaW4gdGhpcyBjYXNlLgoJICAgICogVE9ETzogQnV0IHRoZSBncm91cCBzaG91bGQgYmUgc3Vic3RpdHV0ZWQgYW5kIG5vdCBvY2N1ciBhdAoJICAgICogYWxsIGluIHRoZSBjb250ZW50IG1vZGVsIGF0IHRoaXMgcG9pbnQuIEZpeCB0aGlzLgoJICAgICovCgkgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKCSAgICB4bWxTY2hlbWFJbnRlcm5hbEVycjIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkieG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsIiwKCQkiZm91bmQgdW5leHBlY3RlZCB0ZXJtIG9mIHR5cGUgJyVzJyBpbiBjb250ZW50IG1vZGVsIiwKCQlXWFNfSVRFTV9UWVBFX05BTUUocGFydGljbGUtPmNoaWxkcmVuKSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCiAqCiAqIEJ1aWxkcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgY29tcGxleCB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGlmICgodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwKCSh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkgfHwKCSgodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSAmJgoJKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkpKQoJcmV0dXJuOwoKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICJCdWlsZGluZyBjb250ZW50IG1vZGVsIGZvciAlc1xuIiwgbmFtZSk7CiNlbmRpZgogICAgY3R4dC0+YW0gPSBOVUxMOwogICAgY3R4dC0+YW0gPSB4bWxOZXdBdXRvbWF0YSgpOwogICAgaWYgKGN0eHQtPmFtID09IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCSAgICAiQ2Fubm90IGNyZWF0ZSBhdXRvbWF0YSBmb3IgY29tcGxleCB0eXBlICVzXG4iLCB0eXBlLT5uYW1lKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhR2V0SW5pdFN0YXRlKGN0eHQtPmFtKTsKICAgIC8qCiAgICAqIEJ1aWxkIHRoZSBhdXRvbWF0b24uCiAgICAqLwogICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKGN0eHQsIFdYU19UWVBFX1BBUlRJQ0xFKHR5cGUpKTsKICAgIHhtbEF1dG9tYXRhU2V0RmluYWxTdGF0ZShjdHh0LT5hbSwgY3R4dC0+c3RhdGUpOwogICAgdHlwZS0+Y29udE1vZGVsID0geG1sQXV0b21hdGFDb21waWxlKGN0eHQtPmFtKTsKICAgIGlmICh0eXBlLT5jb250TW9kZWwgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCB0eXBlLT5ub2RlLAoJICAgICJGYWlsZWQgdG8gY29tcGlsZSB0aGUgY29udGVudCBtb2RlbCIsIE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxSZWdleHBJc0RldGVybWluaXN0KHR5cGUtPmNvbnRNb2RlbCkgIT0gMSkgewogICAgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1RfREVURVJNSU5JU1RJQywKCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfTk9UREVURVJNSU5JU1QsICovCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgdHlwZS0+bm9kZSwKCSAgICAiVGhlIGNvbnRlbnQgbW9kZWwgaXMgbm90IGRldGVybWluaXN0IiwgTlVMTCk7CiAgICB9IGVsc2UgewojaWZkZWYgREVCVUdfQ09OVEVOVF9SRUdFWFAKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQgbW9kZWwgb2YgJXM6XG4iLCB0eXBlLT5uYW1lKTsKICAgICAgICB4bWxSZWdleHBQcmludChzdGRlcnIsIHR5cGUtPmNvbnRNb2RlbCk7CiNlbmRpZgogICAgfQogICAgY3R4dC0+c3RhdGUgPSBOVUxMOwogICAgeG1sRnJlZUF1dG9tYXRhKGN0eHQtPmFtKTsKICAgIGN0eHQtPmFtID0gTlVMTDsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVFbGVtZW50UmVmZXJlbmNlczoKICogQGVsZW06ICB0aGUgc2NoZW1hIGVsZW1lbnQgY29udGV4dAogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgdGhlIHJlZmVyZW5jZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgogKiBvciBwYXJ0aWNsZSwgd2hpY2ggaGFzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gYXMgaXQncwogKiB0ZXJtLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZUVsZW1lbnRSZWZlcmVuY2VzKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCgkJCQkgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtRGVjbCA9PSBOVUxMKSB8fAoJKChlbGVtRGVjbCAhPSBOVUxMKSAmJgoJKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfUkVTT0xWRUQpKSkKICAgICAgICByZXR1cm47CiAgICBlbGVtRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9SRVNPTFZFRDsKCiAgICBpZiAoKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAoZWxlbURlY2wtPm5hbWVkVHlwZSAhPSBOVUxMKSkgewoJeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCS8qICh0eXBlIGRlZmluaXRpb24pIC4uLiBvdGhlcndpc2UgdGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3CgkqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdHlwZSBbYXR0cmlidXRlXSAuLi4KCSovCgl0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGVsZW1EZWNsLT5uYW1lZFR5cGUsCgkgICAgZWxlbURlY2wtPm5hbWVkVHlwZU5zKTsKCWlmICh0eXBlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlXWFNfQkFTSUNfQ0FTVCBlbGVtRGVjbCwgZWxlbURlY2wtPm5vZGUsCgkJInR5cGUiLCBlbGVtRGVjbC0+bmFtZWRUeXBlLCBlbGVtRGVjbC0+bmFtZWRUeXBlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7Cgl9IGVsc2UKCSAgICBlbGVtRGVjbC0+c3VidHlwZXMgPSB0eXBlOwogICAgfQogICAgaWYgKGVsZW1EZWNsLT5zdWJzdEdyb3VwICE9IE5VTEwpIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgc3Vic3RIZWFkOwoKCS8qCgkqIEZJWE1FIFRPRE86IERvIHdlIG5lZWQgYSBuZXcgZmllbGQgaW4gX3htbFNjaGVtYUVsZW1lbnQgZm9yCgkqIHN1YnN0aXR1dGlvbkdyb3VwPwoJKi8KCXN1YnN0SGVhZCA9IHhtbFNjaGVtYUdldEVsZW0oY3R4dC0+c2NoZW1hLCBlbGVtRGVjbC0+c3Vic3RHcm91cCwKCSAgICBlbGVtRGVjbC0+c3Vic3RHcm91cE5zKTsKCWlmIChzdWJzdEhlYWQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCVdYU19CQVNJQ19DQVNUIGVsZW1EZWNsLCBOVUxMLAoJCSJzdWJzdGl0dXRpb25Hcm91cCIsIGVsZW1EZWNsLT5zdWJzdEdyb3VwLAoJCWVsZW1EZWNsLT5zdWJzdEdyb3VwTnMsIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUmVzb2x2ZUVsZW1lbnRSZWZlcmVuY2VzKHN1YnN0SGVhZCwgY3R4dCk7CgkgICAgLyoKCSAgICAqIFNldCB0aGUgInN1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbiIuCgkgICAgKiBOT1RFIHRoYXQgbm93IHdlIHVzZSB0aGUgInJlZkRlY2wiIGZpZWxkIGZvciB0aGlzLgoJICAgICovCgkgICAgV1hTX1NVQlNUX0hFQUQoZWxlbURlY2wpID0gc3Vic3RIZWFkOwoJICAgIC8qCgkgICAgKiBUaGUgdHlwZSBkZWZpbml0aW9ucyBpcyBzZXQgdG86CgkgICAgKiBTUEVDICIuLi50aGUge3R5cGUgZGVmaW5pdGlvbn0gb2YgdGhlIGVsZW1lbnQKCSAgICAqIGRlY2xhcmF0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3CgkgICAgKiBvZiB0aGUgc3Vic3RpdHV0aW9uR3JvdXAgW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQiCgkgICAgKi8KCSAgICBpZiAoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpCgkJZWxlbURlY2wtPnN1YnR5cGVzID0gc3Vic3RIZWFkLT5zdWJ0eXBlczsKCX0KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgIlRoZSBkZWZpbml0aW9uIG9mIGFueVR5cGUgc2VydmVzIGFzIHRoZSBkZWZhdWx0IHR5cGUgZGVmaW5pdGlvbgogICAgKiBmb3IgZWxlbWVudCBkZWNsYXJhdGlvbnMgd2hvc2UgWE1MIHJlcHJlc2VudGF0aW9uIGRvZXMgbm90IHNwZWNpZnkgb25lLiIKICAgICovCiAgICBpZiAoKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJgoJKGVsZW1EZWNsLT5uYW1lZFR5cGUgPT0gTlVMTCkgJiYKCShlbGVtRGVjbC0+c3Vic3RHcm91cCA9PSBOVUxMKSkKCWVsZW1EZWNsLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZVVuaW9uTWVtYmVyVHlwZXM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzY2hlbWEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgYW5kIGJ1aWxkcyB0aGUgIm1lbWJlciB0eXBlIGRlZmluaXRpb25zIiBwcm9wZXJ0eSBvZiB0aGUgdW5pb24KICogc2ltcGxlIHR5cGUuIFRoaXMgaGFuZGxlcyBwYXJ0ICgxKSwgcGFydCAoMikgaXMgZG9uZSBpbgogKiB4bWxTY2hlbWFGaW5pc2hNZW1iZXJUeXBlRGVmaW5pdGlvbnNQcm9wZXJ0eSgpCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlc29sdmVVbmlvbk1lbWJlclR5cGVzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKCiAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBsaW5rLCBsYXN0TGluaywgbmV3TGluazsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbWVtYmVyVHlwZTsKCiAgICAvKgogICAgKiBTUEVDICgxKSAiSWYgdGhlIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIFtEZWZpbml0aW9uOl0KICAgICogZGVmaW5lIHRoZSBleHBsaWNpdCBtZW1iZXJzIGFzIHRoZSB0eXBlIGRlZmluaXRpb25zILdyZXNvbHZlZLcKICAgICogdG8gYnkgdGhlIGl0ZW1zIGluIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0sCiAgICAqIGlmIGFueSwgZm9sbG93ZWQgYnkgdGhlIHR5cGUgZGVmaW5pdGlvbnMgY29ycmVzcG9uZGluZyB0byB0aGUKICAgICogPHNpbXBsZVR5cGU+cyBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8dW5pb24+LCBpZiBhbnkuIgogICAgKi8KICAgIC8qCiAgICAqIFJlc29sdmUgcmVmZXJlbmNlcy4KICAgICovCiAgICBsaW5rID0gdHlwZS0+bWVtYmVyVHlwZXM7CiAgICBsYXN0TGluayA9IE5VTEw7CiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7Cgljb25zdCB4bWxDaGFyICpuYW1lLCAqbnNOYW1lOwoKCW5hbWUgPSAoKHhtbFNjaGVtYVFOYW1lUmVmUHRyKSBsaW5rLT50eXBlKS0+bmFtZTsKCW5zTmFtZSA9ICgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGxpbmstPnR5cGUpLT50YXJnZXROYW1lc3BhY2U7CgoJbWVtYmVyVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBuYW1lLCBuc05hbWUpOwoJaWYgKChtZW1iZXJUeXBlID09IE5VTEwpIHx8ICghIFdYU19JU19TSU1QTEUobWVtYmVyVHlwZSkpKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsIHR5cGUtPm5vZGUsICJtZW1iZXJUeXBlcyIsCgkJbmFtZSwgbnNOYW1lLCBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCSAgICAvKgoJICAgICogUmVtb3ZlIHRoZSBtZW1iZXIgdHlwZSBsaW5rLgoJICAgICovCgkgICAgaWYgKGxhc3RMaW5rID09IE5VTEwpCgkJdHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rLT5uZXh0OwoJICAgIGVsc2UKCQlsYXN0TGluay0+bmV4dCA9IGxpbmstPm5leHQ7CgkgICAgbmV3TGluayA9IGxpbms7CgkgICAgbGluayA9IGxpbmstPm5leHQ7CgkgICAgeG1sRnJlZShuZXdMaW5rKTsKCX0gZWxzZSB7CgkgICAgbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CgkgICAgbGFzdExpbmsgPSBsaW5rOwoJICAgIGxpbmsgPSBsaW5rLT5uZXh0OwoJfQogICAgfQogICAgLyoKICAgICogQWRkIGxvY2FsIHNpbXBsZSB0eXBlcywKICAgICovCiAgICBtZW1iZXJUeXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICB3aGlsZSAobWVtYmVyVHlwZSAhPSBOVUxMKSB7CglsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CglsaW5rLT5uZXh0ID0gTlVMTDsKCWlmIChsYXN0TGluayA9PSBOVUxMKQoJICAgIHR5cGUtPm1lbWJlclR5cGVzID0gbGluazsKCWVsc2UKCSAgICBsYXN0TGluay0+bmV4dCA9IGxpbms7CglsYXN0TGluayA9IGxpbms7CgltZW1iZXJUeXBlID0gbWVtYmVyVHlwZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBoYXMgdGhlIGdpdmVuIHZhbHVlIHR5cGUsIG9yCiAqIGlzIGRlcml2ZWQgZnJvbSBzdWNoIGEgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgaW50IHZhbFR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgaWYgKFdYU19JU19DT01QTEVYKHR5cGUpKQoJcmV0dXJuICgwKTsKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IHZhbFR5cGUpCgkgICAgcmV0dXJuKDEpOwoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSB8fAoJICAgICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKSkKCSAgICByZXR1cm4gKDApOwoJcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcywgdmFsVHlwZSkpOwogICAgfQogICAgcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcywgdmFsVHlwZSkpOwp9CgojaWYgMAovKioKICogeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWxUeXBlOiB0aGUgdmFsdWUgdHlwZQogKgogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgaGFzIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLCBvcgogKiBpcyBkZXJpdmVkIGZyb20gc3VjaCBhIHR5cGUuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzVXNlckRlcml2ZWRGcm9tQnVpbHRJblR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgdmFsVHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAoV1hTX0lTX0NPTVBMRVgodHlwZSkpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gdmFsVHlwZSkKCSAgICByZXR1cm4oMSk7CglyZXR1cm4gKDApOwogICAgfSBlbHNlCglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzLCB2YWxUeXBlKSk7CgogICAgcmV0dXJuICgwKTsKfQojZW5kaWYKCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVF1ZXJ5QnVpbHRJblR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmIChXWFNfSVNfQ09NUExFWCh0eXBlKSkKCXJldHVybiAoTlVMTCk7CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCglyZXR1cm4odHlwZSk7CiAgICByZXR1cm4oeG1sU2NoZW1hUXVlcnlCdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcykpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZToKICogQHR5cGU6ICB0aGUgc2ltcGxlVHlwZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIHByaW1pdGl2ZSB0eXBlIG9mIHRoZSBnaXZlbiB0eXBlIG9yCiAqIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CgogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJLyoKCSogTm90ZSB0aGF0IGFueVNpbXBsZVR5cGUgaXMgYWN0dWFsbHkgbm90IGEgcHJpbWl0aXZlIHR5cGUKCSogYnV0IHdlIG5lZWQgdGhhdCBoZXJlLgoJKi8KCWlmICgodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkgfHwKCSAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQlVJTFRJTl9QUklNSVRJVkUpKQoJICAgIHJldHVybiAodHlwZSk7Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CgogICAgcmV0dXJuIChOVUxMKTsKfQoKI2lmIDAKLyoqCiAqIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlQW5jZXN0b3I6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZVR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZ2l2ZW4gdHlwZSBvcgogKiBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRCdWlsdEluVHlwZUFuY2VzdG9yKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKFdYU19JU19MSVNUKHR5cGUpIHx8IFdYU19JU19VTklPTih0eXBlKSkKCXJldHVybiAoMCk7CiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CglpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCgkgICAgcmV0dXJuICh0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlc3Q6ICB0aGUgZGVzdGluYXRpb24gd2lsZGNhcmQKICogQHNvdXJjZTogdGhlIHNvdXJjZSB3aWxkY2FyZAogKgogKiBDbG9uZXMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiBzb3VyY2UKICogYW5kIGFzc2lnbmVzIHRoZW0gdG8gZGVzdC4KICogUmV0dXJucyAtMSBvbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBkZXN0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHNvdXJjZSkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIHRtcCwgbGFzdDsKCiAgICBpZiAoKHNvdXJjZSA9PSBOVUxMKSB8fCAoZGVzdCA9PSBOVUxMKSkKCXJldHVybigtMSk7CiAgICBkZXN0LT5hbnkgPSBzb3VyY2UtPmFueTsKICAgIGN1ciA9IHNvdXJjZS0+bnNTZXQ7CiAgICBsYXN0ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAodG1wID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICBkZXN0LT5uc1NldCA9IHRtcDsKCWVsc2UKCSAgICBsYXN0LT5uZXh0ID0gdG1wOwoJbGFzdCA9IHRtcDsKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIGlmIChkZXN0LT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoZGVzdC0+bmVnTnNTZXQpOwogICAgaWYgKHNvdXJjZS0+bmVnTnNTZXQgIT0gTlVMTCkgewoJZGVzdC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmIChkZXN0LT5uZWdOc1NldCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7CglkZXN0LT5uZWdOc1NldC0+dmFsdWUgPSBzb3VyY2UtPm5lZ05zU2V0LT52YWx1ZTsKICAgIH0gZWxzZQoJZGVzdC0+bmVnTnNTZXQgPSBOVUxMOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hVW5pb25XaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkCiAqCiAqIFVuaW9ucyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgdW5pb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgoJCS8qCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLgoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUKICAgICovCiAgICBpZiAoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSB7CglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLAogICAgKiB0aGVuIHRoZSB1bmlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsKCWludCBmb3VuZDsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc3RhcnQ7CgoJY3VyID0gY3VyV2lsZC0+bnNTZXQ7CglzdGFydCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IHN0YXJ0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmICh0bXAgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CgkJdG1wLT5uZXh0ID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gdG1wOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CgoJcmV0dXJuKDApOwogICAgfQogICAgLyoKICAgICogNCBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IHZhbHVlcyAobmFtZXNwYWNlIG5hbWVzCiAgICAqIG9yILdhYnNlbnS3KSwgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgICogNS4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpbnQgbnNGb3VuZCwgYWJzZW50Rm91bmQgPSAwOwoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uZWdOc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQ7Cgl9Cgluc0ZvdW5kID0gMDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpCgkJYWJzZW50Rm91bmQgPSAxOwoJICAgIGVsc2UgaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpCgkJbnNGb3VuZCA9IDE7CgkgICAgaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpCgkJYnJlYWs7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoKCWlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgYm90aCB0aGUgbmVnYXRlZCBuYW1lc3BhY2UKCSAgICAqIG5hbWUgYW5kILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0gZWxzZSBpZiAobnNGb3VuZCAmJiAoIWFic2VudEZvdW5kKSkgewoJICAgIC8qCgkgICAgKiA1LjIgSWYgdGhlIHNldCBTIGluY2x1ZGVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lCgkgICAgKiBidXQgbm90ILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QKCSAgICAqIGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMyBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcgYnV0IG5vdCB0aGUgbmVnYXRlZAoJICAgICogbmFtZXNwYWNlIG5hbWUsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSwKCQkiVGhlIHVuaW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZS5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSk7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKgoJICAgICogNS40IElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlIGVpdGhlciB0aGUgbmVnYXRlZCBuYW1lc3BhY2UKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QKCSAgICAqIGFuZCBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAgKiA2LgogICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCX0KCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIHsKCQkvKgoJCSogNi4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90CgkgICAgKiBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKDApOwoKfQoKLyoqCiAqIHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQKICoKICogSW50ZXJzZWN0cyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgaW50ZXJzZWN0aW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCBwcmV2LCAgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgoJCS8qCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLgoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsKCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCBjb21wbGV0ZVdpbGQsIGN1cldpbGQpID09IC0xKQoJICAgIHJldHVybigtMSk7CglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGVpdGhlciBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90IGFuZCBhIHZhbHVlIChhIG5hbWVzcGFjZQogICAgKiBuYW1lIG9yILdhYnNlbnS3KSBhbmQgdGhlIG90aGVyIGlzIGEgc2V0IG9mIChuYW1lc3BhY2UgbmFtZXMgb3IKICAgICogt2Fic2VudLcpLCB0aGVuIHRoYXQgc2V0LCBtaW51cyB0aGUgbmVnYXRlZCB2YWx1ZSBpZiBpdCB3YXMgaW4KICAgICogdGhlIHNldCwgbWludXMgt2Fic2VudLcgaWYgaXQgd2FzIGluIHRoZSBzZXQsIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCWNvbnN0IHhtbENoYXIgKm5lZzsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSB7CgkgICAgbmVnID0gY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsIGNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIG5lZyA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCS8qCgkqIFJlbW92ZSBhYnNlbnQgYW5kIG5lZ2F0ZWQuCgkqLwoJcHJldiA9IE5VTEw7CgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQlicmVhazsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAobmVnICE9IE5VTEwpIHsKCSAgICBwcmV2ID0gTlVMTDsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IG5lZykgewoJCSAgICBpZiAocHJldiA9PSBOVUxMKQoJCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCSAgICBlbHNlCgkJCXByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJICAgIHhtbEZyZWUoY3VyKTsKCQkgICAgYnJlYWs7CgkJfQoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0KCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgKiA0IElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CglpbnQgZm91bmQ7CgoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQlpZiAocHJldiA9PSBOVUxMKQoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl0bXAgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWN1ciA9IHRtcDsKCQljb250aW51ZTsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CgoJcmV0dXJuKDApOwogICAgfQogICAgLyogNSBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IG5hbWVzcGFjZSBuYW1lcywKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIGlzIG5vdCBleHByZXNzaWJsZQogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpKSB7CgoJeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUsCgkgICAgIlRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybihYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFKTsKICAgIH0KICAgIC8qCiAgICAqIDYgSWYgdGhlIG9uZSBpcyBhIG5lZ2F0aW9uIG9mIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlcgogICAgKiBpcyBhIG5lZ2F0aW9uIG9mILdhYnNlbnS3LCB0aGVuIHRoZSBvbmUgd2hpY2ggaXMgdGhlIG5lZ2F0aW9uCiAgICAqIG9mIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSAgY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzdWI6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQHN1cGVyOiB0aGUgc2Vjb25kIHdpbGRjYXJkCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogV2lsZGNhcmQgU3Vic2V0IChjb3MtbnMtc3Vic2V0KQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50IG9mIEBzdWIgaXMgYW4gaW50ZW5zaW9uYWwKICogc3Vic2V0IG9mIEBzdXBlciwgMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TTlNTdWJzZXQoeG1sU2NoZW1hV2lsZGNhcmRQdHIgc3ViLAoJCQkgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHN1cGVyKQp7CiAgICAvKgogICAgKiAxIHN1cGVyIG11c3QgYmUgYW55LgogICAgKi8KICAgIGlmIChzdXBlci0+YW55KQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIDIuMSBzdWIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yILdhYnNlbnS3LgogICAgKiAyLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCB0aGUgc2FtZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKHN1Yi0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShzdXBlci0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShzdWItPm5lZ05zU2V0LT52YWx1ZSA9PSBzdWItPm5lZ05zU2V0LT52YWx1ZSkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogMy4xIHN1YiBtdXN0IGJlIGEgc2V0IHdob3NlIG1lbWJlcnMgYXJlIGVpdGhlciBuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcuCiAgICAqLwogICAgaWYgKHN1Yi0+bnNTZXQgIT0gTlVMTCkgewoJLyoKCSogMy4yLjEgc3VwZXIgbXVzdCBiZSB0aGUgc2FtZSBzZXQgb3IgYSBzdXBlcnNldCB0aGVyZW9mLgoJKi8KCWlmIChzdXBlci0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCOwoJICAgIGludCBmb3VuZCA9IDA7CgoJICAgIGN1ciA9IHN1Yi0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWN1ckIgPSBzdXBlci0+bnNTZXQ7CgkJd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQlmb3VuZCA9IDE7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGN1ckIgPSBjdXJCLT5uZXh0OwoJCX0KCQlpZiAoIWZvdW5kKQoJCSAgICByZXR1cm4gKDEpOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGZvdW5kKQoJCXJldHVybiAoMCk7Cgl9IGVsc2UgaWYgKHN1cGVyLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgkgICAgLyoKCSAgICAqIDMuMi4yIHN1cGVyIG11c3QgYmUgYSBwYWlyIG9mIG5vdCBhbmQgYSBuYW1lc3BhY2UgbmFtZSBvcgoJICAgICogt2Fic2VudLcgYW5kIHRoYXQgdmFsdWUgbXVzdCBub3QgYmUgaW4gc3ViJ3Mgc2V0LgoJICAgICovCgkgICAgY3VyID0gc3ViLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBzdXBlci0+bmVnTnNTZXQtPnZhbHVlKQoJCSAgICByZXR1cm4gKDEpOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciBhdHRydXNlLAoJCQkJICAgICBpbnQgKmZpeGVkLAoJCQkJICAgICBjb25zdCB4bWxDaGFyICoqdmFsdWUsCgkJCQkgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsKQp7CiAgICAqZml4ZWQgPSAwOwogICAgKnZhbHVlID0gTlVMTDsKICAgIGlmICh2YWwgIT0gMCkKCSp2YWwgPSBOVUxMOwoKICAgIGlmIChhdHRydXNlLT5kZWZWYWx1ZSAhPSBOVUxMKSB7CSAgICAKCSp2YWx1ZSA9IGF0dHJ1c2UtPmRlZlZhbHVlOwoJaWYgKHZhbCAhPSBOVUxMKQoJICAgICp2YWwgPSBhdHRydXNlLT5kZWZWYWw7CglpZiAoYXR0cnVzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0FUVFJfVVNFX0ZJWEVEKQoJICAgICpmaXhlZCA9IDE7CglyZXR1cm4oMSk7CiAgICB9IGVsc2UgaWYgKChhdHRydXNlLT5hdHRyRGVjbCAhPSBOVUxMKSAmJgoJKGF0dHJ1c2UtPmF0dHJEZWNsLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJKnZhbHVlID0gYXR0cnVzZS0+YXR0ckRlY2wtPmRlZlZhbHVlOwoJaWYgKHZhbCAhPSBOVUxMKQoJICAgICp2YWwgPSBhdHRydXNlLT5hdHRyRGVjbC0+ZGVmVmFsOwoJaWYgKGF0dHJ1c2UtPmF0dHJEZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpCgkgICAgKmZpeGVkID0gMTsKCXJldHVybigxKTsKICAgIH0KICAgIHJldHVybigwKTsKfQovKioKICogeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZToKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKgogKiBWYWxpZGF0aW9uIFJ1bGU6IFdpbGRjYXJkIGFsbG93cyBOYW1lc3BhY2UgTmFtZQogKiAoY3ZjLXdpbGRjYXJkLW5hbWVzcGFjZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDEgb3RoZXJ3aXNlIGFuZCAtMSBvbiBBUEkgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsCgkJCQkgICBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigtMSk7CgogICAgaWYgKHdpbGQtPmFueSkKCXJldHVybigwKTsKICAgIGVsc2UgaWYgKHdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoKCWN1ciA9IHdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGN1ci0+dmFsdWUsIG5zKSkKCQlyZXR1cm4oMCk7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfSBlbHNlIGlmICgod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKG5zICE9IE5VTEwpICYmCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigwKTsKCiAgICByZXR1cm4oMSk7Cn0KCiNkZWZpbmUgWE1MX1NDSEVNQV9BQ1RJT05fREVSSVZFIDAKI2RlZmluZSBYTUxfU0NIRU1BX0FDVElPTl9SRURFRklORSAxCgojZGVmaW5lIFdYU19BQ1RJT05fU1RSKGEpIFwKKChhKSA9PSBYTUxfU0NIRU1BX0FDVElPTl9ERVJJVkUpID8gKGNvbnN0IHhtbENoYXIgKikgImJhc2UiIDogKGNvbnN0IHhtbENoYXIgKikgInJlZGVmaW5lZCIKCi8qCiogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgoqICAgRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpCiogICBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICgyKSAtICg0KQoqCiogQVRURU5USU9OOgoqIEluIFhNTCBTY2hlbWEgMS4xIHRoaXMgd2lsbCBiZToKKiBWYWxpZGF0aW9uIFJ1bGU6CiogICAgIENoZWNraW5nIGNvbXBsZXggdHlwZSBzdWJzdW1wdGlvbiAocHJhY3RpY2FsU3Vic3VtcHRpb24pICgxLCAyIGFuZCAzKQoqCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbjJ0bzQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgICAgICBpbnQgYWN0aW9uLAoJCQkJICAgICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtLAoJCQkJICAgICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBiYXNlSXRlbSwKCQkJCSAgICAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciB1c2VzLAoJCQkJICAgICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGJhc2VVc2VzLAoJCQkJICAgICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsCgkJCQkgICAgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgYmFzZVdpbGQpCnsgICAgICAgIAogICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIGN1ciA9IE5VTEwsIGJjdXI7CiAgICBpbnQgaSwgaiwgZm91bmQ7IC8qIGVyciA9IDA7ICovCiAgICBjb25zdCB4bWxDaGFyICpiRWZmVmFsdWU7CiAgICBpbnQgZWZmRml4ZWQ7CiAgICAKICAgIGlmICh1c2VzICE9IE5VTEwpIHsKCWZvciAoaSA9IDA7IGkgPCB1c2VzLT5uYkl0ZW1zOyBpKyspIHsKCSAgICBjdXIgPSB1c2VzLT5pdGVtc1tpXTsKCSAgICBmb3VuZCA9IDA7CgkgICAgaWYgKGJhc2VVc2VzID09IE5VTEwpCgkJZ290byBub3RfZm91bmQ7CgkgICAgZm9yIChqID0gMDsgaiA8IGJhc2VVc2VzLT5uYkl0ZW1zOyBqKyspIHsKCQliY3VyID0gYmFzZVVzZXMtPml0ZW1zW2pdOwkKCQlpZiAoKFdYU19BVFRSVVNFX0RFQ0xfTkFNRShjdXIpID09CgkJCVdYU19BVFRSVVNFX0RFQ0xfTkFNRShiY3VyKSkgJiYKCQkgICAgKFdYU19BVFRSVVNFX0RFQ0xfVE5TKGN1cikgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9UTlMoYmN1cikpKQoJCXsKCQkgICAgLyoKCQkgICAgKiAoMi4xKSAiSWYgdGhlcmUgaXMgYW4gYXR0cmlidXRlIHVzZSBpbiB0aGUge2F0dHJpYnV0ZQoJCSAgICAqIHVzZXN9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IChjYWxsIHRoaXMgQikgd2hvc2UKCQkgICAgKiB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBoYXMgdGhlIHNhbWUge25hbWV9IGFuZCB7dGFyZ2V0CgkJICAgICogbmFtZXNwYWNlfSwgdGhlbiAgYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKCQkgICAgKi8KCQkgICAgZm91bmQgPSAxOwoJCSAgICAKCQkgICAgaWYgKChjdXItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCQkJKGJjdXItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpCgkJICAgIHsKCQkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkJLyoKCQkJKiAoMi4xLjEpICJvbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJCQkqICgyLjEuMS4xKSAiQidzIHtyZXF1aXJlZH0gaXMgZmFsc2UuIgoJCQkqICgyLjEuMS4yKSAiUidzIHtyZXF1aXJlZH0gaXMgdHJ1ZS4iCgkJCSovCgkJCXhtbFNjaGVtYVBBdHRyVXNlRXJyNChwY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCSAgICBXWFNfSVRFTV9OT0RFKGl0ZW0pLCBpdGVtLCBjdXIsCgkJCSAgICAiVGhlICdvcHRpb25hbCcgYXR0cmlidXRlIHVzZSBpcyBpbmNvbnNpc3RlbnQgIgoJCQkgICAgIndpdGggdGhlIGNvcnJlc3BvbmRpbmcgJ3JlcXVpcmVkJyBhdHRyaWJ1dGUgdXNlIG9mICIKCQkJICAgICJ0aGUgJXMgJXMiLAoJCQkgICAgV1hTX0FDVElPTl9TVFIoYWN0aW9uKSwKCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHIsIGJhc2VJdGVtKSwKCQkJICAgIE5VTEwsIE5VTEwpOwoJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCS8qIGVyciA9IHBjdHh0LT5lcnI7ICovCgkJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhBQ1RYVF9DQVNUIHBjdHh0LAoJCQlXWFNfQVRUUlVTRV9UWVBFREVGKGN1ciksCgkJCVdYU19BVFRSVVNFX1RZUEVERUYoYmN1ciksIDApICE9IDApCgkJICAgIHsKCQkJeG1sQ2hhciAqc3RyQSA9IE5VTEwsICpzdHJCID0gTlVMTCwgKnN0ckMgPSBOVUxMOwoJCQkKCQkJLyoKCQkJKiBTUEVDICgyLjEuMikgIlIncyB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzCgkJCSoge3R5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbQoJCQkqIEIncyB7dHlwZSBkZWZpbml0aW9ufSBnaXZlbiB0aGUgZW1wdHkgc2V0IGFzCgkJCSogZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLiIKCQkJKi8KCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnI0KHBjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMiwKCQkJICAgIFdYU19JVEVNX05PREUoaXRlbSksIGl0ZW0sIGN1ciwKCQkJICAgICJUaGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uJ3MgJXMgIgoJCQkgICAgImlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSAiCgkJCSAgICAidGhlIGNvcnJlc3BvbmRpbmcgJXMgb2YgdGhlICIKCQkJICAgICJhdHRyaWJ1dGUgZGVjbGFyYXRpb24gaW4gdGhlICVzICVzIiwKCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHJBLAoJCQkJV1hTX0FUVFJVU0VfVFlQRURFRihjdXIpKSwKCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHJCLAoJCQkJV1hTX0FUVFJVU0VfVFlQRURFRihiY3VyKSksCgkJCSAgICBXWFNfQUNUSU9OX1NUUihhY3Rpb24pLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckMsIGJhc2VJdGVtKSk7CgkJCSAgICAvKiB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLCBiYXNlSXRlbSksICovCgkJCUZSRUVfQU5EX05VTEwoc3RyQSk7CgkJCUZSRUVfQU5EX05VTEwoc3RyQik7CgkJCUZSRUVfQU5EX05VTEwoc3RyQyk7CgkJCS8qIGVyciA9IHBjdHh0LT5lcnI7ICovCgkJICAgIH0gZWxzZSB7CgkJCS8qCgkJCSogMi4xLjMgW0RlZmluaXRpb246XSAgTGV0IHRoZSBlZmZlY3RpdmUgdmFsdWUKCQkJKiBjb25zdHJhaW50IG9mIGFuIGF0dHJpYnV0ZSB1c2UgYmUgaXRzIHt2YWx1ZQoJCQkqIGNvbnN0cmFpbnR9LCBpZiBwcmVzZW50LCBvdGhlcndpc2UgaXRzIHthdHRyaWJ1dGUKCQkJKiBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0gLgoJCQkqLwoJCQl4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYmN1ciwKCQkJICAgICZlZmZGaXhlZCwgJmJFZmZWYWx1ZSwgTlVMTCk7CgkJCS8qCgkJCSogMi4xLjMgLi4uIG9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZQoJCQkqCgkJCSogMi4xLjMuMSBCJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcwoJCQkqILdhYnNlbnS3IG9yIGRlZmF1bHQuCgkJCSovCgkJCWlmICgoYkVmZlZhbHVlICE9IE5VTEwpICYmCgkJCSAgICAoZWZmRml4ZWQgPT0gMSkpIHsKCQkJICAgIGNvbnN0IHhtbENoYXIgKnJFZmZWYWx1ZSA9IE5VTEw7CgkJCSAgICAKCQkJICAgIHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiY3VyLAoJCQkJJmVmZkZpeGVkLCAmckVmZlZhbHVlLCBOVUxMKTsKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zLjIgUidzILdlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludLcgaXMKCQkJICAgICogZml4ZWQgd2l0aCB0aGUgc2FtZSBzdHJpbmcgYXMgQidzLgoJCQkgICAgKiBNQVlCRSBUT0RPOiBDb21wYXJlIHRoZSBjb21wdXRlZCB2YWx1ZXMuCgkJCSAgICAqICAgICAgIEhtbSwgaXQgc2F5cyAic2FtZSBzdHJpbmciIHNvCgkJCSAgICAqICAgICAgIHN0cmluZy1lcXVhbGl0eSBtaWdodCByZWFsbHkgYmUgc3VmZmljaWVudC4KCQkJICAgICovCgkJCSAgICBpZiAoKGVmZkZpeGVkID09IDApIHx8CgkJCQkoISBXWFNfQVJFX0RFRkFVTFRfU1RSX0VRVUFMKHJFZmZWYWx1ZSwgYkVmZlZhbHVlKSkpCgkJCSAgICB7CgkJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCQkJCgkJCQl4bWxTY2hlbWFQQXR0clVzZUVycjQocGN0eHQsCgkJCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMywKCQkJCSAgICBXWFNfSVRFTV9OT0RFKGl0ZW0pLCBpdGVtLCBjdXIsCgkJCQkgICAgIlRoZSBlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgIgoJCQkJICAgICJhdHRyaWJ1dGUgdXNlIGlzIGluY29uc2lzdGVudCB3aXRoICIKCQkJCSAgICAiaXRzIGNvcnJlc3BvbmRlbnQgaW4gdGhlICVzICVzIiwKCQkJCSAgICBXWFNfQUNUSU9OX1NUUihhY3Rpb24pLAoJCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHIsCgkJCQkJYmFzZUl0ZW0pLAoJCQkJICAgIE5VTEwsIE5VTEwpOwoJCQkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCQkJLyogZXJyID0gcGN0eHQtPmVycjsgKi8KCQkJICAgIH0KCQkJfQoJCSAgICB9CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9Cm5vdF9mb3VuZDoJCgkgICAgaWYgKCFmb3VuZCkgewoJCS8qCgkJKiAoMi4yKSAib3RoZXJ3aXNlIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhbgoJCSoge2F0dHJpYnV0ZSB3aWxkY2FyZH0gYW5kIHRoZSB7dGFyZ2V0IG5hbWVzcGFjZX0gb2YgdGhlCgkJKiBSJ3Mge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdAoJCSogdG8gdGhhdCB3aWxkY2FyZCwgYXMgZGVmaW5lZCBpbiBXaWxkY2FyZCBhbGxvd3MgTmFtZXNwYWNlCgkJKiBOYW1lICinMy4xMC40KS4iCgkJKi8KCQlpZiAoKGJhc2VXaWxkID09IE5VTEwpIHx8CgkJICAgICh4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKGJhc2VXaWxkLAoJCSAgICAoV1hTX0FUVFJVU0VfREVDTChjdXIpKS0+dGFyZ2V0TmFtZXNwYWNlKSAhPSAwKSkKCQl7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIAoJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycjQocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8yLAoJCQlXWFNfSVRFTV9OT0RFKGl0ZW0pLCBpdGVtLCBjdXIsCgkJCSJOZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkibm9yIGEgbWF0Y2hpbmcgd2lsZGNhcmQgZXhpc3RzIGluIHRoZSAlcyAlcyIsCgkJCVdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJCXhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHIsIGJhc2VJdGVtKSwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCQkgICAgLyogZXJyID0gcGN0eHQtPmVycjsgKi8KCQl9CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogU1BFQyBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICgzKTogICAgCiAgICAqICgzKSAiRm9yIGVhY2ggYXR0cmlidXRlIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUge2Jhc2UgdHlwZQogICAgKiBkZWZpbml0aW9ufSB3aG9zZSB7cmVxdWlyZWR9IGlzIHRydWUsIHRoZXJlIG11c3QgYmUgYW4gYXR0cmlidXRlCiAgICAqIHVzZSB3aXRoIGFuIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IHdpdGggdGhlIHNhbWUge25hbWV9IGFuZAogICAgKiB7dGFyZ2V0IG5hbWVzcGFjZX0gYXMgaXRzIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGluIHRoZSB7YXR0cmlidXRlCiAgICAqIHVzZXN9IG9mIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge3JlcXVpcmVkfSBpcyB0cnVlLgogICAgKi8KICAgIGlmIChiYXNlVXNlcyAhPSBOVUxMKSB7Cglmb3IgKGogPSAwOyBqIDwgYmFzZVVzZXMtPm5iSXRlbXM7IGorKykgewoJICAgIGJjdXIgPSBiYXNlVXNlcy0+aXRlbXNbal07CgkgICAgaWYgKGJjdXItPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkKCQljb250aW51ZTsKCSAgICBmb3VuZCA9IDA7CgkgICAgaWYgKHVzZXMgIT0gTlVMTCkgewoJCWZvciAoaSA9IDA7IGkgPCB1c2VzLT5uYkl0ZW1zOyBpKyspIHsKCQkgICAgY3VyID0gdXNlcy0+aXRlbXNbaV07CQoJCSAgICBpZiAoKFdYU19BVFRSVVNFX0RFQ0xfTkFNRShjdXIpID09CgkJCVdYU19BVFRSVVNFX0RFQ0xfTkFNRShiY3VyKSkgJiYKCQkJKFdYU19BVFRSVVNFX0RFQ0xfVE5TKGN1cikgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9UTlMoYmN1cikpKSB7CgkJCWZvdW5kID0gMTsKCQkJYnJlYWs7CgkJICAgIH0KCQl9CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQl4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoJCQoJCXhtbFNjaGVtYUN1c3RvbUVycjQoQUNUWFRfQ0FTVCBwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8zLAoJCSAgICBOVUxMLCBpdGVtLAoJCSAgICAiQSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGZvciB0aGUgIgoJCSAgICAiJ3JlcXVpcmVkJyAlcyBvZiB0aGUgJXMgJXMgaXMgbWlzc2luZyIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHJBLCBiY3VyKSwKCQkgICAgV1hTX0FDVElPTl9TVFIoYWN0aW9uKSwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckIsIGJhc2VJdGVtKSwKCQkgICAgTlVMTCk7CgkJRlJFRV9BTkRfTlVMTChzdHJBKTsKCQlGUkVFX0FORF9OVUxMKHN0ckIpOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gKDQpCiAgICAqLwogICAgaWYgKHdpbGQgIT0gTlVMTCkgewoJLyoKCSogKDQpICJJZiB0aGVyZSBpcyBhbiB7YXR0cmlidXRlIHdpbGRjYXJkfSwgYWxsIG9mIHRoZQoJKiBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKCSovICAgCglpZiAoYmFzZVdpbGQgPT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgoJICAgIC8qCgkgICAgKiAoNC4xKSAiVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGhhdmUgb25lLiIKCSAgICAqLwkgICAgCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyNChBQ1RYVF9DQVNUIHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8xLAoJCU5VTEwsIGl0ZW0sCgkJIlRoZSAlcyBoYXMgYW4gYXR0cmlidXRlIHdpbGRjYXJkLCAiCgkJImJ1dCB0aGUgJXMgJXMgJyVzJyBkb2VzIG5vdCBoYXZlIG9uZSIsCgkJV1hTX0lURU1fVFlQRV9OQU1FKGl0ZW0pLAkJICAgIAoJCVdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJV1hTX0lURU1fVFlQRV9OQU1FKGJhc2VJdGVtKSwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlSXRlbSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICByZXR1cm4ocGN0eHQtPmVycik7Cgl9IGVsc2UgaWYgKChiYXNlV2lsZC0+YW55ID09IDApICYmCgkJeG1sU2NoZW1hQ2hlY2tDT1NOU1N1YnNldCh3aWxkLCBiYXNlV2lsZCkpCgl7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICAvKgoJICAgICogKDQuMikgIlRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgd2lsZGNhcmR9J3MKCSAgICAqIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUge2Jhc2UgdHlwZQoJICAgICogZGVmaW5pdGlvbn0ncyB7YXR0cmlidXRlIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0sCgkgICAgKiBhcyBkZWZpbmVkIGJ5IFdpbGRjYXJkIFN1YnNldCAopzMuMTAuNikuIgoJICAgICovCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyNChBQ1RYVF9DQVNUIHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8yLAoJCU5VTEwsIGl0ZW0sCgkJIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIgoJCSJzdWJzZXQgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSAlcyAlcyAnJXMnIiwKCQlXWFNfQUNUSU9OX1NUUihhY3Rpb24pLAoJCVdYU19JVEVNX1RZUEVfTkFNRShiYXNlSXRlbSksCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgYmFzZUl0ZW0pLAoJCU5VTEwpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICByZXR1cm4ocGN0eHQtPmVycik7Cgl9CgkvKiA0LjMgVW5sZXNzIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3dXItdHlwZQoJKiBkZWZpbml0aW9utywgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZQoJKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30gbXVzdCBiZSBpZGVudGljYWwgdG8gb3IKCSogc3Ryb25nZXIgdGhhbiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUKCSogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9LCB3aGVyZSBzdHJpY3QgaXMgc3Ryb25nZXIKCSogdGhhbiBsYXggaXMgc3Ryb25nZXIgdGhhbiBza2lwLgoJKi8KCWlmICgoISBXWFNfSVNfQU5ZVFlQRShiYXNlSXRlbSkpICYmCgkgICAgKHdpbGQtPnByb2Nlc3NDb250ZW50cyA8IGJhc2VXaWxkLT5wcm9jZXNzQ29udGVudHMpKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnI0KEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzMsCgkJTlVMTCwgYmFzZUl0ZW0sCgkJIlRoZSB7cHJvY2VzcyBjb250ZW50c30gb2YgdGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyAiCgkJIndlYWtlciB0aGFuIHRoZSBvbmUgaW4gdGhlICVzICVzICclcyciLAoJCVdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJV1hTX0lURU1fVFlQRV9OQU1FKGJhc2VJdGVtKSwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlSXRlbSksCgkJTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuKHBjdHh0LT5lcnIpOwoJfQogICAgfQogICAgcmV0dXJuKDApOwp9CgoKc3RhdGljIGludAp4bWxTY2hlbWFFeHBhbmRBdHRyaWJ1dGVHcm91cFJlZnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJCQkgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpjb21wbGV0ZVdpbGQsCgkJCQkgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsCgkJCQkgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHByb2hpYnMpOwovKioKICogeG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqCiAqIEJ1aWxkcyB0aGUgd2lsZGNhcmQgYW5kIHRoZSBhdHRyaWJ1dGUgdXNlcyBvbiB0aGUgZ2l2ZW4gY29tcGxleCB0eXBlLgogKiBSZXR1cm5zIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VycywgMCBvdGhlcndpc2UuCiAqCiAqIEFUVEVOVElPTiBUT0RPOiBFeHBlcmltYW50YWxseSB0aGlzIHVzZXMgcG9pbnRlciBjb21wYXJpc29ucyBmb3IKICogc3RyaW5ncywgc28gcmVjaGVjayB0aGlzIGlmIHdlIHN0YXJ0IHRvIGhhcmRjb2RlIHNvbWUgc2NoZW1hdGEsIHNpbmNlCiAqIHRoZXkgbWlnaHQgbm90IGJlIGluIHRoZSBzYW1lIGRpY3QuCiAqIE5PVEU6IEl0IGlzIGFsbG93ZWQgdG8gImV4dGVuZCIgdGhlIHhzOmFueVR5cGUgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIHVzZTsgICAgCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciB1c2VzLCBiYXNlVXNlcywgcHJvaGlicyA9IE5VTEw7CgogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUZpeHVwVHlwZUF0dHJpYnV0ZVVzZXMiLAoJICAgICJubyBiYXNlIHR5cGUiKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7ICAgICAgICAKICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQoYmFzZVR5cGUpKQoJaWYgKHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgQUNUWFRfQ0FTVCBwY3R4dCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKCiAgICB1c2VzID0gdHlwZS0+YXR0clVzZXM7CiAgICBiYXNlVXNlcyA9IGJhc2VUeXBlLT5hdHRyVXNlczsKICAgIC8qCiAgICAqIEV4cGFuZCBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcy4gQW5kIGJ1aWxkIHRoZSAnY29tcGxldGUnCiAgICAqIHdpbGRjYXJkLCBpLmUuIGludGVyc2VjdCBtdWx0aXBsZSB3aWxkY2FyZHMuCiAgICAqIE1vdmUgYXR0cmlidXRlIHByb2hpYml0aW9ucyBpbnRvIGEgc2VwYXJhdGUgbGlzdC4KICAgICovCiAgICBpZiAodXNlcyAhPSBOVUxMKSB7CQoJaWYgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSkgewoJICAgIC8qCgkgICAgKiBUaGlzIG9uZSB3aWxsIHRyYW5zZmVyIGFsbCBhdHRyLiBwcm9oaWJpdGlvbnMKCSAgICAqIGludG8gcGN0eHQtPmF0dHJQcm9oaWJzLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUV4cGFuZEF0dHJpYnV0ZUdyb3VwUmVmcyhwY3R4dCwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCAmKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSwgdXNlcywKCQlwY3R4dC0+YXR0clByb2hpYnMpID09IC0xKQoJICAgIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFGaXh1cFR5cGVBdHRyaWJ1dGVVc2VzIiwKCQkiZmFpbGVkIHRvIGV4cGFuZCBhdHRyaWJ1dGVzIik7CgkgICAgfQoJICAgIGlmIChwY3R4dC0+YXR0clByb2hpYnMtPm5iSXRlbXMgIT0gMCkKCQlwcm9oaWJzID0gcGN0eHQtPmF0dHJQcm9oaWJzOwoJfSBlbHNlIHsKCSAgICBpZiAoeG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzKHBjdHh0LAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsICYodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpLCB1c2VzLAoJCU5VTEwpID09IC0xKQoJICAgIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFGaXh1cFR5cGVBdHRyaWJ1dGVVc2VzIiwKCQkiZmFpbGVkIHRvIGV4cGFuZCBhdHRyaWJ1dGVzIik7CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogSW5oZXJpdCB0aGUgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZS4KICAgICovCiAgICBpZiAoYmFzZVVzZXMgIT0gTlVMTCkgewoJaW50IGksIGo7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcHJvOwoKCWlmIChXWFNfSVNfUkVTVFJJQ1RJT04odHlwZSkpIHsKCSAgICBpbnQgdXNlc0NvdW50OwoJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB0bXA7IAoKCSAgICBpZiAodXNlcyAhPSBOVUxMKQoJCXVzZXNDb3VudCA9IHVzZXMtPm5iSXRlbXM7CgkgICAgZWxzZQoJCXVzZXNDb3VudCA9IDA7CgoJICAgIC8qIFJlc3RyaWN0aW9uLiAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBiYXNlVXNlcy0+bmJJdGVtczsgaSsrKSB7CgkJdXNlID0gYmFzZVVzZXMtPml0ZW1zW2ldOwoJCWlmIChwcm9oaWJzKSB7CgkJICAgIC8qCgkJICAgICogRmlsdGVyIG91dCBwcm9oaWJpdGVkIHVzZXMuCgkJICAgICovCgkJICAgIGZvciAoaiA9IDA7IGogPCBwcm9oaWJzLT5uYkl0ZW1zOyBqKyspIHsKCQkJcHJvID0gcHJvaGlicy0+aXRlbXNbal07CgkJCWlmICgoV1hTX0FUVFJVU0VfREVDTF9OQU1FKHVzZSkgPT0gcHJvLT5uYW1lKSAmJgoJCQkgICAgKFdYU19BVFRSVVNFX0RFQ0xfVE5TKHVzZSkgPT0KCQkJCXByby0+dGFyZ2V0TmFtZXNwYWNlKSkKCQkJewoJCQkgICAgZ290byBpbmhlcml0X25leHQ7CgkJCX0KCQkgICAgfQoJCX0KCQlpZiAodXNlc0NvdW50KSB7CgkJICAgIC8qCgkJICAgICogRmlsdGVyIG91dCBleGlzdGluZyB1c2VzLgoJCSAgICAqLwoJCSAgICBmb3IgKGogPSAwOyBqIDwgdXNlc0NvdW50OyBqKyspIHsKCQkJdG1wID0gdXNlcy0+aXRlbXNbal07CgkJCWlmICgoV1hTX0FUVFJVU0VfREVDTF9OQU1FKHVzZSkgPT0KCQkJCVdYU19BVFRSVVNFX0RFQ0xfTkFNRSh0bXApKSAmJgoJCQkgICAgKFdYU19BVFRSVVNFX0RFQ0xfVE5TKHVzZSkgPT0KCQkJCVdYU19BVFRSVVNFX0RFQ0xfVE5TKHRtcCkpKQoJCQl7CgkJCSAgICBnb3RvIGluaGVyaXRfbmV4dDsKCQkJfQoJCSAgICB9CgkJfQoJCWlmICh1c2VzID09IE5VTEwpIHsKCQkgICAgdHlwZS0+YXR0clVzZXMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwoJCSAgICBpZiAodHlwZS0+YXR0clVzZXMgPT0gTlVMTCkKCQkJZ290byBleGl0X2ZhaWx1cmU7CgkJICAgIHVzZXMgPSB0eXBlLT5hdHRyVXNlczsKCQl9CgkJeG1sU2NoZW1hSXRlbUxpc3RBZGRTaXplKHVzZXMsIDIsIHVzZSk7CmluaGVyaXRfbmV4dDoge30KCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qIEV4dGVuc2lvbi4gKi8KCSAgICBmb3IgKGkgPSAwOyBpIDwgYmFzZVVzZXMtPm5iSXRlbXM7IGkrKykgewkgICAgCgkJdXNlID0gYmFzZVVzZXMtPml0ZW1zW2ldOwkJCgkJaWYgKHVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyVXNlcyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkJICAgIGlmICh0eXBlLT5hdHRyVXNlcyA9PSBOVUxMKQoJCQlnb3RvIGV4aXRfZmFpbHVyZTsKCQkgICAgdXNlcyA9IHR5cGUtPmF0dHJVc2VzOwoJCX0KCQl4bWxTY2hlbWFJdGVtTGlzdEFkZFNpemUodXNlcywgYmFzZVVzZXMtPm5iSXRlbXMsIHVzZSk7IAoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIFNocmluayBhdHRyLiB1c2VzLgogICAgKi8KICAgIGlmICh1c2VzKSB7CglpZiAodXNlcy0+bmJJdGVtcyA9PSAwKSB7CgkgICAgeG1sU2NoZW1hSXRlbUxpc3RGcmVlKHVzZXMpOwoJICAgIHR5cGUtPmF0dHJVc2VzID0gTlVMTDsKCX0KCS8qCgkqIFRPRE86IFdlIGNvdWxkIHNocmluayB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKCSogdG8gZml0IHRoZSBhY3R1YWwgbnVtYmVyIG9mIGl0ZW1zLgoJKi8KICAgIH0KICAgIC8qCiAgICAqIENvbXB1dGUgdGhlIGNvbXBsZXRlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmIChXWFNfSVNfRVhURU5TSU9OKHR5cGUpKSB7CQoJaWYgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqICgzLjIuMi4xKSAiSWYgdGhlILdiYXNlIHdpbGRjYXJktyBpcyBub24tt2Fic2VudLcsIHRoZW4KCSAgICAqIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmc6IgoJICAgICovCgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCQkvKgoJCSogVW5pb24gdGhlIGNvbXBsZXRlIHdpbGRjYXJkIHdpdGggdGhlIGJhc2Ugd2lsZGNhcmQuCgkJKiBTUEVDIHthdHRyaWJ1dGUgd2lsZGNhcmR9CgkJKiAoMy4yLjIuMS4yKSAib3RoZXJ3aXNlIGEgd2lsZGNhcmQgd2hvc2Uge3Byb2Nlc3MgY29udGVudHN9CgkJKiBhbmQge2Fubm90YXRpb259IGFyZSB0aG9zZSBvZiB0aGUgt2NvbXBsZXRlIHdpbGRjYXJktywKCQkqIGFuZCB3aG9zZSB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IGlzIHRoZSBpbnRlbnNpb25hbCB1bmlvbgoJCSogb2YgdGhlIHtuYW1lc3BhY2UgY29uc3RyYWludH0gb2YgdGhlILdjb21wbGV0ZSB3aWxkY2FyZLcKCQkqIGFuZCBvZiB0aGUgt2Jhc2Ugd2lsZGNhcmS3LCBhcyBkZWZpbmVkIGluIEF0dHJpYnV0ZQoJCSogV2lsZGNhcmQgVW5pb24gKKczLjEwLjYpLiIKCQkqLwoJCWlmICh4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyhwY3R4dCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJICAgIGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJICAgIGdvdG8gZXhpdF9mYWlsdXJlOwkJCgkgICAgfSBlbHNlIHsKCQkvKgoJCSogKDMuMi4yLjEuMSkgIklmIHRoZSC3Y29tcGxldGUgd2lsZGNhcmS3IGlzILdhYnNlbnS3LAoJCSogdGhlbiB0aGUgt2Jhc2Ugd2lsZGNhcmS3LiIKCQkqLwoJCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJICAgIH0JIAoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogKDMuMi4yLjIpICJvdGhlcndpc2UgKHRoZSC3YmFzZSB3aWxkY2FyZLcgaXMgt2Fic2VudLcpIHRoZQoJICAgICogt2NvbXBsZXRlIHdpbGRjYXJkIgoJICAgICogTk9PUAoJICAgICovCgl9CiAgICB9IGVsc2UgewoJLyoKCSogU1BFQyB7YXR0cmlidXRlIHdpbGRjYXJkfQoJKiAoMy4xKSAiSWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIHRoZQoJKiC3Y29tcGxldGUgd2lsZGNhcmS3OyIKCSogTk9PUAoJKi8KICAgIH0KICAgIAogICAgcmV0dXJuICgwKTsKCmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRmluYWxDb250YWluczoKICogQHNjaGVtYTogIHRoZSBzY2hlbWEKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBmaW5hbDogdGhlIGZpbmFsCiAqCiAqIEV2YWx1YXRlcyBpZiBhIHR5cGUgZGVmaW5pdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gImZpbmFsIi4KICogVGhpcyBkb2VzIHRha2UgImZpbmFsRGVmYXVsdCIgaW50byBhY2NvdW50IGFzIHdlbGwuCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBkb2VzIGNvbnRhaW50IHRoZSBnaXZlbiAiZmluYWwiLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgZmluYWwpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPmZsYWdzICYgZmluYWwpCglyZXR1cm4gKDEpOwogICAgZWxzZQoJcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzOgogKiBAdHlwZTogIHRoZSBVbmlvbiBTaW1wbGUgVHlwZQogKgogKiBSZXR1cm5zIGEgbGlzdCBvZiBtZW1iZXIgdHlwZXMgb2YgQHR5cGUgaWYgZXhpc3RpbmcsCiAqIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZUxpbmtQdHIKeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB3aGlsZSAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkpIHsKCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJICAgIHJldHVybiAodHlwZS0+bWVtYmVyVHlwZXMpOwoJZWxzZQoJICAgIHR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW46CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWZmZWN0aXZlIFRvdGFsIFJhbmdlCiAqIChhbGwgYW5kIHNlcXVlbmNlKSArIChjaG9pY2UpCiAqCiAqIFJldHVybnMgdGhlIG1pbmltdW4gRWZmZWN0aXZlIFRvdGFsIFJhbmdlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW4oeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmICgocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHx8CgkocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSkKCXJldHVybiAoMCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWludCBtaW4gPSAtMSwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWlmIChwYXJ0ID09IE5VTEwpCgkgICAgcmV0dXJuICgwKTsKCXdoaWxlIChwYXJ0ICE9IE5VTEwpIHsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5taW5PY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihwYXJ0KTsKCSAgICBpZiAoY3VyID09IDApCgkJcmV0dXJuICgwKTsKCSAgICBpZiAoKG1pbiA+IGN1cikgfHwgKG1pbiA9PSAtMSkpCgkJbWluID0gY3VyOwoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQ7Cgl9CglyZXR1cm4gKHBhcnRpY2xlLT5taW5PY2N1cnMgKiBtaW4pOwogICAgfSBlbHNlIHsKCS8qIDxhbGw+IGFuZCA8c2VxdWVuY2U+ICovCglpbnQgc3VtID0gMDsKCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnQgPQoJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKCglpZiAocGFydCA9PSBOVUxMKQoJICAgIHJldHVybiAoMCk7CglkbyB7CgkgICAgaWYgKChwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgfHwKCQkocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkpCgkJc3VtICs9IHBhcnQtPm1pbk9jY3VyczsKCSAgICBlbHNlCgkJc3VtICs9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihwYXJ0KTsKCSAgICBwYXJ0ID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0LT5uZXh0OwoJfSB3aGlsZSAocGFydCAhPSBOVUxMKTsKCXJldHVybiAocGFydGljbGUtPm1pbk9jY3VycyAqIHN1bSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNYXg6CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWZmZWN0aXZlIFRvdGFsIFJhbmdlCiAqIChhbGwgYW5kIHNlcXVlbmNlKSArIChjaG9pY2UpCiAqCiAqIFJldHVybnMgdGhlIG1heGltdW0gRWZmZWN0aXZlIFRvdGFsIFJhbmdlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNYXgoeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmICgocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHx8CgkocGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybiAoMCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWludCBtYXggPSAtMSwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWZvciAoOyBwYXJ0ICE9IE5VTEw7IHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQpIHsKCSAgICBpZiAocGFydC0+Y2hpbGRyZW4gPT0gTlVMTCkKCQljb250aW51ZTsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5tYXhPY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heChwYXJ0KTsKCSAgICBpZiAoY3VyID09IFVOQk9VTkRFRCkKCQlyZXR1cm4gKFVOQk9VTkRFRCk7CgkgICAgaWYgKChtYXggPCBjdXIpIHx8IChtYXggPT0gLTEpKQoJCW1heCA9IGN1cjsKCX0KCS8qIFRPRE86IEhhbmRsZSBvdmVyZmxvd3M/ICovCglyZXR1cm4gKHBhcnRpY2xlLT5tYXhPY2N1cnMgKiBtYXgpOwogICAgfSBlbHNlIHsKCS8qIDxhbGw+IGFuZCA8c2VxdWVuY2U+ICovCglpbnQgc3VtID0gMCwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWZvciAoOyBwYXJ0ICE9IE5VTEw7IHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQpIHsKCSAgICBpZiAocGFydC0+Y2hpbGRyZW4gPT0gTlVMTCkKCQljb250aW51ZTsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5tYXhPY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heChwYXJ0KTsKCSAgICBpZiAoY3VyID09IFVOQk9VTkRFRCkKCQlyZXR1cm4gKFVOQk9VTkRFRCk7CgkgICAgaWYgKChjdXIgPiAwKSAmJiAocGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQpKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBzdW0gKz0gY3VyOwoJfQoJLyogVE9ETzogSGFuZGxlIG92ZXJmbG93cz8gKi8KCXJldHVybiAocGFydGljbGUtPm1heE9jY3VycyAqIHN1bSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlOgogKiBAcGFydGljbGU6IHRoZSBwYXJ0aWNsZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFBhcnRpY2xlIEVtcHRpYWJsZQogKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGFydGljbGUgaXMgZW1wdGlhYmxlLgogKgogKiBSZXR1cm5zIDEgaWYgZW1wdGlhYmxlLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgLyoKICAgICogU1BFQyAoMSkgIkl0cyB7bWluIG9jY3Vyc30gaXMgMC4iCiAgICAqLwogICAgaWYgKChwYXJ0aWNsZSA9PSBOVUxMKSB8fCAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB8fAoJKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiSXRzIHt0ZXJtfSBpcyBhIGdyb3VwIGFuZCB0aGUgbWluaW11bSBwYXJ0IG9mIHRoZQogICAgKiBlZmZlY3RpdmUgdG90YWwgcmFuZ2Ugb2YgdGhhdCBncm91cCwgWy4uLl0gaXMgMC4iCiAgICAqLwogICAgaWYgKFdYU19JU19NT0RFTF9HUk9VUChwYXJ0aWNsZS0+Y2hpbGRyZW4pKSB7CglpZiAoeG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHBhcnRpY2xlKSA9PSAwKQoJICAgIHJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSzoKICogQGFjdHh0OiBhIGNvbnRleHQKICogQHR5cGU6ICB0aGUgZGVyaXZlZCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBiYXNlVHlwZTogIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbgogKiBAc3Vic2V0OiB0aGUgc3Vic2V0IG9mICgncmVzdHJpY3Rpb24nLCBlY3QuKQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAoY29zLXN0LWRlcml2ZWQtT0spCiAqCiAqIENoZWNrcyB3aGV0ZXIgQHR5cGUgY2FuIGJlIHZhbGlkbHkKICogZGVyaXZlZCBmcm9tIEBiYXNlVHlwZS4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIGFuIHBvc2l0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSwKCQkJICAgICBpbnQgc3Vic2V0KQp7CiAgICAvKgogICAgKiAxIFRoZXkgYXJlIHRoZSBzYW1lIHR5cGUgZGVmaW5pdGlvbi4KICAgICogVE9ETzogVGhlIGlkZW50eSBjaGVjayBtaWdodCBoYXZlIHRvIGJlIG1vcmUgY29tcGxleCB0aGFuIHRoaXMuCiAgICAqLwogICAgaWYgKHR5cGUgPT0gYmFzZVR5cGUpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogMi4xIHJlc3RyaWN0aW9uIGlzIG5vdCBpbiB0aGUgc3Vic2V0LCBvciBpbiB0aGUge2ZpbmFsfQogICAgKiBvZiBpdHMgb3duIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn07CiAgICAqCiAgICAqIE5PVEUgdGhhdCB0aGlzIHdpbGwgYmUgdXNlZCBhbHNvIHZpYSAieHNpOnR5cGUiLgogICAgKgogICAgKiBUT0RPOiBSZXZpc2UgdGhpcywgaXQgbG9va3Mgc3RyYW5nZS4gSG93IGNhbiB0aGUgInR5cGUiCiAgICAqIG5vdCBiZSBmaXhlZCBvciAqaW4qIGZpeGluZz8KICAgICovCiAgICBpZiAoV1hTX0lTX1RZUEVfTk9UX0ZJWEVEKHR5cGUpKQoJaWYgKHhtbFNjaGVtYVR5cGVGaXh1cCh0eXBlLCBhY3R4dCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQoYmFzZVR5cGUpKQoJaWYgKHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgYWN0eHQpID09IC0xKQoJICAgIHJldHVybigtMSk7CiAgICBpZiAoKHN1YnNldCAmIFNVQlNFVF9SRVNUUklDVElPTikgfHwKCSh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh0eXBlLT5iYXNlVHlwZSwKCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkpIHsKCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8xKTsKICAgIH0KICAgIC8qIDIuMiAqLwogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IGJhc2VUeXBlKSB7CgkvKgoJKiAyLjIuMSBEJ3Mgt2Jhc2UgdHlwZSBkZWZpbml0aW9utyBpcyBCLgoJKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAyLjIuMiBEJ3Mgt2Jhc2UgdHlwZSBkZWZpbml0aW9utyBpcyBub3QgdGhlILd1ci10eXBlIGRlZmluaXRpb263CiAgICAqIGFuZCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQsIGFzIGRlZmluZWQgYnkgdGhpcwogICAgKiBjb25zdHJhaW50LgogICAgKi8KICAgIGlmICgoISBXWFNfSVNfQU5ZVFlQRSh0eXBlLT5iYXNlVHlwZSkpICYmCgkoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhhY3R4dCwgdHlwZS0+YmFzZVR5cGUsCgkgICAgYmFzZVR5cGUsIHN1YnNldCkgPT0gMCkpIHsKCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAyLjIuMyBEJ3Mge3ZhcmlldHl9IGlzIGxpc3Qgb3IgdW5pb24gYW5kIEIgaXMgdGhlILdzaW1wbGUgdXItdHlwZQogICAgKiBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoV1hTX0lTX0FOWV9TSU1QTEVfVFlQRShiYXNlVHlwZSkgJiYKCShXWFNfSVNfTElTVCh0eXBlKSB8fCBXWFNfSVNfVU5JT04odHlwZSkpKSB7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogMi4yLjQgQidzIHt2YXJpZXR5fSBpcyB1bmlvbiBhbmQgRCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhIHR5cGUKICAgICogZGVmaW5pdGlvbiBpbiBCJ3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgc3Vic2V0LCBhcwogICAgKiBkZWZpbmVkIGJ5IHRoaXMgY29uc3RyYWludC4KICAgICoKICAgICogTk9URTogVGhpcyBzZWVtcyBub3QgdG8gaW52b2x2ZSBidWlsdC1pbiB0eXBlcywgc2luY2UgdGhlcmUgaXMgbm8KICAgICogYnVpbHQtaW4gVW5pb24gU2ltcGxlIFR5cGUuCiAgICAqLwogICAgaWYgKFdYU19JU19VTklPTihiYXNlVHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGN1cjsKCgljdXIgPSBiYXNlVHlwZS0+bWVtYmVyVHlwZXM7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoV1hTX0lTX1RZUEVfTk9UX0ZJWEVEKGN1ci0+dHlwZSkpCgkJaWYgKHhtbFNjaGVtYVR5cGVGaXh1cChjdXItPnR5cGUsIGFjdHh0KSA9PSAtMSkKCQkgICAgcmV0dXJuKC0xKTsKCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhhY3R4dCwKCQkgICAgdHlwZSwgY3VyLT50eXBlLCBzdWJzZXQpID09IDApCgkgICAgewoJCS8qCgkJKiBJdCBqdXN0IGhhcyB0byBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhdCBsZWFzdCBvbmUKCQkqIG1lbWJlci10eXBlLgoJCSovCgkJcmV0dXJuICgwKTsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfQogICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzIpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXJJbnRlcm5hbDoKICogQHBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY3R4dFR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBhbmNlc3RvcjogYW4gYW5jZXN0b3Igb2YgQGN0eHRUeXBlCiAqCiAqIENoZWNrcyBzdC1wcm9wcy1jb3JyZWN0ICgyKSArIGN0LXByb3BzLWNvcnJlY3QgKDMpLgogKiBDaXJjdWxhciB0eXBlIGRlZmluaXRpb25zIGFyZSBub3QgYWxsb3dlZC4KICoKICogUmV0dXJucyBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIgaWYgdGhlIGdpdmVuIHR5cGUgaXMKICogY2lyY3VsYXIsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGUsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgYW5jZXN0b3IpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChhbmNlc3RvciA9PSBOVUxMKSB8fCAoYW5jZXN0b3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkKCXJldHVybiAoMCk7CgogICAgaWYgKGN0eHRUeXBlID09IGFuY2VzdG9yKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiwKCSAgICBXWFNfQkFTSUNfQ0FTVCBjdHh0VHlwZSwgV1hTX0lURU1fTk9ERShjdHh0VHlwZSksCgkgICAgIlRoZSBkZWZpbml0aW9uIGlzIGNpcmN1bGFyIiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMik7CiAgICB9CiAgICBpZiAoYW5jZXN0b3ItPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQpIHsKCS8qCgkqIEF2b2lkIGluaWZpbml0ZSByZWN1cnNpb24gb24gY2lyY3VsYXIgdHlwZXMgbm90IHlldCBjaGVja2VkLgoJKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBhbmNlc3Rvci0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CiAgICByZXQgPSB4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsKHBjdHh0LCBjdHh0VHlwZSwKCWFuY2VzdG9yLT5iYXNlVHlwZSk7CiAgICBhbmNlc3Rvci0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhcjoKICogQGl0ZW06ICB0aGUgY29tcGxleC9zaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciB0eXBlIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXIoeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGlmICgoaXRlbSA9PSBOVUxMKSB8fAoJKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB8fAoJKGl0ZW0tPmJhc2VUeXBlID09IE5VTEwpKQoJcmV0dXJuOwogICAgeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXJJbnRlcm5hbChjdHh0LCBpdGVtLAoJaXRlbS0+YmFzZVR5cGUpOwp9CgovKgoqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sgKHNyYy1zaW1wbGUtdHlwZSkgNAoqCiogIjQgQ2lyY3VsYXIgdW5pb24gdHlwZSBkZWZpbml0aW9uIGlzIGRpc2FsbG93ZWQuIFRoYXQgaXMsIGlmIHRoZQoqIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVyZSBtdXN0IG5vdCBiZSBhbnkgZW50cmllcyBpbiB0aGUKKiBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBhdCBhbnkgZGVwdGggd2hpY2ggcmVzb2x2ZSB0byB0aGUgY29tcG9uZW50CiogY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+LiIKKgoqIE5vdGUgdGhhdCB0aGlzIHNob3VsZCB3b3JrIG9uIHRoZSAqcmVwcmVzZW50YXRpb24qIG9mIGEgY29tcG9uZW50LAoqIHRodXMgYXNzdW1lcyBhbnkgdW5pb24gdHlwZXMgaW4gdGhlIG1lbWJlciB0eXBlcyBub3QgYmVpbmcgeWV0Ciogc3Vic3RpdHV0ZWQuIEF0IHRoaXMgc3RhZ2Ugd2UgbmVlZCB0aGUgdmFyaWV0eSBvZiB0aGUgdHlwZXMKKiB0byBiZSBhbHJlYWR5IGNvbXB1dGVkLgoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrVW5pb25UeXBlRGVmQ2lyY3VsYXJSZWN1cih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJCXhtbFNjaGVtYVR5cGVQdHIgY3R4VHlwZSwKCQkJCQl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXJzKQp7ICAgIAogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwogICAgeG1sU2NoZW1hVHlwZVB0ciBtZW1iZXJUeXBlOwogICAgCiAgICBtZW1iZXIgPSBtZW1iZXJzOwogICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgltZW1iZXJUeXBlID0gbWVtYmVyLT50eXBlOwoJd2hpbGUgKChtZW1iZXJUeXBlICE9IE5VTEwpICYmCgkgICAgKG1lbWJlclR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkgewoJICAgIGlmIChtZW1iZXJUeXBlID09IGN0eFR5cGUpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfNCwKCQkgICAgV1hTX0JBU0lDX0NBU1QgY3R4VHlwZSwgTlVMTCwKCQkgICAgIlRoZSB1bmlvbiB0eXBlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCSAgICB9CgkgICAgaWYgKChXWFNfSVNfVU5JT04obWVtYmVyVHlwZSkpICYmCgkJKChtZW1iZXJUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEKSA9PSAwKSkKCSAgICB7CgkJaW50IHJlczsKCQltZW1iZXJUeXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKCQlyZXMgPSB4bWxTY2hlbWFDaGVja1VuaW9uVHlwZURlZkNpcmN1bGFyUmVjdXIocGN0eHQsCgkJICAgIGN0eFR5cGUsCgkJICAgIHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKG1lbWJlclR5cGUpKTsKCQltZW1iZXJUeXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKCQlpZiAocmVzICE9IDApCgkJICAgIHJldHVybihyZXMpOwoJICAgIH0KCSAgICBtZW1iZXJUeXBlID0gbWVtYmVyVHlwZS0+YmFzZVR5cGU7Cgl9CgltZW1iZXIgPSBtZW1iZXItPm5leHQ7CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tVbmlvblR5cGVEZWZDaXJjdWxhcih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAoISBXWFNfSVNfVU5JT04odHlwZSkpCglyZXR1cm4oMCk7CiAgICByZXR1cm4oeG1sU2NoZW1hQ2hlY2tVbmlvblR5cGVEZWZDaXJjdWxhclJlY3VyKHBjdHh0LCB0eXBlLAoJdHlwZS0+bWVtYmVyVHlwZXMpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVUeXBlUmVmZXJlbmNlczoKICogQGl0ZW06ICB0aGUgY29tcGxleC9zaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogUmVzb2x2ZXNlIHR5cGUgZGVmaW5pdGlvbiByZWZlcmVuY2VzCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFSZXNvbHZlVHlwZVJlZmVyZW5jZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVmLAoJCQkgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAodHlwZURlZiA9PSBOVUxMKQoJcmV0dXJuOwoKICAgIC8qCiAgICAqIFJlc29sdmUgdGhlIGJhc2UgdHlwZS4KICAgICovCiAgICBpZiAodHlwZURlZi0+YmFzZVR5cGUgPT0gTlVMTCkgewoJdHlwZURlZi0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwKCSAgICB0eXBlRGVmLT5iYXNlLCB0eXBlRGVmLT5iYXNlTnMpOwoJaWYgKHR5cGVEZWYtPmJhc2VUeXBlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlRGVmLCB0eXBlRGVmLT5ub2RlLAoJCSJiYXNlIiwgdHlwZURlZi0+YmFzZSwgdHlwZURlZi0+YmFzZU5zLAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KICAgIH0KICAgIGlmIChXWFNfSVNfU0lNUExFKHR5cGVEZWYpKSB7CglpZiAoV1hTX0lTX1VOSU9OKHR5cGVEZWYpKSB7CgkgICAgLyoKCSAgICAqIFJlc29sdmUgdGhlIG1lbWJlclR5cGVzLgoJICAgICovCgkgICAgeG1sU2NoZW1hUmVzb2x2ZVVuaW9uTWVtYmVyVHlwZXMoY3R4dCwgdHlwZURlZik7CgkgICAgcmV0dXJuOwoJfSBlbHNlIGlmIChXWFNfSVNfTElTVCh0eXBlRGVmKSkgewoJICAgIC8qCgkgICAgKiBSZXNvbHZlIHRoZSBpdGVtVHlwZS4KCSAgICAqLwoJICAgIGlmICgodHlwZURlZi0+c3VidHlwZXMgPT0gTlVMTCkgJiYgKHR5cGVEZWYtPmJhc2UgIT0gTlVMTCkpIHsKCgkJdHlwZURlZi0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwKCQkgICAgdHlwZURlZi0+YmFzZSwgdHlwZURlZi0+YmFzZU5zKTsKCgkJaWYgKCh0eXBlRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSB8fAoJCSAgICAoISBXWFNfSVNfU0lNUExFKHR5cGVEZWYtPnN1YnR5cGVzKSkpCgkJewoJCSAgICB0eXBlRGVmLT5zdWJ0eXBlcyA9IE5VTEw7CgkJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkJV1hTX0JBU0lDX0NBU1QgdHlwZURlZiwgdHlwZURlZi0+bm9kZSwKCQkJIml0ZW1UeXBlIiwgdHlwZURlZi0+YmFzZSwgdHlwZURlZi0+YmFzZU5zLAoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCQl9CgkgICAgfQoJICAgIHJldHVybjsKCX0KICAgIH0gCiAgICAvKgogICAgKiBUaGUgYmFsbCBvZiBsZXR0ZXJzIGJlbG93IG1lYW5zLCB0aGF0IGlmIHdlIGhhdmUgYSBwYXJ0aWNsZQogICAgKiB3aGljaCBoYXMgYSBRTmFtZS1oZWxwZXIgY29tcG9uZW50IGFzIGl0cyB7dGVybX0sIHdlIHdhbnQKICAgICogdG8gcmVzb2x2ZSBpdC4uLgogICAgKi8KICAgIGVsc2UgaWYgKChXWFNfVFlQRV9DT05URU5UVFlQRSh0eXBlRGVmKSAhPSBOVUxMKSAmJgoJKChXWFNfVFlQRV9DT05URU5UVFlQRSh0eXBlRGVmKSktPnR5cGUgPT0KCSAgICBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEUpICYmCgkoV1hTX1RZUEVfUEFSVElDTEVfVEVSTSh0eXBlRGVmKSAhPSBOVUxMKSAmJgoJKChXWFNfVFlQRV9QQVJUSUNMRV9URVJNKHR5cGVEZWYpKS0+dHlwZSA9PQoJICAgIFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUYpKQogICAgewoJeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmID0KCSAgICBXWFNfUU5BTUVfQ0FTVCBXWFNfVFlQRV9QQVJUSUNMRV9URVJNKHR5cGVEZWYpOwoJeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBncm91cERlZjsKCgkvKgoJKiBVUkdFTlQgVE9ETzogVGVzdCB0aGlzLgoJKi8KCVdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZURlZikgPSBOVUxMOwoJLyoKCSogUmVzb2x2ZSB0aGUgTUcgZGVmaW5pdGlvbiByZWZlcmVuY2UuCgkqLwoJZ3JvdXBEZWYgPQoJICAgIFdYU19NT0RFTF9HUk9VUERFRl9DQVNUIHhtbFNjaGVtYUdldE5hbWVkQ29tcG9uZW50KGN0eHQtPnNjaGVtYSwKCQlyZWYtPml0ZW1UeXBlLCByZWYtPm5hbWUsIHJlZi0+dGFyZ2V0TmFtZXNwYWNlKTsKCWlmIChncm91cERlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsIFdYU19JVEVNX05PREUoV1hTX1RZUEVfUEFSVElDTEUodHlwZURlZikpLAoJCSJyZWYiLCByZWYtPm5hbWUsIHJlZi0+dGFyZ2V0TmFtZXNwYWNlLCByZWYtPml0ZW1UeXBlLAoJCU5VTEwpOwoJICAgIC8qIFJlbW92ZSB0aGUgcGFydGljbGUuICovCgkgICAgV1hTX1RZUEVfQ09OVEVOVFRZUEUodHlwZURlZikgPSBOVUxMOwoJfSBlbHNlIGlmIChXWFNfTU9ERUxHUk9VUERFRl9NT0RFTChncm91cERlZikgPT0gTlVMTCkKCSAgICAvKiBSZW1vdmUgdGhlIHBhcnRpY2xlLiAqLwoJICAgIFdYU19UWVBFX0NPTlRFTlRUWVBFKHR5cGVEZWYpID0gTlVMTDsKCWVsc2UgewoJICAgIC8qCgkgICAgKiBBc3NpZ24gdGhlIE1HIGRlZmluaXRpb24ncyB7bW9kZWwgZ3JvdXB9IHRvIHRoZQoJICAgICogcGFydGljbGUncyB7dGVybX0uCgkgICAgKi8KCSAgICBXWFNfVFlQRV9QQVJUSUNMRV9URVJNKHR5cGVEZWYpID0gV1hTX01PREVMR1JPVVBERUZfTU9ERUwoZ3JvdXBEZWYpOwoJICAgIAoJICAgIGlmIChXWFNfTU9ERUxHUk9VUERFRl9NT0RFTChncm91cERlZiktPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgewoJCS8qCgkJKiBTUEVDIGNvcy1hbGwtbGltaXRlZCAoMS4yKQoJCSogIjEuMiB0aGUge3Rlcm19IHByb3BlcnR5IG9mIGEgcGFydGljbGUgd2l0aAoJCSoge21heCBvY2N1cnN9PTEgd2hpY2ggaXMgcGFydCBvZiBhIHBhaXIgd2hpY2ggY29uc3RpdHV0ZXMKCQkqIHRoZSB7Y29udGVudCB0eXBlfSBvZiBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLiIKCQkqLwoJCWlmICgoV1hTX1RZUEVfUEFSVElDTEUodHlwZURlZikpLT5tYXhPY2N1cnMgIT0gMSkgewoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBjdHh0LAoJCQkvKiBUT0RPOiBlcnJvciBjb2RlICovCgkJCVhNTF9TQ0hFTUFQX0NPU19BTExfTElNSVRFRCwKCQkJV1hTX0lURU1fTk9ERShXWFNfVFlQRV9QQVJUSUNMRSh0eXBlRGVmKSksIE5VTEwsCgkJCSJUaGUgcGFydGljbGUncyB7bWF4IG9jY3Vyc30gbXVzdCBiZSAxLCBzaW5jZSB0aGUgIgoJCQkicmVmZXJlbmNlIHJlc29sdmVzIHRvIGFuICdhbGwnIG1vZGVsIGdyb3VwIiwKCQkJTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0KCX0KICAgIH0KfQoKCgovKioKICogeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHN0LXByb3BzLWNvcnJlY3QuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgcHJvcGVydGllcyBhcmUgY29ycmVjdCwKICogaWYgbm90LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgIC8qIFNUQVRFOiBlcnJvciBmdW5jcyBjb252ZXJ0ZWQuICovCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFNpbXBsZSBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAqCiAgICAqIE5PVEU6IFRoaXMgaXMgc29tZWhvdyByZWR1bmRhbnQsIHNpbmNlIHdlIGFjdHVhbGx5IGJ1aWx0IGEgc2ltcGxlIHR5cGUKICAgICogdG8gaGF2ZSBhbGwgdGhlIG5lZWRlZCBpbmZvcm1hdGlvbjsgdGhpcyBhY3RzIGFzIGFuIHNlbGYgdGVzdC4KICAgICovCiAgICAvKiBCYXNlIHR5cGU6IElmIHRoZSBkYXRhdHlwZSBoYXMgYmVlbiC3ZGVyaXZlZLcgYnkgt3Jlc3RyaWN0aW9utwogICAgKiB0aGVuIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGNvbXBvbmVudCBmcm9tIHdoaWNoIGl0IGlzILdkZXJpdmVktywKICAgICogb3RoZXJ3aXNlIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGZvciBhbnlTaW1wbGVUeXBlICinNC4xLjYpLgogICAgKi8KICAgIGlmIChiYXNlVHlwZSA9PSBOVUxMKSB7CgkvKgoJKiBUT0RPOiBUaGluayBhYm91dDogIm1vZHVsbyB0aGUgaW1wYWN0IG9mIE1pc3NpbmcKCSogU3ViLWNvbXBvbmVudHMgKKc1LjMpLiIKCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkgICAgIk5vIGJhc2UgdHlwZSBleGlzdGVudCIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwoKICAgIH0KICAgIGlmICghIFdYU19JU19TSU1QTEUoYmFzZVR5cGUpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkgICAgIlRoZSBiYXNlIHR5cGUgJyVzJyBpcyBub3QgYSBzaW1wbGUgdHlwZSIsCgkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgYmFzZVR5cGUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgaWYgKCAoV1hTX0lTX0xJU1QodHlwZSkgfHwgV1hTX0lTX1VOSU9OKHR5cGUpKSAmJgoJIChXWFNfSVNfUkVTVFJJQ1RJT04odHlwZSkgPT0gMCkgJiYKCSAoISBXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKGJhc2VUeXBlKSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCSAgICAiQSB0eXBlLCBkZXJpdmVkIGJ5IGxpc3Qgb3IgdW5pb24sIG11c3QgaGF2ZSIKCSAgICAidGhlIHNpbXBsZSB1ci10eXBlIGRlZmluaXRpb24gYXMgYmFzZSB0eXBlLCBub3QgJyVzJyIsCgkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgYmFzZVR5cGUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgLyoKICAgICogVmFyaWV0eTogT25lIG9mIHthdG9taWMsIGxpc3QsIHVuaW9ufS4KICAgICovCiAgICBpZiAoKCEgV1hTX0lTX0FUT01JQyh0eXBlKSkgJiYgKCEgV1hTX0lTX1VOSU9OKHR5cGUpKSAmJgoJKCEgV1hTX0lTX0xJU1QodHlwZSkpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkgICAgIlRoZSB2YXJpZXR5IGlzIGFic2VudCIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgLyogVE9ETzogRmluaXNoIHRoaXMuIEhtbSwgaXMgdGhpcyBmaW5pc2hlZD8gKi8KCiAgICAvKgogICAgKiAzIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGJhc2VUeXBlLAoJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzMsCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCSAgICAiVGhlICdmaW5hbCcgb2YgaXRzIGJhc2UgdHlwZSAnJXMnIG11c3Qgbm90IGNvbnRhaW4gIgoJICAgICIncmVzdHJpY3Rpb24nIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlVHlwZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMyk7CiAgICB9CgogICAgLyoKICAgICogMiBBbGwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMgbXVzdCBiZSBkZXJpdmVkIHVsdGltYXRlbHkgZnJvbSB0aGUgt3NpbXBsZQogICAgKiB1ci10eXBlIGRlZmluaXRpb24gKHNvtyBjaXJjdWxhciBkZWZpbml0aW9ucyBhcmUgZGlzYWxsb3dlZCkuIFRoYXQgaXMsIGl0CiAgICAqIG11c3QgYmUgcG9zc2libGUgdG8gcmVhY2ggYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUgb3IgdGhlILdzaW1wbGUKICAgICogdXItdHlwZSBkZWZpbml0aW9utyBieSByZXBlYXRlZGx5IGZvbGxvd2luZyB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KICAgICoKICAgICogTk9URTogdGhpcyBpcyBkb25lIGluIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyKCkuCiAgICAqLwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIFNpbXBsZSkgKGNvcy1zdC1yZXN0cmljdHMpCgogKiBDaGVja3MgaWYgdGhlIGdpdmVuIEB0eXBlIChzaW1wbGVUeXBlKSBpcyBkZXJpdmVkIHZhbGlkbHkgYnkgcmVzdHJpY3Rpb24uCiAqIFNUQVRVUzoKICoKICogUmV0dXJucyAtMSBvbiBpbnRlcm5hbCBlcnJvcnMsIDAgaWYgdGhlIHR5cGUgaXMgdmFsaWRseSBkZXJpdmVkLAogKiBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJICAgICJnaXZlbiB0eXBlIGlzIG5vdCBhIHVzZXItZGVyaXZlZCBzaW1wbGVUeXBlIik7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBwcmltaXRpdmU7CgkvKgoJKiAxLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhbiBhdG9taWMgc2ltcGxlCgkqIHR5cGUgZGVmaW5pdGlvbiBvciBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZS4KCSovCglpZiAoISBXWFNfSVNfQVRPTUlDKHR5cGUtPmJhc2VUeXBlKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzEsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkiVGhlIGJhc2UgdHlwZSAnJXMnIGlzIG5vdCBhbiBhdG9taWMgc2ltcGxlIHR5cGUiLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMSk7Cgl9CgkvKiAxLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbgoJKiByZXN0cmljdGlvbi4KCSovCgkvKiBPUFRJTUlaRSBUT0RPIDogVGhpcyBpcyBhbHJlYWR5IGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tTdFByb3BzQ29ycmVjdCAqLwoJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHR5cGUtPmJhc2VUeXBlLAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMiwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJUaGUgZmluYWwgb2YgaXRzIGJhc2UgdHlwZSAnJXMnIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgdHlwZS0+YmFzZVR5cGUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yKTsKCX0KCgkvKgoJKiAxLjMuMSBERiBtdXN0IGJlIGFuIGFsbG93ZWQgY29uc3RyYWluaW5nIGZhY2V0IGZvciB0aGUge3ByaW1pdGl2ZQoJKiB0eXBlIGRlZmluaXRpb259LCBhcyBzcGVjaWZpZWQgaW4gdGhlIGFwcHJvcHJpYXRlIHN1YnNlY3Rpb24gb2YgMy4yCgkqIFByaW1pdGl2ZSBkYXRhdHlwZXMuCgkqLwoJaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkgICAgaW50IG9rID0gMTsKCgkgICAgcHJpbWl0aXZlID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eXBlKTsKCSAgICBpZiAocHJpbWl0aXZlID09IE5VTEwpIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzIiwKCQkgICAgImZhaWxlZCB0byBnZXQgcHJpbWl0aXZlIHR5cGUiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkgICAgZG8gewoJCWlmICh4bWxTY2hlbWFJc0J1aWx0SW5UeXBlRmFjZXQocHJpbWl0aXZlLCBmYWNldC0+dHlwZSkgPT0gMCkgewoJCSAgICBvayA9IDA7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEsCgkJCXR5cGUsIHByaW1pdGl2ZSwgZmFjZXQpOwoJCX0KCQlmYWNldCA9IGZhY2V0LT5uZXh0OwoJICAgIH0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJICAgIGlmIChvayA9PSAwKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSk7Cgl9CgkvKgoJKiBTUEVDICgxLjMuMikgIklmIHRoZXJlIGlzIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBpbiB0aGUge2ZhY2V0c30KCSogb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gKGNhbGwgdGhpcyBCRiksdGhlbiB0aGUgREYncyB7dmFsdWV9CgkqIG11c3QgYmUgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCRidzIHt2YWx1ZX0gYXMgZGVmaW5lZCBpbgoJKiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uIgoJKgoJKiBOT1RFICgxLjMuMikgRmFjZXQgZGVyaXZhdGlvbiBjb25zdHJhaW50cyBhcmUgY3VycmVudGx5IGhhbmRsZWQgaW4KCSogeG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMoKQoJKi8KICAgIH0gZWxzZSBpZiAoV1hTX0lTX0xJU1QodHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgaXRlbVR5cGUgPSBOVUxMOwoKCWl0ZW1UeXBlID0gdHlwZS0+c3VidHlwZXM7CglpZiAoKGl0ZW1UeXBlID09IE5VTEwpIHx8ICghIFdYU19JU19TSU1QTEUoaXRlbVR5cGUpKSkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCSJmYWlsZWQgdG8gZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChpdGVtVHlwZSkpCgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW1UeXBlLCBBQ1RYVF9DQVNUIHBjdHh0KTsKCS8qCgkqIDIuMSBUaGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgYXRvbWljIG9yCgkqIHVuaW9uIChpbiB3aGljaCBjYXNlIGFsbCB0aGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfQoJKiBtdXN0IGJlIGF0b21pYykuCgkqLwoJaWYgKCghIFdYU19JU19BVE9NSUMoaXRlbVR5cGUpKSAmJgoJICAgICghIFdYU19JU19VTklPTihpdGVtVHlwZSkpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJUaGUgaXRlbSB0eXBlICclcycgZG9lcyBub3QgaGF2ZSBhIHZhcmlldHkgb2YgYXRvbWljIG9yIHVuaW9uIiwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBpdGVtVHlwZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJfSBlbHNlIGlmIChXWFNfSVNfVU5JT04oaXRlbVR5cGUpKSB7CgkgICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCSAgICBtZW1iZXIgPSBpdGVtVHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKCEgV1hTX0lTX0FUT01JQyhtZW1iZXItPnR5cGUpKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCQkiVGhlIGl0ZW0gdHlwZSBpcyBhIHVuaW9uIHR5cGUsIGJ1dCB0aGUgIgoJCQkibWVtYmVyIHR5cGUgJyVzJyBvZiB0aGlzIGl0ZW0gdHlwZSBpcyBub3QgYXRvbWljIiwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgbWVtYmVyLT50eXBlKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCX0KCglpZiAoV1hTX0lTX0FOWV9TSU1QTEVfVFlQRSh0eXBlLT5iYXNlVHlwZSkpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48bGlzdCAuLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4xCgkgICAgKiAyLjMuMS4xIFRoZSB7ZmluYWx9IG9mIHRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkgICAgKiBjb250YWluIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoaXRlbVR5cGUsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNUKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMSwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBmaW5hbCBvZiBpdHMgaXRlbSB0eXBlICclcycgbXVzdCBub3QgY29udGFpbiAnbGlzdCciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBpdGVtVHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4xLjIgVGhlIHtmYWNldHN9IG11c3Qgb25seSBjb250YWluIHRoZSB3aGl0ZVNwYWNlCgkgICAgKiBmYWNldCBjb21wb25lbnQuCgkgICAgKiBPUFRJTUlaRSBUT0RPOiB0aGUgUzRTIGFscmVhZHkgZGlzYWxsb3dzIGFueSBmYWNldAoJICAgICogdG8gYmUgc3BlY2lmaWVkLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkJZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkJZG8gewoJCSAgICBpZiAoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIocGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIsCgkJCSAgICB0eXBlLCBmYWNldCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yKTsKCQkgICAgfQoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJICAgIH0KCSAgICAvKgoJICAgICogTUFZQkUgVE9ETzogKEhtbSwgbm90IHJlYWxseSkgRGF0YXR5cGVzIHN0YXRlczoKCSAgICAqIEEgt2xpc3S3IGRhdGF0eXBlIGNhbiBiZSC3ZGVyaXZlZLcgZnJvbSBhbiC3YXRvbWljtyBkYXRhdHlwZQoJICAgICogd2hvc2Ugt2xleGljYWwgc3BhY2W3IGFsbG93cyBzcGFjZSAoc3VjaCBhcyBzdHJpbmcgb3IgYW55VVJJKW9yCgkgICAgKiBhILd1bmlvbrcgZGF0YXR5cGUgYW55IG9mIHdob3NlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30ncwoJICAgICogt2xleGljYWwgc3BhY2W3IGFsbG93cyBzcGFjZS4KCSAgICAqLwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48cmVzdHJpY3Rpb24gLi4uCgkgICAgKiBJLmUuIHRoZSB2YXJpZXR5IG9mICJsaXN0IiBpcyBpbmhlcml0ZWQuCgkgICAgKi8KCSAgICAvKgoJICAgICogMi4zLjIKCSAgICAqIDIuMy4yLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoISBXWFNfSVNfTElTVCh0eXBlLT5iYXNlVHlwZSkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYmFzZSB0eXBlICclcycgbXVzdCBiZSBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJICAgICogY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh0eXBlLT5iYXNlVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMiwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4yLjMgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQKCSAgICAqIGZyb20gdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0ncyB7aXRlbSB0eXBlIGRlZmluaXRpb259IGdpdmVuCgkgICAgKiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuCgkgICAgKi8KCSAgICB7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlSXRlbVR5cGU7CgoJCWJhc2VJdGVtVHlwZSA9IHR5cGUtPmJhc2VUeXBlLT5zdWJ0eXBlczsKCQlpZiAoKGJhc2VJdGVtVHlwZSA9PSBOVUxMKSB8fCAoISBXWFNfSVNfU0lNUExFKGJhc2VJdGVtVHlwZSkpKSB7CgkJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCQkiZmFpbGVkIHRvIGV2YWwgdGhlIGl0ZW0gdHlwZSBvZiBhIGJhc2UgdHlwZSIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJaWYgKChpdGVtVHlwZSAhPSBiYXNlSXRlbVR5cGUpICYmCgkJICAgICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKEFDVFhUX0NBU1QgcGN0eHQsIGl0ZW1UeXBlLAoJCQliYXNlSXRlbVR5cGUsIDApICE9IDApKSB7CgkJICAgIHhtbENoYXIgKnN0ckJJVCA9IE5VTEwsICpzdHJCVCA9IE5VTEw7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMywKCQkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkJIlRoZSBpdGVtIHR5cGUgJyVzJyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gIgoJCQkidGhlIGl0ZW0gdHlwZSAnJXMnIG9mIHRoZSBiYXNlIHR5cGUgJyVzJyIsCgkJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW1UeXBlKSwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckJJVCwgYmFzZUl0ZW1UeXBlKSwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckJULCB0eXBlLT5iYXNlVHlwZSkpOwoKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQklUKQoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJUKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMyk7CgkJfQoJICAgIH0KCgkgICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkJaW50IG9rID0gMTsKCQkvKgoJCSogMi4zLjIuNCBPbmx5IGxlbmd0aCwgbWluTGVuZ3RoLCBtYXhMZW5ndGgsIHdoaXRlU3BhY2UsIHBhdHRlcm4KCQkqIGFuZCBlbnVtZXJhdGlvbiBmYWNldCBjb21wb25lbnRzIGFyZSBhbGxvd2VkIGFtb25nIHRoZSB7ZmFjZXRzfS4KCQkqLwoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkJICAgIC8qCgkJCSAgICAqIFRPRE86IDIuNS4xLjIgTGlzdCBkYXRhdHlwZXMKCQkJICAgICogVGhlIHZhbHVlIG9mILd3aGl0ZVNwYWNltyBpcyBmaXhlZCB0byB0aGUgdmFsdWUgY29sbGFwc2UuCgkJCSAgICAqLwoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCQkgICAgYnJlYWs7CgkJCWRlZmF1bHQ6IHsKCQkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIocGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzQsCgkJCQl0eXBlLCBmYWNldCk7CgkJCSAgICAvKgoJCQkgICAgKiBXZSBjb3VsZCByZXR1cm4sIGJ1dCBpdCdzIG5pY2VyIHRvIHJlcG9ydCBhbGwKCQkJICAgICogaW52YWxpZCBmYWNldHMuCgkJCSAgICAqLwoJCQkgICAgb2sgPSAwOwoJCQl9CgkJICAgIH0KCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzQpOwoJCS8qCgkJKiBTUEVDICgyLjMuMi41KSAoc2FtZSBhcyAxLjMuMikKCQkqCgkJKiBOT1RFICgyLjMuMi41KSBUaGlzIGlzIGN1cnJlbnRseSBkb25lIGluCgkJKiB4bWxTY2hlbWFEZXJpdmVBbmRWYWxpZGF0ZUZhY2V0cygpCgkJKi8KCSAgICB9Cgl9CiAgICB9IGVsc2UgaWYgKFdYU19JU19VTklPTih0eXBlKSkgewoJLyoKCSogMy4xIFRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgYWxsIGhhdmUge3ZhcmlldHl9IG9mCgkqIGF0b21pYyBvciBsaXN0LgoJKi8KCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcjsKCgltZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQobWVtYmVyLT50eXBlKSkKCQl4bWxTY2hlbWFUeXBlRml4dXAobWVtYmVyLT50eXBlLCBBQ1RYVF9DQVNUIHBjdHh0KTsKCgkgICAgaWYgKCghIFdYU19JU19BVE9NSUMobWVtYmVyLT50eXBlKSkgJiYKCQkoISBXWFNfSVNfTElTVChtZW1iZXItPnR5cGUpKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18xLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIG1lbWJlciB0eXBlICclcycgaXMgbmVpdGhlciBhbiBhdG9taWMsIG5vciBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIG1lbWJlci0+dHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEpOwoJICAgIH0KCSAgICBtZW1iZXIgPSBtZW1iZXItPm5leHQ7Cgl9CgkvKgoJKiAzLjMuMSBJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyB0aGUgt3NpbXBsZSB1ci10eXBlCgkqIGRlZmluaXRpb263CgkqLwoJaWYgKHR5cGUtPmJhc2VUeXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSB7CgkgICAgLyoKCSAgICAqIDMuMy4xLjEgQWxsIG9mIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgaGF2ZSBhCgkgICAgKiB7ZmluYWx9IHdoaWNoIGRvZXMgbm90IGNvbnRhaW4gdW5pb24uCgkgICAgKi8KCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMobWVtYmVyLT50eXBlLAoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xLAoJCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCQkiVGhlICdmaW5hbCcgb2YgbWVtYmVyIHR5cGUgJyVzJyBjb250YWlucyAndW5pb24nIiwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgbWVtYmVyLT50eXBlKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMS4yIFRoZSB7ZmFjZXRzfSBtdXN0IGJlIGVtcHR5LgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJObyBmYWNldHMgYWxsb3dlZCIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMV8yKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAzLjMuMi4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiB1bmlvbi4KCSAgICAqIEkuZS4gdGhlIHZhcmlldHkgb2YgImxpc3QiIGlzIGluaGVyaXRlZC4KCSAgICAqLwoJICAgIGlmICghIFdYU19JU19VTklPTih0eXBlLT5iYXNlVHlwZSkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzEsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYmFzZSB0eXBlICclcycgaXMgbm90IGEgdW5pb24gdHlwZSIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIHJlc3RyaWN0aW9uLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHR5cGUtPmJhc2VUeXBlLAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlICdmaW5hbCcgb2YgaXRzIGJhc2UgdHlwZSAnJXMnIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzIpOwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuMyBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIsIG11c3QgYmUgdmFsaWRseQoJICAgICogZGVyaXZlZCBmcm9tIHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgZGVmaW5pdGlvbnMgaW4gdGhlIHtiYXNlCgkgICAgKiB0eXBlIGRlZmluaXRpb259J3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgZW1wdHkgc2V0LAoJICAgICogYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJICAgICovCgkgICAgewoJCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGJhc2VNZW1iZXI7CgoJCS8qCgkJKiBPUFRJTUlaRTogaWYgdGhlIHR5cGUgaXMgcmVzdHJpY3RpbmcsIGl0IGhhcyBubyBsb2NhbCBkZWZpbmVkCgkJKiBtZW1iZXIgdHlwZXMgYW5kIGluaGVyaXRzIHRoZSBtZW1iZXIgdHlwZXMgb2YgdGhlIGJhc2UgdHlwZTsKCQkqIHRodXMgYSBjaGVjayBmb3IgZXF1YWxpdHkgY2FuIGJlIHNraXBwZWQuCgkJKi8KCQkvKgoJCSogRXZlbiB3b3JzZTogSSBjYW5ub3Qgc2VlIGEgc2NlbmFyaW8gd2hlcmUgYSByZXN0cmljdGluZwoJCSogdW5pb24gc2ltcGxlIHR5cGUgY2FuIGhhdmUgb3RoZXIgbWVtYmVyIHR5cGVzIGFzIHRoZSBtZW1iZXIKCQkqIHR5cGVzIG9mIGl0J3MgYmFzZSB0eXBlLiBUaGlzIGNoZWNrIHNlZW1zIG5vdCBuZWNlc3Nhcnkgd2l0aAoJCSogcmVzcGVjdCB0byB0aGUgZGVyaXZhdGlvbiBwcm9jZXNzIGluIGxpYnhtbDIuCgkJKiBCdXQgbmVjZXNzYXJ5IGlmIGNvbnN0cnVjdGluZyB0eXBlcyB3aXRoIGFuIEFQSS4KCQkqLwoJCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKSB7CgkJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJCSAgICBiYXNlTWVtYmVyID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZS0+YmFzZVR5cGUpOwoJCSAgICBpZiAoKG1lbWJlciA9PSBOVUxMKSAmJiAoYmFzZU1lbWJlciAhPSBOVUxMKSkgewoJCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzIiwKCQkJICAgICJkaWZmZXJlbnQgbnVtYmVyIG9mIG1lbWJlciB0eXBlcyBpbiBiYXNlIik7CgkJICAgIH0KCQkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJCWlmIChiYXNlTWVtYmVyID09IE5VTEwpIHsKCQkJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCQkgICAgImRpZmZlcmVudCBudW1iZXIgb2YgbWVtYmVyIHR5cGVzIGluIGJhc2UiKTsKCQkJfSBlbHNlIGlmICgobWVtYmVyLT50eXBlICE9IGJhc2VNZW1iZXItPnR5cGUpICYmCgkJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhBQ1RYVF9DQVNUIHBjdHh0LAoJCQkJbWVtYmVyLT50eXBlLCBiYXNlTWVtYmVyLT50eXBlLCAwKSAhPSAwKSkgewoJCQkgICAgeG1sQ2hhciAqc3RyQk1UID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zLAoJCQkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkJCSJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgIgoJCQkJImRlcml2ZWQgZnJvbSBpdHMgY29ycmVzcG9uZGluZyBtZW1iZXIgIgoJCQkJInR5cGUgJXMgb2YgdGhlIGJhc2UgdHlwZSAlcyIsCgkJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBtZW1iZXItPnR5cGUpLAoJCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckJNVCwgYmFzZU1lbWJlci0+dHlwZSksCgkJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQlQsIHR5cGUtPmJhc2VUeXBlKSk7CgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyQk1UKQoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCVCkKCQkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zKTsKCQkJfQoJCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkJCWJhc2VNZW1iZXIgPSBiYXNlTWVtYmVyLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuNCBPbmx5IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlCgkgICAgKiBhbGxvd2VkIGFtb25nIHRoZSB7ZmFjZXRzfS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80LAoJCQkJdHlwZSwgZmFjZXQpOwoJCQlvayA9IDA7CgkJICAgIH0KCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQpOwoKCSAgICB9CgkgICAgLyoKCSAgICAqIFNQRUMgKDMuMy4yLjUpIChzYW1lIGFzIDEuMy4yKQoJICAgICoKCSAgICAqIE5PVEUgKDMuMy4yLjUpIFRoaXMgaXMgY3VycmVudGx5IGRvbmUgaW4KCSAgICAqIHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKCkKCSAgICAqLwoJfQogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1NSQ1NpbXBsZVR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBjcmMtc2ltcGxlLXR5cGUgY29uc3RyYWludHMuIAogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCiNpZiAwCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgLyoKICAgICogc3JjLXNpbXBsZS10eXBlLjEgVGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgaWYgYW55LAogICAgKiBtdXN0IHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBTaW1wbGUgVHlwZQogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy4xNC42KS4KICAgICovICAgIAogICAgaWYgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSkgewoJLyoKCSogc3JjLXNpbXBsZS10eXBlLjIgIklmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKCSogZWl0aGVyIGl0IG11c3QgaGF2ZSBhIGJhc2UgW2F0dHJpYnV0ZV0gb3IgYSA8c2ltcGxlVHlwZT4gYW1vbmcgaXRzCgkqIFtjaGlsZHJlbl0sIGJ1dCBub3QgYm90aC4iCgkqIE5PVEU6IFRoaXMgaXMgY2hlY2tlZCBpbiB0aGUgcGFyc2UgZnVuY3Rpb24gb2YgPHJlc3RyaWN0aW9uPi4KCSovCgkvKgoJKiAKCSovCiAgICB9IGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGUpKSB7CgkvKiBzcmMtc2ltcGxlLXR5cGUuMyAiSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIGVpdGhlciBpdCBtdXN0IGhhdmUKCSogYW4gaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb3IgYSA8c2ltcGxlVHlwZT4gYW1vbmcgaXRzIFtjaGlsZHJlbl0sCgkqIGJ1dCBub3QgYm90aC4iCgkqCgkqIE5PVEU6IFRoaXMgaXMgY2hlY2tlZCBpbiB0aGUgcGFyc2UgZnVuY3Rpb24gb2YgPGxpc3Q+LgoJKi8KICAgIH0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUpKSB7CQoJLyogCgkqIHNyYy1zaW1wbGUtdHlwZS40IGlzIGNoZWNrZWQgaW4geG1sU2NoZW1hQ2hlY2tVbmlvblR5cGVEZWZDaXJjdWxhcigpLgoJKi8KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KI2VuZGlmCgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCWN0eHQtPnZjdHh0ID0geG1sU2NoZW1hTmV3VmFsaWRDdHh0KE5VTEwpOwoJaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQsICIKCQkiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKGN0eHQtPnZjdHh0LAoJICAgIGN0eHQtPmVycm9yLCBjdHh0LT53YXJuaW5nLCBjdHh0LT5lcnJDdHh0KTsKCXhtbFNjaGVtYVNldFZhbGlkU3RydWN0dXJlZEVycm9ycyhjdHh0LT52Y3R4dCwKCSAgICBjdHh0LT5zZXJyb3IsIGN0eHQtPmVyckN0eHQpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgIHhtbFNjaGVtYVZhbFB0ciAqcmV0VmFsLAoJCQkgICAgIGludCBmaXJlRXJyb3JzLAoJCQkgICAgIGludCBub3JtYWxpemUsCgkJCSAgICAgaW50IGlzTm9ybWFsaXplZCk7CgovKioKICogeG1sU2NoZW1hUGFyc2VDaGVja0NPU1ZhbGlkRGVmYXVsdDoKICogQHBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWx1ZTogdGhlIGRlZmF1bHQgdmFsdWUKICogQG5vZGU6IGFuIG9wdGlvbmFsIG5vZGUgKHRoZSBob2xkZXIgb2YgdGhlIHZhbHVlKQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogKiAoY29zLXZhbGlkLWRlZmF1bHQpCiAqIFRoaXMgd2lsbCBiZSB1c2VkIGJ5IHRoZSBwYXJzZXIgb25seS4gRm9yIHRoZSB2YWxpZGF0b3IgdGhlcmUncwogKiBhbiBvdGhlciB2ZXJzaW9uLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlQ2hlY2tDT1NWYWxpZERlZmF1bHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkJICAgeG1sU2NoZW1hVmFsUHRyICp2YWwpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIGNvcy12YWxpZC1kZWZhdWx0OgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogICAgKiBGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0IHdpdGggcmVzcGVjdCB0byBhIHR5cGUKICAgICogZGVmaW5pdGlvbiB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBpZiBXWFNfSVNfQ09NUExFWCh0eXBlKSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIFNQRUMgKDIuMSkgIml0cyB7Y29udGVudCB0eXBlfSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgoJKiBvciBtaXhlZC4iCgkqIFNQRUMgKDIuMi4yKSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIG1peGVkLCB0aGVuIHRoZSB7Y29udGVudAoJKiB0eXBlfSdzIHBhcnRpY2xlIG11c3QgYmUgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBieQoJKiBQYXJ0aWNsZSBFbXB0aWFibGUgKKczLjkuNikuIgoJKi8KCWlmICgoISBXWFNfSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKSAmJgoJICAgICgoISBXWFNfSEFTX01JWEVEX0NPTlRFTlQodHlwZSkpIHx8ICghIFdYU19FTVBUSUFCTEUodHlwZSkpKSkgewoJICAgIC8qIE5PVEUgdGhhdCB0aGlzIGNvdmVycyAoMi4yLjIpIGFzIHdlbGwuICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfVkFMSURfREVGQVVMVF8yXzEsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgdHlwZS0+bm9kZSwKCQkiRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCwgdGhlIHR5cGUgZGVmaW5pdGlvbiAiCgkJIm11c3QgYmUgYSBzaW1wbGUgdHlwZSBvciBhIGNvbXBsZXggdHlwZSB3aXRoIG1peGVkIGNvbnRlbnQgIgoJCSJhbmQgYSBwYXJ0aWNsZSBlbXB0aWFibGUiLCBOVUxMKTsKCSAgICByZXR1cm4oWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIDEgSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIHN0cmluZwogICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZwogICAgKiBWYWxpZCAopzMuMTQuNCkuCiAgICAqCiAgICAqIEFORAogICAgKgogICAgKiAyLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZQogICAgKiBzdHJpbmcgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICAgICogYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgogICAgKi8KICAgIGlmIChXWFNfSVNfU0lNUExFKHR5cGUpKQoJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShBQ1RYVF9DQVNUIHBjdHh0LCBub2RlLAoJICAgIHR5cGUsIHZhbHVlLCB2YWwsIDEsIDEsIDApOwogICAgZWxzZSBpZiAoV1hTX0hBU19TSU1QTEVfQ09OVEVOVCh0eXBlKSkKCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoQUNUWFRfQ0FTVCBwY3R4dCwgbm9kZSwKCSAgICB0eXBlLT5jb250ZW50VHlwZURlZiwgdmFsdWUsIHZhbCwgMSwgMSwgMCk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7CgogICAgaWYgKHJldCA8IDApIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlQ2hlY2tDT1NWYWxpZERlZmF1bHQiLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ1RQcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKi4oNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCAoY3QtcHJvcHMtY29ycmVjdCkKICogU1RBVFVTOiAoc2VlbXMpIGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgLyoKICAgICogVE9ETzogQ29ycmVjdCB0aGUgZXJyb3IgY29kZTsgWE1MX1NDSEVNQVBfU1JDX0NUXzEgaXMgdXNlZCB0ZW1wb3JhcmlseS4KICAgICoKICAgICogU1BFQyAoMSkgIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBtdXN0CiAgICAqIGJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgQ29tcGxleCBUeXBlIERlZmluaXRpb24KICAgICogU2NoZW1hIENvbXBvbmVudCAopzMuNC4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZwogICAgKiBTdWItY29tcG9uZW50cyAopzUuMykuIgogICAgKi8KICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgJiYKCShXWFNfSVNfU0lNUExFKHR5cGUtPmJhc2VUeXBlKSkgJiYKCShXWFNfSVNfRVhURU5TSU9OKHR5cGUpID09IDApKSB7CgkvKgoJKiBTUEVDICgyKSAiSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLAoJKiB0aGUge2Rlcml2YXRpb24gbWV0aG9kfSBtdXN0IGJlIGV4dGVuc2lvbi4iCgkqLwoJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkgICAgTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwgCgkgICAgIklmIHRoZSBiYXNlIHR5cGUgaXMgYSBzaW1wbGUgdHlwZSwgdGhlIGRlcml2YXRpb24gbWV0aG9kIG11c3QgYmUgIgoJICAgICInZXh0ZW5zaW9uJyIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CiAgICB9CiAgICAvKgogICAgKiBTUEVDICgzKSAiQ2lyY3VsYXIgZGVmaW5pdGlvbnMgYXJlIGRpc2FsbG93ZWQsIGV4Y2VwdCBmb3IgdGhlILd1ci10eXBlCiAgICAqIGRlZmluaXRpb263LiBUaGF0IGlzLCBpdCBtdXN0IGJlIHBvc3NpYmxlIHRvIHJlYWNoIHRoZSC3dXItdHlwZQogICAgKiBkZWZpbml0aW9uIGJ5IHJlcGVhdGVkbHkgZm9sbG93aW5nIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LiIKICAgICoKICAgICogTk9URSAoMykgaXMgZG9uZSBpbiB4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhcigpLgogICAgKi8KICAgIC8qCiAgICAqIE5PVEUgdGhhdCAoNCkgYW5kICg1KSBuZWVkIHRoZSBmb2xsb3dpbmc6CiAgICAqICAgLSBhdHRyaWJ1dGUgdXNlcyBuZWVkIHRvIGJlIGFscmVhZHkgaW5oZXJpdGVkIChhcHBseSBhdHRyLiBwcm9oaWJpdGlvbnMpCiAgICAqICAgLSBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcyBuZWVkIHRvIGJlIGV4cGFuZGVkIGFscmVhZHkKICAgICogICAtIHNpbXBsZSB0eXBlcyBuZWVkIHRvIGJlIHR5cGVmaXhlZCBhbHJlYWR5CiAgICAqLyAgICAKICAgIGlmICh0eXBlLT5hdHRyVXNlcyAmJgoJKCgoeG1sU2NoZW1hSXRlbUxpc3RQdHIpIHR5cGUtPmF0dHJVc2VzKS0+bmJJdGVtcyA+IDEpKQogICAgewoJeG1sU2NoZW1hSXRlbUxpc3RQdHIgdXNlcyA9ICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgdHlwZS0+YXR0clVzZXM7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlLCB0bXA7CglpbnQgaSwgaiwgaGFzSWQgPSAwOwoKCWZvciAoaSA9IHVzZXMtPm5iSXRlbXMgLTE7IGkgPj0gMDsgaS0tKSB7CgkgICAgdXNlID0gdXNlcy0+aXRlbXNbaV07CgkgICAgCgkgICAgLyogCgkgICAgKiBTUEVDIGN0LXByb3BzLWNvcnJlY3QKCSAgICAqICg0KSAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlCgkgICAgKiB7YXR0cmlidXRlIHVzZXN9IG11c3Qgbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kCgkgICAgKiB7dGFyZ2V0IG5hbWVzcGFjZX1zLiIKCSAgICAqLwoJICAgIGlmIChpID4gMCkgewoJCWZvciAoaiA9IGkgLTE7IGogPj0gMDsgai0tKSB7CgkJICAgIHRtcCA9IHVzZXMtPml0ZW1zW2pdOwoJCSAgICBpZiAoKFdYU19BVFRSVVNFX0RFQ0xfTkFNRSh1c2UpID09CgkJCVdYU19BVFRSVVNFX0RFQ0xfTkFNRSh0bXApKSAmJgoJCQkoV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKSA9PQoJCQlXWFNfQVRUUlVTRV9ERUNMX1ROUyh0bXApKSkKCQkgICAgewoJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9BR19QUk9QU19DT1JSRUNULAoJCQkgICAgTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwKCQkJICAgICJEdXBsaWNhdGUgJXMiLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgdXNlKSwKCQkJICAgIE5VTEwpOwoJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCS8qCgkJCSogUmVtb3ZlIHRoZSBkdXBsaWNhdGUuCgkJCSovCgkJCWlmICh4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZSh1c2VzLCBpKSA9PSAtMSkKCQkJICAgIGdvdG8gZXhpdF9mYWlsdXJlOwoJCQlnb3RvIG5leHRfdXNlOwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogU1BFQyBjdC1wcm9wcy1jb3JyZWN0CgkgICAgKiAoNSkgIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZQoJICAgICoge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IG5vdCBoYXZlIHt0eXBlIGRlZmluaXRpb259cyB3aGljaAoJICAgICogYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuIgoJICAgICovCgkgICAgaWYgKFdYU19BVFRSVVNFX1RZUEVERUYodXNlKSAhPSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSgKCQkgICAgV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpLCBYTUxfU0NIRU1BU19JRCkpCgkJewkJCgkJICAgIGlmIChoYXNJZCkgewoJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCQkKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9BR19QUk9QU19DT1JSRUNULAoJCQkgICAgTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwKCQkJICAgICJUaGVyZSBtdXN0IG5vdCBleGlzdCBtb3JlIHRoYW4gb25lIGF0dHJpYnV0ZSAiCgkJCSAgICAiZGVjbGFyYXRpb24gb2YgdHlwZSAneHM6SUQnICIKCQkJICAgICIob3IgZGVyaXZlZCBmcm9tICd4czpJRCcpLiBUaGUgJXMgdmlvbGF0ZXMgdGhpcyAiCgkJCSAgICAiY29uc3RyYWludCIsCgkJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLCB1c2UpLAoJCQkgICAgTlVMTCk7CgkJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQkJaWYgKHhtbFNjaGVtYUl0ZW1MaXN0UmVtb3ZlKHVzZXMsIGkpID09IC0xKQoJCQkgICAgZ290byBleGl0X2ZhaWx1cmU7CgkJICAgIH0KCQkgICAgCgkJICAgIGhhc0lkID0gMTsKCQl9CgkgICAgfQpuZXh0X3VzZToge30KCX0KICAgIH0KICAgIHJldHVybiAoMCk7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXJlRXF1YWxUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVBLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVCKQp7CiAgICAvKgogICAgKiBUT0RPOiBUaGlzIHNob3VsZCBpbXBsZW1lbnQgY29tcG9uZW50LWlkZW50aXR5CiAgICAqIGluIHRoZSBmdXR1cmUuCiAgICAqLwogICAgaWYgKCh0eXBlQSA9PSBOVUxMKSB8fCAodHlwZUIgPT0gTlVMTCkpCglyZXR1cm4gKDApOwogICAgcmV0dXJuICh0eXBlQSA9PSB0eXBlQik7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU0NURGVyaXZlZE9LOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdG8tYmUgZGVyaXZlZCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAc2V0OiB0aGUgZ2l2ZW4gc2V0CiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAoY29zLWN0LWRlcml2ZWQtb2spCiAqCiAqIFNUQVRVUzogY29tcGxldGVkCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgb3IgMQogKiBpZiBub3QuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TQ1REZXJpdmVkT0soeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICAgIGludCBzZXQpCnsKICAgIGludCBlcXVhbCA9IHhtbFNjaGVtYUFyZUVxdWFsVHlwZXModHlwZSwgYmFzZVR5cGUpOwogICAgLyogVE9ETzogRXJyb3IgY29kZXMuICovCiAgICAvKgogICAgKiBTUEVDICJGb3IgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiAoY2FsbCBpdCBELCBmb3IgZGVyaXZlZCkKICAgICogdG8gYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gYSB0eXBlIGRlZmluaXRpb24gKGNhbGwgdGhpcwogICAgKiBCLCBmb3IgYmFzZSkgZ2l2ZW4gYSBzdWJzZXQgb2Yge2V4dGVuc2lvbiwgcmVzdHJpY3Rpb259CiAgICAqIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCiAgICAqLwogICAgaWYgKCEgZXF1YWwpIHsKCS8qCgkqIFNQRUMgKDEpICJJZiBCIGFuZCBEIGFyZSBub3QgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZQoJKiB7ZGVyaXZhdGlvbiBtZXRob2R9IG9mIEQgbXVzdCBub3QgYmUgaW4gdGhlIHN1YnNldC4iCgkqLwoJaWYgKCgoc2V0ICYgU1VCU0VUX0VYVEVOU0lPTikgJiYgKFdYU19JU19FWFRFTlNJT04odHlwZSkpKSB8fAoJICAgICgoc2V0ICYgU1VCU0VUX1JFU1RSSUNUSU9OKSAmJiAoV1hTX0lTX1JFU1RSSUNUSU9OKHR5cGUpKSkpCgkgICAgcmV0dXJuICgxKTsKICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDICgyLjEpICJCIGFuZCBEIG11c3QgYmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLiIKCSovCglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogU1BFQyAoMi4yKSAiQiBtdXN0IGJlIEQncyB7YmFzZSB0eXBlIGRlZmluaXRpb259LiIKICAgICovCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gYmFzZVR5cGUpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogU1BFQyAoMi4zLjEpICJEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBiZSB0aGUgt3VyLXR5cGUKICAgICogZGVmaW5pdGlvbrcuIgogICAgKi8KICAgIGlmIChXWFNfSVNfQU5ZVFlQRSh0eXBlLT5iYXNlVHlwZSkpCglyZXR1cm4gKDEpOwoKICAgIGlmIChXWFNfSVNfQ09NUExFWCh0eXBlLT5iYXNlVHlwZSkpIHsKCS8qCgkqIFNQRUMgKDIuMy4yLjEpICJJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4LCB0aGVuIGl0CgkqIG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0IGFzIGRlZmluZWQgYnkgdGhpcwoJKiBjb25zdHJhaW50LiIKCSovCglyZXR1cm4gKHhtbFNjaGVtYUNoZWNrQ09TQ1REZXJpdmVkT0soYWN0eHQsIHR5cGUtPmJhc2VUeXBlLAoJICAgIGJhc2VUeXBlLCBzZXQpKTsKICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDICgyLjMuMi4yKSAiSWYgRCdzIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgc2ltcGxlLCB0aGVuIGl0CgkqIG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0IGFzIGRlZmluZWQgaW4gVHlwZQoJKiBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSovCglyZXR1cm4gKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soYWN0eHQsIHR5cGUtPmJhc2VUeXBlLAoJICAgIGJhc2VUeXBlLCBzZXQpKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LOgogKiBAdHlwZTogIHRoZSBkZXJpdmVkIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGJhc2VUeXBlOiAgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENhbGxzOgogKiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgQU5EIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkKICoKICogQ2hlY2tzIHdoZXRlciBAdHlwZSBjYW4gYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gQGJhc2VUeXBlLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYW4gcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICBpbnQgc2V0KQp7CiAgICBpZiAoV1hTX0lTX1NJTVBMRSh0eXBlKSkKCXJldHVybiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhhY3R4dCwgdHlwZSwgYmFzZVR5cGUsIHNldCkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFDaGVja0NPU0NURGVyaXZlZE9LKGFjdHh0LCB0eXBlLCBiYXNlVHlwZSwgc2V0KSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqICgzLjQuNikgQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pIChjb3MtY3QtZXh0ZW5kcykKICoKICogU1RBVFVTOgogKiAgIG1pc3Npbmc6CiAqICAgICAoMS41KQogKiAgICAgKDEuNC4zLjIuMi4yKSAiUGFydGljbGUgVmFsaWQgKEV4dGVuc2lvbikiCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgLyoKICAgICogVE9ETzogQ29ycmVjdCB0aGUgZXJyb3IgY29kZTsgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xIGlzIHVzZWQKICAgICogdGVtcG9yYXJpbHkgb25seS4KICAgICovCiAgICAvKgogICAgKiBTUEVDICgxKSAiSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwKICAgICogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgogICAgKi8KICAgIGlmIChXWFNfSVNfQ09NUExFWChiYXNlKSkgewkKCS8qCgkqIFNQRUMgKDEuMSkgIlRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkqIGNvbnRhaW4gZXh0ZW5zaW9uLiIKCSovCglpZiAoYmFzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTikgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkiVGhlICdmaW5hbCcgb2YgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uICIKCQkiY29udGFpbnMgJ2V4dGVuc2lvbiciLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CgkKCS8qCgkqIEFUVEVOVElPTjogVGhlIGNvbnN0cmFpbnMgKDEuMikgYW5kICgxLjMpIGFyZSBub3QgYXBwbGllZCwKCSogc2luY2UgdGhleSBhcmUgYXV0b21hdGljYWxseSBzYXRpc2ZpZWQgdGhyb3VnaCB0aGUKCSogaW5oZXJpdGluZyBtZWNoYW5pc20uCgkqIE5vdGUgdGhhdCBldmVuIGlmIHJlZGVmaW5pbmcgY29tcG9uZW50cywgdGhlIGluaGVyaXRpbmcgbWVjaGFuaXNtCgkqIGlzIHVzZWQuCgkqLwojaWYgMAoJLyoKCSogU1BFQyAoMS4yKSAiSXRzIHthdHRyaWJ1dGUgdXNlc30gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUge2F0dHJpYnV0ZQoJKiB1c2VzfQoJKiBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmLCB0aGF0IGlzLCBmb3IgZXZlcnkgYXR0cmlidXRlCgkqIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSwgdGhlcmUKCSogbXVzdCBiZSBhbiBhdHRyaWJ1dGUgdXNlIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSBjb21wbGV4CgkqIHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIHRoZSBzYW1lCgkqIHtuYW1lfSwge3RhcmdldCBuYW1lc3BhY2V9IGFuZCB7dHlwZSBkZWZpbml0aW9ufSBhcyBpdHMgYXR0cmlidXRlCgkqIGRlY2xhcmF0aW9uIgoJKi8KCWlmIChiYXNlLT5hdHRyVXNlcyAhPSBOVUxMKSB7CgkgICAgaW50IGksIGosIGZvdW5kOwoJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2UsIGJ1c2U7CgoJICAgIGZvciAoaSA9IDA7IGkgPCAoV1hTX0xJU1RfQ0FTVCBiYXNlLT5hdHRyVXNlcyktPm5iSXRlbXM7IGkgKyspIHsKCQlidXNlID0gKFdYU19MSVNUX0NBU1QgYmFzZS0+YXR0clVzZXMpLT5pdGVtc1tpXTsKCQlmb3VuZCA9IDA7CgkJaWYgKHR5cGUtPmF0dHJVc2VzICE9IE5VTEwpIHsKCQkgICAgdXNlID0gKFdYU19MSVNUX0NBU1QgdHlwZS0+YXR0clVzZXMpLT5pdGVtc1tqXTsKCQkgICAgZm9yIChqID0gMDsgaiA8IChXWFNfTElTVF9DQVNUIHR5cGUtPmF0dHJVc2VzKS0+bmJJdGVtczsgaiArKykKCQkgICAgewoJCQlpZiAoKFdYU19BVFRSVVNFX0RFQ0xfTkFNRSh1c2UpID09CgkJCQlXWFNfQVRUUlVTRV9ERUNMX05BTUUoYnVzZSkpICYmCgkJCSAgICAoV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKSA9PQoJCQkJV1hTX0FUVFJVU0VfREVDTF9UTlMoYnVzZSkpICYmCgkJCSAgICAoV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpID09CgkJCQlXWFNfQVRUUlVTRV9UWVBFREVGKGJ1c2UpKQoJCQl7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJfQoJCWlmICghIGZvdW5kKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJCgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMiwKCQkJTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwKCQkJLyogCgkJCSogVE9ETzogVGhlIHJlcG9ydCBkb2VzIG5vdCBpbmRpY2F0ZSB0aGF0IGFsc28gdGhlCgkJCSogdHlwZSBuZWVkcyB0byBiZSB0aGUgc2FtZS4KCQkJKi8KCQkJIlRoaXMgdHlwZSBpcyBtaXNzaW5nIGEgbWF0Y2hpbmcgY29ycmVzcG9uZGVudCAiCgkJCSJmb3IgaXRzIHtiYXNlIHR5cGV9J3MgJXMgaW4gaXRzIHthdHRyaWJ1dGUgdXNlc30iLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLAoJCQkgICAgYnVzZS0+Y2hpbGRyZW4pLAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJfQoJICAgIH0KCX0KCS8qCgkqIFNQRUMgKDEuMykgIklmIGl0IGhhcyBhbiB7YXR0cmlidXRlIHdpbGRjYXJkfSwgdGhlIGNvbXBsZXggdHlwZQoJKiBkZWZpbml0aW9uIG11c3QgYWxzbyBoYXZlIG9uZSwgYW5kIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbidzCgkqIHthdHRyaWJ1dGUgIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldAoJKiBvZiB0aGUgY29tcGxleCAgdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlCgkqIGNvbnN0cmFpbnR9LCBhcyBkZWZpbmVkIGJ5IFdpbGRjYXJkIFN1YnNldCAopzMuMTAuNikuIgoJKi8KICAKCS8qCgkqIE1BWUJFIFRPRE86IEVuYWJsZSBpZiBldmVyIG5lZWRlZC4gQnV0IHRoaXMgd2lsbCBiZSBuZWVkZWQgb25seQoJKiBpZiBjcmVhdGVkIHRoZSB0eXBlIHZpYSBhIHNjaGVtYSBjb25zdHJ1Y3Rpb24gQVBJLgoJKi8KCWlmIChiYXNlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGNhcmQgPT0gTlVMTCkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkgICAgTlVMTCwgdHlwZSwKCQkgICAgIlRoZSBiYXNlICVzIGhhcyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQsICIKCQkgICAgImJ1dCB0aGlzIHR5cGUgaXMgbWlzc2luZyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQiLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLCBiYXNlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgoJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NOU1N1YnNldCgKCQliYXNlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpKQoJICAgIHsKCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCQoJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzMsCgkJICAgIE5VTEwsIHR5cGUsCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIKCQkgICAgInN1cGVyc2V0IG9mIHRoZSBvbmUgaW4gdGhlIGJhc2UgJXMiLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLCBiYXNlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgfQoJfQojZW5kaWYKCS8qCgkqIFNQRUMgKDEuNCkgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkqLwoJaWYgKCh0eXBlLT5jb250ZW50VHlwZURlZiAhPSBOVUxMKSAmJgoJICAgICh0eXBlLT5jb250ZW50VHlwZURlZiA9PSBiYXNlLT5jb250ZW50VHlwZURlZikpIHsKCSAgICAvKgoJICAgICogU1BFQyAoMS40LjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0KCSAgICAqIGFuZCB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZgoJICAgICogbXVzdCBiZSB0aGUgc2FtZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpICYmCgkgICAgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDEuNC4yKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIGJvdGggdGhlIHtiYXNlIHR5cGUKCSAgICAqIGRlZmluaXRpb259IGFuZCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmIG11c3QKCSAgICAqIGJlIGVtcHR5LiIKCSAgICAqIFBBU1MKCSAgICAqLwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogU1BFQyAoMS40LjMpICJBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJICAgICovCgkgICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCQkvKgoJCSogU1BFQyAxLjQuMy4xIFRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlCgkJKiBkZWZpbml0aW9uIGl0c2VsZiBtdXN0IHNwZWNpZnkgYSBwYXJ0aWNsZS4KCQkqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGNvbnRlbnQgdHlwZSBtdXN0IHNwZWNpZnkgYSBwYXJ0aWNsZSIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFNQRUMgKDEuNC4zLjIpICJPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJICAgICovCgkgICAgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCS8qCgkJKiBTUEVDICgxLjQuMy4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUKCQkqIGRlZmluaXRpb259IG11c3QgYmUgZW1wdHkuCgkJKiBQQVNTCgkJKi8KCSAgICB9IGVsc2UgewoJCS8qCgkJKiBTUEVDICgxLjQuMy4yLjIpICJBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJCSovCgkJaWYgKCh0eXBlLT5jb250ZW50VHlwZSAhPSBiYXNlLT5jb250ZW50VHlwZSkgfHwKCQkgICAgKCh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkJICAgICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKSkgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDEuNC4zLjIuMi4xKSAiQm90aCB7Y29udGVudCB0eXBlfXMgbXVzdCBiZSBtaXhlZAoJCSAgICAqIG9yIGJvdGggbXVzdCBiZSBlbGVtZW50LW9ubHkuIgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkJIlRoZSBjb250ZW50IHR5cGUgb2YgYm90aCwgdGhlIHR5cGUgYW5kIGl0cyBiYXNlICIKCQkJInR5cGUsIG11c3QgZWl0aGVyICdtaXhlZCcgb3IgJ2VsZW1lbnQtb25seSciLCBOVUxMKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJCX0KCQkvKgoJCSogVVJHRU5UIFRPRE8gU1BFQyAoMS40LjMuMi4yLjIpICJUaGUgcGFydGljbGUgb2YgdGhlCgkJKiBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBtdXN0IGJlIGEgt3ZhbGlkIGV4dGVuc2lvbrcKCQkqIG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3MgcGFydGljbGUsIGFzIGRlZmluZWQKCQkqIGluIFBhcnRpY2xlIFZhbGlkIChFeHRlbnNpb24pICinMy45LjYpLiIKCQkqCgkJKiBOT1RFIHRoYXQgd2Ugd29uJ3QgY2hlY2sgIlBhcnRpY2xlIFZhbGlkIChFeHRlbnNpb24pIiwKCQkqIHNpbmNlIGl0IGlzIGVuc3VyZWQgYnkgdGhlIGRlcml2YXRpb24gcHJvY2VzcyBpbgoJCSogeG1sU2NoZW1hVHlwZUZpeHVwKCkuIFdlIG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgd2hlbiBoZWFkaW5nCgkJKiBmb3IgYSBjb25zdHJ1Y3Rpb24gQVBJCgkJKiBUT0RPOiAhISBUaGlzIGlzIG5lZWRlZCB0byBiZSBjaGVja2VkIGlmIHJlZGVmaW5pbmcgYSB0eXBlICEhCgkJKi8KCSAgICB9CgkgICAgLyoKCSAgICAqIFVSR0VOVCBUT0RPICgxLjUpCgkgICAgKi8KCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDICgyKSAiSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLAoJKiB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkqLwoJaWYgKHR5cGUtPmNvbnRlbnRUeXBlRGVmICE9IGJhc2UpIHsKCSAgICAvKgoJICAgICogU1BFQyAoMi4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG11c3QgYmUgdGhlIHNhbWUgc2ltcGxlIHR5cGUKCSAgICAqIGRlZmluaXRpb24uIgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJUaGUgY29udGVudCB0eXBlIG11c3QgYmUgdGhlIHNpbXBsZSBiYXNlIHR5cGUiLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CglpZiAoYmFzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTikgewoJICAgIC8qCgkgICAgKiBTUEVDICgyLjIpICJUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJICAgICogY29udGFpbiBleHRlbnNpb24iCgkgICAgKiBOT1RFIHRoYXQgdGhpcyBpcyB0aGUgc2FtZSBhcyAoMS4xKS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkiVGhlICdmaW5hbCcgb2YgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uICIKCQkiY29udGFpbnMgJ2V4dGVuc2lvbiciLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqICgzLjQuNikgQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkgKGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24pCiAqCiAqIFNUQVRVUzoKICogICBtaXNzaW5nOgogKiAgICAgKDUuNC4yKSA/Pz8KICoKICogQVRURU5USU9OOgogKiBJbiBYTUwgU2NoZW1hIDEuMSB0aGlzIHdpbGwgYmU6CiAqIFZhbGlkYXRpb24gUnVsZTogQ2hlY2tpbmcgY29tcGxleCB0eXBlIHN1YnN1bXB0aW9uCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCiAgICAvKgogICAgKiBUT0RPOiBDb3JyZWN0IHRoZSBlcnJvciBjb2RlOyBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzEgaXMgdXNlZAogICAgKiB0ZW1wb3JhcmlseSBvbmx5LgogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmICghIFdYU19JU19DT01QTEVYKGJhc2UpKSB7Cgl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBjdHh0LAkgICAgCgkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8xLAoJICAgIHR5cGUtPm5vZGUsIFdYU19CQVNJQ19DQVNUIHR5cGUsCgkgICAgIlRoZSBiYXNlIHR5cGUgbXVzdCBiZSBhIGNvbXBsZXggdHlwZSIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuKGN0eHQtPmVycik7CiAgICB9CiAgICBpZiAoYmFzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSB7CgkvKgoJKiBTUEVDICgxKSAiVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhIGNvbXBsZXggdHlwZQoJKiBkZWZpbml0aW9uIHdob3NlIHtmaW5hbH0gZG9lcyBub3QgY29udGFpbiByZXN0cmljdGlvbi4iCgkqLwoJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwJICAgIAoJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMSwKCSAgICB0eXBlLT5ub2RlLCBXWFNfQkFTSUNfQ0FTVCB0eXBlLAoJICAgICJUaGUgJ2ZpbmFsJyBvZiB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gIgoJICAgICJjb250YWlucyAncmVzdHJpY3Rpb24nIiwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgKiBTUEVDICgyKSwgKDMpIGFuZCAoNCkKICAgICogVGhvc2UgYXJlIGhhbmRsZWQgaW4gYSBzZXBhcmF0ZSBmdW5jdGlvbiwgc2luY2UgdGhlCiAgICAqIHNhbWUgY29uc3RyYWludHMgYXJlIG5lZWRlZCBmb3IgcmVkZWZpbml0aW9uIG9mCiAgICAqIGF0dHJpYnV0ZSBncm91cHMgYXMgd2VsbC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbjJ0bzQoY3R4dCwKCVhNTF9TQ0hFTUFfQUNUSU9OX0RFUklWRSwKCVdYU19CQVNJQ19DQVNUIHR5cGUsIFdYU19CQVNJQ19DQVNUIGJhc2UsCgl0eXBlLT5hdHRyVXNlcywgYmFzZS0+YXR0clVzZXMsCgl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCWJhc2UtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKICAgIHsKCXJldHVybigtMSk7CiAgICB9CiAgICAvKgogICAgKiBTUEVDICg1KSAiT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICovCiAgICBpZiAoYmFzZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkgewoJLyoKCSogU1BFQyAoNS4xKSAiVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB0aGUKCSogt3VyLXR5cGUgZGVmaW5pdGlvbrcuIgoJKiBQQVNTCgkqLwogICAgfSBlbHNlIGlmICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwKCSAgICAodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgewoJLyoKCSogU1BFQyAoNS4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCgkqIG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIgoJKgoJKiBTUEVDICg1LjIuMikgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkqLwoJaWYgKChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fAoJICAgIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKQoJewoJICAgIGludCBlcnI7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuMi4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUKCSAgICAqIGRlZmluaXRpb259IG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGZyb20gd2hpY2gKCSAgICAqIHRoZSB7Y29udGVudCB0eXBlfSBpcyB2YWxpZGx5IGRlcml2ZWQgZ2l2ZW4gdGhlIGVtcHR5CgkgICAgKiBzZXQgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLiIKCSAgICAqCgkgICAgKiBBVFRFTlRJT04gVE9ETzogVGhpcyBzZWVtcyBub3QgbmVlZGVkIGlmIHRoZSB0eXBlIGltcGxpY2l0ZWx5CgkgICAgKiBkZXJpdmVkIGZyb20gdGhlIGJhc2UgdHlwZS4KCSAgICAqIAoJICAgICovCgkgICAgZXJyID0geG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhBQ1RYVF9DQVNUIGN0eHQsCgkJdHlwZS0+Y29udGVudFR5cGVEZWYsIGJhc2UtPmNvbnRlbnRUeXBlRGVmLCAwKTsKCSAgICBpZiAoZXJyICE9IDApIHsKCQl4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoKCQlpZiAoZXJyID09IC0xKQoJCSAgICByZXR1cm4oLTEpOwoJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMSwKCQkgICAgTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwKCQkgICAgIlRoZSB7Y29udGVudCB0eXBlfSAlcyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gdGhlICIKCQkgICAgImJhc2UgdHlwZSdzIHtjb250ZW50IHR5cGV9ICVzIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckEsCgkJCXR5cGUtPmNvbnRlbnRUeXBlRGVmKSwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckIsCgkJCWJhc2UtPmNvbnRlbnRUeXBlRGVmKSk7CgkJRlJFRV9BTkRfTlVMTChzdHJBKTsKCQlGUkVFX0FORF9OVUxMKHN0ckIpOwoJCXJldHVybihjdHh0LT5lcnIpOwoJICAgIH0KCX0gZWxzZSBpZiAoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCSAgICAoeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSgKCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIGJhc2UtPnN1YnR5cGVzKSkpIHsKCSAgICAvKgoJICAgICogU1BFQyAoNS4yLjIuMikgIlRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgbWl4ZWQKCSAgICAqIGFuZCBoYXZlIGEgcGFydGljbGUgd2hpY2ggaXMgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBpbgoJICAgICogUGFydGljbGUgRW1wdGlhYmxlICinMy45LjYpLiIKCSAgICAqIFBBU1MKCSAgICAqLwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8xLAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJIlRoZSBjb250ZW50IHR5cGUgb2YgdGhlIGJhc2UgdHlwZSBtdXN0IGJlIGVpdGhlciAiCgkJImEgc2ltcGxlIHR5cGUgb3IgJ21peGVkJyBhbmQgYW4gZW1wdGlhYmxlIHBhcnRpY2xlIiwgTlVMTCk7CgkgICAgcmV0dXJuIChjdHh0LT5lcnIpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCS8qCgkqIFNQRUMgKDUuMy4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUgaXRzZWxmIG11c3QKCSogYmUgZW1wdHkiCgkqLwoJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJICAgIC8qCgkgICAgKiBTUEVDICg1LjMuMi4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB7YmFzZSB0eXBlCgkgICAgKiBkZWZpbml0aW9ufSBtdXN0IGFsc28gYmUgZW1wdHkuIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgaWYgKCgoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSB8fAoJICAgIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKSAmJgoJICAgIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoCgkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlLT5zdWJ0eXBlcykpIHsKCSAgICAvKgoJICAgICogU1BFQyAoNS4zLjIuMikgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZQoJICAgICogZGVmaW5pdGlvbn0gbXVzdCBiZSBlbGVtZW50T25seSBvciBtaXhlZCBhbmQgaGF2ZSBhIHBhcnRpY2xlCgkgICAgKiB3aGljaCBpcyC3ZW1wdGlhYmxltyBhcyBkZWZpbmVkIGluIFBhcnRpY2xlIEVtcHRpYWJsZSAopzMuOS42KS4iCgkgICAgKiBQQVNTCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJUaGUgY29udGVudCB0eXBlIG9mIHRoZSBiYXNlIHR5cGUgbXVzdCBiZSBlaXRoZXIgIgoJCSJlbXB0eSBvciAnbWl4ZWQnIChvciAnZWxlbWVudHMtb25seScpIGFuZCBhbiBlbXB0aWFibGUgIgoJCSJwYXJ0aWNsZSIsIE5VTEwpOwoJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKCX0KICAgIH0gZWxzZSBpZiAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgfHwKCVdYU19IQVNfTUlYRURfQ09OVEVOVCh0eXBlKSkgewoJLyoKCSogU1BFQyAoNS40LjEuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KCSogaXRzZWxmIG11c3QgYmUgZWxlbWVudC1vbmx5IgoJKi8JIAoJaWYgKFdYU19IQVNfTUlYRURfQ09OVEVOVCh0eXBlKSAmJiAoISBXWFNfSEFTX01JWEVEX0NPTlRFTlQoYmFzZSkpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuNC4xLjIpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZQoJICAgICogZGVmaW5pdGlvbiBpdHNlbGYgYW5kIG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUKCSAgICAqIG1peGVkIgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJJZiB0aGUgY29udGVudCB0eXBlIGlzICdtaXhlZCcsIHRoZW4gdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgIgoJCSJiYXNlIHR5cGUgbXVzdCBhbHNvIGJlICdtaXhlZCciLCBOVUxMKTsKCSAgICByZXR1cm4gKGN0eHQtPmVycik7Cgl9CgkvKgoJKiBTUEVDICg1LjQuMikgIlRoZSBwYXJ0aWNsZSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmCgkqIG11c3QgYmUgYSC3dmFsaWQgcmVzdHJpY3Rpb263IG9mIHRoZSBwYXJ0aWNsZSBvZiB0aGUge2NvbnRlbnQKCSogdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBQYXJ0aWNsZSBWYWxpZAoJKiAoUmVzdHJpY3Rpb24pICinMy45LjYpLgoJKgoJKiBVUkdFTlQgVE9ETzogKDUuNC4yKQoJKi8KICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8xLAoJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkgICAgIlRoZSB0eXBlIGlzIG5vdCBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIGl0cyBiYXNlIHR5cGUiLCBOVUxMKTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NUQ29tcG9uZW50OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1RDb21wb25lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJldDsKICAgIC8qCiAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ1RQcm9wc0NvcnJlY3QoY3R4dCwgdHlwZSk7CiAgICBpZiAocmV0ICE9IDApCglyZXR1cm4gKHJldCk7CiAgICBpZiAoV1hTX0lTX0VYVEVOU0lPTih0eXBlKSkKCXJldCA9IHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzKGN0eHQsIHR5cGUpOwogICAgZWxzZQoJcmV0ID0geG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbihjdHh0LCB0eXBlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDQ1Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy40LjMpIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgQ29tcGxleCBUeXBlIERlZmluaXRpb25zOgogKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sgKHNyYy1jdCkKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NSQ0NUKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBUT0RPOiBBZGp1c3QgdGhlIGVycm9yIGNvZGVzIGhlcmUsIGFzIEkgdXNlZAogICAgKiBYTUxfU0NIRU1BUF9TUkNfQ1RfMSBvbmx5IHlldC4KICAgICovCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoISBXWFNfSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKSB7CgkvKgoJKiAxIElmIHRoZSA8Y29tcGxleENvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlIHR5cGUgZGVmaW5pdGlvbgoJKiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXQoJKiBtdXN0IGJlIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb247CgkqLwoJaWYgKCEgV1hTX0lTX0NPTVBMRVgoYmFzZSkpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCB0eXBlLT5ub2RlLAoJCSJJZiB1c2luZyA8Y29tcGxleENvbnRlbnQ+LCB0aGUgYmFzZSB0eXBlIGlzIGV4cGVjdGVkIHRvIGJlICIKCQkiYSBjb21wbGV4IHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyBpcyBhIHNpbXBsZSB0eXBlIiwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBiYXNlLT50YXJnZXROYW1lc3BhY2UsCgkJYmFzZS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMKCSogMiBJZiB0aGUgPHNpbXBsZUNvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgYWxsIG9mIHRoZQoJKiBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKiAyLjEgVGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUKCSogYmFzZSBbYXR0cmlidXRlXSBtdXN0IGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOgoJKi8KCWlmIChXWFNfSVNfU0lNUExFKGJhc2UpKSB7CgkgICAgaWYgKFdYU19JU19FWFRFTlNJT04odHlwZSkgPT0gMCkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJLyoKCQkqIDIuMS4zIG9ubHkgaWYgdGhlIDxleHRlbnNpb24+IGFsdGVybmF0aXZlIGlzIGFsc28KCQkqIGNob3NlbiwgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJCSovCgkJLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzFfMy4gKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiSWYgdXNpbmcgPHNpbXBsZUNvbnRlbnQ+IGFuZCA8cmVzdHJpY3Rpb24+LCB0aGUgYmFzZSAiCgkJICAgICJ0eXBlIG11c3QgYmUgYSBjb21wbGV4IHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyBpcyAiCgkJICAgICJhIHNpbXBsZSB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCQliYXNlLT5uYW1lKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKiBCYXNlIHR5cGUgaXMgYSBjb21wbGV4IHR5cGUuICovCgkgICAgaWYgKChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fAoJCShiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJLyoKCQkqIDIuMS4xIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0gaXMgYQoJCSogc2ltcGxlIHR5cGUgZGVmaW5pdGlvbjsKCQkqIFBBU1MKCQkqLwoJCWlmIChiYXNlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkiJyVzJywgYmFzZSB0eXBlIGhhcyBubyBjb250ZW50IHR5cGUiLAoJCQl0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJICAgIH0gZWxzZSBpZiAoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCQkoV1hTX0lTX1JFU1RSSUNUSU9OKHR5cGUpKSkgewoKCQkvKgoJCSogMi4xLjIgb25seSBpZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBhbHNvCgkJKiBjaG9zZW4sIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0KCQkqIGlzIG1peGVkIGFuZCBhIHBhcnRpY2xlIGVtcHRpYWJsZS4KCQkqLwoJCWlmICghIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoCgkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgYmFzZS0+c3VidHlwZXMpKSB7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX1NSQ19DVF8xOwoJCX0gZWxzZSAKCQkgICAgLyoKCQkgICAgKiBBdHRlbnRpb246IGF0IHRoaXMgcG9pbnQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBpcyBpbgoJCSAgICAqIC0+Y29udGVudFR5cGVEZWYgKHB1dCB0aGVyZSBkdXJpbmcgcGFyc2luZykuCgkJICAgICovCQkgICAgCgkJICAgIGlmICh0eXBlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogMi4yIElmIGNsYXVzZSAyLjEuMiBhYm92ZSBpcyBzYXRpc2ZpZWQsIHRoZW4gdGhlcmUKCQkgICAgKiBtdXN0IGJlIGEgPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mCgkJICAgICogPHJlc3RyaWN0aW9uPi4KCQkgICAgKi8KCQkgICAgLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzIuICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJCSJBIDxzaW1wbGVUeXBlPiBpcyBleHBlY3RlZCBhbW9uZyB0aGUgY2hpbGRyZW4gIgoJCQkib2YgPHJlc3RyaWN0aW9uPiwgaWYgPHNpbXBsZUNvbnRlbnQ+IGlzIHVzZWQgYW5kICIKCQkJInRoZSBiYXNlIHR5cGUgJyVzJyBpcyBhIGNvbXBsZXggdHlwZSIsCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkJYmFzZS0+bmFtZSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJfQoJICAgIH0gZWxzZSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfU1JDX0NUXzE7CgkgICAgfQoJfQoJaWYgKHJldCA+IDApIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIGlmIChXWFNfSVNfUkVTVFJJQ1RJT04odHlwZSkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiSWYgPHNpbXBsZUNvbnRlbnQ+IGFuZCA8cmVzdHJpY3Rpb24+IGlzIHVzZWQsIHRoZSAiCgkJICAgICJiYXNlIHR5cGUgbXVzdCBiZSBhIHNpbXBsZSB0eXBlIG9yIGEgY29tcGxleCB0eXBlIHdpdGggIgoJCSAgICAibWl4ZWQgY29udGVudCBhbmQgcGFydGljbGUgZW1wdGlhYmxlLiBUaGUgYmFzZSB0eXBlICIKCQkgICAgIiclcycgaXMgbm9uZSBvZiB0aG9zZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgYmFzZS0+bmFtZSkpOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIklmIDxzaW1wbGVDb250ZW50PiBhbmQgPGV4dGVuc2lvbj4gaXMgdXNlZCwgdGhlICIKCQkgICAgImJhc2UgdHlwZSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyAiCgkJICAgICJpcyBhIGNvbXBsZXggdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgYmFzZS0+bmFtZSkpOwoJICAgIH0KCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCX0KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDMpICJUaGUgY29ycmVzcG9uZGluZyBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBjb21wb25lbnQgbXVzdAogICAgKiBzYXRpc2Z5IHRoZSBjb25kaXRpb25zIHNldCBvdXQgaW4gQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlCiAgICAqIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjQuNik7IgogICAgKiBOT1RFICgzKSB3aWxsIGJlIGRvbmUgaW4geG1sU2NoZW1hVHlwZUZpeHVwKCkuCiAgICAqLwogICAgLyoKICAgICogU1BFQyAoNCkgSWYgY2xhdXNlIDIuMi4xIG9yIGNsYXVzZSAyLjIuMiBpbiB0aGUgY29ycmVzcG9uZGVuY2Ugc3BlY2lmaWNhdGlvbgogICAgKiBhYm92ZSBmb3Ige2F0dHJpYnV0ZSB3aWxkY2FyZH0gaXMgc2F0aXNmaWVkLCB0aGUgaW50ZW5zaW9uYWwKICAgICogaW50ZXJzZWN0aW9uIG11c3QgYmUgZXhwcmVzc2libGUsIGFzIGRlZmluZWQgaW4gQXR0cmlidXRlIFdpbGRjYXJkCiAgICAqIEludGVyc2VjdGlvbiAopzMuMTAuNikuCiAgICAqIE5PVEUgKDQpIGlzIGRvbmUgaW4geG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlcygpLgogICAgKi8KICAgIHJldHVybiAocmV0KTsKfQoKI2lmZGVmIEVOQUJMRV9QQVJUSUNMRV9SRVNUUklDVElPTgovKioKICogeG1sU2NoZW1hQ2hlY2tQYXJ0aWNsZVJhbmdlT0s6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogT2NjdXJyZW5jZSBSYW5nZSBPSyAocmFuZ2Utb2spCiAqCiAqIFNUQVRVUzogY29tcGxldGUKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhpbnQgcm1pbiwgaW50IHJtYXgsCgkJCSAgICAgIGludCBibWluLCBpbnQgYm1heCkKewogICAgaWYgKHJtaW4gPCBibWluKQoJcmV0dXJuICgxKTsKICAgIGlmICgoYm1heCAhPSBVTkJPVU5ERUQpICYmCgkocm1heCA+IGJtYXgpKQoJcmV0dXJuICgxKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1JDYXNlTmFtZUFuZFR5cGVPSzoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgcmVzdHJpY3RpbmcgZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZQogKiBAYjogdGhlIGJhc2UgZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgUmVzdHJpY3Rpb24gT0sgKEVsdDpFbHQgLS0gTmFtZUFuZFR5cGVPSykKICogKHJjYXNlLU5hbWVBbmRUeXBlT0spCiAqCiAqIFNUQVRVUzoKICogICBNSVNTSU5HICgzLjIuMykKICogICBDTEFSSUZZOiAoMy4yLjIpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZU5hbWVBbmRUeXBlT0soeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCQkgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtUiwgZWxlbUI7CgogICAgLyogVE9ETzogRXJyb3IgY29kZXMgKHJjYXNlLU5hbWVBbmRUeXBlT0spLiAqLwogICAgZWxlbVIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgci0+Y2hpbGRyZW47CiAgICBlbGVtQiA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBiLT5jaGlsZHJlbjsKICAgIC8qCiAgICAqIFNQRUMgKDEpICJUaGUgZGVjbGFyYXRpb25zJyB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zIGFyZQogICAgKiB0aGUgc2FtZS4iCiAgICAqLwogICAgaWYgKChlbGVtUiAhPSBlbGVtQikgJiYKCSgoISB4bWxTdHJFcXVhbChlbGVtUi0+bmFtZSwgZWxlbUItPm5hbWUpKSB8fAoJKCEgeG1sU3RyRXF1YWwoZWxlbVItPnRhcmdldE5hbWVzcGFjZSwgZWxlbUItPnRhcmdldE5hbWVzcGFjZSkpKSkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykgIT0gMCkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgzLjEpICJCb3RoIEIncyBkZWNsYXJhdGlvbidzIHtzY29wZX0gYW5kIFIncyBkZWNsYXJhdGlvbidzCiAgICAqIHtzY29wZX0gYXJlIGdsb2JhbC4iCiAgICAqLwogICAgaWYgKGVsZW1SID09IGVsZW1CKQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIFNQRUMgKDMuMi4xKSAiRWl0aGVyIEIncyB7bmlsbGFibGV9IGlzIHRydWUgb3IgUidzIHtuaWxsYWJsZX0gaXMgZmFsc2UuIgogICAgKi8KICAgIGlmICgoKGVsZW1CLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpID09IDApICYmCgkoZWxlbVItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkpCgkgcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDMuMi4yKSAiZWl0aGVyIEIncyBkZWNsYXJhdGlvbidzIHt2YWx1ZSBjb25zdHJhaW50fSBpcyBhYnNlbnQsCiAgICAqIG9yIGlzIG5vdCBmaXhlZCwgb3IgUidzIGRlY2xhcmF0aW9uJ3Mge3ZhbHVlIGNvbnN0cmFpbnR9IGlzIGZpeGVkCiAgICAqIHdpdGggdGhlIHNhbWUgdmFsdWUuIgogICAgKi8KICAgIGlmICgoZWxlbUItPnZhbHVlICE9IE5VTEwpICYmIChlbGVtQi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSAmJgoJKChlbGVtUi0+dmFsdWUgPT0gTlVMTCkgfHwKCSAoKGVsZW1SLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpID09IDApIHx8CgkgLyogVE9ETzogRXF1YWxpdHkgb2YgdGhlIGluaXRpYWwgdmFsdWUgb3Igbm9ybWFsaXplZCBvciBjYW5vbmljYWw/ICovCgkgKCEgeG1sU3RyRXF1YWwoZWxlbVItPnZhbHVlLCBlbGVtQi0+dmFsdWUpKSkpCgkgcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFRPRE86IFNQRUMgKDMuMi4zKSAiUidzIGRlY2xhcmF0aW9uJ3Mge2lkZW50aXR5LWNvbnN0cmFpbnQKICAgICogZGVmaW5pdGlvbnN9IGlzIGEgc3Vic2V0IG9mIEIncyBkZWNsYXJhdGlvbidzIHtpZGVudGl0eS1jb25zdHJhaW50CiAgICAqIGRlZmluaXRpb25zfSwgaWYgYW55LiIKICAgICovCiAgICBpZiAoZWxlbUItPmlkY3MgIT0gTlVMTCkgewoJLyogVE9ETyAqLwogICAgfQogICAgLyoKICAgICogU1BFQyAoMy4yLjQpICJSJ3MgZGVjbGFyYXRpb24ncyB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBpcyBhCiAgICAqIHN1cGVyc2V0IG9mIEIncyBkZWNsYXJhdGlvbidzIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9LiIKICAgICovCiAgICBpZiAoKChlbGVtQi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTikgJiYKCSAoKGVsZW1SLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OKSA9PSAwKSkgfHwKCSgoZWxlbUItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTikgJiYKCSAoKGVsZW1SLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKSB8fAoJKChlbGVtQi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTikgJiYKCSAoKGVsZW1SLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OKSA9PSAwKSkpCgkgcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDMuMi41KSAiUidzIHt0eXBlIGRlZmluaXRpb259IGlzIHZhbGlkbHkgZGVyaXZlZCBnaXZlbgogICAgKiB7ZXh0ZW5zaW9uLCBsaXN0LCB1bmlvbn0gZnJvbSBCJ3Mge3R5cGUgZGVmaW5pdGlvbn0iCiAgICAqCiAgICAqIEJBRFNQRUMgVE9ETzogV2hhdCdzIHRoZSBwb2ludCBvZiBhZGRpbmcgImxpc3QiIGFuZCAidW5pb24iIHRvIHRoZQogICAgKiBzZXQsIGlmIHRoZSBjb3JyZXNwb25kaW5nIGNvbnN0cmFpbnRzIGhhbmRsZSAicmVzdHJpY3Rpb24iIGFuZAogICAgKiAiZXh0ZW5zaW9uIiBvbmx5PwogICAgKgogICAgKi8KICAgIHsKCWludCBzZXQgPSAwOwoKCXNldCB8PSBTVUJTRVRfRVhURU5TSU9OOwoJc2V0IHw9IFNVQlNFVF9MSVNUOwoJc2V0IHw9IFNVQlNFVF9VTklPTjsKCWlmICh4bWxTY2hlbWFDaGVja0NPU0Rlcml2ZWRPSyhBQ1RYVF9DQVNUIGN0eHQsIGVsZW1SLT5zdWJ0eXBlcywKCSAgICBlbGVtQi0+c3VidHlwZXMsIHNldCkgIT0gMCkKCSAgICByZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VOU0NvbXBhdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgcmVzdHJpY3RpbmcgZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZQogKiBAYjogdGhlIGJhc2Ugd2lsZGNhcmQgcGFydGljbGUKICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFBhcnRpY2xlIERlcml2YXRpb24gT0sgKEVsdDpBbnkgLS0gTlNDb21wYXQpCiAqIChyY2FzZS1OU0NvbXBhdCkKICoKICogU1RBVFVTOiBjb21wbGV0ZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VOU0NvbXBhdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgLyogVE9ETzpFcnJvciBjb2RlcyAocmNhc2UtTlNDb21wYXQpLiAqLwogICAgLyoKICAgICogU1BFQyAiRm9yIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGUgdG8gYmUgYSC3dmFsaWQgcmVzdHJpY3Rpb263CiAgICAqIG9mIGEgd2lsZGNhcmQgcGFydGljbGUgYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICoKICAgICogU1BFQyAoMSkgIlRoZSBlbGVtZW50IGRlY2xhcmF0aW9uJ3Mge3RhcmdldCBuYW1lc3BhY2V9IGlzILd2YWxpZLcKICAgICogd2l0aCByZXNwZWN0IHRvIHRoZSB3aWxkY2FyZCdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gYXMgZGVmaW5lZCBieQogICAgKiBXaWxkY2FyZCBhbGxvd3MgTmFtZXNwYWNlIE5hbWUgKKczLjEwLjQpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZSgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGItPmNoaWxkcmVuLAoJKCh4bWxTY2hlbWFFbGVtZW50UHRyKSByLT5jaGlsZHJlbiktPnRhcmdldE5hbWVzcGFjZSkgIT0gMCkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykgIT0gMCkKCXJldHVybiAoMSk7CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlQXNJZkdyb3VwOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSByZXN0cmljdGluZyBlbGVtZW50IGRlY2xhcmF0aW9uIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSBtb2RlbCBncm91cCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoRWx0OkFsbC9DaG9pY2UvU2VxdWVuY2UgLS0gUmVjdXJzZUFzSWZHcm91cCkKICogKHJjYXNlLVJlY3Vyc2VBc0lmR3JvdXApCiAqCiAqIFNUQVRVUzogVE9ETwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlQXNJZkdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1SZWN1cnNlQXNJZkdyb3VwKS4gKi8KICAgIFRPRE8KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1JDYXNlTlNTdWJzZXQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIHJlc3RyaWN0aW5nIHdpbGRjYXJkIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSB3aWxkY2FyZCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoQW55OkFueSAtLSBOU1N1YnNldCkKICogKHJjYXNlLU5TU3Vic2V0KQogKgogKiBTVEFUVVM6IGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TU3Vic2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIsCgkJCQkgICAgaW50IGlzQW55VHlwZUJhc2UpCnsKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1OU1N1YnNldCkuICovCiAgICAvKgogICAgKiBTUEVDICgxKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMikgIlIncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IG11c3QgYmUgYW4gaW50ZW5zaW9uYWwgc3Vic2V0CiAgICAqIG9mIEIncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IGFzIGRlZmluZWQgYnkgV2lsZGNhcmQgU3Vic2V0ICinMy4xMC42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TTlNTdWJzZXQoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSByLT5jaGlsZHJlbiwKCSh4bWxTY2hlbWFXaWxkY2FyZFB0cikgYi0+Y2hpbGRyZW4pKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDMpICJVbmxlc3MgQiBpcyB0aGUgY29udGVudCBtb2RlbCB3aWxkY2FyZCBvZiB0aGUgt3VyLXR5cGUKICAgICogZGVmaW5pdGlvbrcsIFIncyB7cHJvY2VzcyBjb250ZW50c30gbXVzdCBiZSBpZGVudGljYWwgdG8gb3Igc3Ryb25nZXIKICAgICogdGhhbiBCJ3Mge3Byb2Nlc3MgY29udGVudHN9LCB3aGVyZSBzdHJpY3QgaXMgc3Ryb25nZXIgdGhhbiBsYXggaXMKICAgICogc3Ryb25nZXIgdGhhbiBza2lwLiIKICAgICovCiAgICBpZiAoISBpc0FueVR5cGVCYXNlKSB7CglpZiAoICgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHItPmNoaWxkcmVuKS0+cHJvY2Vzc0NvbnRlbnRzIDwKCSAgICAoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBiLT5jaGlsZHJlbiktPnByb2Nlc3NDb250ZW50cykKCSAgICByZXR1cm4gKDEpOwogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU1BhcnRpY2xlUmVzdHJpY3Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgVmFsaWQgKFJlc3RyaWN0aW9uKSAoY29zLXBhcnRpY2xlLXJlc3RyaWN0KQogKgogKiBTVEFUVVM6IFRPRE8KICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1BhcnRpY2xlUmVzdHJpY3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKnBhcnQgPSBXWFNfVFlQRV9QQVJUSUNMRSh0eXBlKTsKICAgIGJhc2VQYXJ0ID0gV1hTX1RZUEVfUEFSVElDTEUoYmFzZSk7CiAgICAqLwoKICAgIFRPRE8KCiAgICAvKgogICAgKiBTUEVDICgxKSAiVGhleSBhcmUgdGhlIHNhbWUgcGFydGljbGUuIgogICAgKi8KICAgIGlmIChyID09IGIpCglyZXR1cm4gKDApOwoKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHk6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIG1vZGVsIGdyb3VwIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSB3aWxkY2FyZCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoQWxsL0Nob2ljZS9TZXF1ZW5jZTpBbnkgLS0KICogICAgICAgICAgICAgICAgICAgICAgICAgTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eSkKICogKHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkpCiAqCiAqIFNUQVRVUzogVE9ETzogc3Vic3QtZ3JvdXBzCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJCSAgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgciwKCQkJCQkgICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnQ7CiAgICAvKiBUT0RPOiBFcnJvciBjb2RlcyAocmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eSkuICovCiAgICBpZiAoKHItPmNoaWxkcmVuID09IE5VTEwpIHx8IChyLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFNQRUMgIkZvciBhIGdyb3VwIHBhcnRpY2xlIHRvIGJlIGEgt3ZhbGlkIHJlc3RyaWN0aW9utyBvZiBhCiAgICAqIHdpbGRjYXJkIHBhcnRpY2xlLi4uIgogICAgKgogICAgKiBTUEVDICgxKSAiRXZlcnkgbWVtYmVyIG9mIHRoZSB7cGFydGljbGVzfSBvZiB0aGUgZ3JvdXAgaXMgYSC3dmFsaWQKICAgICogcmVzdHJpY3Rpb263IG9mIHRoZSB3aWxkY2FyZCBhcyBkZWZpbmVkIGJ5CiAgICAqIFBhcnRpY2xlIFZhbGlkIChSZXN0cmljdGlvbikgKKczLjkuNikuIgogICAgKi8KICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHItPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgIGRvIHsKCWlmICh4bWxTY2hlbWFDaGVja0NPU1BhcnRpY2xlUmVzdHJpY3QoY3R4dCwgcGFydCwgYikpCgkgICAgcmV0dXJuICgxKTsKCXBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQ7CiAgICB9IHdoaWxlIChwYXJ0ICE9IE5VTEwpOwogICAgLyoKICAgICogU1BFQyAoMikgIlRoZSBlZmZlY3RpdmUgdG90YWwgcmFuZ2Ugb2YgdGhlIGdyb3VwIFsuLi5dIGlzIGEKICAgICogdmFsaWQgcmVzdHJpY3Rpb24gb2YgQidzIG9jY3VycmVuY2UgcmFuZ2UgYXMgZGVmaW5lZCBieQogICAgKiBPY2N1cnJlbmNlIFJhbmdlIE9LICinMy45LjYpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tQYXJ0aWNsZVJhbmdlT0soCgkgICAgeG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHIpLAoJICAgIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heChyKSwKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykgIT0gMCkKCXJldHVybiAoMSk7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tSQ2FzZVJlY3Vyc2U6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIDxhbGw+IG9yIDxzZXF1ZW5jZT4gbW9kZWwgZ3JvdXAgcGFydGljbGUKICogQGI6IHRoZSBiYXNlIDxhbGw+IG9yIDxzZXF1ZW5jZT4gbW9kZWwgZ3JvdXAgcGFydGljbGUKICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFBhcnRpY2xlIERlcml2YXRpb24gT0sgKEFsbDpBbGwsU2VxdWVuY2U6U2VxdWVuY2UgLS0KICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVjdXJzZSkKICogKHJjYXNlLVJlY3Vyc2UpCiAqCiAqIFNUQVRVUzogID8KICogVE9ETzogc3Vic3QtZ3JvdXBzCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZVJlY3Vyc2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICAvKiB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0OyAqLwogICAgLyogVE9ETzogRXJyb3IgY29kZXMgKHJjYXNlLVJlY3Vyc2UpLiAqLwogICAgaWYgKChyLT5jaGlsZHJlbiA9PSBOVUxMKSB8fCAoYi0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShyLT5jaGlsZHJlbi0+dHlwZSAhPSBiLT5jaGlsZHJlbi0+dHlwZSkpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFNQRUMgIkZvciBhbiBhbGwgb3Igc2VxdWVuY2UgZ3JvdXAgcGFydGljbGUgdG8gYmUgYSC3dmFsaWQKICAgICogcmVzdHJpY3Rpb263IG9mIGFub3RoZXIgZ3JvdXAgcGFydGljbGUgd2l0aCB0aGUgc2FtZSB7Y29tcG9zaXRvcn0uLi4iCiAgICAqCiAgICAqIFNQRUMgKDEpICJSJ3Mgb2NjdXJyZW5jZSByYW5nZSBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEIncwogICAgKiBvY2N1cnJlbmNlIHJhbmdlIGFzIGRlZmluZWQgYnkgT2NjdXJyZW5jZSBSYW5nZSBPSyAopzMuOS42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKHItPm1pbk9jY3Vycywgci0+bWF4T2NjdXJzLAoJICAgIGItPm1pbk9jY3VycywgYi0+bWF4T2NjdXJzKSkKCXJldHVybiAoMSk7CgoKICAgIHJldHVybiAoMCk7Cn0KCiNlbmRpZgoKI2RlZmluZSBGQUNFVF9SRVNUUl9NVVRVQUxfRVJSKGZhYzEsIGZhYzIpIFwKICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsICAgICAgXAoJWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRSwgXAoJV1hTX0JBU0lDX0NBU1QgZmFjMSwgZmFjMS0+bm9kZSwgXAoJIkl0IGlzIGFuIGVycm9yIGZvciBib3RoICclcycgYW5kICclcycgdG8gYmUgc3BlY2lmaWVkIG9uIHRoZSAiXAoJInNhbWUgdHlwZSBkZWZpbml0aW9uIiwgXAoJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjMS0+dHlwZSksIFwKCUJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhYzItPnR5cGUpLCBOVUxMKTsKCiNkZWZpbmUgRkFDRVRfUkVTVFJfRVJSKGZhYzEsIG1zZykgXAogICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwgICAgICBcCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLCBcCglXWFNfQkFTSUNfQ0FTVCBmYWMxLCBmYWMxLT5ub2RlLCBcCgltc2csIE5VTEwpOwoKI2RlZmluZSBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZmFjKSBcCiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LCBcCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLCBcCglXWFNfQkFTSUNfQ0FTVCBmYWMsIGZhYy0+bm9kZSwgXAoJIlRoZSBiYXNlIHR5cGUncyBmYWNldCBpcyAnZml4ZWQnLCB0aHVzIHRoZSB2YWx1ZSBtdXN0IG5vdCAiIFwKCSJkaWZmZXIiLCBOVUxMKTsKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0MSwKCQkJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQyLAoJCQlpbnQgbGVzc0dyZWF0ZXIsCgkJCWludCBvckVxdWFsLAoJCQlpbnQgb2ZCYXNlKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMOwoKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQxLT50eXBlKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyBoYXMgdG8gYmUiKTsKICAgIGlmIChsZXNzR3JlYXRlciA9PSAwKQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBlcXVhbCB0byIpOwogICAgaWYgKGxlc3NHcmVhdGVyID09IDEpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIGdyZWF0ZXIgdGhhbiIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBsZXNzIHRoYW4iKTsKCiAgICBpZiAob3JFcXVhbCkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgb3IgZXF1YWwgdG8iKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgJyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQyLT50eXBlKSk7CiAgICBpZiAob2ZCYXNlKQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIicgb2YgdGhlIGJhc2UgdHlwZSIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiciKTsKCiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRSwKCVdYU19CQVNJQ19DQVNUIGZhY2V0MSwgTlVMTCwKCShjb25zdCBjaGFyICopIG1zZywgTlVMTCk7CgogICAgaWYgKG1zZyAhPSBOVUxMKQoJeG1sRnJlZShtc2cpOwp9CgovKgoqIHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzOgoqCiogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBSZXN0cmljdGlvbiAoRmFjZXRzKQoqIChzdC1yZXN0cmljdC1mYWNldHMpCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbmssIGN1ciwgbGFzdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgYmZhY2V0LAoJZmxlbmd0aCA9IE5VTEwsIGZ0b3RkaWcgPSBOVUxMLCBmZnJhY2RpZyA9IE5VTEwsCglmbWF4bGVuID0gTlVMTCwgZm1pbmxlbiA9IE5VTEwsIC8qIGZhY2V0cyBvZiB0aGUgY3VycmVudCB0eXBlICovCglmbWluaW5jID0gTlVMTCwgZm1heGluYyA9IE5VTEwsCglmbWluZXhjID0gTlVMTCwgZm1heGV4YyA9IE5VTEwsCgliZmxlbmd0aCA9IE5VTEwsIGJmdG90ZGlnID0gTlVMTCwgYmZmcmFjZGlnID0gTlVMTCwKCWJmbWF4bGVuID0gTlVMTCwgYmZtaW5sZW4gPSBOVUxMLCAvKiBmYWNldHMgb2YgdGhlIGJhc2UgdHlwZSAqLwoJYmZtaW5pbmMgPSBOVUxMLCBiZm1heGluYyA9IE5VTEwsCgliZm1pbmV4YyA9IE5VTEwsIGJmbWF4ZXhjID0gTlVMTDsKICAgIGludCByZXM7IC8qIGVyciA9IDAsIGZpeGVkRXJyOyAqLwoKICAgIC8qCiAgICAqIFNQRUMgc3QtcmVzdHJpY3QtZmFjZXRzIDE6CiAgICAqICJUaGUge3ZhcmlldHl9IG9mIFIgaXMgdGhlIHNhbWUgYXMgdGhhdCBvZiBCLiIgICAgCiAgICAqLwogICAgLyoKICAgICogU1BFQyBzdC1yZXN0cmljdC1mYWNldHMgMjoKICAgICogIklmIHt2YXJpZXR5fSBpcyBhdG9taWMsIHRoZSB7cHJpbWl0aXZlIHR5cGUgZGVmaW5pdGlvbn0KICAgICogb2YgUiBpcyB0aGUgc2FtZSBhcyB0aGF0IG9mIEIuIgogICAgKgogICAgKiBOT1RFOiB3ZSBsZWF2ZSAxICYgMiBvdXQgZm9yIG5vdywgc2luY2UgdGhpcyB3aWxsIGJlCiAgICAqIHNhdGlzZmllZCBieSB0aGUgZGVyaXZhdGlvbiBwcm9jZXNzLgogICAgKiBDT05TVFJVQ1RJT04gVE9ETzogTWF5YmUgbmVlZGVkIGlmIHVzaW5nIGEgY29uc3RydWN0aW9uIEFQSS4KICAgICovCiAgICAvKgogICAgKiBTUEVDIHN0LXJlc3RyaWN0LWZhY2V0cyAzOgogICAgKiAiVGhlIHtmYWNldHN9IG9mIFIgYXJlIHRoZSB1bmlvbiBvZiBTIGFuZCB0aGUge2ZhY2V0c30KICAgICogb2YgQiwgZWxpbWluYXRpbmcgZHVwbGljYXRlcy4gVG8gZWxpbWluYXRlIGR1cGxpY2F0ZXMsCiAgICAqIHdoZW4gYSBmYWNldCBvZiB0aGUgc2FtZSBraW5kIG9jY3VycyBpbiBib3RoIFMgYW5kIHRoZQogICAgKiB7ZmFjZXRzfSBvZiBCLCB0aGUgb25lIGluIHRoZSB7ZmFjZXRzfSBvZiBCIGlzIG5vdAogICAgKiBpbmNsdWRlZCwgd2l0aCB0aGUgZXhjZXB0aW9uIG9mIGVudW1lcmF0aW9uIGFuZCBwYXR0ZXJuCiAgICAqIGZhY2V0cywgZm9yIHdoaWNoIG11bHRpcGxlIG9jY3VycmVuY2VzIHdpdGggZGlzdGluY3QgdmFsdWVzCiAgICAqIGFyZSBhbGxvd2VkLiIKICAgICovCgogICAgaWYgKCh0eXBlLT5mYWNldFNldCA9PSBOVUxMKSAmJiAoYmFzZS0+ZmFjZXRTZXQgPT0gTlVMTCkpCglyZXR1cm4gKDApOwoKICAgIGxhc3QgPSB0eXBlLT5mYWNldFNldDsKICAgIGlmIChsYXN0ICE9IE5VTEwpCgl3aGlsZSAobGFzdC0+bmV4dCAhPSBOVUxMKQoJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwoKICAgIGZvciAoY3VyID0gdHlwZS0+ZmFjZXRTZXQ7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCWZhY2V0ID0gY3VyLT5mYWNldDsKCXN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCWZsZW5ndGggPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQlmbWlubGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CgkJZm1pbmluYyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgoJCWZtaW5leGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQlmbWF4bGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgkJZm1heGluYyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJCWZtYXhleGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJCWZ0b3RkaWcgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJCWZmcmFjZGlnID0gZmFjZXQ7IGJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBmb3IgKGN1ciA9IGJhc2UtPmZhY2V0U2V0OyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CglmYWNldCA9IGN1ci0+ZmFjZXQ7Cglzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQliZmxlbmd0aCA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCWJmbWlubGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CgkJYmZtaW5pbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCQliZm1pbmV4YyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJCWJmbWF4bGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgkJYmZtYXhpbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCQliZm1heGV4YyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CgkJYmZ0b3RkaWcgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJCWJmZnJhY2RpZyA9IGZhY2V0OyBicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogbGVuZ3RoIGFuZCBtaW5MZW5ndGggb3IgbWF4TGVuZ3RoICgyLjIpICsgKDMuMikKICAgICovCiAgICBpZiAoZmxlbmd0aCAmJiAoZm1pbmxlbiB8fCBmbWF4bGVuKSkgewoJRkFDRVRfUkVTVFJfRVJSKGZsZW5ndGgsICJJdCBpcyBhbiBlcnJvciBmb3IgYm90aCAnbGVuZ3RoJyBhbmQgIgoJICAgICJlaXRoZXIgb2YgJ21pbkxlbmd0aCcgb3IgJ21heExlbmd0aCcgdG8gYmUgc3BlY2lmaWVkIG9uICIKCSAgICAidGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uIikKICAgIH0KICAgIC8qCiAgICAqIE11dHVhbCBleGNsdXNpb25zIGluIHRoZSBzYW1lIGRlcml2YXRpb24gc3RlcC4KICAgICovCiAgICBpZiAoKGZtYXhpbmMpICYmIChmbWF4ZXhjKSkgewoJLyoKCSogU0NDICJtYXhJbmNsdXNpdmUgYW5kIG1heEV4Y2x1c2l2ZSIKCSovCglGQUNFVF9SRVNUUl9NVVRVQUxfRVJSKGZtYXhpbmMsIGZtYXhleGMpCiAgICB9CiAgICBpZiAoKGZtaW5pbmMpICYmIChmbWluZXhjKSkgewoJLyoKCSogU0NDICJtaW5JbmNsdXNpdmUgYW5kIG1pbkV4Y2x1c2l2ZSIKCSovCglGQUNFVF9SRVNUUl9NVVRVQUxfRVJSKGZtaW5pbmMsIGZtaW5leGMpCiAgICB9CgogICAgaWYgKGZsZW5ndGggJiYgYmZsZW5ndGgpIHsKCS8qCgkqIFNDQyAibGVuZ3RoIHZhbGlkIHJlc3RyaWN0aW9uIgoJKiBUaGUgdmFsdWVzIGhhdmUgdG8gYmUgZXF1YWwuCgkqLwoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbGVuZ3RoLT52YWwsIGJmbGVuZ3RoLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyAhPSAwKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbGVuZ3RoLCBiZmxlbmd0aCwgMCwgMCwgMSk7CglpZiAoKHJlcyAhPSAwKSAmJiAoYmZsZW5ndGgtPmZpeGVkKSkgewoJICAgIEZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbGVuZ3RoKQoJfQoKICAgIH0KICAgIGlmIChmbWlubGVuICYmIGJmbWlubGVuKSB7CgkvKgoJKiBTQ0MgIm1pbkxlbmd0aCB2YWxpZCByZXN0cmljdGlvbiIKCSogbWluTGVuZ3RoID49IEJBU0UgbWluTGVuZ3RoCgkqLwoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWlubGVuLT52YWwsIGJmbWlubGVuLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyA9PSAtMSkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmxlbiwgYmZtaW5sZW4sIDEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmbWlubGVuLT5maXhlZCkpIHsKCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1pbmxlbikKCX0KICAgIH0KICAgIGlmIChmbWF4bGVuICYmIGJmbWF4bGVuKSB7CgkvKgoJKiBTQ0MgIm1heExlbmd0aCB2YWxpZCByZXN0cmljdGlvbiIKCSogbWF4TGVuZ3RoIDw9IEJBU0UgbWluTGVuZ3RoCgkqLwoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4bGVuLT52YWwsIGJmbWF4bGVuLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyA9PSAxKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4bGVuLCBiZm1heGxlbiwgLTEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmbWF4bGVuLT5maXhlZCkpIHsKCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1heGxlbikKCX0KICAgIH0KICAgIC8qCiAgICAqIFNDQyAibGVuZ3RoIGFuZCBtaW5MZW5ndGggb3IgbWF4TGVuZ3RoIgogICAgKi8KICAgIGlmICghIGZsZW5ndGgpCglmbGVuZ3RoID0gYmZsZW5ndGg7CiAgICBpZiAoZmxlbmd0aCkgewoJaWYgKCEgZm1pbmxlbikKCSAgICBmbGVuZ3RoID0gYmZsZW5ndGg7CglpZiAoZm1pbmxlbikgewoJICAgIC8qICgxLjEpIGxlbmd0aCA+PSBtaW5MZW5ndGggKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZsZW5ndGgtPnZhbCwgZm1pbmxlbi0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZmxlbmd0aCwgZm1pbmxlbiwgMSwgMSwgMCk7Cgl9CglpZiAoISBmbWF4bGVuKQoJICAgIGZtYXhsZW4gPSBiZm1heGxlbjsKCWlmIChmbWF4bGVuKSB7CgkgICAgLyogKDIuMSkgbGVuZ3RoIDw9IG1heExlbmd0aCAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZmxlbmd0aC0+dmFsLCBmbWF4bGVuLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpCgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZsZW5ndGgsIGZtYXhsZW4sIC0xLCAxLCAwKTsKCX0KICAgIH0KICAgIGlmIChmbWF4aW5jKSB7CgkvKgoJKiAibWF4SW5jbHVzaXZlIgoJKi8KCWlmIChmbWluaW5jKSB7CgkgICAgLyogU0NDICJtYXhJbmNsdXNpdmUgPj0gbWluSW5jbHVzaXZlIiAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGluYy0+dmFsLCBmbWluaW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhpbmMsIGZtaW5pbmMsIDEsIDEsIDApOwoJICAgIH0KCX0KCS8qCgkqIFNDQyAibWF4SW5jbHVzaXZlIHZhbGlkIHJlc3RyaWN0aW9uIgoJKi8KCWlmIChiZm1heGluYykgewoJICAgIC8qIG1heEluY2x1c2l2ZSA8PSBCQVNFIG1heEluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGluYy0+dmFsLCBiZm1heGluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKQoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4aW5jLCBiZm1heGluYywgLTEsIDEsIDEpOwoJICAgIGlmICgocmVzICE9IDApICYmIChiZm1heGluYy0+Zml4ZWQpKSB7CgkJRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtYXhpbmMpCgkgICAgfQoJfQoJaWYgKGJmbWF4ZXhjKSB7CgkgICAgLyogbWF4SW5jbHVzaXZlIDwgQkFTRSBtYXhFeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhpbmMtPnZhbCwgYmZtYXhleGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGluYywgYmZtYXhleGMsIC0xLCAwLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5pbmMpIHsKCSAgICAvKiBtYXhJbmNsdXNpdmUgPj0gQkFTRSBtaW5JbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhpbmMtPnZhbCwgYmZtaW5pbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGluYywgYmZtaW5pbmMsIDEsIDEsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1pbmV4YykgewoJICAgIC8qIG1heEluY2x1c2l2ZSA+IEJBU0UgbWluRXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4aW5jLT52YWwsIGJmbWluZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGluYywgYmZtaW5leGMsIDEsIDAsIDEpOwoJICAgIH0KCX0KICAgIH0KICAgIGlmIChmbWF4ZXhjKSB7CgkvKgoJKiAibWF4RXhjbHVzaXZlID49IG1pbkV4Y2x1c2l2ZSIKCSovCglpZiAoZm1pbmV4YykgewoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGV4Yy0+dmFsLCBmbWluZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhleGMsIGZtaW5leGMsIDEsIDEsIDApOwoJICAgIH0KCX0KCS8qCgkqICJtYXhFeGNsdXNpdmUgdmFsaWQgcmVzdHJpY3Rpb24iCgkqLwoJaWYgKGJmbWF4ZXhjKSB7CgkgICAgLyogbWF4RXhjbHVzaXZlIDw9IEJBU0UgbWF4RXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4ZXhjLT52YWwsIGJmbWF4ZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGV4YywgYmZtYXhleGMsIC0xLCAxLCAxKTsKCSAgICB9CgkgICAgaWYgKChyZXMgIT0gMCkgJiYgKGJmbWF4ZXhjLT5maXhlZCkpIHsKCQlGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1heGV4YykKCSAgICB9Cgl9CglpZiAoYmZtYXhpbmMpIHsKCSAgICAvKiBtYXhFeGNsdXNpdmUgPD0gQkFTRSBtYXhJbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhleGMtPnZhbCwgYmZtYXhpbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4ZXhjLCBiZm1heGluYywgLTEsIDEsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1pbmluYykgewoJICAgIC8qIG1heEV4Y2x1c2l2ZSA+IEJBU0UgbWluSW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4ZXhjLT52YWwsIGJmbWluaW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGV4YywgYmZtaW5pbmMsIDEsIDAsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1pbmV4YykgewoJICAgIC8qIG1heEV4Y2x1c2l2ZSA+IEJBU0UgbWluRXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4ZXhjLT52YWwsIGJmbWluZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGV4YywgYmZtaW5leGMsIDEsIDAsIDEpOwoJICAgIH0KCX0KICAgIH0KICAgIGlmIChmbWluZXhjKSB7CgkvKgoJKiAibWluRXhjbHVzaXZlIDwgbWF4SW5jbHVzaXZlIgoJKi8KCWlmIChmbWF4aW5jKSB7CgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluZXhjLT52YWwsIGZtYXhpbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmV4YywgZm1heGluYywgLTEsIDAsIDApOwoJICAgIH0KCX0KCS8qCgkqICJtaW5FeGNsdXNpdmUgdmFsaWQgcmVzdHJpY3Rpb24iCgkqLwoJaWYgKGJmbWluZXhjKSB7CgkgICAgLyogbWluRXhjbHVzaXZlID49IEJBU0UgbWluRXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluZXhjLT52YWwsIGJmbWluZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5leGMsIGJmbWluZXhjLCAxLCAxLCAxKTsKCSAgICB9CgkgICAgaWYgKChyZXMgIT0gMCkgJiYgKGJmbWluZXhjLT5maXhlZCkpIHsKCQlGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1pbmV4YykKCSAgICB9Cgl9CglpZiAoYmZtYXhpbmMpIHsKCSAgICAvKiBtaW5FeGNsdXNpdmUgPD0gQkFTRSBtYXhJbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5leGMtPnZhbCwgYmZtYXhpbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluZXhjLCBiZm1heGluYywgLTEsIDEsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1pbmluYykgewoJICAgIC8qIG1pbkV4Y2x1c2l2ZSA+PSBCQVNFIG1pbkluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmV4Yy0+dmFsLCBiZm1pbmluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluZXhjLCBiZm1pbmluYywgMSwgMSwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWF4ZXhjKSB7CgkgICAgLyogbWluRXhjbHVzaXZlIDwgQkFTRSBtYXhFeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5leGMtPnZhbCwgYmZtYXhleGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmV4YywgYmZtYXhleGMsIC0xLCAwLCAxKTsKCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoZm1pbmluYykgewoJLyoKCSogIm1pbkluY2x1c2l2ZSA8IG1heEV4Y2x1c2l2ZSIKCSovCglpZiAoZm1heGV4YykgewoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBmbWF4ZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5pbmMsIGZtYXhleGMsIC0xLCAwLCAwKTsKCSAgICB9Cgl9CgkvKgoJKiAibWluRXhjbHVzaXZlIHZhbGlkIHJlc3RyaWN0aW9uIgoJKi8KCWlmIChiZm1pbmluYykgewoJICAgIC8qIG1pbkluY2x1c2l2ZSA+PSBCQVNFIG1pbkluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1pbmluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluaW5jLCBiZm1pbmluYywgMSwgMSwgMSk7CgkgICAgfQoJICAgIGlmICgocmVzICE9IDApICYmIChiZm1pbmluYy0+Zml4ZWQpKSB7CgkJRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtaW5pbmMpCgkgICAgfQoJfQoJaWYgKGJmbWF4aW5jKSB7CgkgICAgLyogbWluSW5jbHVzaXZlIDw9IEJBU0UgbWF4SW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluaW5jLT52YWwsIGJmbWF4aW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtYXhpbmMsIC0xLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5leGMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPiBCQVNFIG1pbkV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAxKQoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluaW5jLCBiZm1pbmV4YywgMSwgMCwgMSk7Cgl9CglpZiAoYmZtYXhleGMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPCBCQVNFIG1heEV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtYXhleGMsIC0xLCAwLCAxKTsKCX0KICAgIH0KICAgIGlmIChmdG90ZGlnICYmIGJmdG90ZGlnKSB7CgkvKgoJKiBTQ0MgIiB0b3RhbERpZ2l0cyB2YWxpZCByZXN0cmljdGlvbiIKCSogdG90YWxEaWdpdHMgPD0gQkFTRSB0b3RhbERpZ2l0cwoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZnRvdGRpZy0+dmFsLCBiZnRvdGRpZy0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgPT0gMSkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZnRvdGRpZywgYmZ0b3RkaWcsCgkgICAgLTEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmdG90ZGlnLT5maXhlZCkpIHsKCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZnRvdGRpZykKCX0KICAgIH0KICAgIGlmIChmZnJhY2RpZyAmJiBiZmZyYWNkaWcpIHsKCS8qCgkqIFNDQyAgImZyYWN0aW9uRGlnaXRzIHZhbGlkIHJlc3RyaWN0aW9uIgoJKiBmcmFjdGlvbkRpZ2l0cyA8PSBCQVNFIGZyYWN0aW9uRGlnaXRzCgkqLwoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmZnJhY2RpZy0+dmFsLCBiZmZyYWNkaWctPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzID09IDEpCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZmcmFjZGlnLCBiZmZyYWNkaWcsCgkgICAgLTEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmZnJhY2RpZy0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZmcmFjZGlnKQoJfQogICAgfQogICAgLyoKICAgICogU0NDICJmcmFjdGlvbkRpZ2l0cyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdG90YWxEaWdpdHMiCiAgICAqLwogICAgaWYgKCEgZnRvdGRpZykKCWZ0b3RkaWcgPSBiZnRvdGRpZzsKICAgIGlmICghIGZmcmFjZGlnKQoJZmZyYWNkaWcgPSBiZmZyYWNkaWc7CiAgICBpZiAoZnRvdGRpZyAmJiBmZnJhY2RpZykgewoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmZnJhY2RpZy0+dmFsLCBmdG90ZGlnLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyA9PSAxKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmZnJhY2RpZywgZnRvdGRpZywKCQktMSwgMSwgMCk7CiAgICB9CiAgICAvKgogICAgKiAqRW51bWVyYXRpb25zKiB3b24nIGJlIGFkZGVkIGhlcmUsIHNpbmNlIG9ubHkgdGhlIGZpcnN0IHNldAogICAgKiBvZiBlbnVtZXJhdGlvbnMgaW4gdGhlIGFuY2VzdG9yLW9yLXNlbGYgYXhpcyBpcyB1c2VkCiAgICAqIGZvciB2YWxpZGF0aW9uLCBwbHVzIHdlIG5lZWQgdG8gdXNlIHRoZSBiYXNlIHR5cGUgb2YgdGhvc2UKICAgICogZW51bWVyYXRpb25zIGZvciB3aGl0ZXNwYWNlLgogICAgKgogICAgKiAqUGF0dGVybnMqOiB3b24ndCBiZSBhZGQgaGVyZSwgc2luY2UgdGhleSBhcmUgT1JlZCBhdAogICAgKiB0eXBlIGxldmVsIGFuZCBBTkRlZCBhdCBhbmNlc3RvciBsZXZlbC4gVGhpcyB3aWxsCiAgICAqIGhhcHBlZCBkdXJpbmcgdmFsaWRhdGlvbiBieSB3YWxraW5nIHRoZSBiYXNlIGF4aXMKICAgICogb2YgdGhlIHR5cGUuCiAgICAqLwogICAgZm9yIChjdXIgPSBiYXNlLT5mYWNldFNldDsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJYmZhY2V0ID0gY3VyLT5mYWNldDsKCS8qCgkqIFNwZWNpYWwgaGFuZGxpbmcgb2YgZW51bWVyYXRpb25zIGFuZCBwYXR0ZXJucy4KCSogVE9ETzogaG1tLCB0aGV5IHNob3VsZCBub3QgYXBwZWFyIGluIHRoZSBzZXQsIHNvIHJlbW92ZSB0aGlzLgoJKi8KCWlmICgoYmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgfHwKCSAgICAoYmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pKQoJICAgIGNvbnRpbnVlOwoJLyoKCSogU2VhcmNoIGZvciBhIGR1cGxpY2F0ZSBmYWNldCBpbiB0aGUgY3VycmVudCB0eXBlLgoJKi8KCWxpbmsgPSB0eXBlLT5mYWNldFNldDsKCS8qIGVyciA9IDA7ICovCgkvKiBmaXhlZEVyciA9IDA7ICovCgl3aGlsZSAobGluayAhPSBOVUxMKSB7CgkgICAgZmFjZXQgPSBsaW5rLT5mYWNldDsKCSAgICBpZiAoZmFjZXQtPnR5cGUgPT0gYmZhY2V0LT50eXBlKSB7CgkJc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkJLyoKCQkJKiBUaGUgd2hpdGVzcGFjZSBtdXN0IGJlIHN0cm9uZ2VyLgoJCQkqLwoJCQlpZiAoZmFjZXQtPndoaXRlc3BhY2UgPCBiZmFjZXQtPndoaXRlc3BhY2UpIHsKCQkJICAgIEZBQ0VUX1JFU1RSX0VSUihmbGVuZ3RoLAoJCQkJIlRoZSAnd2hpdGVzcGFjZScgdmFsdWUgaGFzIHRvIGJlIGVxdWFsIHRvICIKCQkJCSJvciBzdHJvbmdlciB0aGFuIHRoZSAnd2hpdGVzcGFjZScgdmFsdWUgb2YgIgoJCQkJInRoZSBiYXNlIHR5cGUiKQoJCQl9CgkJCWlmICgoYmZhY2V0LT5maXhlZCkgJiYKCQkJICAgIChmYWNldC0+d2hpdGVzcGFjZSAhPSBiZmFjZXQtPndoaXRlc3BhY2UpKSB7CgkJCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZmFjZXQpCgkJCX0KCQkJYnJlYWs7CgkJICAgIGRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCQkvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJYnJlYWs7CgkgICAgfQoJICAgIGxpbmsgPSBsaW5rLT5uZXh0OwoJfQoJLyoKCSogSWYgbm8gZHVwbGljYXRlIHdhcyBmb3VuZDogYWRkIHRoZSBiYXNlIHR5cGVzJ3MgZmFjZXQKCSogdG8gdGhlIHNldC4KCSovCglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgbGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpCgkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldExpbmspKTsKCSAgICBpZiAobGluayA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCQkgICAgImRlcml2aW5nIGZhY2V0cywgY3JlYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGxpbmstPmZhY2V0ID0gY3VyLT5mYWNldDsKCSAgICBsaW5rLT5uZXh0ID0gTlVMTDsKCSAgICBpZiAobGFzdCA9PSBOVUxMKQoJCXR5cGUtPmZhY2V0U2V0ID0gbGluazsKCSAgICBlbHNlCgkJbGFzdC0+bmV4dCA9IGxpbms7CgkgICAgbGFzdCA9IGxpbms7Cgl9CgogICAgfQoKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMiLAoJImFuIGVycm9yIG9jY3VyZWQiKTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rLCBwcmV2TGluaywgc3ViTGluaywgbmV3TGluazsKICAgIC8qCiAgICAqIFRoZSBhY3R1YWwgdmFsdWUgaXMgdGhlbiBmb3JtZWQgYnkgcmVwbGFjaW5nIGFueSB1bmlvbiB0eXBlCiAgICAqIGRlZmluaXRpb24gaW4gdGhlILdleHBsaWNpdCBtZW1iZXJztyB3aXRoIHRoZSBtZW1iZXJzIG9mIHRoZWlyCiAgICAqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLgogICAgKgogICAgKiBUT0RPOiBUaGVyZSdzIGEgYnVnIGVudHJ5IGF0CiAgICAqICJodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3cteG1sLXNjaGVtYS1jb21tZW50cy8yMDA1SnVsU2VwLzAyODcuaHRtbCIKICAgICogd2hpY2ggaW5kaWNhdGVzIHRoYXQgd2UnbGwga2VlcCB0aGUgdW5pb24gdHlwZXMgdGhlIGZ1dHVyZS4KICAgICovCiAgICBsaW5rID0gdHlwZS0+bWVtYmVyVHlwZXM7CiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7CgoJaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChsaW5rLT50eXBlKSkKCSAgICB4bWxTY2hlbWFUeXBlRml4dXAobGluay0+dHlwZSwgQUNUWFRfQ0FTVCBwY3R4dCk7CgoJaWYgKFdYU19JU19VTklPTihsaW5rLT50eXBlKSkgewoJICAgIHN1YkxpbmsgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyhsaW5rLT50eXBlKTsKCSAgICBpZiAoc3ViTGluayAhPSBOVUxMKSB7CgkJbGluay0+dHlwZSA9IHN1YkxpbmstPnR5cGU7CgkJaWYgKHN1YkxpbmstPm5leHQgIT0gTlVMTCkgewoJCSAgICBsYXN0TGluayA9IGxpbmstPm5leHQ7CgkJICAgIHN1YkxpbmsgPSBzdWJMaW5rLT5uZXh0OwoJCSAgICBwcmV2TGluayA9IGxpbms7CgkJICAgIHdoaWxlIChzdWJMaW5rICE9IE5VTEwpIHsKCQkJbmV3TGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikKCQkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZUxpbmspKTsKCQkJaWYgKG5ld0xpbmsgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLAoJCQkJTlVMTCk7CgkJCSAgICByZXR1cm4gKC0xKTsKCQkJfQoJCQluZXdMaW5rLT50eXBlID0gc3ViTGluay0+dHlwZTsKCQkJcHJldkxpbmstPm5leHQgPSBuZXdMaW5rOwoJCQlwcmV2TGluayA9IG5ld0xpbms7CgkJCW5ld0xpbmstPm5leHQgPSBsYXN0TGluazsKCgkJCXN1YkxpbmsgPSBzdWJMaW5rLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCWxpbmsgPSBsaW5rLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwT3B0aW1GYWNldHMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgICAgIAogICAgaW50IGhhcyA9IDAsIG5lZWRWYWwgPSAwLCBub3JtVmFsID0gMDsKCiAgICBoYXMJPSAodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTKSA/IDEgOiAwOwogICAgaWYgKGhhcykgewoJbmVlZFZhbCA9ICh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJgoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFKSA/IDEgOiAwOwoJbm9ybVZhbCA9ICh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJgoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEKSA/IDEgOiAwOwogICAgfQogICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWM7CgkKCWZvciAoZmFjID0gdHlwZS0+ZmFjZXRzOyBmYWMgIT0gTlVMTDsgZmFjID0gZmFjLT5uZXh0KSB7CgkgICAgc3dpdGNoIChmYWMtPnR5cGUpIHsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJICAgIG5vcm1WYWwgPSAxOwoJCSAgICBoYXMgPSAxOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJICAgIG5lZWRWYWwgPSAxOwoJCSAgICBub3JtVmFsID0gMTsKCQkgICAgaGFzID0gMTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgaGFzID0gMTsKCQkgICAgYnJlYWs7CgkgICAgfQoJfQkKICAgIH0KICAgIGlmIChub3JtVmFsKQoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9OT1JNVkFMVUVORUVERUQ7CiAgICBpZiAobmVlZFZhbCkKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFOwogICAgaWYgKGhhcykKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUzsKCiAgICBpZiAoaGFzICYmICghIG5lZWRWYWwpICYmIFdYU19JU19BVE9NSUModHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgcHJpbSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHlwZSk7CgkvKgoJKiBPUFRJTUlaRSBWQUwgVE9ETzogU29tZSBmYWNldHMgbmVlZCBhIGNvbXB1dGVkIHZhbHVlLgoJKi8KCWlmICgocHJpbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkgJiYKCSAgICAocHJpbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfU1RSSU5HKSkgewoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFOwoJfSAJCiAgICB9ICAgICAgIAp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVR5cGVGaXh1cFdoaXRlc3BhY2UoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICAKICAgIAogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIHdoaXRlc3BhY2UtZmFjZXQgdmFsdWUuCiAgICAqLyAgICAKICAgIGlmIChXWFNfSVNfTElTVCh0eXBlKSkgewoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX0NPTExBUFNFOwoJcmV0dXJuICgwKTsKICAgIH0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUpKQoJcmV0dXJuICgwKTsKICAgIAogICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBsaW47CgoJZm9yIChsaW4gPSB0eXBlLT5mYWNldFNldDsgbGluICE9IE5VTEw7IGxpbiA9IGxpbi0+bmV4dCkgewoJICAgIGlmIChsaW4tPmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCXN3aXRjaCAobGluLT5mYWNldC0+d2hpdGVzcGFjZSkgewoJCWNhc2UgWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkU6CgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9QUkVTRVJWRTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOgoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUkVQTEFDRTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRToKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX0NPTExBUFNFOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJcmV0dXJuICgwKTsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBGb3IgYWxsILdhdG9taWO3IGRhdGF0eXBlcyBvdGhlciB0aGFuIHN0cmluZyAoYW5kIHR5cGVzILdkZXJpdmVktyAKICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0byAKICAgICogY29sbGFwc2UKICAgICovCiAgICB7Cgl4bWxTY2hlbWFUeXBlUHRyIGFuYzsKCglmb3IgKGFuYyA9IHR5cGUtPmJhc2VUeXBlOyBhbmMgIT0gTlVMTCAmJiAKCQlhbmMtPmJ1aWx0SW5UeXBlICE9IFhNTF9TQ0hFTUFTX0FOWVRZUEU7CgkJYW5jID0gYW5jLT5iYXNlVHlwZSkgewoKCSAgICBpZiAoYW5jLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCWlmIChhbmMtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PUk1TVFJJTkcpIHsJICAgIAoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUkVQTEFDRTsKCgkJfSBlbHNlIGlmICgoYW5jLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHx8CgkJICAgIChhbmMtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSB7CQkgICAgCgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9QUkVTRVJWRTsKCgkJfSBlbHNlCgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9DT0xMQVBTRTsKCQlicmVhazsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpeHVwU2ltcGxlVHlwZVN0YWdlT25lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKQoJcmV0dXJuKDApOwogICAgaWYgKCEgV1hTX0lTX1RZUEVfTk9UX0ZJWEVEXzEodHlwZSkpCglyZXR1cm4oMCk7CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJWFVQXzE7CgogICAgaWYgKFdYU19JU19MSVNUKHR5cGUpKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8c2ltcGxlVHlwZT48bGlzdD4uLi4KCSovCglpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUaGlzIG9uZSBpcyByZWFsbHkgbmVlZGVkLCBzbyBnZXQgb3V0LgoJICAgICovCgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VPbmUiLAoJCSJsaXN0IHR5cGUgaGFzIG5vIGl0ZW0tdHlwZSBhc3NpZ25lZCIpOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9IGVsc2UgaWYgKFdYU19JU19VTklPTih0eXBlKSkgewoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPHNpbXBsZVR5cGU+PHVuaW9uPi4uLgoJKi8JCglpZiAodHlwZS0+bWVtYmVyVHlwZXMgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUaGlzIG9uZSBpcyByZWFsbHkgbmVlZGVkLCBzbyBnZXQgb3V0LgoJICAgICovCgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VPbmUiLAoJCSJ1bmlvbiB0eXBlIGhhcyBubyBtZW1iZXItdHlwZXMgYXNzaWduZWQiKTsKCSAgICByZXR1cm4oLTEpOwoJfQkgICAgCiAgICB9IGVsc2UgeyAgICAKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbj4uLi4KCSovCglpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUZpeHVwU2ltcGxlVHlwZVN0YWdlT25lIiwKCQkidHlwZSBoYXMgbm8gYmFzZS10eXBlIGFzc2lnbmVkIik7CgkgICAgcmV0dXJuKC0xKTsKCX0KCWlmIChXWFNfSVNfVFlQRV9OT1RfRklYRURfMSh0eXBlLT5iYXNlVHlwZSkpCgkgICAgaWYgKHhtbFNjaGVtYUZpeHVwU2ltcGxlVHlwZVN0YWdlT25lKHBjdHh0LCB0eXBlLT5iYXNlVHlwZSkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCS8qCgkqIFZhcmlldHkKCSogSWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIHRoZQoJKiB7dmFyaWV0eX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkqLwoJaWYgKFdYU19JU19BVE9NSUModHlwZS0+YmFzZVR5cGUpKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUM7CgllbHNlIGlmIChXWFNfSVNfTElTVCh0eXBlLT5iYXNlVHlwZSkpIHsKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVDsKCSAgICAvKgoJICAgICogSW5oZXJpdCB0aGUgaXRlbVR5cGUuCgkgICAgKi8KCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHR5cGUtPmJhc2VUeXBlLT5zdWJ0eXBlczsKCX0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUtPmJhc2VUeXBlKSkgewoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsKCSAgICAvKgoJICAgICogTk9URSB0aGF0IHdlIHdvbid0IGFzc2lnbiB0aGUgbWVtYmVyVHlwZXMgb2YgdGhlIGJhc2UsCgkgICAgKiBzaW5jZSB0aGlzIHdpbGwgbWFrZSB0cm91YmxlIHdoZW4gZnJlZWluZyB0aGVtOyB3ZSB3aWxsCgkgICAgKiB1c2UgYSBsb29rdXAgZnVuY3Rpb24gdG8gYWNjZXNzIHRoZW0gaW5zdGVhZC4KCSAgICAqLwoJfQogICAgfQogICAgcmV0dXJuKDApOwp9CgojaWZkZWYgREVCVUdfVFlQRQpzdGF0aWMgdm9pZAp4bWxTY2hlbWFEZWJ1Z0ZpeGVkVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlLT5ub2RlICE9IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIlR5cGUgb2YgJXMgOiAlczolZCA6IiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bm9kZS0+ZG9jLT5VUkwsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEdldExpbmVObyh0eXBlLT5ub2RlKSk7CiAgICB9IGVsc2UgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiVHlwZSBvZiAlcyA6IiwgbmFtZSk7CiAgICB9CiAgICBpZiAoKFdYU19JU19TSU1QTEUodHlwZSkpIHx8IChXWFNfSVNfQ09NUExFWCh0eXBlKSkpIHsKCXN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJzaW1wbGVcbiIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZWxlbWVudHNcbiIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJ1bmtub3duICEhIVxuIik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbXB0eVxuIik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CgkJaWYgKHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKQoJCSAgICB0eXBlLT5zdWJ0eXBlcykpCgkJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkibWl4ZWQgYXMgZW1wdGlhYmxlIHBhcnRpY2xlXG4iKTsKCQllbHNlCgkJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWRcbiIpOwoJCWJyZWFrOwoJCS8qIFJlbW92ZWQsIHNpbmNlIG5vdCB1c2VkLiAqLwoJCS8qCgkJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZCBvciBlbGVtc1xuIik7CgkJYnJlYWs7CgkJKi8KCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImJhc2ljXG4iKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAibm90IHJlZ2lzdGVyZWQgISEhXG4iKTsKCQlicmVhazsKCX0KICAgIH0KfQojZW5kaWYKCi8qCiogMy4xNC42IENvbnN0cmFpbnRzIG9uIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMKKi8Kc3RhdGljIGludAp4bWxTY2hlbWFGaXh1cFNpbXBsZVR5cGVTdGFnZVR3byh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJlcywgb2xkZXJycyA9IHBjdHh0LT5uYmVycm9yczsKCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKQoJcmV0dXJuKC0xKTsKCiAgICBpZiAoISBXWFNfSVNfVFlQRV9OT1RfRklYRUQodHlwZSkpCglyZXR1cm4oMCk7CgogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9SRVNPTFZFRDsKICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VUd28iLAoJICAgICJtaXNzaW5nIGJhc2VUeXBlIik7Cglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIH0KICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQodHlwZS0+YmFzZVR5cGUpKQoJeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGUtPmJhc2VUeXBlLCBBQ1RYVF9DQVNUIHBjdHh0KTsKICAgIC8qIAogICAgKiBJZiBhIG1lbWJlciB0eXBlIG9mIGEgdW5pb24gaXMgYSB1bmlvbiBpdHNlbGYsIHdlIG5lZWQgdG8gc3Vic3RpdHV0ZQogICAgKiB0aGF0IG1lbWJlciB0eXBlIGZvciBpdHMgbWVtYmVyIHR5cGVzLgogICAgKiBOT1RFIHRoYXQgdGhpcyBtaWdodCBjaGFuZ2UgaW4gV1hTIDEuMTsgaS5lLiB3ZSB3aWxsIGtlZXAgdGhlIHVuaW9uCiAgICAqIHR5cGVzIGluIFdYUyAxLjEuCiAgICAqLwogICAgaWYgKCh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKSAmJgoJKHhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KHBjdHh0LCB0eXBlKSA9PSAtMSkpCglyZXR1cm4oLTEpOyAgICAgICAgCiAgICAvKgogICAgKiBTUEVDIHNyYy1zaW1wbGUtdHlwZSAxIAogICAgKiAiVGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgaWYgYW55LCBtdXN0IHNhdGlzZnkKICAgICogdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uCiAgICAqIFNjaGVtYSBDb21wb25lbnRzICinMy4xNC42KS4iCiAgICAqLwogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKiAoc3QtcHJvcHMtY29ycmVjdCkKICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KHBjdHh0LCB0eXBlKTsKICAgIEhGQUlMVVJFIEhFUlJPUgogICAgLyogCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIFNpbXBsZSkKICAgICogKGNvcy1zdC1yZXN0cmljdHMpCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyhwY3R4dCwgdHlwZSk7CiAgICBIRkFJTFVSRSBIRVJST1IKICAgIC8qCiAgICAqIFRPRE86IFJlbW92ZWQgdGhlIGVycm9yIHJlcG9ydCwgc2luY2UgaXQgZ290IGFubm95aW5nIHRvIGdldCBhbgogICAgKiBleHRyYSBlcnJvciByZXBvcnQsIGlmIGFueXRoaW5nIGZhaWxlZCB1bnRpbCBub3cuCiAgICAqIEVuYWJsZSB0aGlzIGlmIG5lZWRlZC4KICAgICoKICAgICogeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAogICAgKiAgICBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMSwKICAgICogICAgIlNpbXBsZSB0eXBlICclcycgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY29uc3RyYWludHMgIgogICAgKiAgICAib24gc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMuXG4iLAogICAgKiAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgICovCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFNpbXBsZSBUeXBlIFJlc3RyaWN0aW9uIChGYWNldHMpCiAgICAqIChzdC1yZXN0cmljdC1mYWNldHMpCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh0eXBlLCBwY3R4dCk7CiAgICBIRkFJTFVSRSBIRVJST1IKICAgIGlmICgodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgfHwKCSh0eXBlLT5iYXNlVHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCXJlcyA9IHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKHBjdHh0LCB0eXBlKTsKCUhGQUlMVVJFIEhFUlJPUgogICAgfQogICAgLyoKICAgICogV2hpdGVzcGFjZSB2YWx1ZS4KICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFUeXBlRml4dXBXaGl0ZXNwYWNlKHR5cGUpOwogICAgSEZBSUxVUkUgSEVSUk9SCiAgICB4bWxTY2hlbWFUeXBlRml4dXBPcHRpbUZhY2V0cyh0eXBlKTsgICAgCgpleGl0X2Vycm9yOgojaWZkZWYgREVCVUdfVFlQRQogICAgeG1sU2NoZW1hRGVidWdGaXhlZFR5cGUocGN0eHQsIHR5cGUpOwojZW5kaWYKICAgIGlmIChvbGRlcnJzICE9IHBjdHh0LT5uYmVycm9ycykKCXJldHVybihwY3R4dC0+ZXJyKTsKICAgIHJldHVybigwKTsKCmV4aXRfZmFpbHVyZToKI2lmZGVmIERFQlVHX1RZUEUKICAgIHhtbFNjaGVtYURlYnVnRml4ZWRUeXBlKHBjdHh0LCB0eXBlKTsKI2VuZGlmCiAgICByZXR1cm4oLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpeHVwQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGludCByZXMgPSAwLCBvbGRlcnJzID0gcGN0eHQtPm5iZXJyb3JzOwogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoKICAgIGlmICghIFdYU19JU19UWVBFX05PVF9GSVhFRCh0eXBlKSkKCXJldHVybigwKTsKICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfUkVTT0xWRUQ7CiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hRml4dXBDb21wbGV4VHlwZSIsCgkgICAgIm1pc3NpbmcgYmFzZVR5cGUiKTsKCWdvdG8gZXhpdF9mYWlsdXJlOwogICAgfSAgICAKICAgIC8qCiAgICAqIEZpeHVwIHRoZSBiYXNlIHR5cGUuCiAgICAqLwogICAgaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChiYXNlVHlwZSkpCgl4bWxTY2hlbWFUeXBlRml4dXAoYmFzZVR5cGUsIEFDVFhUX0NBU1QgcGN0eHQpOwogICAgaWYgKGJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfSU5WQUxJRCkgewoJLyoKCSogU2tpcCBmaXh1cCBpZiB0aGUgYmFzZSB0eXBlIGlzIGludmFsaWQuCgkqIFRPRE86IEdlbmVyYXRlIGEgd2FybmluZyEKCSovCglyZXR1cm4oMCk7CiAgICB9CQogICAgLyoKICAgICogVGhpcyBiYXNpY2FsbHkgY2hlY2tzIGlmIHRoZSBiYXNlIHR5cGUgY2FuIGJlIGRlcml2ZWQuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQ2hlY2tTUkNDVChwY3R4dCwgdHlwZSk7CiAgICBIRkFJTFVSRSBIRVJST1IgICAKICAgIC8qCiAgICAqIEZpeHVwIHRoZSBjb250ZW50IHR5cGUuCiAgICAqLwogICAgaWYgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHsKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxjb21wbGV4VHlwZT48c2ltcGxlQ29udGVudD4uLi4KCSovCglpZiAoKFdYU19JU19DT01QTEVYKGJhc2VUeXBlKSkgJiYKCSAgICAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlRGVmICE9IE5VTEwpICYmCgkgICAgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSkpIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIGNvbnRlbnRCYXNlLCBjb250ZW50OwojaWZkZWYgRU5BQkxFX05BTUVEX0xPQ0FMUwoJICAgIGNoYXIgYnVmWzMwXTsKCSAgICBjb25zdCB4bWxDaGFyICp0bXBuYW1lOwojZW5kaWYKCSAgICAvKgoJICAgICogU1BFQyAoMSkgSWYgPHJlc3RyaWN0aW9uPiArIGJhc2UgdHlwZSBpcyA8Y29tcGxleFR5cGU+LAoJICAgICogIndob3NlIG93biB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlLi4uIgoJICAgICovCgkgICAgaWYgKHR5cGUtPmNvbnRlbnRUeXBlRGVmICE9IE5VTEwpIHsKCQkvKgoJCSogU1BFQyAoMS4xKSAidGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUKCQkqIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8cmVzdHJpY3Rpb24+IGlmIHRoZXJlCgkJKiBpcyBvbmU7IgoJCSogTm90ZSB0aGF0IHRoaXMgIjxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSIgd2FzIHB1dAoJCSogaW50byAtPmNvbnRlbnRUeXBlRGVmIGR1cmluZyBwYXJzaW5nLgoJCSovCgkJY29udGVudEJhc2UgPSB0eXBlLT5jb250ZW50VHlwZURlZjsKCQl0eXBlLT5jb250ZW50VHlwZURlZiA9IE5VTEw7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogKDEuMikgIi4uLm90aGVyd2lzZSAoPHJlc3RyaWN0aW9uPiBoYXMgbm8gPHNpbXBsZVR5cGU+CgkJKiBhbW9uZyBpdHMgW2NoaWxkcmVuXSksIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHdoaWNoCgkJKiBpcyB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIC4uLiBiYXNlIHR5cGUuIgoJCSovCgkJY29udGVudEJhc2UgPSBiYXNlVHlwZS0+Y29udGVudFR5cGVEZWY7CgkgICAgfQoJICAgIC8qCgkgICAgKiBTUEVDCgkgICAgKiAiLi4uIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiB3aGljaCByZXN0cmljdHMgdGhlIHNpbXBsZQoJICAgICogdHlwZSBkZWZpbml0aW9uIGlkZW50aWZpZWQgaW4gY2xhdXNlIDEuMSBvciBjbGF1c2UgMS4yCgkgICAgKiB3aXRoIGEgc2V0IG9mIGZhY2V0IGNvbXBvbmVudHMiCgkgICAgKgoJICAgICogQ3JlYXRlIHRoZSBhbm9ueW1vdXMgc2ltcGxlIHR5cGUsIHdoaWNoIHdpbGwgYmUgdGhlIGNvbnRlbnQKCSAgICAqIHR5cGUgb2YgdGhlIGNvbXBsZXggdHlwZS4KCSAgICAqLwojaWZkZWYgRU5BQkxFX05BTUVEX0xPQ0FMUwoJICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjc2NTVCVkIiwgKysocGN0eHQtPmNvdW50ZXIpKTsKCSAgICB0bXBuYW1lID0geG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwgQkFEX0NBU1QgYnVmLCAtMSk7CgkgICAgY29udGVudCA9IHhtbFNjaGVtYUFkZFR5cGUocGN0eHQsIHBjdHh0LT5zY2hlbWEsCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgdG1wbmFtZSwgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCXR5cGUtPm5vZGUsIDApOwojZWxzZQoJICAgIGNvbnRlbnQgPSB4bWxTY2hlbWFBZGRUeXBlKHBjdHh0LCBwY3R4dC0+c2NoZW1hLAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSwKCQl0eXBlLT5ub2RlLCAwKTsKI2VuZGlmCgkgICAgaWYgKGNvbnRlbnQgPT0gTlVMTCkKCQlnb3RvIGV4aXRfZmFpbHVyZTsKCSAgICAvKgoJICAgICogV2Ugd2lsbCB1c2UgdGhlIHNhbWUgbm9kZSBhcyBmb3IgdGhlIDxjb21wbGV4VHlwZT4KCSAgICAqIHRvIGhhdmUgaXQgc29tZWhvdyBhbmNob3JlZCBpbiB0aGUgc2NoZW1hIGRvYy4KCSAgICAqLwoJICAgIGNvbnRlbnQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJICAgIGNvbnRlbnQtPmJhc2VUeXBlID0gY29udGVudEJhc2U7CgkgICAgLyoKCSAgICAqIE1vdmUgdGhlIGZhY2V0cywgcHJldmlvdXNseSBhbmNob3JlZCBvbiB0aGUKCSAgICAqIGNvbXBsZXhUeXBlIGR1cmluZyBwYXJzaW5nLgoJICAgICovCgkgICAgY29udGVudC0+ZmFjZXRzID0gdHlwZS0+ZmFjZXRzOwoJICAgIHR5cGUtPmZhY2V0cyA9IE5VTEw7CgkgICAgY29udGVudC0+ZmFjZXRTZXQgPSB0eXBlLT5mYWNldFNldDsKCSAgICB0eXBlLT5mYWNldFNldCA9IE5VTEw7CgkgICAgCgkgICAgdHlwZS0+Y29udGVudFR5cGVEZWYgPSBjb250ZW50OwoJICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQoY29udGVudEJhc2UpKQoJCXhtbFNjaGVtYVR5cGVGaXh1cChjb250ZW50QmFzZSwgQUNUWFRfQ0FTVCBwY3R4dCk7CgkgICAgLyoKCSAgICAqIEZpeHVwIHRoZSBuZXdseSBjcmVhdGVkIHR5cGUuIFdlIGRvbid0IG5lZWQgdG8gY2hlY2sKCSAgICAqIGZvciBjaXJjdWxhcml0eSBoZXJlLgoJICAgICovCgkgICAgcmVzID0geG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VPbmUocGN0eHQsIGNvbnRlbnQpOwoJICAgIEhGQUlMVVJFIEhFUlJPUiAKCSAgICByZXMgPSB4bWxTY2hlbWFGaXh1cFNpbXBsZVR5cGVTdGFnZVR3byhwY3R4dCwgY29udGVudCk7CgkgICAgSEZBSUxVUkUgSEVSUk9SIAoJCQoJfSBlbHNlIGlmICgoV1hTX0lTX0NPTVBMRVgoYmFzZVR5cGUpKSAmJgoJICAgIChiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSAmJgoJICAgIChXWFNfSVNfUkVTVFJJQ1RJT04odHlwZSkpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDIpIElmIDxyZXN0cmljdGlvbj4gKyBiYXNlIGlzIGEgbWl4ZWQgPGNvbXBsZXhUeXBlPiB3aXRoCgkgICAgKiBhbiBlbXB0aWFibGUgcGFydGljbGUsIHRoZW4gYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHdoaWNoCgkgICAgKiByZXN0cmljdHMgdGhlIDxyZXN0cmljdGlvbj4ncyA8c2ltcGxlVHlwZT4gY2hpbGQuCgkgICAgKi8KCSAgICBpZiAoKHR5cGUtPmNvbnRlbnRUeXBlRGVmID09IE5VTEwpIHx8CgkJKHR5cGUtPmNvbnRlbnRUeXBlRGVmLT5iYXNlVHlwZSA9PSBOVUxMKSkgewoJCS8qCgkJKiBUT0RPOiBDaGVjayBpZiB0aGlzIGV2ZXIgaGFwcGVucy4KCQkqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVR5cGVGaXh1cCwgIgoJCSAgICAiY29tcGxleCB0eXBlICclcyc6IHRoZSA8c2ltcGxlQ29udGVudD48cmVzdHJpY3Rpb24+ICIKCQkgICAgImlzIG1pc3NpbmcgYSA8c2ltcGxlVHlwZT4gY2hpbGQsIGJ1dCB3YXMgbm90IGNhdGNoZWQgIgoJCSAgICAiYnkgeG1sU2NoZW1hQ2hlY2tTUkNDVCgpIiwgdHlwZS0+bmFtZSk7CgkJZ290byBleGl0X2ZhaWx1cmU7CgkgICAgfQoJfSBlbHNlIGlmICgoV1hTX0lTX0NPTVBMRVgoYmFzZVR5cGUpKSAmJiBXWFNfSVNfRVhURU5TSU9OKHR5cGUpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDMpIElmIDxleHRlbnNpb24+ICsgYmFzZSBpcyA8Y29tcGxleFR5cGU+IHdpdGgKCSAgICAqIDxzaW1wbGVUeXBlPiBjb250ZW50LCAiLi4udGhlbiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhhdAoJICAgICogY29tcGxleCB0eXBlIGRlZmluaXRpb24iCgkgICAgKi8KCSAgICBpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlRGVmID09IE5VTEwpIHsKCQkvKgoJCSogVE9ETzogQ2hlY2sgaWYgdGhpcyBldmVyIGhhcHBlbnMuIHhtbFNjaGVtYUNoZWNrU1JDQ1QKCQkqIHNob3VsZCBoYXZlIGNhdGNoZWQgdGhpcyBhbHJlYWR5LgoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVHlwZUZpeHVwLCAiCgkJICAgICJjb21wbGV4IHR5cGUgJyVzJzogdGhlIDxleHRlbnNpb24+ZWQgYmFzZSB0eXBlIGlzICIKCQkgICAgImEgY29tcGxleCB0eXBlIHdpdGggbm8gc2ltcGxlIGNvbnRlbnQgdHlwZSIsCgkJICAgIHR5cGUtPm5hbWUpOwoJCWdvdG8gZXhpdF9mYWlsdXJlOwoJICAgIH0KCSAgICB0eXBlLT5jb250ZW50VHlwZURlZiA9IGJhc2VUeXBlLT5jb250ZW50VHlwZURlZjsKCX0gZWxzZSBpZiAoKFdYU19JU19TSU1QTEUoYmFzZVR5cGUpKSAmJiBXWFNfSVNfRVhURU5TSU9OKHR5cGUpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDQpIDxleHRlbnNpb24+ICsgYmFzZSBpcyA8c2ltcGxlVHlwZT4KCSAgICAqICIuLi4gdGhlbiB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24iCgkgICAgKi8KCSAgICB0eXBlLT5jb250ZW50VHlwZURlZiA9IGJhc2VUeXBlOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogVE9ETzogQ2hlY2sgaWYgdGhpcyBldmVyIGhhcHBlbnMuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFUeXBlRml4dXAsICIKCQkiY29tcGxleCB0eXBlICclcycgd2l0aCA8c2ltcGxlQ29udGVudD46IHVuaGFuZGxlZCAiCgkJImRlcml2YXRpb24gY2FzZSIsIHR5cGUtPm5hbWUpOwoJICAgIGdvdG8gZXhpdF9mYWlsdXJlOwoJfQogICAgfSBlbHNlIHsKCWludCBkdW1teVNlcXVlbmNlID0gMDsKCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzOwoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxjb21wbGV4Q29udGVudD4uLi4KCSoKCSogTk9URSB0aGF0IHRoZSBlZmZlY3RpdmUgbWl4ZWQgd2FzIGFscmVhZHkgc2V0IGR1cmluZyBwYXJzaW5nIG9mCgkqIDxjb21wbGV4VHlwZT4gYW5kIDxjb21wbGV4Q29udGVudD47IGl0cyBmbGFnIHZhbHVlIGlzCgkqIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQuCgkqCgkqIENvbXB1dGUgdGhlICJlZmZlY3RpdmUgY29udGVudCI6CgkqICgyLjEuMSkgKyAoMi4xLjIpICsgKDIuMS4zKQoJKi8KCWlmICgocGFydGljbGUgPT0gTlVMTCkgfHwKCSAgICAoKHBhcnRpY2xlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkgJiYKCSAgICAoKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB8fAoJICAgIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB8fAoJICAgICgocGFydGljbGUtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpICYmCgkgICAgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkpKSAmJgoJICAgICggKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcGFydGljbGUtPmNoaWxkcmVuKS0+Y2hpbGRyZW4gPT0gTlVMTCkpKSB7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewoJCS8qCgkJKiBTUEVDICgyLjEuNCkgIklmIHRoZSC3ZWZmZWN0aXZlIG1peGVktyBpcyB0cnVlLCB0aGVuCgkJKiBhIHBhcnRpY2xlIHdob3NlIHByb3BlcnRpZXMgYXJlIGFzIGZvbGxvd3M6Li4uIgoJCSoKCQkqIEVtcHR5IHNlcXVlbmNlIG1vZGVsIGdyb3VwIHdpdGgKCQkqIG1pbk9jY3Vycy9tYXhPY2N1cnMgPSAxIChpLmUuIGEgInBhcnRpY2xlIGVtcHRpYWJsZSIpLgoJCSogTk9URSB0aGF0IHdlIHNpbGwgYXNzaWduIGl0IHRoZSA8Y29tcGxleFR5cGU+IG5vZGUgdG8KCQkqIHNvbWVob3cgYW5jaG9yIGl0IGluIHRoZSBkb2MuCgkJKi8KCQlpZiAoKHBhcnRpY2xlID09IE5VTEwpIHx8CgkJICAgIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkgewoJCSAgICAvKgoJCSAgICAqIENyZWF0ZSB0aGUgcGFydGljbGUuCgkJICAgICovCgkJICAgIHBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUocGN0eHQsCgkJCXR5cGUtPm5vZGUsIDEsIDEpOwoJCSAgICBpZiAocGFydGljbGUgPT0gTlVMTCkKCQkJZ290byBleGl0X2ZhaWx1cmU7CgkJICAgIC8qCgkJICAgICogQ3JlYXRlIHRoZSBtb2RlbCBncm91cC4KCQkgICAgKi8gLyogVVJHRU5UIFRPRE86IGF2b2lkIGFkZGluZyB0byBwZW5kaW5nIGl0ZW1zLiAqLwoJCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgkJCXhtbFNjaGVtYUFkZE1vZGVsR3JvdXAocGN0eHQsIHBjdHh0LT5zY2hlbWEsCgkJCVhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgdHlwZS0+bm9kZSk7CgkJICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkJZ290byBleGl0X2ZhaWx1cmU7CgkJICAgIAoJCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKSBwYXJ0aWNsZTsKCQl9CgkJZHVtbXlTZXF1ZW5jZSA9IDE7CgkJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU1BFQyAoMi4xLjUpICJvdGhlcndpc2UgZW1wdHkiCgkJKi8KCQl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBTUEVDICgyLjIpICJvdGhlcndpc2UgdGhlIHBhcnRpY2xlIGNvcnJlc3BvbmRpbmcgdG8gdGhlCgkgICAgKiA8YWxsPiwgPGNob2ljZT4sIDxncm91cD4gb3IgPHNlcXVlbmNlPiBhbW9uZyB0aGUKCSAgICAqIFtjaGlsZHJlbl0uIgoJICAgICovCgkgICAgdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7Cgl9CgkvKgoJKiBDb21wdXRlIHRoZSAiY29udGVudCB0eXBlIi4KCSovCglpZiAoV1hTX0lTX1JFU1RSSUNUSU9OKHR5cGUpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDMuMSkgIklmIDxyZXN0cmljdGlvbj4uLi4iCgkgICAgKiAoMy4xLjEpICsgKDMuMS4yKSAqLwoJICAgIGlmICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQlpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBTUEVDICgzLjIpICJJZiA8ZXh0ZW5zaW9uPi4uLiIKCSAgICAqLwoJICAgIGlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkvKgoJCSogU1BFQyAoMy4yLjEpCgkJKiAiSWYgdGhlILdlZmZlY3RpdmUgY29udGVudLcgaXMgZW1wdHksIHRoZW4gdGhlCgkJKiAge2NvbnRlbnQgdHlwZX0gb2YgdGhlIFsuLi5dIGJhc2UgLi4uIgoJCSovCgkJdHlwZS0+Y29udGVudFR5cGUgPSBiYXNlVHlwZS0+Y29udGVudFR5cGU7CgkJdHlwZS0+c3VidHlwZXMgPSBiYXNlVHlwZS0+c3VidHlwZXM7CgkJLyoKCQkqIEZpeGVzIGJ1ZyAjMzQ3MzE2OgoJCSogVGhpcyBpcyB0aGUgY2FzZSB3aGVuIHRoZSBiYXNlIHR5cGUgaGFzIGEgc2ltcGxlCgkJKiB0eXBlIGRlZmluaXRpb24gYXMgY29udGVudC4KCQkqLwoJCXR5cGUtPmNvbnRlbnRUeXBlRGVmID0gYmFzZVR5cGUtPmNvbnRlbnRUeXBlRGVmOwoJCS8qCgkJKiBOT1RFIHRoYXQgdGhlIGVmZmVjdGl2ZSBtaXhlZCBpcyBpZ25vcmVkIGhlcmUuCgkJKi8KCSAgICB9IGVsc2UgaWYgKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkvKgoJCSogU1BFQyAoMy4yLjIpCgkJKi8KCQlpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiBTUEVDICgzLjIuMykKCQkqLwoJCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkJICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwoJCSAgICAvKgoJCSAgICAqICJBIG1vZGVsIGdyb3VwIHdob3NlIHtjb21wb3NpdG9yfSBpcyBzZXF1ZW5jZSBhbmQgd2hvc2UKCQkgICAgKiB7cGFydGljbGVzfSBhcmUuLi4iCgkJICAgICovCgkJaWYgKChXWFNfVFlQRV9QQVJUSUNMRSh0eXBlKSAhPSBOVUxMKSAmJgoJCSAgICAoV1hTX1RZUEVfUEFSVElDTEVfVEVSTSh0eXBlKSAhPSBOVUxMKSAmJgoJCSAgICAoKFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZSkpLT50eXBlID09CgkJCVhNTF9TQ0hFTUFfVFlQRV9BTEwpKQoJCXsKCQkgICAgLyoKCQkgICAgKiBTUEVDIGNvcy1hbGwtbGltaXRlZCAoMSkKCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCS8qIFRPRE86IGVycm9yIGNvZGUgKi8KCQkJWE1MX1NDSEVNQVBfQ09TX0FMTF9MSU1JVEVELAoJCQlXWFNfSVRFTV9OT0RFKHR5cGUpLCBOVUxMLAoJCQkiVGhlIHR5cGUgaGFzIGFuICdhbGwnIG1vZGVsIGdyb3VwIGluIGl0cyAiCgkJCSJ7Y29udGVudCB0eXBlfSBhbmQgdGh1cyBjYW5ub3QgYmUgZGVyaXZlZCBmcm9tICIKCQkJImEgbm9uLWVtcHR5IHR5cGUsIHNpbmNlIHRoaXMgd291bGQgcHJvZHVjZSBhICIKCQkJIidzZXF1ZW5jZScgbW9kZWwgZ3JvdXAgY29udGFpbmluZyB0aGUgJ2FsbCcgIgoJCQkibW9kZWwgZ3JvdXA7ICdhbGwnIG1vZGVsIGdyb3VwcyBhcmUgbm90ICIKCQkJImFsbG93ZWQgdG8gYXBwZWFyIGluc2lkZSBvdGhlciBtb2RlbCBncm91cHMiLAoJCQlOVUxMLCBOVUxMKTsKCgkJfSBlbHNlIGlmICgoV1hTX1RZUEVfUEFSVElDTEUoYmFzZVR5cGUpICE9IE5VTEwpICYmCgkJICAgIChXWFNfVFlQRV9QQVJUSUNMRV9URVJNKGJhc2VUeXBlKSAhPSBOVUxMKSAmJgoJCSAgICAoKFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0oYmFzZVR5cGUpKS0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfQUxMKSkKCQl7CgkJICAgIC8qCgkJICAgICogU1BFQyBjb3MtYWxsLWxpbWl0ZWQgKDEpCgkJICAgICovCgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQkvKiBUT0RPOiBlcnJvciBjb2RlICovCgkJCVhNTF9TQ0hFTUFQX0NPU19BTExfTElNSVRFRCwKCQkJV1hTX0lURU1fTk9ERSh0eXBlKSwgTlVMTCwKCQkJIkEgdHlwZSBjYW5ub3QgYmUgZGVyaXZlZCBieSBleHRlbnNpb24gZnJvbSBhIHR5cGUgIgoJCQkid2hpY2ggaGFzIGFuICdhbGwnIG1vZGVsIGdyb3VwIGluIGl0cyAiCgkJCSJ7Y29udGVudCB0eXBlfSwgc2luY2UgdGhpcyB3b3VsZCBwcm9kdWNlIGEgIgoJCQkiJ3NlcXVlbmNlJyBtb2RlbCBncm91cCBjb250YWluaW5nIHRoZSAnYWxsJyAiCgkJCSJtb2RlbCBncm91cDsgJ2FsbCcgbW9kZWwgZ3JvdXBzIGFyZSBub3QgIgoJCQkiYWxsb3dlZCB0byBhcHBlYXIgaW5zaWRlIG90aGVyIG1vZGVsIGdyb3VwcyIsCgkJCU5VTEwsIE5VTEwpOwoKCQl9IGVsc2UgaWYgKCEgZHVtbXlTZXF1ZW5jZSkgewoJCSAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBlZmZlY3RpdmVDb250ZW50ID0KCQkJKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB0eXBlLT5zdWJ0eXBlczsKCQkgICAgLyoKCQkgICAgKiBDcmVhdGUgdGhlIHBhcnRpY2xlLgoJCSAgICAqLwoJCSAgICBwYXJ0aWNsZSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKHBjdHh0LAoJCQl0eXBlLT5ub2RlLCAxLCAxKTsKCQkgICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCgkJCWdvdG8gZXhpdF9mYWlsdXJlOwoJCSAgICAvKgoJCSAgICAqIENyZWF0ZSB0aGUgInNlcXVlbmNlIiBtb2RlbCBncm91cC4KCQkgICAgKi8KCQkgICAgcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKQoJCQl4bWxTY2hlbWFBZGRNb2RlbEdyb3VwKHBjdHh0LCBwY3R4dC0+c2NoZW1hLAoJCQlYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIHR5cGUtPm5vZGUpOwoJCSAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpCgkJCWdvdG8gZXhpdF9mYWlsdXJlOwoJCSAgICBXWFNfVFlQRV9DT05URU5UVFlQRSh0eXBlKSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBwYXJ0aWNsZTsKCQkgICAgLyoKCQkgICAgKiBTUEVDICJ0aGUgcGFydGljbGUgb2YgdGhlIHtjb250ZW50IHR5cGV9IG9mCgkJICAgICogdGhlIC4uLiBiYXNlIC4uLiIKCQkgICAgKiBDcmVhdGUgYSBkdXBsaWNhdGUgb2YgdGhlIGJhc2UgdHlwZSdzIHBhcnRpY2xlCgkJICAgICogYW5kIGFzc2lnbiBpdHMgInRlcm0iIHRvIGl0LgoJCSAgICAqLwoJCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID0KCQkJKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShwY3R4dCwKCQkJdHlwZS0+bm9kZSwKCQkJKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgdHlwZS0+c3VidHlwZXMpLT5taW5PY2N1cnMsCgkJCSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzKS0+bWF4T2NjdXJzKTsKCQkgICAgaWYgKHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkJZ290byBleGl0X2ZhaWx1cmU7CgkJICAgIHBhcnRpY2xlID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKQoJCQlwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoJCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4gPQoJCQkoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlVHlwZS0+c3VidHlwZXMpLT5jaGlsZHJlbjsKCQkgICAgLyoKCQkgICAgKiBTUEVDICJmb2xsb3dlZCBieSB0aGUgt2VmZmVjdGl2ZSBjb250ZW50ty4iCgkJICAgICovCgkJICAgIHBhcnRpY2xlLT5uZXh0ID0gZWZmZWN0aXZlQ29udGVudDsKCQkgICAgLyoKCQkgICAgKiBUaGlzIGFsbCB3aWxsIHJlc3VsdCBpbjoKCQkgICAgKiBuZXctcGFydGljbGUKCQkgICAgKiAgIC0tPiBuZXctc2VxdWVuY2UoCgkJICAgICogICAgICAgICBuZXctcGFydGljbGUKCQkgICAgKiAgICAgICAgICAgLS0+IGJhc2UtbW9kZWwsCgkJICAgICogICAgICAgICB0aGlzLXBhcnRpY2xlCgkJICAgICoJICAgICAgICAtLT4gdGhpcy1tb2RlbAoJCSAgICAqCSAgICApCgkJICAgICovCgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIHdoZW4gdGhlcmUgaXMgYWxyZWFkeSBhbiBlbXB0eQoJCSAgICAqIDxzZXF1ZW5jZT4gd2l0aCBtaW5PY2N1cnM9PW1heE9jY3Vycz09MS4KCQkgICAgKiBKdXN0IGFkZCB0aGUgYmFzZSB0eXBlcydzIGNvbnRlbnQgdHlwZS4KCQkgICAgKiBOT1RFIHRoYXQsIGFsdGhvdWdoIHdlIG1pc3MgdG8gYWRkIGFuIGludGVybWVkaWF0ZQoJCSAgICAqIDxzZXF1ZW5jZT4sIHRoaXMgc2hvdWxkIHByb2R1Y2Ugbm8gZGlmZmVyZW5jZSB0bwoJCSAgICAqIG5laXRoZXIgdGhlIHJlZ2V4IGNvbXBpbGF0aW9uIG9mIHRoZSBjb250ZW50IG1vZGVsLAoJCSAgICAqIG5vciB0byB0aGUgY29tcGxleCB0eXBlIGNvbnRyYWludHMuCgkJICAgICovCgkJICAgIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPQoJCQkoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGJhc2VUeXBlLT5zdWJ0eXBlczsKCQl9CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogTm93IGZpeHVwIGF0dHJpYnV0ZSB1c2VzOgogICAgKiAgIC0gZXhwYW5kIGF0dHIuIGdyb3VwIHJlZmVyZW5jZXMKICAgICogICAgIC0gaW50ZXJzZWN0IGF0dHJpYnV0ZSB3aWxkY2FyZHMKICAgICogICAtIGluaGVyaXQgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZQogICAgKiAgIC0gaW5oZXJpdCBvciB1bmlvbiBhdHRyLiB3aWxkY2FyZHMgaWYgZXh0ZW5kaW5nCiAgICAqICAgLSBhcHBseSBhdHRyLiB1c2UgcHJvaGliaXRpb25zIGlmIHJlc3RyaWN0aW5nCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlcyhwY3R4dCwgdHlwZSk7CiAgICBIRkFJTFVSRSBIRVJST1IKICAgIC8qCiAgICAqIEFwcGx5IHRoZSBjb21wbGV4IHR5cGUgY29tcG9uZW50IGNvbnN0cmFpbnRzOyB0aGlzIHdpbGwgbm90CiAgICAqIGNoZWNrIGF0dHJpYnV0ZXMsIHNpbmNlIHRoaXMgaXMgZG9uZSBpbgogICAgKiB4bWxTY2hlbWFGaXh1cFR5cGVBdHRyaWJ1dGVVc2VzKCkuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQ2hlY2tDVENvbXBvbmVudChwY3R4dCwgdHlwZSk7CiAgICBIRkFJTFVSRSBIRVJST1IKCiNpZmRlZiBERUJVR19UWVBFCiAgICB4bWxTY2hlbWFEZWJ1Z0ZpeGVkVHlwZShwY3R4dCwgdHlwZSk7CiNlbmRpZgogICAgaWYgKG9sZGVycnMgIT0gcGN0eHQtPm5iZXJyb3JzKQoJcmV0dXJuKHBjdHh0LT5lcnIpOwogICAgZWxzZQoJcmV0dXJuKDApOwoKZXhpdF9lcnJvcjoKICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfSU5WQUxJRDsKI2lmZGVmIERFQlVHX1RZUEUKICAgIHhtbFNjaGVtYURlYnVnRml4ZWRUeXBlKHBjdHh0LCB0eXBlKTsKI2VuZGlmCiAgICByZXR1cm4ocGN0eHQtPmVycik7CgpleGl0X2ZhaWx1cmU6CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0lOVEVSTkFMX0lOVkFMSUQ7CiNpZmRlZiBERUJVR19UWVBFCiAgICB4bWxTY2hlbWFEZWJ1Z0ZpeGVkVHlwZShwY3R4dCwgdHlwZSk7CiNlbmRpZgogICAgcmV0dXJuKC0xKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFUeXBlRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgdHlwZS4KICogVVJHRU5UIFRPRE86IFdlIG5lZWQgYW4gaW50IHJlc3VsdCEKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4oMCk7CiAgICBpZiAoYWN0eHQtPnR5cGUgIT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikgewoJQUVSUk9SX0lOVCgieG1sU2NoZW1hVHlwZUZpeHVwIiwKCSAgICAidGhpcyBmdW5jdGlvbiBuZWVkcyBhIHBhcnNlciBjb250ZXh0Iik7CglyZXR1cm4oLTEpOwogICAgfQogICAgaWYgKCEgV1hTX0lTX1RZUEVfTk9UX0ZJWEVEKHR5cGUpKQoJcmV0dXJuKDApOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpCglyZXR1cm4oeG1sU2NoZW1hRml4dXBDb21wbGV4VHlwZShQQ1RYVF9DQVNUIGFjdHh0LCB0eXBlKSk7CiAgICBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpCglyZXR1cm4oeG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VUd28oUENUWFRfQ0FTVCBhY3R4dCwgdHlwZSkpOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tGYWNldDoKICogQGZhY2V0OiAgdGhlIGZhY2V0CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBwY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQgb3IgTlVMTAogKiBAbmFtZTogdGhlIG9wdGlvbmFsIG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIGFuZCBjb21wdXRlcyB0aGUgdmFsdWVzIG9mIGZhY2V0cy4KICoKICogUmV0dXJucyAwIGlmIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYgbm90IHZhbGlkIGFuZAogKiAgICAgICAgIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYUNoZWNrRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpbnQgcmV0ID0gMCwgY3R4dEdpdmVuOwoKICAgIGlmICgoZmFjZXQgPT0gTlVMTCkgfHwgKHR5cGVEZWNsID09IE5VTEwpKQogICAgICAgIHJldHVybigtMSk7CiAgICAvKgogICAgKiBUT0RPOiB3aWxsIHRoZSBwYXJzZXIgY29udGV4dCBiZSBnaXZlbiBpZiB1c2VkIGZyb20KICAgICogdGhlIHJlbGF4TkcgbW9kdWxlPwogICAgKi8KICAgIGlmIChwY3R4dCA9PSBOVUxMKQoJY3R4dEdpdmVuID0gMDsKICAgIGVsc2UKCWN0eHRHaXZlbiA9IDE7CgogICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046IHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBPa2F5IHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBhdCB0aGF0IHBvaW50LgogICAgICAgICAgICAgICAgICovCgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKCQkvKiA0LjMuNS41IENvbnN0cmFpbnRzIG9uIGVudW1lcmF0aW9uIFNjaGVtYSBDb21wb25lbnRzCgkJKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IGVudW1lcmF0aW9uIHZhbGlkIHJlc3RyaWN0aW9uCgkJKiBJdCBpcyBhbiC3ZXJyb3K3IGlmIGFueSBtZW1iZXIgb2Yge3ZhbHVlfSBpcyBub3QgaW4gdGhlCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkJKgoJCSogbWluSW5jbHVzaXZlLCBtYXhJbmNsdXNpdmUsIG1pbkV4Y2x1c2l2ZSwgbWF4RXhjbHVzaXZlOgoJCSogVGhlIHZhbHVlILdtdXN0tyBiZSBpbiB0aGUKCQkqILd2YWx1ZSBzcGFjZbcgb2YgdGhlILdiYXNlIHR5cGW3LgoJCSovCgkJLyoKCQkqIFRoaXMgZnVuY3Rpb24gaXMgaW50ZW5kZWQgdG8gZGVsaXZlciBhIGNvbXBpbGVkIHZhbHVlCgkJKiBvbiB0aGUgZmFjZXQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24gb2YgWE1MIFNjaGVtYXRhIHRoZQoJCSogdHlwZSBob2xkaW5nIGEgZmFjZXQsIHdvbid0IGJlIGEgYnVpbHQtaW4gdHlwZS4KCQkqIFRodXMgdG8gZW5zdXJlIHRoYXQgb3RoZXIgQVBJCgkJKiBjYWxscyAocmVsYXhuZykgZG8gd29yaywgaWYgdGhlIGdpdmVuIHR5cGUgaXMgYSBidWlsdC1pbgoJCSogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZSAqaXMKCQkqIGFscmVhZHkqIHRoZSBiYXNlIHR5cGUuCgkJKi8KCQlpZiAodHlwZURlY2wtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkJICAgIGJhc2UgPSB0eXBlRGVjbC0+YmFzZVR5cGU7CgkJICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCSAgICAiYSB0eXBlIHVzZXIgZGVyaXZlZCB0eXBlIGhhcyBubyBiYXNlIHR5cGUiKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQl9IGVsc2UKCQkgICAgYmFzZSA9IHR5cGVEZWNsOwoJICAgICAgICAgICAgICAgICAKCQlpZiAoISBjdHh0R2l2ZW4pIHsKCQkgICAgLyoKCQkgICAgKiBBIGNvbnRleHQgaXMgbmVlZGVkIGlmIGNhbGxlZCBmcm9tIFJlbGF4TkcuCgkJICAgICovCQkgICAgCgkJICAgIHBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOwoJCSAgICBpZiAocGN0eHQgPT0gTlVMTCkKCQkJcmV0dXJuICgtMSk7CgkJfQoJCS8qCgkJKiBOT1RFOiBUaGlzIGNhbGwgZG9lcyBub3QgY2hlY2sgdGhlIGNvbnRlbnQgbm9kZXMsCgkJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldAoJCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqCgkJKiBvZiB0aGUgZmFjZXQuCgkJKi8JCQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkJICAgIEFDVFhUX0NBU1QgcGN0eHQsIGZhY2V0LT5ub2RlLCBiYXNlLAoJCSAgICBmYWNldC0+dmFsdWUsICYoZmFjZXQtPnZhbCksIDEsIDEsIDApOwogICAgICAgICAgICAgICAgaWYgKHJldCAhPSAwKSB7CgkJICAgIGlmIChyZXQgPCAwKSB7CgkJCS8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJCWlmIChjdHh0R2l2ZW4pIHsJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBmYWNldC0+bm9kZSwgTlVMTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIiAKCQkJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJCSJmYWNldCAnJXMnIGFnYWluc3QgdGhlIGJhc2UgdHlwZSIsCgkJCQlmYWNldC0+dmFsdWUsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CgkJCX0KCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkgICAgfQoJCSAgICByZXQgPSBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFOwoJCSAgICAvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJICAgIHJldCwgZmFjZXQtPm5vZGUsIFdYU19CQVNJQ19DQVNUIGZhY2V0LAoJCQkgICAgIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCBkb2VzIG5vdCB2YWxpZGF0ZSAiCgkJCSAgICAiYWdhaW5zdCB0aGUgYmFzZSB0eXBlICclcyciLAoJCQkgICAgZmFjZXQtPnZhbHVlLAoJCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJCWJhc2UtPnRhcmdldE5hbWVzcGFjZSwgYmFzZS0+bmFtZSkpOwoJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJICAgIH0KCQkgICAgZ290byBleGl0OwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmYWNldC0+dmFsID09IE5VTEwpIHsKCQkgICAgaWYgKGN0eHRHaXZlbikgewoJCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0ZhY2V0IiwKCQkJICAgICJ2YWx1ZSB3YXMgbm90IGNvbXB1dGVkIik7CgkJICAgIH0KCQkgICAgVE9ETwoJCX0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGZhY2V0LT5yZWdleHAgPSB4bWxSZWdleHBDb21waWxlKGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgIGlmIChmYWNldC0+cmVnZXhwID09IE5VTEwpIHsKCQlyZXQgPSBYTUxfU0NIRU1BUF9SRUdFWFBfSU5WQUxJRDsKCQkvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCWlmIChjdHh0R2l2ZW4pIHsKCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCXJldCwgZmFjZXQtPm5vZGUsIFdYU19CQVNJQ19DQVNUIHR5cGVEZWNsLAoJCQkiVGhlIHZhbHVlICclcycgb2YgdGhlIGZhY2V0ICdwYXR0ZXJuJyBpcyBub3QgYSAiCgkJCSJ2YWxpZCByZWd1bGFyIGV4cHJlc3Npb24iLAoJCQlmYWNldC0+dmFsdWUsIE5VTEwpOwoJCX0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoKCSAgICBpZiAoZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUykgewoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUoCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1BJTlRFR0VSKSwKCQkgICAgZmFjZXQtPnZhbHVlLCAmKGZhY2V0LT52YWwpKTsKCSAgICB9IGVsc2UgewoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUoCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05OSU5URUdFUiksCgkJICAgIGZhY2V0LT52YWx1ZSwgJihmYWNldC0+dmFsKSk7CgkgICAgfQoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIC8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJICAgIGlmIChjdHh0R2l2ZW4pIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCSAgICAidmFsaWRhdGluZyBmYWNldCB2YWx1ZSIpOwoJCSAgICB9CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUU7CgkJLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQlpZiAoY3R4dEdpdmVuKSB7CgkJICAgIC8qIGVycm9yIGNvZGUgKi8KCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyNChBQ1RYVF9DQVNUIHBjdHh0LAoJCQlyZXQsIGZhY2V0LT5ub2RlLCBXWFNfQkFTSUNfQ0FTVCB0eXBlRGVjbCwKCQkJIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCAnJXMnIGlzIG5vdCBhIHZhbGlkICclcyciLAkJCQoJCQlmYWNldC0+dmFsdWUsCgkJCXhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCQkJKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFMpID8gCgkJCSAgICBCQURfQ0FTVCAibm9uTmVnYXRpdmVJbnRlZ2VyIiA6CgkJCSAgICBCQURfQ0FTVCAicG9zaXRpdmVJbnRlZ2VyIiwKCQkJTlVMTCk7CgkJfQoJICAgIH0KCSAgICBicmVhazsKICAgICAgICAgICAgCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6ewogICAgICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInByZXNlcnZlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1BSRVNFUlZFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJyZXBsYWNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgImNvbGxhcHNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRTsKICAgICAgICAgICAgICAgICAgICAvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCS8qIGVycm9yIHdhcyBwcmV2aW91c2x5OiBYTUxfU0NIRU1BUF9JTlZBTElEX1dISVRFX1NQQUNFICovCgkJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQkgICAgcmV0LCBmYWNldC0+bm9kZSwgV1hTX0JBU0lDX0NBU1QgdHlwZURlY2wsCgkJCSAgICAiVGhlIHZhbHVlICclcycgb2YgdGhlIGZhY2V0ICd3aGl0ZXNwYWNlJyBpcyBub3QgIgoJCQkgICAgInZhbGlkIiwgZmFjZXQtPnZhbHVlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KZXhpdDoKICAgIGlmICgoISBjdHh0R2l2ZW4pICYmIChwY3R4dCAhPSBOVUxMKSkKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHBjdHh0KTsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICBpZiAoKCEgY3R4dEdpdmVuKSAmJiAocGN0eHQgIT0gTlVMTCkpCgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChwY3R4dCk7CiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRmFjZXRWYWx1ZXM6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBDaGVja3MgdGhlIGRlZmF1bHQgdmFsdWVzIHR5cGVzLCBlc3BlY2lhbGx5IGZvciBmYWNldHMKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAoJCQkgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQpCnsKICAgIGludCByZXMsIG9sZGVycnMgPSBwY3R4dC0+bmJlcnJvcnM7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gdHlwZURlY2wtPm5hbWU7CiAgICAvKgogICAgKiBOT1RFOiBJdCBpcyBpbnRlbmRlZCB0byB1c2UgdGhlIGZhY2V0cyBsaXN0LCBpbnN0ZWFkCiAgICAqIG9mIGZhY2V0U2V0LgogICAgKi8KICAgIGlmICh0eXBlRGVjbC0+ZmFjZXRzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0ID0gdHlwZURlY2wtPmZhY2V0czsKCgkvKgoJKiBUZW1wb3JhcmlseSBhc3NpZ24gdGhlICJzY2hlbWEiIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKCSogb2YgdGhlIHBhcnNlciBjb250ZXh0LiBUaGlzIGlzIG5lZWRlZCBmb3IgTk9UQVRJT04gdmFsaWRhdGlvbi4KCSovCglpZiAocGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KHBjdHh0KSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJfQoJcGN0eHQtPnZjdHh0LT5zY2hlbWEgPSBwY3R4dC0+c2NoZW1hOwoJd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKCSAgICByZXMgPSB4bWxTY2hlbWFDaGVja0ZhY2V0KGZhY2V0LCB0eXBlRGVjbCwgcGN0eHQsIG5hbWUpOwoJICAgIEhGQUlMVVJFCgkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCX0KCXBjdHh0LT52Y3R4dC0+c2NoZW1hID0gTlVMTDsKICAgIH0KICAgIGlmIChvbGRlcnJzICE9IHBjdHh0LT5uYmVycm9ycykKCXJldHVybihwY3R4dC0+ZXJyKTsKICAgIHJldHVybigwKTsKZXhpdF9mYWlsdXJlOgogICAgcmV0dXJuKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmOgogKiBAY3R4dE1Hcm91cDogdGhlIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBzZWxmTUdyb3VwOiB0aGUgc2Vjb25kIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBwYXJ0aWNsZTogdGhlIGZpcnN0IHBhcnRpY2xlCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIHBhcnRpY2xlIHdpdGggdGhlIGNpcmN1bGFyIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLAogKiBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGdyb3VwRGVmLAoJCQkgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBwYXJ0aWNsZSkKewogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2lyYyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciB0ZXJtOwogICAgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBnZGVmOwoKICAgIGZvciAoOyBwYXJ0aWNsZSAhPSBOVUxMOyBwYXJ0aWNsZSA9IHBhcnRpY2xlLT5uZXh0KSB7Cgl0ZXJtID0gcGFydGljbGUtPmNoaWxkcmVuOwoJaWYgKHRlcm0gPT0gTlVMTCkKCSAgICBjb250aW51ZTsKCXN3aXRjaCAodGVybS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCWdkZWYgPSAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgdGVybTsKCQlpZiAoZ2RlZiA9PSBncm91cERlZikKCQkgICAgcmV0dXJuIChwYXJ0aWNsZSk7CgkJLyoKCQkqIE1hcmsgdGhpcyBtb2RlbCBncm91cCBkZWZpbml0aW9uIHRvIGF2b2lkIGluZmluaXRlCgkJKiByZWN1cnNpb24gb24gY2lyY3VsYXIgcmVmZXJlbmNlcyBub3QgeWV0IGV4YW1pbmVkLgoJCSovCgkJaWYgKGdkZWYtPmZsYWdzICYgWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEKQoJCSAgICBjb250aW51ZTsKCQlpZiAoZ2RlZi0+Y2hpbGRyZW4gIT0gTlVMTCkgewoJCSAgICBnZGVmLT5mbGFncyB8PSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQ7CgkJICAgIGNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihncm91cERlZiwKCQkJZ2RlZi0+Y2hpbGRyZW4tPmNoaWxkcmVuKTsKCQkgICAgZ2RlZi0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEOwoJCSAgICBpZiAoY2lyYyAhPSBOVUxMKQoJCQlyZXR1cm4gKGNpcmMpOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihncm91cERlZiwgdGVybS0+Y2hpbGRyZW4pOwoJCWlmIChjaXJjICE9IE5VTEwpCgkJICAgIHJldHVybiAoY2lyYyk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXI6CiAqIEBpdGVtOiAgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgdG8gbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtLAoJCQkgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IE1vZGVsIEdyb3VwIENvcnJlY3QKICAgICogMiBDaXJjdWxhciBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIHdpdGhpbiB0aGUge3BhcnRpY2xlc30KICAgICogb2YgYSBncm91cCB0aGVyZSBtdXN0IG5vdCBiZSBhdCBhbnkgZGVwdGggYSBwYXJ0aWNsZSB3aG9zZSB7dGVybX0KICAgICogaXMgdGhlIGdyb3VwIGl0c2VsZi4KICAgICovCiAgICBpZiAoKGl0ZW0gPT0gTlVMTCkgfHwKCShpdGVtLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgfHwKCShpdGVtLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKGl0ZW0sIGl0ZW0tPmNoaWxkcmVuLT5jaGlsZHJlbik7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICAvKgoJICAgICogVE9ETzogVGhlIGVycm9yIHJlcG9ydCBpcyBub3QgYWRlcXVhdGU6IHRoaXMgY29uc3RyYWludAoJICAgICogaXMgZGVmaW5lZCBmb3IgbW9kZWwgZ3JvdXBzIGJ1dCBub3QgZGVmaW5pdGlvbnMsIGJ1dCBzaW5jZQoJICAgICogdGhlcmUgY2Fubm90IGJlIGFueSBjaXJjdWxhciBtb2RlbCBncm91cHMgd2l0aG91dCBhIG1vZGVsIGdyb3VwCgkgICAgKiBkZWZpbml0aW9uIChpZiBub3QgdXNpbmcgYSBjb25zdHJ1Y3Rpb24gQVBJKSwgd2UgY2hlY2sgdGhvc2UKCSAgICAqIGRlZmludGlvbnMgb25seS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9NR19QUk9QU19DT1JSRUNUXzIsCgkJTlVMTCwgV1hTX0lURU1fTk9ERShjaXJjKSwKCQkiQ2lyY3VsYXIgcmVmZXJlbmNlIHRvIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uICclcycgIgoJCSJkZWZpbmVkIiwgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgaXRlbS0+dGFyZ2V0TmFtZXNwYWNlLCBpdGVtLT5uYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgLyoKCSAgICAqIE5PVEU6IFdlIHdpbGwgY3V0IHRoZSByZWZlcmVuY2UgdG8gYXZvaWQgZnVydGhlcgoJICAgICogY29uZnVzaW9uIG9mIHRoZSBwcm9jZXNzb3IuIFRoaXMgaXMgYSBmYXRhbCBlcnJvci4KCSAgICAqLwoJICAgIGNpcmMtPmNoaWxkcmVuID0gTlVMTDsKCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYU1vZGVsR3JvdXBUb01vZGVsR3JvdXBEZWZGaXh1cDoKICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG1nOiAgdGhlIG1vZGVsIGdyb3VwCiAqCiAqIEFzc2lnbnMgdGhlIG1vZGVsIGdyb3VwIG9mIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zIHRvIHRoZSAidGVybSIKICogb2YgdGhlIHJlZmVyZW5jaW5nIHBhcnRpY2xlLgogKiBJbiB4bWxTY2hlbWFSZXNvbHZlTW9kZWxHcm91cFBhcnRpY2xlUmVmZXJlbmNlcyB0aGUgbW9kZWwgZ3JvdXAKICogZGVmaW5pdGlvbnMgd2VyZSBhc3NpZ25lZCB0byB0aGUgInRlcm0iLCBzaW5jZSBuZWVkZWQgZm9yIHRoZQogKiBjaXJjdWxhcml0eSBjaGVjay4KICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiAgICAgQWxsIEdyb3VwIExpbWl0ZWQgKGNvcy1hbGwtbGltaXRlZCkgKDEuMikKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYU1vZGVsR3JvdXBUb01vZGVsR3JvdXBEZWZGaXh1cCgKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCBBVFRSSUJVVEVfVU5VU0VELAogICAgeG1sU2NoZW1hTW9kZWxHcm91cFB0ciBtZykKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUgPSBXWFNfTU9ERUxHUk9VUF9QQVJUSUNMRShtZyk7CgogICAgd2hpbGUgKHBhcnRpY2xlICE9IE5VTEwpIHsKCWlmICgoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpID09IE5VTEwpIHx8CgkgICAgKChXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSkpLT50eXBlICE9CgkJWE1MX1NDSEVNQV9UWVBFX0dST1VQKSkKCXsKCSAgICBwYXJ0aWNsZSA9IFdYU19QVENfQ0FTVCBwYXJ0aWNsZS0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0gCglpZiAoV1hTX01PREVMR1JPVVBERUZfTU9ERUwoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpKSA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlbW92ZSB0aGUgcGFydGljbGUuCgkgICAgKi8KCSAgICBXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSkgPSBOVUxMOwoJICAgIHBhcnRpY2xlID0gV1hTX1BUQ19DQVNUIHBhcnRpY2xlLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQoJLyoKCSogQXNzaWduIHRoZSBtb2RlbCBncm91cCB0byB0aGUge3Rlcm19IG9mIHRoZSBwYXJ0aWNsZS4KCSovCglXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSkgPQoJICAgIFdYU19UUkVFX0NBU1QgV1hTX01PREVMR1JPVVBERUZfTU9ERUwoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpKTsKCglwYXJ0aWNsZSA9IFdYU19QVENfQ0FTVCBwYXJ0aWNsZS0+bmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXJSZWN1cjoKICogQGN0eHRHcjogdGhlIHNlYXJjaGVkIGF0dHJpYnV0ZSBncm91cAogKiBAYXR0cjogdGhlIGN1cnJlbnQgYXR0cmlidXRlIGxpc3QgdG8gYmUgcHJvY2Vzc2VkCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tBdHRyR3JvdXBDaXJjdWxhciBvbmx5LgogKgogKiBSZXR1cm5zIHRoZSBjaXJjdWxhciBhdHRyaWJ1dGUgZ3JvdSByZWZlcmVuY2UsIG90aGVyd2lzZSBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYVFOYW1lUmVmUHRyCnhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXJSZWN1cih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjdHh0R3IsCgkJCQkgICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGdyOwogICAgeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmLCBjaXJjOwogICAgaW50IGk7CiAgICAvKgogICAgKiBXZSB3aWxsIHNlYXJjaCBmb3IgYW4gYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZSB3aGljaAogICAgKiByZWZlcmVuY2VzIHRoZSBjb250ZXh0IGF0dHJpYnV0ZSBncm91cC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CglyZWYgPSBsaXN0LT5pdGVtc1tpXTsKCWlmICgocmVmLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUYpICYmCgkgICAgKHJlZi0+aXRlbVR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSAmJgoJICAgIChyZWYtPml0ZW0gIT0gTlVMTCkpCgl7CgkgICAgZ3IgPSBXWFNfQVRUUl9HUk9VUF9DQVNUIHJlZi0+aXRlbTsKCSAgICBpZiAoZ3IgPT0gY3R4dEdyKQoJCXJldHVybihyZWYpOwoJICAgIGlmIChnci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfTUFSS0VEKQoJCWNvbnRpbnVlOwkgICAgCgkgICAgLyoKCSAgICAqIE1hcmsgYXMgdmlzaXRlZCB0byBhdm9pZCBpbmZpbml0ZSByZWN1cnNpb24gb24KCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCSAgICAqLwoJICAgIGlmICgoZ3ItPmF0dHJVc2VzKSAmJgoJCShnci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfSEFTX1JFRlMpKQoJICAgIHsKCQlnci0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRDsKCQljaXJjID0geG1sU2NoZW1hQ2hlY2tBdHRyR3JvdXBDaXJjdWxhclJlY3VyKGN0eHRHciwKCQkgICAgKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSBnci0+YXR0clVzZXMpOwkJCgkJZ3ItPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCSAgICB9CgkgICAgCgl9CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tBdHRyR3JvdXBDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIG9mIGF0dHJpYnV0ZSBncm91cHMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyLAoJCQkJeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICAvKgogICAgKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKICAgICogQXR0cmlidXRlIEdyb3VwIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sKICAgICogMyBDaXJjdWxhciBncm91cCByZWZlcmVuY2UgaXMgZGlzYWxsb3dlZCBvdXRzaWRlIDxyZWRlZmluZT4uCiAgICAqIFRoYXQgaXMsIHVubGVzcyB0aGlzIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHBhcmVudCBpcwogICAgKiA8cmVkZWZpbmU+LCB0aGVuIGFtb25nIHRoZSBbY2hpbGRyZW5dLCBpZiBhbnksIHRoZXJlIG11c3QKICAgICogbm90IGJlIGFuIDxhdHRyaWJ1dGVHcm91cD4gd2l0aCByZWYgW2F0dHJpYnV0ZV0gd2hpY2ggcmVzb2x2ZXMKICAgICogdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4gSW5kaXJlY3QKICAgICogY2lyY3VsYXJpdHkgaXMgYWxzbyBydWxlZCBvdXQuIFRoYXQgaXMsIHdoZW4gUU5hbWUgcmVzb2x1dGlvbgogICAgKiAoU2NoZW1hIERvY3VtZW50KSAopzMuMTUuMykgaXMgYXBwbGllZCB0byBhILdRTmFtZbcgYXJpc2luZyBmcm9tCiAgICAqIGFueSA8YXR0cmlidXRlR3JvdXA+cyB3aXRoIGEgcmVmIFthdHRyaWJ1dGVdIGFtb25nIHRoZSBbY2hpbGRyZW5dLAogICAgKiBpdCBtdXN0IG5vdCBiZSB0aGUgY2FzZSB0aGF0IGEgt1FOYW1ltyBpcyBlbmNvdW50ZXJlZCBhdCBhbnkgZGVwdGgKICAgICogd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4KICAgICovCiAgICBpZiAoYXR0ckdyLT5hdHRyVXNlcyA9PSBOVUxMKQoJcmV0dXJuKDApOwogICAgZWxzZSBpZiAoKGF0dHJHci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfSEFTX1JFRlMpID09IDApCglyZXR1cm4oMCk7CiAgICBlbHNlIHsKCXhtbFNjaGVtYVFOYW1lUmVmUHRyIGNpcmM7CgkKCWNpcmMgPSB4bWxTY2hlbWFDaGVja0F0dHJHcm91cENpcmN1bGFyUmVjdXIoYXR0ckdyLAoJICAgICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgYXR0ckdyLT5hdHRyVXNlcyk7CQoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfR1JPVVBfMywKCQlOVUxMLCBXWFNfSVRFTV9OT0RFKFdYU19CQVNJQ19DQVNUIGNpcmMpLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIGF0dHJpYnV0ZSBncm91cCAnJXMnICIKCQkiZGVmaW5lZCIsIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGF0dHJHcikpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICAvKgoJICAgICogTk9URTogV2Ugd2lsbCBjdXQgdGhlIHJlZmVyZW5jZSB0byBhdm9pZCBmdXJ0aGVyCgkgICAgKiBjb25mdXNpb24gb2YgdGhlIHByb2Nlc3Nvci4KCSAgICAqIEJBRFNQRUMgVE9ETzogVGhlIHNwZWMgc2hvdWxkIGRlZmluZSBob3cgdG8gcHJvY2VzcyBpbiB0aGlzIGNhc2UuCgkgICAgKi8KCSAgICBjaXJjLT5pdGVtID0gTlVMTDsKCSAgICByZXR1cm4oY3R4dC0+ZXJyKTsKCX0KICAgIH0KICAgIHJldHVybigwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cEV4cGFuZFJlZnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyKTsKCi8qKgogKiB4bWxTY2hlbWFFeHBhbmRBdHRyaWJ1dGVHcm91cFJlZnM6CiAqIEBwY3R4dDogdGhlIHBhcnNlciBjb250ZXh0CiAqIEBub2RlOiB0aGUgbm9kZSBvZiB0aGUgY29tcG9uZW50IGhvbGRpbmcgdGhlIGF0dHJpYnV0ZSB1c2VzCiAqIEBjb21wbGV0ZVdpbGQ6IHRoZSBpbnRlcnNlY3RlZCB3aWxkY2FyZCB0byBiZSByZXR1cm5lZCAKICogQGxpc3Q6IHRoZSBhdHRyaWJ1dGUgdXNlcwogKgogKiBTdWJzdGl0dXRlcyBjb250YWluZWQgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMKICogZm9yIHRoZWlyIGF0dHJpYnV0ZSB1c2VzLiBXaWxjYXJkcyBhcmUgaW50ZXJzZWN0ZWQuCiAqIEF0dHJpYnV0ZSB1c2UgcHJvaGliaXRpb25zIGFyZSByZW1vdmVkIGZyb20gdGhlIGxpc3QKICogYW5kIHJldHVybmVkIHZpYSB0aGUgQHByb2hpYnMgbGlzdC4KICogUG9pbnRsZXNzbmVzcyBvZiBhdHRyLiBwcm9oaWJzLCBpZiBhIG1hdGNoaW5nIGF0dHIuIGRlY2wKICogaXMgZXhpc3RlbnQgYSB3ZWxsLCBhcmUgY2hlY2tlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtLAoJCQkJICB4bWxTY2hlbWFXaWxkY2FyZFB0ciAqY29tcGxldGVXaWxkLAoJCQkJICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LAoJCQkJICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBwcm9oaWJzKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncjsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2U7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBzdWJsaXN0OwogICAgaW50IGksIGo7CiAgICBpbnQgY3JlYXRlZCA9ICgqY29tcGxldGVXaWxkID09IE5VTEwpID8gMCA6IDE7CgogICAgaWYgKHByb2hpYnMpCglwcm9oaWJzLT5uYkl0ZW1zID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7Cgl1c2UgPSBsaXN0LT5pdGVtc1tpXTsKCglpZiAodXNlLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfQVRUUl9VU0VfUFJPSElCKSB7CSAgICAKCSAgICBpZiAocHJvaGlicyA9PSBOVUxMKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzIiwKCQkgICAgInVuZXhwZWN0ZWQgYXR0ciBwcm9oaWJpdGlvbiBmb3VuZCIpOwoJCXJldHVybigtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBSZW1vdmUgZnJvbSBhdHRyaWJ1dGUgdXNlcy4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZShsaXN0LCBpKSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJICAgIGktLTsKCSAgICAvKgoJICAgICogTm90ZSB0aGF0IGR1cGxpY2F0ZSBwcm9oaWJpdGlvbnMgd2VyZSBhbHJlYWR5CgkgICAgKiBoYW5kbGVkIGF0IHBhcnNpbmcgdGltZS4KCSAgICAqLwkgICAgCgkgICAgLyoKCSAgICAqIEFkZCB0byBsaXN0IG9mIHByb2hpYml0aW9ucy4KCSAgICAqLwoJICAgIHhtbFNjaGVtYUl0ZW1MaXN0QWRkU2l6ZShwcm9oaWJzLCAyLCB1c2UpOwoJICAgIGNvbnRpbnVlOwoJfQoJaWYgKCh1c2UtPnR5cGUgPT0gWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRikgJiYKCSAgICAoKFdYU19RTkFNRV9DQVNUIHVzZSktPml0ZW1UeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkpCgl7CgkgICAgaWYgKChXWFNfUU5BTUVfQ0FTVCB1c2UpLT5pdGVtID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCSAgICBnciA9IFdYU19BVFRSX0dST1VQX0NBU1QgKFdYU19RTkFNRV9DQVNUIHVzZSktPml0ZW07CgkgICAgLyoKCSAgICAqIEV4cGFuZCB0aGUgcmVmZXJlbmNlZCBhdHRyLiBncm91cC4KCSAgICAqIFRPRE86IHJlbW92ZSB0aGlzLCB0aGlzIGlzIGRvbmUgaW4gYSBwcmV2aW91cyBzdGVwLCBzbwoJICAgICogYWxyZWFkeSBkb25lIGhlcmUuCgkgICAgKi8KCSAgICBpZiAoKGdyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEKSA9PSAwKSB7CgkJaWYgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwRXhwYW5kUmVmcyhwY3R4dCwgZ3IpID09IC0xKQoJCSAgICByZXR1cm4oLTEpOwoJICAgIH0KCSAgICAvKgoJICAgICogQnVpbGQgdGhlICdjb21wbGV0ZScgd2lsZGNhcmQ7IGkuZS4gaW50ZXJzZWN0IG11bHRpcGxlCgkgICAgKiB3aWxkY2FyZHMuCgkgICAgKi8KCSAgICBpZiAoZ3ItPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCQlpZiAoKmNvbXBsZXRlV2lsZCA9PSBOVUxMKSB7CgkJICAgICpjb21wbGV0ZVdpbGQgPSBnci0+YXR0cmlidXRlV2lsZGNhcmQ7CgkJfSBlbHNlIHsKCQkgICAgaWYgKCEgY3JlYXRlZCkgewoJCQl4bWxTY2hlbWFXaWxkY2FyZFB0ciB0bXBXaWxkOwoKCQkJIC8qCgkJCSogQ29weSB0aGUgZmlyc3QgZW5jb3VudGVyZWQgd2lsZGNhcmQgYXMgY29udGV4dCwKCQkJKiBleGNlcHQgZm9yIHRoZSBhbm5vdGF0aW9uLgoJCQkqCgkJCSogQWx0aG91Z2ggdGhlIGNvbXBsZXRlIHdpbGRjYXJkIG1pZ2h0IG5vdCBjb3JyZXNwb25kCgkJCSogdG8gYW55IG5vZGUgaW4gdGhlIHNjaGVtYSwgd2Ugd2lsbCBhbmNob3IgaXQgb24KCQkJKiB0aGUgbm9kZSBvZiB0aGUgb3duZXIgY29tcG9uZW50LgoJCQkqLwoJCQl0bXBXaWxkID0gIHhtbFNjaGVtYUFkZFdpbGRjYXJkKHBjdHh0LCBwY3R4dC0+c2NoZW1hLAoJCQkgICAgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEUsCgkJCSAgICBXWFNfSVRFTV9OT0RFKGl0ZW0pKTsKCQkJaWYgKHRtcFdpbGQgPT0gTlVMTCkKCQkJICAgIHJldHVybigtMSk7CgkJCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhwY3R4dCwKCQkJICAgIHRtcFdpbGQsICpjb21wbGV0ZVdpbGQpID09IC0xKQoJCQkgICAgcmV0dXJuICgtMSk7CgkJCXRtcFdpbGQtPnByb2Nlc3NDb250ZW50cyA9ICgqY29tcGxldGVXaWxkKS0+cHJvY2Vzc0NvbnRlbnRzOwoJCQkqY29tcGxldGVXaWxkID0gdG1wV2lsZDsKCQkJY3JlYXRlZCA9IDE7CgkJICAgIH0KCQkgICAgCgkJICAgIGlmICh4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMocGN0eHQsICpjb21wbGV0ZVdpbGQsCgkJCWdyLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybigtMSk7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogSnVzdCByZW1vdmUgdGhlIHJlZmVyZW5jZSBpZiB0aGUgcmVmZXJlbmNlZCBncm91cCBkb2VzIG5vdAoJICAgICogY29udGFpbiBhbnkgYXR0cmlidXRlIHVzZXMuCgkgICAgKi8KCSAgICBpZiAoZ3ItPmF0dHJVc2VzID09IE5VTEwpIHsKCQlpZiAoeG1sU2NoZW1hSXRlbUxpc3RSZW1vdmUobGlzdCwgaSkgPT0gLTEpCgkJICAgIHJldHVybigtMSk7CgkJaS0tOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICAvKgoJICAgICogQWRkIHRoZSBhdHRyaWJ1dGUgdXNlcy4KCSAgICAqLwoJICAgIHN1Ymxpc3QgPSAoKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSBnci0+YXR0clVzZXMpOwoJICAgIGlmIChzdWJsaXN0LT5uYkl0ZW1zICE9IDApIHsKCQlsaXN0LT5pdGVtc1tpXSA9IHN1Ymxpc3QtPml0ZW1zWzBdOwoJCWlmIChzdWJsaXN0LT5uYkl0ZW1zICE9IDEpIHsKCQkgICAgZm9yIChqID0gMTsgaiA8IHN1Ymxpc3QtPm5iSXRlbXM7IGorKykgewoJCQlpKys7CgkJCWlmICh4bWxTY2hlbWFJdGVtTGlzdEluc2VydChsaXN0LAoJCQkJc3VibGlzdC0+aXRlbXNbal0sIGkpID09IC0xKQoJCQkgICAgcmV0dXJuKC0xKTsKCQkgICAgfQoJCX0KCSAgICB9CSAgICAgIAoJfQoKICAgIH0KICAgIC8qCiAgICAqIEhhbmRsZSBwb2ludGxlc3MgcHJvaGliaXRpb25zIG9mIGRlY2xhcmVkIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKHByb2hpYnMgJiYgKHByb2hpYnMtPm5iSXRlbXMgIT0gMCkgJiYgKGxpc3QtPm5iSXRlbXMgIT0gMCkpIHsKCXhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0ciBwcm9oaWI7CgoJZm9yIChpID0gcHJvaGlicy0+bmJJdGVtcyAtMTsgaSA+PSAwOyBpLS0pIHsKCSAgICBwcm9oaWIgPSBwcm9oaWJzLT5pdGVtc1tpXTsKCSAgICBmb3IgKGogPSAwOyBqIDwgbGlzdC0+bmJJdGVtczsgaisrKSB7CgkJdXNlID0gbGlzdC0+aXRlbXNbal07CgoJCWlmICgocHJvaGliLT5uYW1lID09IFdYU19BVFRSVVNFX0RFQ0xfTkFNRSh1c2UpKSAmJgoJCSAgICAocHJvaGliLT50YXJnZXROYW1lc3BhY2UgPT0gV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKSkpCgkJewoJCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKCQkgICAgeG1sU2NoZW1hQ3VzdG9tV2FybmluZyhBQ1RYVF9DQVNUIHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9XQVJOX0FUVFJfUE9JTlRMRVNTX1BST0gsCgkJCXByb2hpYi0+bm9kZSwgTlVMTCwKCQkJIlNraXBwaW5nIHBvaW50bGVzcyBhdHRyaWJ1dGUgdXNlIHByb2hpYml0aW9uICIKCQkJIiclcycsIHNpbmNlIGEgY29ycmVzcG9uZGluZyBhdHRyaWJ1dGUgdXNlICIKCQkJImV4aXN0cyBhbHJlYWR5IGluIHRoZSB0eXBlIGRlZmluaXRpb24iLAoJCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkgICAgcHJvaGliLT50YXJnZXROYW1lc3BhY2UsIHByb2hpYi0+bmFtZSksCgkJCU5VTEwsIE5VTEwpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkJICAgIC8qCgkJICAgICogUmVtb3ZlIHRoZSBwcm9oaWJpdGlvbi4KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYUl0ZW1MaXN0UmVtb3ZlKHByb2hpYnMsIGkpID09IC0xKQoJCQlyZXR1cm4oLTEpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBFeHBhbmRSZWZzOgogKiBAcGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQGF0dHJHcjogIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiAKICoKICogQ29tcHV0YXRpb24gb2Y6CiAqIHthdHRyaWJ1dGUgdXNlc30gcHJvcGVydHkKICoge2F0dHJpYnV0ZSB3aWxkY2FyZH0gcHJvcGVydHkKICoKICogU3Vic3RpdHV0ZXMgY29udGFpbmVkIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzCiAqIGZvciB0aGVpciBhdHRyaWJ1dGUgdXNlcy4gV2lsY2FyZHMgYXJlIGludGVyc2VjdGVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cEV4cGFuZFJlZnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyKQp7ICAKICAgIGlmICgoYXR0ckdyLT5hdHRyVXNlcyA9PSBOVUxMKSB8fAoJKGF0dHJHci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCkpCglyZXR1cm4oMCk7CgogICAgYXR0ckdyLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRDsKICAgIGlmICh4bWxTY2hlbWFFeHBhbmRBdHRyaWJ1dGVHcm91cFJlZnMocGN0eHQsIFdYU19CQVNJQ19DQVNUIGF0dHJHciwKCSYoYXR0ckdyLT5hdHRyaWJ1dGVXaWxkY2FyZCksIGF0dHJHci0+YXR0clVzZXMsIE5VTEwpID09IC0xKQoJcmV0dXJuKC0xKTsgICAgCiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cEV4cGFuZFJlZnM6CiAqIEBwY3R4dDogIHRoZSBwYXJzZXIgY29udGV4dAogKiBAYXR0ckdyOiAgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIAogKgogKiBTdWJzdGl0dXRlcyBjb250YWluZWQgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMKICogZm9yIHRoZWlyIGF0dHJpYnV0ZSB1c2VzLiBXaWxjYXJkcyBhcmUgaW50ZXJzZWN0ZWQuCiAqIAogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqICAgIEF0dHJpYnV0ZSBHcm91cCBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCAoYWctcHJvcHMtY29ycmVjdCkgCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQUdQcm9wc0NvcnJlY3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyKQp7ICAKICAgIC8qCiAgICAqIFNQRUMgYWctcHJvcHMtY29ycmVjdAogICAgKiAoMSkgIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24KICAgICogbXVzdCBiZSBhcyBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gVGhlIEF0dHJpYnV0ZQogICAgKiBHcm91cCBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnQgKKczLjYuMSksIG1vZHVsbyB0aGUgaW1wYWN0IG9mCiAgICAqIE1pc3NpbmcgU3ViLWNvbXBvbmVudHMgKKc1LjMpOyIKICAgICovCiAgICAKICAgIGlmICgoYXR0ckdyLT5hdHRyVXNlcyAhPSBOVUxMKSAmJgoJKFdYU19MSVNUX0NBU1QgYXR0ckdyLT5hdHRyVXNlcyktPm5iSXRlbXMgPiAxKQogICAgewoJeG1sU2NoZW1hSXRlbUxpc3RQdHIgdXNlcyA9IFdYU19MSVNUX0NBU1QgYXR0ckdyLT5hdHRyVXNlczsKCXhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2UsIHRtcDsKCWludCBpLCBqLCBoYXNJZCA9IDA7CgoJZm9yIChpID0gdXNlcy0+bmJJdGVtcyAtMTsgaSA+PSAwOyBpLS0pIHsKCSAgICB1c2UgPSB1c2VzLT5pdGVtc1tpXTsJICAgIAoJICAgIC8qCgkgICAgKiBTUEVDIGFnLXByb3BzLWNvcnJlY3QKCSAgICAqICgyKSAiVHdvIGRpc3RpbmN0IG1lbWJlcnMgb2YgdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCBub3QgaGF2ZQoJICAgICoge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn1zIGJvdGggb2Ygd2hvc2Uge25hbWV9cyBtYXRjaCBhbmQgd2hvc2UKCSAgICAqIHt0YXJnZXQgbmFtZXNwYWNlfXMgYXJlIGlkZW50aWNhbC4iCgkgICAgKi8KCSAgICBpZiAoaSA+IDApIHsKCQlmb3IgKGogPSBpIC0xOyBqID49IDA7IGotLSkgewoJCSAgICB0bXAgPSB1c2VzLT5pdGVtc1tqXTsKCQkgICAgaWYgKChXWFNfQVRUUlVTRV9ERUNMX05BTUUodXNlKSA9PQoJCQlXWFNfQVRUUlVTRV9ERUNMX05BTUUodG1wKSkgJiYKCQkJKFdYU19BVFRSVVNFX0RFQ0xfVE5TKHVzZSkgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9UTlModG1wKSkpCgkJICAgIHsKCQkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkJCgkJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfQUdfUFJPUFNfQ09SUkVDVCwKCQkJICAgIGF0dHJHci0+bm9kZSwgV1hTX0JBU0lDX0NBU1QgYXR0ckdyLAoJCQkgICAgIkR1cGxpY2F0ZSAlcyIsCgkJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyLCB1c2UpLAoJCQkgICAgTlVMTCk7CgkJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQkJLyoKCQkJKiBSZW1vdmUgdGhlIGR1cGxpY2F0ZS4KCQkJKi8KCQkJaWYgKHhtbFNjaGVtYUl0ZW1MaXN0UmVtb3ZlKHVzZXMsIGkpID09IC0xKQoJCQkgICAgcmV0dXJuKC0xKTsKCQkJZ290byBuZXh0X3VzZTsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIFNQRUMgYWctcHJvcHMtY29ycmVjdAoJICAgICogKDMpICJUd28gZGlzdGluY3QgbWVtYmVycyBvZiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IG5vdCBoYXZlCgkgICAgKiB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufXMgYm90aCBvZiB3aG9zZSB7dHlwZSBkZWZpbml0aW9ufXMgYXJlIG9yCgkgICAgKiBhcmUgZGVyaXZlZCBmcm9tIElELiIKCSAgICAqIFRPRE86IERvZXMgJ2Rlcml2ZWQnIGluY2x1ZGUgbWVtYmVyLXR5cGVzIG9mIHVuaW9ucz8KCSAgICAqLwoJICAgIGlmIChXWFNfQVRUUlVTRV9UWVBFREVGKHVzZSkgIT0gTlVMTCkgewkJCgkJaWYgKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSgKCQkgICAgV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpLCBYTUxfU0NIRU1BU19JRCkpCgkJewkJCgkJICAgIGlmIChoYXNJZCkgewoJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCQkKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9BR19QUk9QU19DT1JSRUNULAoJCQkgICAgYXR0ckdyLT5ub2RlLCBXWFNfQkFTSUNfQ0FTVCBhdHRyR3IsCgkJCSAgICAiVGhlcmUgbXVzdCBub3QgZXhpc3QgbW9yZSB0aGFuIG9uZSBhdHRyaWJ1dGUgIgoJCQkgICAgImRlY2xhcmF0aW9uIG9mIHR5cGUgJ3hzOklEJyAiCgkJCSAgICAiKG9yIGRlcml2ZWQgZnJvbSAneHM6SUQnKS4gVGhlICVzIHZpb2xhdGVzIHRoaXMgIgoJCQkgICAgImNvbnN0cmFpbnQiLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgdXNlKSwKCQkJICAgIE5VTEwpOwoJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCWlmICh4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZSh1c2VzLCBpKSA9PSAtMSkKCQkJICAgIHJldHVybigtMSk7CgkJICAgIH0JCSAgICAKCQkgICAgaGFzSWQgPSAxOwoJCX0KCSAgICB9Cm5leHRfdXNlOiB7fQoJfQogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZUF0dHJHcm91cFJlZmVyZW5jZXM6CiAqIEBhdHRyZ3JwRGVjbDogIHRoZSBzY2hlbWEgYXR0cmlidXRlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqCiAqIFJlc29sdmVzIHJlZmVyZW5jZXMgdG8gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZXNvbHZlQXR0ckdyb3VwUmVmZXJlbmNlcyh4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWYsCgkJCQkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncm91cDsKCiAgICBpZiAocmVmLT5pdGVtICE9IE5VTEwpCiAgICAgICAgcmV0dXJuKDApOwogICAgZ3JvdXAgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChjdHh0LT5zY2hlbWEsCglyZWYtPm5hbWUsCglyZWYtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBpZiAoZ3JvdXAgPT0gTlVMTCkgewoJeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkgICAgTlVMTCwgcmVmLT5ub2RlLAoJICAgICJyZWYiLCByZWYtPm5hbWUsIHJlZi0+dGFyZ2V0TmFtZXNwYWNlLAoJICAgIHJlZi0+aXRlbVR5cGUsIE5VTEwpOwoJcmV0dXJuKGN0eHQtPmVycik7CiAgICB9CiAgICByZWYtPml0ZW0gPSBXWFNfQkFTSUNfQ0FTVCBncm91cDsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQXR0clByb3BzQ29ycmVjdDoKICogQGl0ZW06ICBhbiBzY2hlbWEgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqICAgIEF0dHJpYnV0ZSBEZWNsYXJhdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QgKGEtcHJvcHMtY29ycmVjdCkKICoKICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBjb25zdHJhaW50cyBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKiBOT1RFIHRoYXQgdGhpcyBuZWVkcyB0aGUgc2ltbGUgdHlwZSBkZWZpbml0aW9ucyB0byBiZSBhbHJlYWR5CiAqICAgYnVpbGRlZCBhbmQgY2hlY2tlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tBdHRyUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKewoKICAgIC8qCiAgICAqIFNQRUMgYS1wcm9wcy1jb3JyZWN0ICgxKQogICAgKiAiVGhlIHZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbXVzdAogICAgKiBiZSBhcyBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gVGhlIEF0dHJpYnV0ZQogICAgKiBEZWNsYXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50ICinMy4yLjEpLCBtb2R1bG8gdGhlIGltcGFjdCBvZgogICAgKiBNaXNzaW5nIFN1Yi1jb21wb25lbnRzICinNS4zKS4iCiAgICAqLwogICAgCiAgICBpZiAoV1hTX0FUVFJfVFlQRURFRihhdHRyKSA9PSBOVUxMKQoJcmV0dXJuKDApOwoKICAgIGlmIChhdHRyLT5kZWZWYWx1ZSAhPSBOVUxMKSB7CglpbnQgcmV0OwoKCS8qCgkqIFNQRUMgYS1wcm9wcy1jb3JyZWN0ICgzKQoJKiAiSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlCgkqIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LiIKCSovCglpZiAoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKAoJICAgIFdYU19BVFRSX1RZUEVERUYoYXR0ciksIFhNTF9TQ0hFTUFTX0lEKSkKCXsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9BX1BST1BTX0NPUlJFQ1RfMywKCQlOVUxMLCBXWFNfQkFTSUNfQ0FTVCBhdHRyLAoJCSJWYWx1ZSBjb25zdHJhaW50cyBhcmUgbm90IGFsbG93ZWQgaWYgdGhlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImlzIG9yIGlzIGRlcml2ZWQgZnJvbSB4czpJRCIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKHBjdHh0LT5lcnIpOwoJfQoJLyoKCSogU1BFQyBhLXByb3BzLWNvcnJlY3QgKDIpCgkqICJpZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsCgkqIHJlcHJlc2VudGF0aW9uIG9mIGl0cyB2YWx1ZSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0CgkqIHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIgoJKiBUT0RPOiBEb24ndCBjYXJlIGFib3V0IHRoZSAqY29ub25pY2FsKiBzdHVmZiBoZXJlLCB0aGlzIHJlcXVpcmVtZW50CgkqIHdpbGwgYmUgcmVtb3ZlZCBpbiBXWFMgMS4xIGFueXdheS4KCSovCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKEFDVFhUX0NBU1QgcGN0eHQsCgkgICAgYXR0ci0+bm9kZSwgV1hTX0FUVFJfVFlQRURFRihhdHRyKSwKCSAgICBhdHRyLT5kZWZWYWx1ZSwgJihhdHRyLT5kZWZWYWwpLAoJICAgIDEsIDEsIDApOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0F0dHJQcm9wc0NvcnJlY3QiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9BX1BST1BTX0NPUlJFQ1RfMiwKCQlOVUxMLCBXWFNfQkFTSUNfQ0FTVCBhdHRyLAoJCSJUaGUgdmFsdWUgb2YgdGhlIHZhbHVlIGNvbnN0cmFpbnQgaXMgbm90IHZhbGlkIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4ocGN0eHQtPmVycik7Cgl9CiAgICB9CiAgIAogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFDaGVja1N1YnN0R3JvdXBDaXJjdWxhcih4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLAoJCQkJIHhtbFNjaGVtYUVsZW1lbnRQdHIgYW5jZXN0b3IpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwoKICAgIGlmIChXWFNfU1VCU1RfSEVBRChhbmNlc3RvcikgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICBpZiAoV1hTX1NVQlNUX0hFQUQoYW5jZXN0b3IpID09IGVsZW1EZWNsKQoJcmV0dXJuIChhbmNlc3Rvcik7CgogICAgaWYgKFdYU19TVUJTVF9IRUFEKGFuY2VzdG9yKS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0NJUkNVTEFSKQoJcmV0dXJuIChOVUxMKTsKICAgIFdYU19TVUJTVF9IRUFEKGFuY2VzdG9yKS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9DSVJDVUxBUjsKICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrU3Vic3RHcm91cENpcmN1bGFyKGVsZW1EZWNsLAoJV1hTX1NVQlNUX0hFQUQoYW5jZXN0b3IpKTsKICAgIFdYU19TVUJTVF9IRUFEKGFuY2VzdG9yKS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRUxFTV9DSVJDVUxBUjsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1Qcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIEVsZW1lbnQgRGVjbGFyYXRpb24gUHJvcGVydGllcyBDb3JyZWN0IChlLXByb3BzLWNvcnJlY3QpCiAqCiAqIFNUQVRVUzoKICogICBtaXNzaW5nOiAoNikKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZiA9IFdYU19FTEVNX1RZUEVERUYoZWxlbURlY2wpOwogICAgLyoKICAgICogU1BFQyAoMSkgIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgogICAgKiBtdXN0IGJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgRWxlbWVudAogICAgKiBEZWNsYXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50ICinMy4zLjEpLCBtb2R1bG8gdGhlIGltcGFjdCBvZiBNaXNzaW5nCiAgICAqIFN1Yi1jb21wb25lbnRzICinNS4zKS4iCiAgICAqLwogICAgaWYgKFdYU19TVUJTVF9IRUFEKGVsZW1EZWNsKSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQgPSBXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCksIGNpcmM7CgoJeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudChoZWFkLCBwY3R4dCk7CgkvKgoJKiBTUEVDICgzKSAiSWYgdGhlcmUgaXMgYSBub24tt2Fic2VudLcge3N1YnN0aXR1dGlvbiBncm91cAoJKiBhZmZpbGlhdGlvbn0sIHRoZW4ge3Njb3BlfSBtdXN0IGJlIGdsb2JhbC4iCgkqLwoJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkgPT0gMCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzMsCgkJV1hTX0JBU0lDX0NBU1QgZWxlbURlY2wsIE5VTEwsCgkJIk9ubHkgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGNhbiBoYXZlIGEgIgoJCSJzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb24iLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfMzsKCX0KCS8qCgkqIFRPRE86IFNQRUMgKDYpICJDaXJjdWxhciBzdWJzdGl0dXRpb24gZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLgoJKiBUaGF0IGlzLCBpdCBtdXN0IG5vdCBiZSBwb3NzaWJsZSB0byByZXR1cm4gdG8gYW4gZWxlbWVudCBkZWNsYXJhdGlvbgoJKiBieSByZXBlYXRlZGx5IGZvbGxvd2luZyB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0KCSogcHJvcGVydHkuIgoJKi8KCWlmIChoZWFkID09IGVsZW1EZWNsKQoJICAgIGNpcmMgPSBoZWFkOwoJZWxzZSBpZiAoV1hTX1NVQlNUX0hFQUQoaGVhZCkgIT0gTlVMTCkKCSAgICBjaXJjID0geG1sU2NoZW1hQ2hlY2tTdWJzdEdyb3VwQ2lyY3VsYXIoaGVhZCwgaGVhZCk7CgllbHNlCgkgICAgY2lyYyA9IE5VTEw7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgeG1sQ2hhciAqc3RyQSA9IE5VTEwsICpzdHJCID0gTlVMTDsKCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwKCQlYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNiwKCQlXWFNfQkFTSUNfQ0FTVCBjaXJjLCBOVUxMLAoJCSJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiAnJXMnIGRlZmluZXMgYSBjaXJjdWxhciAiCgkJInN1YnN0aXR1dGlvbiBncm91cCB0byBlbGVtZW50IGRlY2xhcmF0aW9uICclcyciLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJBLCBjaXJjKSwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQiwgaGVhZCksCgkJTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHJBKQoJICAgIEZSRUVfQU5EX05VTEwoc3RyQikKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNjsKCX0KCS8qCgkqIFNQRUMgKDQpICJJZiB0aGVyZSBpcyBhIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LAoJKiB0aGUge3R5cGUgZGVmaW5pdGlvbn0KCSogb2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUge3R5cGUKCSogZGVmaW5pdGlvbn0gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCBnaXZlbiB0aGUgdmFsdWUKCSogb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9uc30gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAKCSogYWZmaWxpYXRpb259LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkgKKczLjQuNikKCSogKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4KSBvciBhcyBkZWZpbmVkIGluCgkqIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikgKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcwoJKiBzaW1wbGUpLiIKCSoKCSogTk9URToge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBtZWFucyB0aGUgdmFsdWVzIG9mIHRoZQoJKiBhdHRyaWJ1dGUgImZpbmFsIi4KCSovCgoJaWYgKHR5cGVEZWYgIT0gV1hTX0VMRU1fVFlQRURFRihXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCkpKSB7CgkgICAgaW50IHNldCA9IDA7CgoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfRVhURU5TSU9OKQoJCXNldCB8PSBTVUJTRVRfRVhURU5TSU9OOwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04pCgkJc2V0IHw9IFNVQlNFVF9SRVNUUklDVElPTjsKCgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LKEFDVFhUX0NBU1QgcGN0eHQsIHR5cGVEZWYsCgkJV1hTX0VMRU1fVFlQRURFRihoZWFkKSwgc2V0KSAhPSAwKSB7CgkJeG1sQ2hhciAqc3RyQSA9IE5VTEwsICpzdHJCID0gTlVMTCwgKnN0ckMgPSBOVUxMOwoKCQlyZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNDsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNCwKCQkgICAgV1hTX0JBU0lDX0NBU1QgZWxlbURlY2wsIE5VTEwsCgkJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uICclcycgd2FzICIKCQkgICAgImVpdGhlciByZWplY3RlZCBieSB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwICIKCQkgICAgImFmZmlsaWF0aW9uICclcycsIG9yIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSBpdHMgdHlwZSAiCgkJICAgICJkZWZpbml0aW9uICclcyciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQSwgdHlwZURlZiksCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCLCBoZWFkKSwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckMsIFdYU19FTEVNX1RZUEVERUYoaGVhZCkpKTsKCQlGUkVFX0FORF9OVUxMKHN0ckEpCgkJRlJFRV9BTkRfTlVMTChzdHJCKQoJCUZSRUVfQU5EX05VTEwoc3RyQykKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBTUEVDICg1KSAiSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IG9yIHt0eXBlIGRlZmluaXRpb259J3MKICAgICoge2NvbnRlbnQgdHlwZX0KICAgICogaXMgb3IgaXMgZGVyaXZlZCBmcm9tIElEIHRoZW4gdGhlcmUgbXVzdCBub3QgYmUgYSB7dmFsdWUgY29uc3RyYWludH0uCiAgICAqIE5vdGU6IFRoZSB1c2Ugb2YgSUQgYXMgYSB0eXBlIGRlZmluaXRpb24gZm9yIGVsZW1lbnRzIGdvZXMgYmV5b25kCiAgICAqIFhNTCAxLjAsIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBpZiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBpcyBkZXNpcmVkIgogICAgKi8KICAgIGlmICgoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpICYmCgkoKFdYU19JU19TSU1QTEUodHlwZURlZikgJiYKCSAgeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGVEZWYsIFhNTF9TQ0hFTUFTX0lEKSkgfHwKCSAoV1hTX0lTX0NPTVBMRVgodHlwZURlZikgJiYKCSAgV1hTX0hBU19TSU1QTEVfQ09OVEVOVCh0eXBlRGVmKSAmJgoJICB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUodHlwZURlZi0+Y29udGVudFR5cGVEZWYsCgkgICAgWE1MX1NDSEVNQVNfSUQpKSkpIHsKCglyZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNTsKCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzUsCgkgICAgV1hTX0JBU0lDX0NBU1QgZWxlbURlY2wsIE5VTEwsCgkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gKG9yIHR5cGUgZGVmaW5pdGlvbidzIGNvbnRlbnQgdHlwZSkgaXMgb3IgIgoJICAgICJpcyBkZXJpdmVkIGZyb20gSUQ7IHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBub3QgYWxsb3dlZCBpbiAiCgkgICAgImNvbmp1bmN0aW9uIHdpdGggc3VjaCBhIHR5cGUgZGVmaW5pdGlvbiIsIE5VTEwpOwogICAgfSBlbHNlIGlmIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJaW50IHZjcmV0OwoJeG1sTm9kZVB0ciBub2RlID0gTlVMTDsKCgkvKgoJKiBTUEVDICgyKSAiSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbAoJKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUKCSoge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKCSogKKczLjMuNikuIgoJKi8KCWlmICh0eXBlRGVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKHBjdHh0LCBlbGVtRGVjbC0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInRoZSB2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAoZWxlbURlY2wtPm5vZGUgIT0gTlVMTCkgewoJICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChlbGVtRGVjbC0+bm9kZSwKCQkgICAgQkFEX0NBU1QgImZpeGVkIik7CgkgICAgZWxzZQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChlbGVtRGVjbC0+bm9kZSwKCQkgICAgQkFEX0NBU1QgImRlZmF1bHQiKTsKCX0KCXZjcmV0ID0geG1sU2NoZW1hUGFyc2VDaGVja0NPU1ZhbGlkRGVmYXVsdChwY3R4dCwgbm9kZSwKCSAgICB0eXBlRGVmLCBlbGVtRGVjbC0+dmFsdWUsICYoZWxlbURlY2wtPmRlZlZhbCkpOwoJaWYgKHZjcmV0ICE9IDApIHsKCSAgICBpZiAodmNyZXQgPCAwKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hRWxlbUNoZWNrVmFsQ29uc3RyIiwKCQkgICAgImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBhbiAiCgkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9uIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHJldHVybiAodmNyZXQpOwoJfQogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRWxlbVN1YnN0R3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFN1YnN0aXR1dGlvbiBHcm91cCAoY29zLWVxdWl2LWNsYXNzKQogKgogKiBJbiBMaWJ4bWwyIHRoZSBzdWJzdC4gZ3JvdXBzIHdpbGwgYmUgcHJlY29tcHV0ZWQsIGluIHRlcm1zIG9mIHRoYXQKICogYSBsaXN0IHdpbGwgYmUgYnVpbHQgZm9yIGVhY2ggc3Vic3QuIGdyb3VwIGhlYWQsIGhvbGRpbmcgYWxsIGRpcmVjdAogKiByZWZlcmVudHMgdG8gdGhpcyBoZWFkLgogKiBOT1RFIHRoYXQgdGhpcyBmdW5jdGlvbiBuZWVkczoKICogICAxLiBjaXJjdWxhciBzdWJzdC4gZ3JvdXBzIHRvIGJlIGNoZWNrZWQgYmVmb3JlaGFuZAogKiAgIDIuIHRoZSBkZWNsYXJhdGlvbidzIHR5cGUgdG8gYmUgZGVyaXZlZCBmcm9tIHRoZSBoZWFkJ3MgdHlwZQogKgogKiBTVEFUVVM6CiAqCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0VsZW1TdWJzdEdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICBpZiAoKFdYU19TVUJTVF9IRUFEKGVsZW1EZWNsKSA9PSBOVUxMKSB8fAoJLyogU1BFQyAoMSkgIkl0cyB7YWJzdHJhY3R9IGlzIGZhbHNlLiIgKi8KCShlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZDsKCXhtbFNjaGVtYVR5cGVQdHIgaGVhZFR5cGUsIHR5cGU7CglpbnQgc2V0LCBtZXRoU2V0OwoJLyoKCSogU1BFQyAoMikgIkl0IGlzIHZhbGlkbHkgc3Vic3RpdHV0YWJsZSBmb3IgSEVBRCBzdWJqZWN0IHRvIEhFQUQncwoJKiB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBhcyB0aGUgYmxvY2tpbmcgY29uc3RyYWludCwgYXMgZGVmaW5lZCBpbgoJKiBTdWJzdGl0dXRpb24gR3JvdXAgT0sgKFRyYW5zaXRpdmUpICinMy4zLjYpLiIKCSovCglmb3IgKGhlYWQgPSBXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCk7IGhlYWQgIT0gTlVMTDsKCSAgICBoZWFkID0gV1hTX1NVQlNUX0hFQUQoaGVhZCkpIHsKCSAgICBzZXQgPSAwOwoJICAgIG1ldGhTZXQgPSAwOwoJICAgIC8qCgkgICAgKiBUaGUgYmxvY2tpbmcgY29uc3RyYWludHMuCgkgICAgKi8KCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTikKCQljb250aW51ZTsKCSAgICBoZWFkVHlwZSA9IGhlYWQtPnN1YnR5cGVzOwoJICAgIHR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXM7CgkgICAgaWYgKGhlYWRUeXBlID09IHR5cGUpCgkJZ290byBhZGRfbWVtYmVyOwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04pCgkJc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT047CgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pCgkJc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwoJICAgIC8qCgkgICAgKiBTUEVDOiBTdWJzdGl0dXRpb24gR3JvdXAgT0sgKFRyYW5zaXRpdmUpICgyLjMpCgkgICAgKiAiVGhlIHNldCBvZiBhbGwge2Rlcml2YXRpb24gbWV0aG9kfXMgaW52b2x2ZWQgaW4gdGhlCgkgICAgKiBkZXJpdmF0aW9uIG9mIEQncyB7dHlwZSBkZWZpbml0aW9ufSBmcm9tIEMncyB7dHlwZSBkZWZpbml0aW9ufQoJICAgICogZG9lcyBub3QgaW50ZXJzZWN0IHdpdGggdGhlIHVuaW9uIG9mIHRoZSBibG9ja2luZyBjb25zdHJhaW50LAoJICAgICogQydzIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9IChpZiBDIGlzIGNvbXBsZXgsIG90aGVyd2lzZSB0aGUKCSAgICAqIGVtcHR5IHNldCkgYW5kIHRoZSB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSAocmVzcGVjdGl2ZWx5IHRoZQoJICAgICogZW1wdHkgc2V0KSBvZiBhbnkgaW50ZXJtZWRpYXRlIHt0eXBlIGRlZmluaXRpb259cyBpbiB0aGUKCSAgICAqIGRlcml2YXRpb24gb2YgRCdzIHt0eXBlIGRlZmluaXRpb259IGZyb20gQydzIHt0eXBlIGRlZmluaXRpb259LiIKCSAgICAqLwoJICAgIC8qCgkgICAgKiBPUFRJTUlaRSBUT0RPOiBPcHRpbWl6ZSB0aGlzIGEgYml0LCBzaW5jZSwgaWYgdHJhdmVyc2luZyB0aGUKCSAgICAqIHN1YnN0LmhlYWQgYXhpcywgdGhlIG1ldGhTZXQgZG9lcyBub3QgbmVlZCB0byBiZSBjb21wdXRlZCBmb3IKCSAgICAqIHRoZSBmdWxsIGRlcHRoIG92ZXIgYW5kIG92ZXIuCgkgICAgKi8KCSAgICAvKgoJICAgICogVGhlIHNldCBvZiBhbGwge2Rlcml2YXRpb24gbWV0aG9kfXMgaW52b2x2ZWQgaW4gdGhlIGRlcml2YXRpb24KCSAgICAqLwoJICAgIHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZSAhPSBoZWFkVHlwZSkpIHsKCQlpZiAoKFdYU19JU19FWFRFTlNJT04odHlwZSkpICYmCgkJICAgICgobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKQoJCSAgICBtZXRoU2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwoKCQlpZiAoV1hTX0lTX1JFU1RSSUNUSU9OKHR5cGUpICYmCgkJICAgICgobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKQoJCSAgICBtZXRoU2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT047CgoJCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFRoZSB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSBvZiBhbGwgaW50ZXJtZWRpYXRlIHR5cGVzICsKCSAgICAqIHRoZSBoZWFkJ3MgdHlwZS4KCSAgICAqLwoJICAgIHR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXMtPmJhc2VUeXBlOwoJICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCQlpZiAoV1hTX0lTX0NPTVBMRVgodHlwZSkpIHsKCQkgICAgaWYgKCh0eXBlLT5mbGFncyAmCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgJiYKCQkJKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgPT0gMCkpCgkJICAgIHNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTjsKCQkgICAgaWYgKCh0eXBlLT5mbGFncyAmCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSAmJgoJCQkoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKQoJCSAgICBzZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCQl9IGVsc2UKCQkgICAgYnJlYWs7CgkJaWYgKHR5cGUgPT0gaGVhZFR5cGUpCgkJICAgIGJyZWFrOwoJCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKCSAgICB9CgkgICAgaWYgKChzZXQgIT0gMCkgJiYKCQkoKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgJiYKCQkobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSkgfHwKCQkoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pICYmCgkJKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSkpKSB7CgkJY29udGludWU7CgkgICAgfQphZGRfbWVtYmVyOgoJICAgIHhtbFNjaGVtYUFkZEVsZW1lbnRTdWJzdGl0dXRpb25NZW1iZXIoY3R4dCwgaGVhZCwgZWxlbURlY2wpOwoJICAgIGlmICgoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1NVQlNUX0dST1VQX0hFQUQpID09IDApCgkJaGVhZC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9TVUJTVF9HUk9VUF9IRUFEOwoJfQogICAgfQp9CgojaWZkZWYgV1hTX0VMRU1fREVDTF9DT05TX0VOQUJMRUQgLyogZW5hYmxlIHdoZW4gZmluaXNoZWQgKi8KLyoqCiAqIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQKICogQHBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjdHh0Q29tcG9uZW50OiB0aGUgY29udGV4dCBjb21wb25lbnQgKGFuIGVsZW1lbnQgZGVjbGFyYXRpb24pCiAqIEBjdHh0UGFydGljbGU6IHRoZSBmaXJzdCBwYXJ0aWNsZSBvZiB0aGUgY29udGV4dCBjb21wb25lbnQKICogQHNlYXJjaFBhcnRpY2xlOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZSB0byBiZSBhbmFseXNlZAogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVjbGFyYXRpb25zIENvbnNpc3RlbnQgCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb25zaXN0ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGN0eHRDb21wb25lbnQsCgkJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgY3R4dFBhcnRpY2xlLAkJCQkgICAgCgkJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgc2VhcmNoUGFydGljbGUsCgkJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgY3VyUGFydGljbGUsCgkJCQkgICAgaW50IHNlYXJjaCkKewogICAgcmV0dXJuKDApOwoKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgY3VyID0gY3VyUGFydGljbGU7CiAgICBpZiAoY3VyUGFydGljbGUgPT0gTlVMTCkgewkKCXJldHVybigwKTsKICAgIH0KICAgIGlmIChXWFNfUEFSVElDTEVfVEVSTShjdXJQYXJ0aWNsZSkgPT0gTlVMTCkgewoJLyoKCSogSnVzdCByZXR1cm4gaW4gdGhpcyBjYXNlLiBBIG1pc3NpbmcgInRlcm0iIG9mIHRoZSBwYXJ0aWNsZQoJKiBtaWdodCBhcmlzZSBkdWUgdG8gYW4gaW52YWxpZCAidGVybSIgY29tcG9uZW50LgoJKi8KCXJldHVybigwKTsKICAgIH0gICAgCiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXN3aXRjaCAoV1hTX1BBUlRJQ0xFX1RFUk0oY3VyKS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCWlmIChzZWFyY2ggPT0gMCkgewoJCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29uc2lzdGVudChwY3R4dCwKCQkJY3R4dENvbXBvbmVudCwgY3R4dFBhcnRpY2xlLCBjdXIsIGN0eHRQYXJ0aWNsZSwgMSk7CgkJICAgIGlmIChyZXQgIT0gMCkKCQkJcmV0dXJuKHJldCk7CQkgICAgCgkJfSBlbHNlIHsKCQkgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtID0KCQkJV1hTX0VMRU1fQ0FTVChXWFNfUEFSVElDTEVfVEVSTShjdXIpKTsKCQkgICAgLyoKCQkgICAgKiBTUEVDIEVsZW1lbnQgRGVjbGFyYXRpb25zIENvbnNpc3RlbnQ6CgkJICAgICogIklmIHRoZSB7cGFydGljbGVzfSBjb250YWlucywgZWl0aGVyIGRpcmVjdGx5LAoJCSAgICAqIGluZGlyZWN0bHkgKHRoYXQgaXMsIHdpdGhpbiB0aGUge3BhcnRpY2xlc30gb2YgYQoJCSAgICAqIGNvbnRhaW5lZCBtb2RlbCBncm91cCwgcmVjdXJzaXZlbHkpIG9yILdpbXBsaWNpdGx5twoJCSAgICAqIHR3byBvciBtb3JlIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGVzIHdpdGgKCQkgICAgKiB0aGUgc2FtZSB7bmFtZX0gYW5kIHt0YXJnZXQgbmFtZXNwYWNlfSwgdGhlbgoJCSAgICAqIGFsbCB0aGVpciB0eXBlIGRlZmluaXRpb25zIG11c3QgYmUgdGhlIHNhbWUKCQkgICAgKiB0b3AtbGV2ZWwgZGVmaW5pdGlvbiBbLi4uXSIKCQkgICAgKi8KCQkgICAgaWYgKHhtbFN0ckVxdWFsKFdYU19QQVJUSUNMRV9URVJNX0FTX0VMRU0oY3VyKS0+bmFtZSwKCQkJICAgIFdYU19QQVJUSUNMRV9URVJNX0FTX0VMRU0oc2VhcmNoUGFydGljbGUpLT5uYW1lKSAmJgoJCQl4bWxTdHJFcXVhbChXWFNfUEFSVElDTEVfVEVSTV9BU19FTEVNKGN1ciktPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgIFdYU19QQVJUSUNMRV9URVJNX0FTX0VMRU0oc2VhcmNoUGFydGljbGUpLT50YXJnZXROYW1lc3BhY2UpKQoJCSAgICB7CgkJCXhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgkJCQoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJICAgIC8qIFRPRE86IGVycm9yIGNvZGUgKi8KCQkJICAgIFhNTF9TQ0hFTUFQX0NPU19OT05BTUJJRywKCQkJICAgIFdYU19JVEVNX05PREUoY3VyKSwgTlVMTCwKCQkJICAgICJJbiB0aGUgY29udGVudCBtb2RlbCBvZiAlcywgdGhlcmUgYXJlIG11bHRpcGxlICIKCQkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9ucyBmb3IgJyVzJyB3aXRoIGRpZmZlcmVudCAiCgkJCSAgICAidHlwZSBkZWZpbml0aW9ucyIsCgkJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyQSwKCQkJCWN0eHRDb21wb25lbnQpLAoJCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ckIsCgkJCQlXWFNfUEFSVElDTEVfVEVSTV9BU19FTEVNKGN1ciktPnRhcmdldE5hbWVzcGFjZSwKCQkJCVdYU19QQVJUSUNMRV9URVJNX0FTX0VMRU0oY3VyKS0+bmFtZSkpOwoJCQlGUkVFX0FORF9OVUxMKHN0ckEpOwoJCQlGUkVFX0FORF9OVUxMKHN0ckIpOwoJCQlyZXR1cm4oWE1MX1NDSEVNQVBfQ09TX05PTkFNQklHKTsKCQkgICAgfQoJCX0JICAgIAoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOiB7CQkKCQlicmVhazsKCQl9CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOnsKCQkvKgoJCXhtbFNjaGVtYVRyZWVJdGVtUHRyIHN1YjsKCQkKCQlzdWIgPSBXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSktPmNoaWxkcmVuOyAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSAKCQl3aGlsZSAoc3ViICE9IE5VTEwpIHsKCQkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbnNpc3RlbnQocGN0eHQsIGN0eHRDb21wb25lbnQsCgkJCWN0eHRQYXJ0aWNsZSwgY3R4dEVsZW0pOwoJCSAgICBpZiAocmV0ICE9IDApCgkJCXJldHVybihyZXQpOwoJCSAgICBzdWIgPSBzdWItPm5leHQ7CgkJfQoJCSovCgkJYnJlYWs7CgkJfQoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXhtbFNjaGVtYUludGVybmFsRXJyMihBQ1RYVF9DQVNUIHBjdHh0LAoJCSAgICAieG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbnNpc3RlbnQiLAoJCSAgICAiZm91bmQgdW5leHBlY3RlZCB0ZXJtIG9mIHR5cGUgJyVzJyBpbiBjb250ZW50IG1vZGVsIiwKCQkgICAgV1hTX0lURU1fVFlQRV9OQU1FKFdYU19QQVJUSUNMRV9URVJNKGN1cikpLCBOVUxMKTsKCQlyZXR1cm4oLTEpOwoJfQoJY3VyID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBjdXItPm5leHQ7CiAgICB9CgpleGl0OgogICAgcmV0dXJuKHJldCk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudAogKiBAaXRlbTogIGFuIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uL3BhcnRpY2xlCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KICogQWRkcyBzdWJzdGl0dXRpb24gZ3JvdXAgbWVtYmVycy4gCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCgkJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfQ0hFQ0tFRCkKCXJldHVybjsKICAgIGVsZW1EZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX0NIRUNLRUQ7CiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0KGN0eHQsIGVsZW1EZWNsKSA9PSAwKSB7CgkvKgoJKiBBZGRzIHN1YnN0aXR1dGlvbiBncm91cCBtZW1iZXJzLgoJKi8KCXhtbFNjaGVtYUNoZWNrRWxlbVN1YnN0R3JvdXAoY3R4dCwgZWxlbURlY2wpOwkKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVNb2RlbEdyb3VwUGFydGljbGVSZWZlcmVuY2VzOgogKiBAcGFydGljbGU6ICBhIHBhcnRpY2xlIGNvbXBvbmVudAogKiBAY3R4dDogIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgcmVmZXJlbmNlcyBvZiBhIG1vZGVsIGdyb3VwJ3Mge3BhcnRpY2xlc30gdG8KICogbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMgYW5kIHRvIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZU1vZGVsR3JvdXBQYXJ0aWNsZVJlZmVyZW5jZXMoCiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIG1nKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IFdYU19NT0RFTEdST1VQX1BBUlRJQ0xFKG1nKTsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciByZWZJdGVtOwoKICAgIC8qCiAgICAqIFVSR0VOVCBUT0RPOiBUZXN0IHRoaXMuCiAgICAqLwogICAgd2hpbGUgKHBhcnRpY2xlICE9IE5VTEwpIHsKCWlmICgoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpID09IE5VTEwpIHx8CgkgICAgKChXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSkpLT50eXBlICE9CgkJWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRikpCgl7CgkgICAgZ290byBuZXh0X3BhcnRpY2xlOwoJfSAKCXJlZiA9IFdYU19RTkFNRV9DQVNUIFdYU19QQVJUSUNMRV9URVJNKHBhcnRpY2xlKTsKCS8qCgkqIFJlc29sdmUgdGhlIHJlZmVyZW5jZS4KCSogTlVMTCB0aGUge3Rlcm19IGJ5IGRlZmF1bHQuCgkqLwoJcGFydGljbGUtPmNoaWxkcmVuID0gTlVMTDsKCglyZWZJdGVtID0geG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoY3R4dC0+c2NoZW1hLAoJICAgIHJlZi0+aXRlbVR5cGUsIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UpOwoJaWYgKHJlZkl0ZW0gPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCBXWFNfSVRFTV9OT0RFKHBhcnRpY2xlKSwgInJlZiIsIHJlZi0+bmFtZSwKCQlyZWYtPnRhcmdldE5hbWVzcGFjZSwgcmVmLT5pdGVtVHlwZSwgTlVMTCk7CgkgICAgLyogVE9ETzogcmVtb3ZlIHRoZSBwYXJ0aWNsZS4gKi8KCSAgICBnb3RvIG5leHRfcGFydGljbGU7Cgl9IAoJaWYgKHJlZkl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB7CgkgICAgaWYgKFdYU19NT0RFTEdST1VQREVGX01PREVMKHJlZkl0ZW0pID09IE5VTEwpCgkJLyogVE9ETzogcmVtb3ZlIHRoZSBwYXJ0aWNsZS4gKi8KCQlnb3RvIG5leHRfcGFydGljbGU7CgkgICAgLyoKCSAgICAqIE5PVEUgdGhhdCB3ZSB3aWxsIGFzc2lnbiB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgoJICAgICogaXRzZWxmIHRvIHRoZSAidGVybSIgb2YgdGhlIHBhcnRpY2xlLiBUaGlzIHdpbGwgZWFzZQoJICAgICogdGhlIGNoZWNrIGZvciBjaXJjdWxhciBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4gQWZ0ZXIKCSAgICAqIHRoYXQgdGhlICJ0ZXJtIiB3aWxsIGJlIGFzc2lnbmVkIHRoZSBtb2RlbCBncm91cCBvZiB0aGUKCSAgICAqIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCgkgICAgKi8KCSAgICBpZiAoKFdYU19NT0RFTEdST1VQREVGX01PREVMKHJlZkl0ZW0pKS0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMKSB7CgkJLyoKCQkqIFNQRUMgY29zLWFsbC1saW1pdGVkICgxKQoJCSogU1BFQyBjb3MtYWxsLWxpbWl0ZWQgKDEuMikKCQkqICJJdCBhcHBlYXJzIG9ubHkgYXMgdGhlIHZhbHVlIG9mIG9uZSBvciBib3RoIG9mIHRoZQoJCSogZm9sbG93aW5nIHByb3BlcnRpZXM6IgoJCSogKDEuMSkgInRoZSB7bW9kZWwgZ3JvdXB9IHByb3BlcnR5IG9mIGEgbW9kZWwgZ3JvdXAKCQkqICAgICAgICBkZWZpbml0aW9uLiIKCQkqICgxLjIpICJ0aGUge3Rlcm19IHByb3BlcnR5IG9mIGEgcGFydGljbGUgWy4uLiBvZl0gdGhlICIKCQkqIHtjb250ZW50IHR5cGV9IG9mIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24uIgoJCSovCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwKCQkgICAgLyogVE9ETzogZXJyb3IgY29kZSAqLwoJCSAgICBYTUxfU0NIRU1BUF9DT1NfQUxMX0xJTUlURUQsCgkJICAgIFdYU19JVEVNX05PREUocGFydGljbGUpLCBOVUxMLAoJCSAgICAiQSBtb2RlbCBncm91cCBkZWZpbml0aW9uIGlzIHJlZmVyZW5jZWQsIGJ1dCAiCgkJICAgICJpdCBjb250YWlucyBhbiAnYWxsJyBtb2RlbCBncm91cCwgd2hpY2ggIgoJCSAgICAiY2Fubm90IGJlIGNvbnRhaW5lZCBieSBtb2RlbCBncm91cHMiLAoJCSAgICBOVUxMLCBOVUxMKTsKCQkvKiBUT0RPOiByZW1vdmUgdGhlIHBhcnRpY2xlLiAqLwoJCWdvdG8gbmV4dF9wYXJ0aWNsZTsKCSAgICB9CgkgICAgcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSByZWZJdGVtOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogVE9ETzogQXJlIHJlZmVyZW5jZWQgZWxlbWVudCBkZWNsYXJhdGlvbnMgdGhlIG9ubHkKCSAgICAqIG90aGVyIGNvbXBvbmVudHMgd2UgZXhwZWN0IGhlcmU/CgkgICAgKi8KCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHJlZkl0ZW07Cgl9Cm5leHRfcGFydGljbGU6CglwYXJ0aWNsZSA9IFdYU19QVENfQ0FTVCBwYXJ0aWNsZS0+bmV4dDsKICAgIH0KfQoKc3RhdGljIGludAp4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCh4bWxTY2hlbWFWYWxQdHIgeCwKCQkgICAgICAgeG1sU2NoZW1hVmFsUHRyIHkpIAp7ICAgCiAgICB4bWxTY2hlbWFUeXBlUHRyIHR4LCB0eSwgcHR4LCBwdHk7ICAgIAogICAgaW50IHJldDsKCiAgICB3aGlsZSAoeCAhPSBOVUxMKSB7CgkvKiBTYW1lIHR5cGVzLiAqLwoJdHggPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZSh4bWxTY2hlbWFHZXRWYWxUeXBlKHgpKTsKCXR5ID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoeG1sU2NoZW1hR2V0VmFsVHlwZSh5KSk7CglwdHggPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR4KTsKCXB0eSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHkpOwoJLyoKCSogKDEpIGlmIGEgZGF0YXR5cGUgVCcgaXMgt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBhbgoJKiBhdG9taWMgZGF0YXR5cGUgVCB0aGVuIHRoZSC3dmFsdWUgc3BhY2W3IG9mIFQnIGlzIGEgc3Vic2V0IG9mCgkqIHRoZSC3dmFsdWUgc3BhY2W3IG9mIFQuICovCgkvKgoJKiAoMikgaWYgZGF0YXR5cGVzIFQnIGFuZCBUJycgYXJlILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263CgkqIGZyb20gYSBjb21tb24gYXRvbWljIGFuY2VzdG9yIFQgdGhlbiB0aGUgt3ZhbHVlIHNwYWNlt3Mgb2YgVCcKCSogYW5kIFQnJyBtYXkgb3ZlcmxhcC4KCSovCglpZiAocHR4ICE9IHB0eSkKCSAgICByZXR1cm4oMCk7CgkvKgoJKiBXZSBhc3N1bWUgY29tcHV0ZWQgdmFsdWVzIHRvIGJlIG5vcm1hbGl6ZWQsIHNvIGRvIGEgZmFzdAoJKiBzdHJpbmcgY29tcGFyaXNvbiBmb3Igc3RyaW5nIGJhc2VkIHR5cGVzLgoJKi8KCWlmICgocHR4LT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHx8CgkgICAgV1hTX0lTX0FOWV9TSU1QTEVfVFlQRShwdHgpKSB7CgkgICAgaWYgKCEgeG1sU3RyRXF1YWwoCgkJeG1sU2NoZW1hVmFsdWVHZXRBc1N0cmluZyh4KSwKCQl4bWxTY2hlbWFWYWx1ZUdldEFzU3RyaW5nKHkpKSkKCQlyZXR1cm4gKDApOwoJfSBlbHNlIHsKCSAgICByZXQgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzV2h0c3AoCgkJeCwgWE1MX1NDSEVNQV9XSElURVNQQUNFX1BSRVNFUlZFLAoJCXksIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSk7CgkgICAgaWYgKHJldCA9PSAtMikKCQlyZXR1cm4oLTEpOwoJICAgIGlmIChyZXQgIT0gMCkKCQlyZXR1cm4oMCk7Cgl9CgkvKgoJKiBMaXN0cy4KCSovCgl4ID0geG1sU2NoZW1hVmFsdWVHZXROZXh0KHgpOwoJaWYgKHggIT0gTlVMTCkgewoJICAgIHkgPSB4bWxTY2hlbWFWYWx1ZUdldE5leHQoeSk7CgkgICAgaWYgKHkgPT0gTlVMTCkKCQlyZXR1cm4gKDApOwkgICAgCgl9IGVsc2UgaWYgKHhtbFNjaGVtYVZhbHVlR2V0TmV4dCh5KSAhPSBOVUxMKQoJICAgIHJldHVybiAoMCk7CgllbHNlCgkgICAgcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlQXR0clVzZVJlZmVyZW5jZXM6CiAqIEBpdGVtOiAgYW4gYXR0cmlidXRlIHVzZQogKiBAY3R4dDogIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgdGhlIHJlZmVyZW5jZWQgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZXNvbHZlQXR0clVzZVJlZmVyZW5jZXMoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIGF1c2UsCgkJCQkgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChhdXNlID09IE5VTEwpKQoJcmV0dXJuKC0xKTsKICAgIGlmICgoYXVzZS0+YXR0ckRlY2wgPT0gTlVMTCkgfHwKCShhdXNlLT5hdHRyRGVjbC0+dHlwZSAhPSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGKSkKCXJldHVybigwKTsKCiAgICB7Cgl4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWYgPSBXWFNfUU5BTUVfQ0FTVCBhdXNlLT5hdHRyRGVjbDsKCgkvKgoJKiBUT0RPOiBFdmFsdWF0ZSwgd2hhdCBlcnJvcnMgY291bGQgb2NjdXIgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIG5vdAoJKiBmb3VuZC4KCSovCglhdXNlLT5hdHRyRGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2woY3R4dC0+c2NoZW1hLAoJICAgIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UpOwogICAgICAgIGlmIChhdXNlLT5hdHRyRGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkgICAgCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCVdYU19CQVNJQ19DQVNUIGF1c2UsIGF1c2UtPm5vZGUsCgkJInJlZiIsIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UsCgkJWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybihjdHh0LT5lcnIpOzsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0F0dHJVc2VQcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgYSBwYXJzZXIgY29udGV4dAogKiBAdXNlOiAgYW4gYXR0cmlidXRlIHVzZSAKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBBdHRyaWJ1dGUgVXNlIENvcnJlY3QgKGF1LXByb3BzLWNvcnJlY3QpCiAqIAogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0F0dHJVc2VQcm9wc0NvcnJlY3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2UpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodXNlID09IE5VTEwpKQoJcmV0dXJuKC0xKTsKICAgIGlmICgodXNlLT5kZWZWYWx1ZSA9PSBOVUxMKSB8fCAoV1hTX0FUVFJVU0VfREVDTCh1c2UpID09IE5VTEwpIHx8CgkoKFdYU19BVFRSVVNFX0RFQ0wodXNlKSktPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSkpCglyZXR1cm4oMCk7CQoKICAgIC8qCiAgICAqIFNQRUMgYXUtcHJvcHMtY29ycmVjdCAoMSkKICAgICogIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gYXR0cmlidXRlIHVzZSBtdXN0IGJlIGFzCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgQXR0cmlidXRlIFVzZSBTY2hlbWEKICAgICogQ29tcG9uZW50ICinMy41LjEpLCBtb2R1bG8gdGhlIGltcGFjdCBvZiBNaXNzaW5nCiAgICAqIFN1Yi1jb21wb25lbnRzICinNS4zKS4iCiAgICAqLwogICAgCiAgICBpZiAoKChXWFNfQVRUUlVTRV9ERUNMKHVzZSkpLT5kZWZWYWx1ZSAhPSBOVUxMKSAmJgoJKChXWFNfQVRUUlVTRV9ERUNMKHVzZSkpLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpICYmCiAgICAgICAgKCh1c2UtPmZsYWdzICYgWE1MX1NDSEVNQV9BVFRSX1VTRV9GSVhFRCkgPT0gMCkpCiAgICB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfQVVfUFJPUFNfQ09SUkVDVF8yLAoJICAgIFdYU19CQVNJQ19DQVNUIHVzZSwgTlVMTCwKCSAgICAiVGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBoYXMgYSAnZml4ZWQnIHZhbHVlIGNvbnN0cmFpbnQgIgoJICAgICIsIHRodXMgdGhlIGF0dHJpYnV0ZSB1c2UgbXVzdCBhbHNvIGhhdmUgYSAnZml4ZWQnIHZhbHVlICIKCSAgICAiY29uc3RyYWludCIsCgkgICAgTlVMTCk7CglyZXR1cm4oY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIENvbXB1dGUgYW5kIGNoZWNrIHRoZSB2YWx1ZSBjb25zdHJhaW50J3MgdmFsdWUuCiAgICAqLwogICAgaWYgKCh1c2UtPmRlZlZhbCAhPSBOVUxMKSAmJiAoV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpICE9IE5VTEwpKSB7CglpbnQgcmV0OwoJLyoKCSogVE9ETzogVGhlIHNwZWMgc2VlbXMgdG8gYmUgbWlzc2luZyBhIGNoZWNrIG9mIHRoZSAKCSogdmFsdWUgY29uc3RyYWludCBvZiB0aGUgYXR0cmlidXRlIHVzZS4gV2Ugd2lsbCBkbyBpdCBoZXJlLgoJKi8KCS8qCgkqIFNQRUMgYS1wcm9wcy1jb3JyZWN0ICgzKQoJKi8KCWlmICh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoCgkgICAgV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpLCBYTUxfU0NIRU1BU19JRCkpCgl7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwKCQlYTUxfU0NIRU1BUF9BVV9QUk9QU19DT1JSRUNULAoJCU5VTEwsIFdYU19CQVNJQ19DQVNUIHVzZSwKCQkiVmFsdWUgY29uc3RyYWludHMgYXJlIG5vdCBhbGxvd2VkIGlmIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSJpcyBvciBpcyBkZXJpdmVkIGZyb20geHM6SUQiLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybihjdHh0LT5lcnIpOwoJfQoJCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKEFDVFhUX0NBU1QgY3R4dCwKCSAgICB1c2UtPm5vZGUsIFdYU19BVFRSVVNFX1RZUEVERUYodXNlKSwKCSAgICB1c2UtPmRlZlZhbHVlLCAmKHVzZS0+ZGVmVmFsKSwKCSAgICAxLCAxLCAwKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJUEVSUk9SX0lOVDIoInhtbFNjaGVtYUNoZWNrQXR0clVzZVByb3BzQ29ycmVjdCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJCXJldHVybigtMSk7CgkgICAgfQoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJWE1MX1NDSEVNQVBfQVVfUFJPUFNfQ09SUkVDVCwKCQlOVUxMLCBXWFNfQkFTSUNfQ0FTVCB1c2UsCgkJIlRoZSB2YWx1ZSBvZiB0aGUgdmFsdWUgY29uc3RyYWludCBpcyBub3QgdmFsaWQiLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybihjdHh0LT5lcnIpOwoJfQogICAgfQogICAgLyoKICAgICogU1BFQyBhdS1wcm9wcy1jb3JyZWN0ICgyKQogICAgKiAiSWYgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyBhIGZpeGVkCiAgICAqIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlbiBpZiB0aGUgYXR0cmlidXRlIHVzZSBpdHNlbGYgaGFzIGEKICAgICoge3ZhbHVlIGNvbnN0cmFpbnR9LCBpdCBtdXN0IGFsc28gYmUgZml4ZWQgYW5kIGl0cyB2YWx1ZSBtdXN0IG1hdGNoCiAgICAqIHRoYXQgb2YgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9LiIKICAgICovCiAgICBpZiAoKChXWFNfQVRUUlVTRV9ERUNMKHVzZSkpLT5kZWZWYWwgIT0gTlVMTCkgJiYKCSgoKFdYU19BVFRSVVNFX0RFQ0wodXNlKSktPmZsYWdzICYgWE1MX1NDSEVNQV9BVFRSX1VTRV9GSVhFRCkgPT0gMCkpCiAgICB7CglpZiAoISB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCh1c2UtPmRlZlZhbCwKCQkoV1hTX0FUVFJVU0VfREVDTCh1c2UpKS0+ZGVmVmFsKSkKCXsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQVVfUFJPUFNfQ09SUkVDVF8yLAoJCVdYU19CQVNJQ19DQVNUIHVzZSwgTlVMTCwKCQkiVGhlICdmaXhlZCcgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgYXR0cmlidXRlIHVzZSAiCgkJIm11c3QgbWF0Y2ggdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbidzIHZhbHVlICIKCQkiY29uc3RyYWludCAnJXMnIiwKCQkoV1hTX0FUVFJVU0VfREVDTCh1c2UpKS0+ZGVmVmFsdWUpOwoJfQoJcmV0dXJuKGN0eHQtPmVycik7CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCgoKCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlQXR0clR5cGVSZWZlcmVuY2VzOgogKiBAaXRlbTogIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbgogKiBAY3R4dDogIGEgcGFyc2VyIGNvbnRleHQgCiAqCiAqIFJlc29sdmVzIHRoZSByZWZlcmVuY2VkIHR5cGUgZGVmaW5pdGlvbiBjb21wb25lbnQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlc29sdmVBdHRyVHlwZVJlZmVyZW5jZXMoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGl0ZW0sCgkJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIC8qCiAgICAqIFRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiBlbGVtZW50CiAgICAqIGluZm9ybWF0aW9uIGl0ZW0gaW4gdGhlIFtjaGlsZHJlbl0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgc2ltcGxlCiAgICAqIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdHlwZQogICAgKiBbYXR0cmlidXRlXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuCiAgICAqLwogICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9JTlRFUk5BTF9SRVNPTFZFRCkKCXJldHVybigwKTsKICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfSU5URVJOQUxfUkVTT0xWRUQ7CiAgICBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm4oMCk7CiAgICBpZiAoaXRlbS0+dHlwZU5hbWUgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCgl0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW0tPnR5cGVOYW1lLAoJICAgIGl0ZW0tPnR5cGVOcyk7CglpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKCEgV1hTX0lTX1NJTVBMRSh0eXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlXWFNfQkFTSUNfQ0FTVCBpdGVtLCBpdGVtLT5ub2RlLAoJCSJ0eXBlIiwgaXRlbS0+dHlwZU5hbWUsIGl0ZW0tPnR5cGVOcywKCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCSAgICByZXR1cm4oY3R4dC0+ZXJyKTsKCX0gZWxzZQoJICAgIGl0ZW0tPnN1YnR5cGVzID0gdHlwZTsKCiAgICB9IGVsc2UgewoJLyoKCSogVGhlIHR5cGUgZGVmYXVsdHMgdG8gdGhlIHhzOmFueVNpbXBsZVR5cGUuCgkqLwoJaXRlbS0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKICAgIH0KICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWZlcmVuY2VzOgogKiBAaWRjOiAgdGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogUmVzb2x2ZSBrZXlSZWYgcmVmZXJlbmNlcyB0byBrZXkvdW5pcXVlIElEQ3MuCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogICBJZGVudGl0eS1jb25zdHJhaW50IERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0IChjLXByb3BzLWNvcnJlY3QpCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWZlcmVuY2VzKHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCkKewogICAgaWYgKGlkYy0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikKICAgICAgICByZXR1cm4oMCk7CiAgICBpZiAoaWRjLT5yZWYtPm5hbWUgIT0gTlVMTCkgewoJaWRjLT5yZWYtPml0ZW0gPSAoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKQoJICAgIHhtbFNjaGVtYUdldElEQyhwY3R4dC0+c2NoZW1hLCBpZGMtPnJlZi0+bmFtZSwKCQlpZGMtPnJlZi0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgICAgICBpZiAoaWRjLT5yZWYtPml0ZW0gPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBJdCBpcyBhY3R1YWxseSBub3QgYW4gZXJyb3IgdG8gZmFpbCB0byByZXNvbHZlCgkgICAgKiBhdCB0aGlzIHN0YWdlLiBCVVQgd2UgbmVlZCB0byBiZSB0aGF0IHN0cmljdCEKCSAgICAqLwoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlXWFNfQkFTSUNfQ0FTVCBpZGMsIGlkYy0+bm9kZSwKCQkicmVmZXIiLCBpZGMtPnJlZi0+bmFtZSwKCQlpZGMtPnJlZi0+dGFyZ2V0TmFtZXNwYWNlLAoJCVhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuKHBjdHh0LT5lcnIpOwoJfSBlbHNlIGlmIChpZGMtPnJlZi0+aXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIC8qCgkgICAgKiBTUEVDIGMtcHJvcHMtY29ycmVjdCAoMSkKCSAgICAqLwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0NfUFJPUFNfQ09SUkVDVCwKCQlOVUxMLCBXWFNfQkFTSUNfQ0FTVCBpZGMsCgkJIlRoZSBrZXlyZWYgcmVmZXJlbmNlcyBhIGtleXJlZiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgaWRjLT5yZWYtPml0ZW0gPSBOVUxMOwoJICAgIHJldHVybihwY3R4dC0+ZXJyKTsKCX0gZWxzZSB7CgkgICAgaWYgKGlkYy0+bmJGaWVsZHMgIT0KCQkoKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW0pLT5uYkZpZWxkcykgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJeG1sU2NoZW1hSURDUHRyIHJlZmVyOwoJCQoJCXJlZmVyID0gKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW07CgkJLyoKCQkqIFNQRUMgYy1wcm9wcy1jb3JyZWN0KDIpCgkJKiAiSWYgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyBrZXlyZWYsCgkJKiB0aGUgY2FyZGluYWxpdHkgb2YgdGhlIHtmaWVsZHN9IG11c3QgZXF1YWwgdGhhdCBvZgoJCSogdGhlIHtmaWVsZHN9IG9mIHRoZSB7cmVmZXJlbmNlZCBrZXl9LgoJCSovCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NfUFJPUFNfQ09SUkVDVCwKCQkgICAgTlVMTCwgV1hTX0JBU0lDX0NBU1QgaWRjLAoJCSAgICAiVGhlIGNhcmRpbmFsaXR5IG9mIHRoZSBrZXlyZWYgZGlmZmVycyBmcm9tIHRoZSAiCgkJICAgICJjYXJkaW5hbGl0eSBvZiB0aGUgcmVmZXJlbmNlZCBrZXkvdW5pcXVlICclcyciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCByZWZlci0+dGFyZ2V0TmFtZXNwYWNlLAoJCQlyZWZlci0+bmFtZSksCgkJICAgIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybihwY3R4dC0+ZXJyKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVzb2x2ZUF0dHJVc2VQcm9oaWJSZWZlcmVuY2VzKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0ciBwcm9oaWIsCgkJCQkgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCkKewogICAgaWYgKHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2wocGN0eHQtPnNjaGVtYSwgcHJvaGliLT5uYW1lLAoJcHJvaGliLT50YXJnZXROYW1lc3BhY2UpID09IE5VTEwpIHsKCgl4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkgICAgTlVMTCwgcHJvaGliLT5ub2RlLAoJICAgICJyZWYiLCBwcm9oaWItPm5hbWUsIHByb2hpYi0+dGFyZ2V0TmFtZXNwYWNlLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUsIE5VTEwpOwoJcmV0dXJuKFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFKTsKICAgIH0KICAgIHJldHVybigwKTsKfQoKI2RlZmluZSBXWFNfUkVERUZJTkVEX1RZUEUoYykgXAooKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1JFREVGSU5FRCkKCiNkZWZpbmUgV1hTX1JFREVGSU5FRF9NT0RFTF9HUk9VUF9ERUYoYykgXAooKCh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSBpdGVtKS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9SRURFRklORUQpCgojZGVmaW5lIFdYU19SRURFRklORURfQVRUUl9HUk9VUChjKSBcCigoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtKS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfUkVERUZJTkVEKQoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NSQ1JlZGVmaW5lRmlyc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCkKewogICAgaW50IGVyciA9IDA7CiAgICB4bWxTY2hlbWFSZWRlZlB0ciByZWRlZiA9IFdYU19DT05TVFJVQ1RPUihwY3R4dCktPnJlZGVmczsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBwcmV2LCBpdGVtOwogICAgaW50IHdhc1JlZGVmaW5lZDsKCiAgICBpZiAocmVkZWYgPT0gTlVMTCkKCXJldHVybigwKTsgICAJCgogICAgZG8gewoJaXRlbSA9IHJlZGVmLT5pdGVtOwoJLyoKCSogRmlyc3QgdHJ5IHRvIGxvY2F0ZSB0aGUgcmVkZWZpbmVkIGNvbXBvbmVudCBpbiB0aGUKCSogc2NoZW1hIGdyYXBoIHN0YXJ0aW5nIHdpdGggdGhlIHJlZGVmaW5lZCBzY2hlbWEuCgkqIE5PVEU6IEFjY29yZGluZyB0byB0aGlzIHNjaGVtYSBidWcgZW50cnk6CgkqICAgaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LXhtbC1zY2hlbWEtY29tbWVudHMvMjAwNU9jdERlYy8wMDE5Lmh0bWwKCSogICBpdCdzIG5vdCBjbGVhciBpZiB0aGUgcmVmZXJlbmNlZCBjb21wb25lbnQgbmVlZHMgdG8gb3JpZ2luYXRlCgkqICAgZnJvbSB0aGUgPHJlZGVmaW5lPmQgc2NoZW1hIF9kb2N1bWVudF8gb3IgdGhlIHNjaGVtYTsgdGhlIGxhdHRlcgoJKiAgIHdvdWxkIGluY2x1ZGUgYWxsIGltcG9ydGVkIGFuZCBpbmNsdWRlZCBzdWItc2NoZW1hcyBvZiB0aGUKCSogICA8cmVkZWZpbmU+ZCBzY2hlbWEuIEN1cnJlbmx0eSB3ZSBsYXR0ZXIgYXBwcm9hY2ggaXMgdXNlZC4KCSogICBTVVBQTEVNRU5UOiBJdCBzZWVtcyB0aGF0IHRoZSBXRyBtb3ZlcyB0b3dhcmRzIHRoZSBsYXR0ZXIKCSogICBhcHByb2FjaCwgc28gd2UgYXJlIGRvaW5nIGl0IHJpZ2h0LgoJKiAgIAoJKi8KCXByZXYgPSB4bWxTY2hlbWFGaW5kUmVkZWZDb21wSW5HcmFwaCgKCSAgICByZWRlZi0+dGFyZ2V0QnVja2V0LCBpdGVtLT50eXBlLAoJICAgIHJlZGVmLT5yZWZOYW1lLCByZWRlZi0+cmVmVGFyZ2V0TnMpOwoJaWYgKHByZXYgPT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgeG1sTm9kZVB0ciBub2RlOwoKCSAgICAvKgoJICAgICogU1BFQyBzcmMtcmVkZWZpbmU6CgkgICAgKiAoNi4yLjEpICJUaGUgt2FjdHVhbCB2YWx1Zbcgb2YgaXRzIG93biBuYW1lIGF0dHJpYnV0ZSBwbHVzCgkgICAgKiB0YXJnZXQgbmFtZXNwYWNlIG11c3Qgc3VjY2Vzc2Z1bGx5ILdyZXNvbHZltyB0byBhIG1vZGVsCgkgICAgKiBncm91cCBkZWZpbml0aW9uIGluIEkuIgoJICAgICogKDcuMi4xKSAiVGhlILdhY3R1YWwgdmFsdWW3IG9mIGl0cyBvd24gbmFtZSBhdHRyaWJ1dGUgcGx1cwoJICAgICogdGFyZ2V0IG5hbWVzcGFjZSBtdXN0IHN1Y2Nlc3NmdWxseSC3cmVzb2x2ZbcgdG8gYW4gYXR0cmlidXRlCgkgICAgKiBncm91cCBkZWZpbml0aW9uIGluIEkuIgoKCSAgICAqCgkgICAgKiBOb3RlIHRoYXQsIGlmIHdlIGFyZSByZWRlZmluaW5nIHdpdGggdGhlIHVzZSBvZiByZWZlcmVuY2VzCgkgICAgKiB0byBjb21wb25lbnRzLCB0aGUgc3BlYyBhc3N1bWVzIHRoZSBzcmMtcmVzb2x2ZSB0byBiZSB1c2VkOwoJICAgICogYnV0IHRoaXMgd29uJ3QgYXNzdXJlIHRoYXQgd2Ugc2VhcmNoIG9ubHkgKmluc2lkZSogdGhlCgkgICAgKiByZWRlZmluZWQgc2NoZW1hLgoJICAgICovCgkgICAgaWYgKHJlZGVmLT5yZWZlcmVuY2UpCgkJbm9kZSA9IFdYU19JVEVNX05PREUocmVkZWYtPnJlZmVyZW5jZSk7CgkgICAgZWxzZQoJCW5vZGUgPSBXWFNfSVRFTV9OT0RFKGl0ZW0pOwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCS8qCgkJKiBUT0RPOiBlcnJvciBjb2RlLgoJCSogUHJvYmFibHkgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIGlmIHRoaXMgaXMgdXNpbmcgdGhlCgkJKiByZWZlcmVuY2Uga2luZC4JCQoJCSovCgkJWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FLCBub2RlLCBOVUxMLAoJCSJUaGUgJXMgJyVzJyB0byBiZSByZWRlZmluZWQgY291bGQgbm90IGJlIGZvdW5kIGluICIKCQkidGhlIHJlZGVmaW5lZCBzY2hlbWEiLAoJCVdYU19JVEVNX1RZUEVfTkFNRShpdGVtKSwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCByZWRlZi0+cmVmVGFyZ2V0TnMsCgkJICAgIHJlZGVmLT5yZWZOYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwkgICAgCgkgICAgZXJyID0gcGN0eHQtPmVycjsKCSAgICByZWRlZiA9IHJlZGVmLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQoJLyoKCSogVE9ETzogT2J0YWluaW5nIGFuZCBzZXR0aW5nIHRoZSByZWRlZmluaXRpb24gc3RhdGUgaXMgcmVhbGx5CgkqIGNsdW1zeS4KCSovCgl3YXNSZWRlZmluZWQgPSAwOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJaWYgKChXWFNfVFlQRV9DQVNUIHByZXYpLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfUkVERUZJTkVEKQoJCXsKCQkgICAgd2FzUmVkZWZpbmVkID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCS8qIE1hcmsgaXQgYXMgcmVkZWZpbmVkLiAqLwoJCShXWFNfVFlQRV9DQVNUIHByZXYpLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1JFREVGSU5FRDsKCQkvKgoJCSogQXNzaWduIHRoZSByZWRlZmluZWQgdHlwZSB0byB0aGUKCQkqIGJhc2UgdHlwZSBvZiB0aGUgcmVkZWZpbmluZyB0eXBlLgoJCSogVE9ETzogSG93CgkJKi8KCQkoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pLT5iYXNlVHlwZSA9IAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgcHJldjsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQlpZiAoKFdYU19NT0RFTF9HUk9VUERFRl9DQVNUIHByZXYpLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX1JFREVGSU5FRCkKCQl7CgkJICAgIHdhc1JlZGVmaW5lZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQkvKiBNYXJrIGl0IGFzIHJlZGVmaW5lZC4gKi8KCQkoV1hTX01PREVMX0dST1VQREVGX0NBU1QgcHJldiktPmZsYWdzIHw9CgkJICAgIFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX1JFREVGSU5FRDsKCQlpZiAocmVkZWYtPnJlZmVyZW5jZSAhPSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogT3ZlcndyaXRlIHRoZSBRTmFtZS1yZWZlcmVuY2Ugd2l0aCB0aGUKCQkgICAgKiByZWZlcmVuY2VkIG1vZGVsIGdyb3VwIGRlZi4KCQkgICAgKi8KCQkgICAgKFdYU19QVENfQ0FTVCByZWRlZi0+cmVmZXJlbmNlKS0+Y2hpbGRyZW4gPQoJCQlXWFNfVFJFRV9DQVNUIHByZXY7CgkJfQoJCXJlZGVmLT50YXJnZXQgPSBwcmV2OwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCWlmICgoV1hTX0FUVFJfR1JPVVBfQ0FTVCBwcmV2KS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BU19BVFRSR1JPVVBfUkVERUZJTkVEKQoJCXsKCQkgICAgd2FzUmVkZWZpbmVkID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCShXWFNfQVRUUl9HUk9VUF9DQVNUIHByZXYpLT5mbGFncyB8PQoJCSAgICBYTUxfU0NIRU1BU19BVFRSR1JPVVBfUkVERUZJTkVEOwoJCWlmIChyZWRlZi0+cmVmZXJlbmNlICE9IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBBc3NpZ24gdGhlIHJlZGVmaW5lZCBhdHRyaWJ1dGUgZ3JvdXAgdG8gdGhlCgkJICAgICogUU5hbWUtcmVmZXJlbmNlIGNvbXBvbmVudC4KCQkgICAgKiBUaGlzIGlzIHRoZSBlYXN5IGNhc2UsIHNpbmNlIHdlIHdpbGwganVzdAoJCSAgICAqIGV4cGFuZCB0aGUgcmVkZWZpbmVkIGdyb3VwLgoJCSAgICAqLwoJCSAgICAoV1hTX1FOQU1FX0NBU1QgcmVkZWYtPnJlZmVyZW5jZSktPml0ZW0gPSBwcmV2OwoJCSAgICByZWRlZi0+dGFyZ2V0ID0gTlVMTDsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqIFRoaXMgaXMgdGhlIGNvbXBsaWNhdGVkIGNhc2U6IHdlIG5lZWQKCQkgICAgKiB0byBhcHBseSBzcmMtcmVkZWZpbmUgKDcuMi4yKSBhdCBhIGxhdGVyCgkJICAgICogc3RhZ2UsIGkuZS4gd2hlbiBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcwoJCSAgICAqIGhhdmUgYmVlZCBleHBhbmRlZCBhbmQgc2ltcGxlIHR5cGVzIGhhdmUKCQkgICAgKiBiZWVkIGZpeGVkLgoJCSAgICAqLwoJCSAgICByZWRlZi0+dGFyZ2V0ID0gcHJldjsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFSZXNvbHZlUmVkZWZSZWZlcmVuY2VzIiwKCQkgICAgIlVuZXhwZWN0ZWQgcmVkZWZpbmVkIGNvbXBvbmVudCB0eXBlIik7CgkJcmV0dXJuKC0xKTsJCgl9CglpZiAod2FzUmVkZWZpbmVkKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICB4bWxOb2RlUHRyIG5vZGU7CgoJICAgIGlmIChyZWRlZi0+cmVmZXJlbmNlKQoJCW5vZGUgPSBXWFNfSVRFTV9OT0RFKHJlZGVmLT5yZWZlcmVuY2UpOwoJICAgIGVsc2UKCQlub2RlID0gV1hTX0lURU1fTk9ERShyZWRlZi0+aXRlbSk7CgkgICAgCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJLyogVE9ETzogZXJyb3IgY29kZS4gKi8KCQlYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsCgkJbm9kZSwgTlVMTCwKCQkiVGhlIHJlZmVyZW5jZWQgJXMgd2FzIGFscmVhZHkgcmVkZWZpbmVkLiBNdWx0aXBsZSAiCgkJInJlZGVmaW5pdGlvbiBvZiB0aGUgc2FtZSBjb21wb25lbnQgaXMgbm90IHN1cHBvcnRlZCIsCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgcHJldiksCgkJTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCSAgICAKCSAgICBlcnIgPSBwY3R4dC0+ZXJyOwoJICAgIHJlZGVmID0gcmVkZWYtPm5leHQ7CgkgICAgY29udGludWU7Cgl9CglyZWRlZiA9IHJlZGVmLT5uZXh0OwkKICAgIH0gd2hpbGUgKHJlZGVmICE9IE5VTEwpOwoKICAgIHJldHVybihlcnIpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrU1JDUmVkZWZpbmVTZWNvbmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCkKewogICAgaW50IGVyciA9IDA7CiAgICB4bWxTY2hlbWFSZWRlZlB0ciByZWRlZiA9IFdYU19DT05TVFJVQ1RPUihwY3R4dCktPnJlZGVmczsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOwoKICAgIGlmIChyZWRlZiA9PSBOVUxMKQoJcmV0dXJuKDApOyAgIAkKCiAgICBkbyB7CglpZiAocmVkZWYtPnRhcmdldCA9PSBOVUxMKSB7CgkgICAgcmVkZWYgPSByZWRlZi0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0KCWl0ZW0gPSByZWRlZi0+aXRlbTsKCQkKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCS8qCgkJKiBTaW5jZSB0aGUgc3BlYyB3YW50cyB0aGUge25hbWV9IG9mIHRoZSByZWRlZmluZWQKCQkqIHR5cGUgdG8gYmUgJ2Fic2VudCcsIHdlJ2xsIE5VTEwgaXQuCgkJKi8KCQkoV1hTX1RZUEVfQ0FTVCByZWRlZi0+dGFyZ2V0KS0+bmFtZSA9IE5VTEw7CgkJCgkJLyoKCQkqIFRPRE86IFNlZW1zIGxpa2UgdGhlcmUncyBub3RoaW5nIG1vcmUgdG8gZG8uIFRoZSBub3JtYWwKCQkqIGluaGVyaXRhbmNlIG1lY2hhbmlzbSBpcyB1c2VkLiBCdXQgbm90IDEwMCUgc3VyZS4KCQkqLwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCS8qCgkJKiBVUkdFTlQgVE9ETzoKCQkqIFNQRUMgc3JjLXJlZGVmaW5lOgoJCSogKDYuMi4yKSAiVGhlIHttb2RlbCBncm91cH0gb2YgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KCQkqIHdoaWNoIGNvcnJlc3BvbmRzIHRvIGl0IHBlciBYTUwgUmVwcmVzZW50YXRpb24gb2YgTW9kZWwKCQkqIEdyb3VwIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjcuMikgbXVzdCBiZSBhCgkJKiC3dmFsaWQgcmVzdHJpY3Rpb263IG9mIHRoZSB7bW9kZWwgZ3JvdXB9IG9mIHRoYXQgbW9kZWwKCQkqIGdyb3VwIGRlZmluaXRpb24gaW4gSSwgYXMgZGVmaW5lZCBpbiBQYXJ0aWNsZSBWYWxpZAoJCSogKFJlc3RyaWN0aW9uKSAopzMuOS42KS4iCgkJKi8KCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQkvKgoJCSogU1BFQyBzcmMtcmVkZWZpbmU6CgkJKiAoNy4yLjIpICJUaGUge2F0dHJpYnV0ZSB1c2VzfSBhbmQge2F0dHJpYnV0ZSB3aWxkY2FyZH0gb2YKCQkqIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiB3aGljaCBjb3JyZXNwb25kcyB0byBpdAoJCSogcGVyIFhNTCBSZXByZXNlbnRhdGlvbiBvZiBBdHRyaWJ1dGUgR3JvdXAgRGVmaW5pdGlvbiBTY2hlbWEKCQkqIENvbXBvbmVudHMgKKczLjYuMikgbXVzdCBiZSC3dmFsaWQgcmVzdHJpY3Rpb25ztyBvZiB0aGUKCQkqIHthdHRyaWJ1dGUgdXNlc30gYW5kIHthdHRyaWJ1dGUgd2lsZGNhcmR9IG9mIHRoYXQgYXR0cmlidXRlCgkJKiBncm91cCBkZWZpbml0aW9uIGluIEksIGFzIGRlZmluZWQgaW4gY2xhdXNlIDIsIGNsYXVzZSAzIGFuZAoJCSogY2xhdXNlIDQgb2YgRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpCgkJKiAopzMuNC42KSAod2hlcmUgcmVmZXJlbmNlcyB0byB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gYXJlCgkJKiB1bmRlcnN0b29kIGFzIHJlZmVyZW5jZXMgdG8gdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCgkJKiBpbiBJKS4iCgkJKi8KCQllcnIgPSB4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25PS1Jlc3RyaWN0aW9uMnRvNChwY3R4dCwKCQkgICAgWE1MX1NDSEVNQV9BQ1RJT05fUkVERUZJTkUsCgkJICAgIGl0ZW0sIHJlZGVmLT50YXJnZXQsCgkJICAgIChXWFNfQVRUUl9HUk9VUF9DQVNUIGl0ZW0pLT5hdHRyVXNlcywKCQkgICAgKFdYU19BVFRSX0dST1VQX0NBU1QgcmVkZWYtPnRhcmdldCktPmF0dHJVc2VzLAoJCSAgICAoV1hTX0FUVFJfR1JPVVBfQ0FTVCBpdGVtKS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJICAgIChXWFNfQVRUUl9HUk9VUF9DQVNUIHJlZGVmLT50YXJnZXQpLT5hdHRyaWJ1dGVXaWxkY2FyZCk7CgkJaWYgKGVyciA9PSAtMSkKCQkgICAgcmV0dXJuKC0xKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQoJcmVkZWYgPSByZWRlZi0+bmV4dDsKICAgIH0gd2hpbGUgKHJlZGVmICE9IE5VTEwpOwogICAgcmV0dXJuKDApOwp9CgkKCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkQ29tcG9uZW50cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0KQp7CiAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbTsKICAgIGludCBlcnI7CiAgICB4bWxIYXNoVGFibGVQdHIgKnRhYmxlOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGludCBpOwoKI2RlZmluZSBXWFNfR0VUX0dMT0JBTF9IQVNIKGMsIHNsb3QpIHsgXAogICAgaWYgKFdYU19JU19CVUNLRVRfSU1QTUFJTigoYyktPnR5cGUpKSBcCgl0YWJsZSA9ICYoV1hTX0lNUEJVQ0tFVCgoYykpLT5zY2hlbWEtPnNsb3QpOyBcCiAgICBlbHNlIFwKCXRhYmxlID0gJihXWFNfSU5DQlVDS0VUKChjKSktPm93bmVySW1wb3J0LT5zY2hlbWEtPnNsb3QpOyB9CgogICAgLyoKICAgICogQWRkIGdsb2JhbCBjb21wb25lbnRzIHRvIHRoZSBzY2hlbWEncyBoYXNoIHRhYmxlcy4KICAgICogVGhpcyBpcyB0aGUgcGxhY2Ugd2hlcmUgZHVwbGljYXRlIGNvbXBvbmVudHMgd2lsbCBiZQogICAgKiBkZXRlY3RlZC4KICAgICogVE9ETzogSSB0aGluayBub3JtYWxseSB3ZSBzaG91bGQgc3VwcG9ydCBpbXBvcnRzIG9mIHRoZQogICAgKiAgIHNhbWUgbmFtZXNwYWNlIGZyb20gbXVsdGlwbGUgbG9jYXRpb25zLiBXZSBkb24ndCBkbyBjdXJyZW50bHksCiAgICAqICAgYnV0IGlmIHdlIGRvIHRoZW4gYWNjb3JkaW5nIHRvOgogICAgKiAgIGh0dHA6Ly93d3cudzMub3JnL0J1Z3MvUHVibGljL3Nob3dfYnVnLmNnaT9pZD0yMjI0CiAgICAqICAgd2Ugd291bGQgbmVlZCwgaWYgaW1wb3J0ZWQgZGlyZWN0bHksIHRvIGltcG9ydCByZWRlZmluZWQKICAgICogICBjb21wb25lbnRzIGFzIHdlbGwgdG8gYmUgYWJsZSB0byBjYXRjaCBjbGFzaGluZyBjb21wb25lbnRzLgogICAgKiAgIChJIGhvcGUgSSdsbCBzdGlsbCBrbm93IHdoYXQgdGhpcyBtZWFucyBhZnRlciBzb21lIG1vbnRocyA6LSgpCiAgICAqLwogICAgaWYgKGJ1Y2tldCA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKICAgIGlmIChidWNrZXQtPmZsYWdzICYgWE1MX1NDSEVNQV9CVUNLRVRfQ09NUFNfQURERUQpCglyZXR1cm4oMCk7CiAgICBidWNrZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfQlVDS0VUX0NPTVBTX0FEREVEOyAKICAgIAogICAgZm9yIChpID0gMDsgaSA8IGJ1Y2tldC0+Z2xvYmFscy0+bmJJdGVtczsgaSsrKSB7CglpdGVtID0gYnVja2V0LT5nbG9iYWxzLT5pdGVtc1tpXTsKCXRhYmxlID0gTlVMTDsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCWlmIChXWFNfUkVERUZJTkVEX1RZUEUoaXRlbSkpCgkJICAgIGNvbnRpbnVlOwoJCW5hbWUgPSAoV1hTX1RZUEVfQ0FTVCBpdGVtKS0+bmFtZTsKCQlXWFNfR0VUX0dMT0JBTF9IQVNIKGJ1Y2tldCwgdHlwZURlY2wpCgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQluYW1lID0gKFdYU19FTEVNX0NBU1QgaXRlbSktPm5hbWU7CgkJV1hTX0dFVF9HTE9CQUxfSEFTSChidWNrZXQsIGVsZW1EZWNsKQoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQluYW1lID0gKFdYU19BVFRSX0NBU1QgaXRlbSktPm5hbWU7CgkJV1hTX0dFVF9HTE9CQUxfSEFTSChidWNrZXQsIGF0dHJEZWNsKQoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCWlmIChXWFNfUkVERUZJTkVEX01PREVMX0dST1VQX0RFRihpdGVtKSkKCQkgICAgY29udGludWU7CgkJbmFtZSA9IChXWFNfTU9ERUxfR1JPVVBERUZfQ0FTVCBpdGVtKS0+bmFtZTsKCQlXWFNfR0VUX0dMT0JBTF9IQVNIKGJ1Y2tldCwgZ3JvdXBEZWNsKQoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCWlmIChXWFNfUkVERUZJTkVEX0FUVFJfR1JPVVAoaXRlbSkpCgkJICAgIGNvbnRpbnVlOwoJCW5hbWUgPSAoV1hTX0FUVFJfR1JPVVBfQ0FTVCBpdGVtKS0+bmFtZTsKCQlXWFNfR0VUX0dMT0JBTF9IQVNIKGJ1Y2tldCwgYXR0cmdycERlY2wpCgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUY6CgkJbmFtZSA9IChXWFNfSURDX0NBU1QgaXRlbSktPm5hbWU7CgkJV1hTX0dFVF9HTE9CQUxfSEFTSChidWNrZXQsIGlkY0RlZikKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCQluYW1lID0gKCh4bWxTY2hlbWFOb3RhdGlvblB0cikgaXRlbSktPm5hbWU7CgkJV1hTX0dFVF9HTE9CQUxfSEFTSChidWNrZXQsIG5vdGFEZWNsKQoJCWJyZWFrOwkgICAgCgkgICAgZGVmYXVsdDoKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFBZGRDb21wb25lbnRzIiwKCQkgICAgIlVuZXhwZWN0ZWQgZ2xvYmFsIGNvbXBvbmVudCB0eXBlIik7CgkJY29udGludWU7ICAgIAkJCgl9CQoJaWYgKCp0YWJsZSA9PSBOVUxMKSB7CgkgICAgKnRhYmxlID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIHBjdHh0LT5kaWN0KTsKCSAgICBpZiAoKnRhYmxlID09IE5VTEwpIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFBZGRDb21wb25lbnRzIiwKCQkgICAgImZhaWxlZCB0byBjcmVhdGUgYSBjb21wb25lbnQgaGFzaCB0YWJsZSIpOwoJCXJldHVybigtMSk7CgkgICAgfQoJfQkKCWVyciA9IHhtbEhhc2hBZGRFbnRyeSgqdGFibGUsIG5hbWUsIGl0ZW0pOwoJaWYgKGVyciAhPSAwKSB7CQoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX1RZUEUsCgkJV1hTX0lURU1fTk9ERShpdGVtKSwKCQlXWFNfQkFTSUNfQ0FTVCBpdGVtLAoJCSJBIGdsb2JhbCAlcyAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsCgkJV1hTX0lURU1fVFlQRV9OQU1FKGl0ZW0pLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW0pKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CSAKCX0KICAgIH0KICAgIC8qCiAgICAqIFByb2Nlc3MgaW1wb3J0ZWQvaW5jbHVkZWQgc2NoZW1hcy4KICAgICovCiAgICBpZiAoYnVja2V0LT5yZWxhdGlvbnMgIT0gTlVMTCkgewoJeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgcmVsID0gYnVja2V0LT5yZWxhdGlvbnM7CglkbyB7CgkgICAgaWYgKChyZWwtPmJ1Y2tldCAhPSBOVUxMKSAmJgoJCSgocmVsLT5idWNrZXQtPmZsYWdzICYgWE1MX1NDSEVNQV9CVUNLRVRfQ09NUFNfQURERUQpID09IDApKSB7CgkJaWYgKHhtbFNjaGVtYUFkZENvbXBvbmVudHMocGN0eHQsIHJlbC0+YnVja2V0KSA9PSAtMSkKCQkgICAgcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgcmVsID0gcmVsLT5uZXh0OwoJfSB3aGlsZSAocmVsICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpeHVwQ29tcG9uZW50cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgeG1sU2NoZW1hQnVja2V0UHRyIHJvb3RCdWNrZXQpCnsKICAgIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIgY29uID0gcGN0eHQtPmNvbnN0cnVjdG9yOwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbSwgKml0ZW1zOwogICAgaW50IG5iSXRlbXMsIGksIHJldCA9IDA7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgb2xkYnVja2V0ID0gY29uLT5idWNrZXQ7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOwoKI2RlZmluZSBGSVhIRkFJTFVSRSBpZiAocGN0eHQtPmVyciA9PSBYTUxfU0NIRU1BUF9JTlRFUk5BTCkgZ290byBleGl0X2ZhaWx1cmU7CgogICAgaWYgKChjb24tPnBlbmRpbmcgPT0gTlVMTCkgfHwKCShjb24tPnBlbmRpbmctPm5iSXRlbXMgPT0gMCkpCglyZXR1cm4oMCk7ICAgIAoKICAgIC8qCiAgICAqIFNpbmNlIHhtbFNjaGVtYUZpeHVwQ29tcGxleFR5cGUoKSB3aWxsIGNyZWF0ZSBuZXcgcGFydGljbGVzCiAgICAqIChsb2NhbCBjb21wb25lbnRzKSwgYW5kIHRob3NlIHBhcnRpY2xlIGNvbXBvbmVudHMgbmVlZCBhIGJ1Y2tldAogICAgKiBvbiB0aGUgY29uc3RydWN0b3IsIHdlJ2xsIGFzc3VyZSBoZXJlIHRoYXQgdGhlIGNvbnN0cnVjdG9yIGhhcwogICAgKiBhIGJ1Y2tldC4KICAgICogVE9ETzogVGhpbmsgYWJvdXQgc3RvcmluZyBsb2NhbHMgX29ubHlfIG9uIHRoZSBtYWluIGJ1Y2tldC4gICAgCiAgICAqLyAgICAKICAgIGlmIChjb24tPmJ1Y2tldCA9PSBOVUxMKQoJY29uLT5idWNrZXQgPSByb290QnVja2V0OyAgICAKCiAgICAvKiBUT0RPOgogICAgKiBTUEVDIChzcmMtcmVkZWZpbmUpOgogICAgKiAoNi4yKSAiSWYgaXQgaGFzIG5vIHN1Y2ggc2VsZi1yZWZlcmVuY2UsIHRoZW4gYWxsIG9mIHRoZQogICAgKiBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgIAogICAgKiAoNi4yLjIpIFRoZSB7bW9kZWwgZ3JvdXB9IG9mIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uIHdoaWNoCiAgICAqIGNvcnJlc3BvbmRzIHRvIGl0IHBlciBYTUwgUmVwcmVzZW50YXRpb24gb2YgTW9kZWwgR3JvdXAKICAgICogRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cyAopzMuNy4yKSBtdXN0IGJlIGEgt3ZhbGlkCiAgICAqIHJlc3RyaWN0aW9utyBvZiB0aGUge21vZGVsIGdyb3VwfSBvZiB0aGF0IG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICAgICogaW4gSSwgYXMgZGVmaW5lZCBpbiBQYXJ0aWNsZSBWYWxpZCAoUmVzdHJpY3Rpb24pICinMy45LjYpLiIKICAgICovCiAgICB4bWxTY2hlbWFDaGVja1NSQ1JlZGVmaW5lRmlyc3QocGN0eHQpOwoKICAgIC8qCiAgICAqIEFkZCBnbG9iYWwgY29tcG9uZW50cyB0byB0aGUgc2NoZW1hdGEncyBoYXNoIHRhYmxlcy4KICAgICovICAgIAogICAgeG1sU2NoZW1hQWRkQ29tcG9uZW50cyhwY3R4dCwgcm9vdEJ1Y2tldCk7CgogICAgcGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKICAgIGl0ZW1zID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyICopIGNvbi0+cGVuZGluZy0+aXRlbXM7CiAgICBuYkl0ZW1zID0gY29uLT5wZW5kaW5nLT5uYkl0ZW1zOwogICAgLyoKICAgICogTm93IHRoYXQgd2UgaGF2ZSBwYXJzZWQgKmFsbCogdGhlIHNjaGVtYSBkb2N1bWVudChzKSBhbmQgY29udmVydGVkCiAgICAqIHRoZW0gdG8gc2NoZW1hIGNvbXBvbmVudHMsIHdlIGNhbiByZXNvbHZlIHJlZmVyZW5jZXMsIGFwcGx5IGNvbXBvbmVudAogICAgKiBjb25zdHJhaW50cywgY3JlYXRlIHRoZSBGU0EgZnJvbSB0aGUgY29udGVudCBtb2RlbCwgZXRjLgogICAgKi8gICAgCiAgICAvKgogICAgKiBSZXNvbHZlIHJlZmVyZW5jZXMgb2YuLgogICAgKgogICAgKiAxLiBlbGVtZW50IGRlY2xhcmF0aW9uczoKICAgICogICAtIHRoZSB0eXBlIGRlZmluaXRpb24KICAgICogICAtIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb24KICAgICogMi4gc2ltcGxlL2NvbXBsZXggdHlwZXM6CiAgICAqICAgLSB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICAgICogICAtIHRoZSBtZW1iZXJUeXBlcyBvZiB1bmlvbiB0eXBlcwogICAgKiAgIC0gdGhlIGl0ZW1UeXBlIG9mIGxpc3QgdHlwZXMKICAgICogMy4gYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMgYW5kIGF0dHJpYnV0ZSB1c2VzOgogICAgKiAgIC0gdGhlIHR5cGUgZGVmaW5pdGlvbgogICAgKiAgIC0gaWYgYW4gYXR0cmlidXRlIHVzZSwgdGhlbiB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uCiAgICAqIDQuIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzOgogICAgKiAgIC0gdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAgICAqIDUuIHBhcnRpY2xlczoKICAgICogICAtIHRoZSB0ZXJtIG9mIHRoZSBwYXJ0aWNsZSAoZS5nLiBhIG1vZGVsIGdyb3VwKQogICAgKiA2LiBJREMga2V5LXJlZmVyZW5jZXM6CiAgICAqICAgLSB0aGUgcmVmZXJlbmNlZCBJREMgJ2tleScgb3IgJ3VuaXF1ZScgZGVmaW5pdGlvbgogICAgKiA3LiBBdHRyaWJ1dGUgcHJvaGliaXRpb25zIHdoaWNoIGhhZCBhICJyZWYiIGF0dHJpYnV0ZS4KICAgICovICAgICAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hUmVzb2x2ZUVsZW1lbnRSZWZlcmVuY2VzKAoJCSAgICAoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCXhtbFNjaGVtYVJlc29sdmVUeXBlUmVmZXJlbmNlcygKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIHBjdHh0KTsKCQlGSVhIRkFJTFVSRTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hUmVzb2x2ZUF0dHJUeXBlUmVmZXJlbmNlcygKCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURV9VU0U6CgkJeG1sU2NoZW1hUmVzb2x2ZUF0dHJVc2VSZWZlcmVuY2VzKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyKSBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGOgoJCWlmICgoV1hTX1FOQU1FX0NBU1QgaXRlbSktPml0ZW1UeXBlID09IAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApCgkJewoJCSAgICB4bWxTY2hlbWFSZXNvbHZlQXR0ckdyb3VwUmVmZXJlbmNlcygKCQkJV1hTX1FOQU1FX0NBU1QgaXRlbSwgcGN0eHQpOwoJCX0KCQlGSVhIRkFJTFVSRTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJCXhtbFNjaGVtYVJlc29sdmVNb2RlbEdyb3VwUGFydGljbGVSZWZlcmVuY2VzKHBjdHh0LAoJCSAgICBXWFNfTU9ERUxfR1JPVVBfQ0FTVCBpdGVtKTsKCQlGSVhIRkFJTFVSRTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCQl4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmZXJlbmNlcygKCQkgICAgKHhtbFNjaGVtYUlEQ1B0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUI6CgkJLyoKCQkqIEhhbmRsZSBhdHRyaWJ1ZSBwcm9oaWJpdGlvbiB3aGljaCBoYWQgYQoJCSogInJlZiIgYXR0cmlidXRlLgoJCSovCgkJeG1sU2NoZW1hUmVzb2x2ZUF0dHJVc2VQcm9oaWJSZWZlcmVuY2VzKAoJCSAgICBXWFNfQVRUUl9QUk9ISUJfQ0FTVCBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIAogICAgLyoKICAgICogTm93IHRoYXQgYWxsIHJlZmVyZW5jZXMgYXJlIHJlc29sdmVkIHdlCiAgICAqIGNhbiBjaGVjayBmb3IgY2lyY3VsYXJpdHkgb2YuLi4KICAgICogMS4gdGhlIGJhc2UgYXhpcyBvZiB0eXBlIGRlZmluaXRpb25zIAogICAgKiAyLiBuZXN0ZWQgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMKICAgICogMy4gbmVzdGVkIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9ucwogICAgKiBUT0RPOiBjaGVjayBmb3IgY2lyY3VhbCBzdWJzdGl0dXRpb24gZ3JvdXBzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCS8qCgkqIExldCdzIGJldHRlciBzdG9wIG9uIHRoZSBmaXJzdCBlcnJvciBoZXJlLgoJKi8KCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCXhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCQkgICAgZ290byBleGl0X2Vycm9yOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCXhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGl0ZW0sIHBjdHh0KTsKCQlGSVhIRkFJTFVSRTsKCQlpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCgkJICAgIGdvdG8gZXhpdF9lcnJvcjsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQl4bWxTY2hlbWFDaGVja0F0dHJHcm91cENpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIHBjdHh0KTsKCQlGSVhIRkFJTFVSRTsKCQlpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCgkJICAgIGdvdG8gZXhpdF9lcnJvcjsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQkKICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIC8qCiAgICAqIE1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlczoKICAgICogU3VjaCBhIHJlZmVyZW5jZSBpcyByZWZsZWN0ZWQgYnkgYSBwYXJ0aWNsZSBhdCB0aGUgY29tcG9uZW50CiAgICAqIGxldmVsLiBVbnRpbCBub3cgdGhlICd0ZXJtJyBvZiBzdWNoIHBhcnRpY2xlcyBwb2ludGVkCiAgICAqIHRvIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uOyB0aGlzIHdhcyBkb25lLCBpbiBvcmRlciB0bwogICAgKiBlYXNlIGNpcmN1bGFyaXR5IGNoZWNrcy4gTm93IHdlIG5lZWQgdG8gc2V0IHRoZSAndGVybScgb2YKICAgICogc3VjaCBwYXJ0aWNsZXMgdG8gdGhlIG1vZGVsIGdyb3VwIG9mIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToJCgkJeG1sU2NoZW1hTW9kZWxHcm91cFRvTW9kZWxHcm91cERlZkZpeHVwKHBjdHh0LAoJCSAgICBXWFNfTU9ERUxfR1JPVVBfQ0FTVCBpdGVtKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogRXhwYW5kIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzIG9mIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9ucy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJaWYgKCghIFdYU19BVFRSX0dST1VQX0VYUEFOREVEKGl0ZW0pKSAmJgoJCSAgICBXWFNfQVRUUl9HUk9VUF9IQVNfUkVGUyhpdGVtKSkKCQl7CgkJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwRXhwYW5kUmVmcyhwY3R4dCwKCQkJV1hTX0FUVFJfR1JPVVBfQ0FTVCBpdGVtKTsKCQkgICAgRklYSEZBSUxVUkU7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CiAgICAvKiAKICAgICogRmlyc3QgY29tcHV0ZSB0aGUgdmFyaWV0eSBvZiBzaW1wbGUgdHlwZXMuIFRoaXMgaXMgbmVlZGVkIGFzCiAgICAqIGEgc2VwZXJhdGUgc3RlcCwgc2luY2Ugb3RoZXJ3aXNlIHdlIHdvbid0IGJlIGFibGUgdG8gZGV0ZWN0CiAgICAqIGNpcmN1bGFyIHVuaW9uIHR5cGVzIGluIGFsbCBjYXNlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCWlmIChXWFNfSVNfVFlQRV9OT1RfRklYRURfMSgoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSkpIHsKCQkgICAgeG1sU2NoZW1hRml4dXBTaW1wbGVUeXBlU3RhZ2VPbmUocGN0eHQsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKTsKCQkgICAgRklYSEZBSUxVUkU7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CiAgICAvKgogICAgKiBEZXRlY3QgY2lyY3VsYXIgdW5pb24gdHlwZXMuIE5vdGUgdGhhdCB0aGlzIG5lZWRzIHRoZSB2YXJpZXR5IHRvCiAgICAqIGJlIGFscmVhZHkgY29tcHV0ZWQuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQlpZiAoKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFDaGVja1VuaW9uVHlwZURlZkNpcmN1bGFyKHBjdHh0LAkKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIAogICAgLyoKICAgICogRG8gdGhlIGNvbXBsZXRlIHR5cGUgZml4dXAgZm9yIHNpbXBsZSB0eXBlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCWlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQoV1hTX1RZUEVfQ0FTVCBpdGVtKSkgewoJCSAgICB4bWxTY2hlbWFGaXh1cFNpbXBsZVR5cGVTdGFnZVR3byhwY3R4dCwgV1hTX1RZUEVfQ0FTVCBpdGVtKTsKCQkgICAgRklYSEZBSUxVUkU7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CiAgICAvKgogICAgKiBBdCB0aGlzIHBvaW50IHdlIG5lZWQgYnVpbGQgYW5kIGNoZWNrIGFsbCBzaW1wbGUgdHlwZXMuCiAgICAqLwogICAgLyoKICAgICogQXBwbHkgY29udHJhaW50cyBmb3IgYXR0cmlidXRlIGRlY2xhcmF0aW9ucy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CQkKCQl4bWxTY2hlbWFDaGVja0F0dHJQcm9wc0NvcnJlY3QocGN0eHQsIFdYU19BVFRSX0NBU1QgaXRlbSk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CSAgICAKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogQXBwbHkgY29uc3RyYWludHMgZm9yIGF0dHJpYnV0ZSB1c2VzLgogICAgKi8gICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOgoJCWlmICgoKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cilpdGVtKS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFDaGVja0F0dHJVc2VQcm9wc0NvcnJlY3QocGN0eHQsCgkJCVdYU19BVFRSX1VTRV9DQVNUIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKgogICAgKiBBcHBseSBjb25zdHJhaW50cyBmb3IgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb25zLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgaWYgKCggKFdYU19BVFRSX0dST1VQX0NBU1QgaXRlbSktPmF0dHJVc2VzICE9IE5VTEwpICYmCgkJKCAoV1hTX0xJU1RfQ0FTVCAoV1hTX0FUVFJfR1JPVVBfQ0FTVCBpdGVtKS0+YXR0clVzZXMpLT5uYkl0ZW1zID4gMSkpCgkgICAgewoJCXhtbFNjaGVtYUNoZWNrQUdQcm9wc0NvcnJlY3QocGN0eHQsIFdYU19BVFRSX0dST1VQX0NBU1QgaXRlbSk7CgkJRklYSEZBSUxVUkU7CgkgICAgfQoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKgogICAgKiBBcHBseSBjb25zdHJhaW50cyBmb3IgcmVkZWZpbml0aW9ucy4KICAgICovCiAgICBpZiAoV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+cmVkZWZzICE9IE5VTEwpCgl4bWxTY2hlbWFDaGVja1NSQ1JlZGVmaW5lU2Vjb25kKHBjdHh0KTsKICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKiAgICAKICAgICogQ29tcGxleCB0eXBlcyBhcmUgYnVpbGRlZCBhbmQgY2hlY2tlZC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gY29uLT5wZW5kaW5nLT5pdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChXWFNfVFlQRV9DQVNUIGl0ZW0pKSB7CgkJICAgIHhtbFNjaGVtYUZpeHVwQ29tcGxleFR5cGUocGN0eHQsIFdYU19UWVBFX0NBU1QgaXRlbSk7CgkJICAgIEZJWEhGQUlMVVJFOwoJCX0KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwoKICAgIC8qCiAgICAqIFRoZSBsaXN0IGNvdWxkIGhhdmUgY2hhbmdlZCwgc2luY2UgeG1sU2NoZW1hRml4dXBDb21wbGV4VHlwZSgpCiAgICAqIHdpbGwgY3JlYXRlIHBhcnRpY2xlcyBhbmQgbW9kZWwgZ3JvdXBzIGluIHNvbWUgY2FzZXMuCiAgICAqLwogICAgaXRlbXMgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIgKikgY29uLT5wZW5kaW5nLT5pdGVtczsKICAgIG5iSXRlbXMgPSBjb24tPnBlbmRpbmctPm5iSXRlbXM7ICAgIAogICAgCiAgICAvKgogICAgKiBBcHBseSBzb21lIGNvbnN0cmFpbnRzIGZvciBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCWVsZW1EZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW07CgkJCgkJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX0NIRUNLRUQpID09IDApCgkJewoJCSAgICB4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KAoJCQkoeG1sU2NoZW1hRWxlbWVudFB0cikgZWxlbURlY2wsIHBjdHh0KTsKCQkgICAgRklYSEZBSUxVUkU7CgkJfQoKI2lmZGVmIFdYU19FTEVNX0RFQ0xfQ09OU19FTkFCTEVECgkJLyoKCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWxlbWVudCBEZWNsYXJhdGlvbnMgQ29uc2lzdGVudAoJCSogQXBwbHkgdGhpcyBjb25zdHJhaW50IHRvIGxvY2FsIHR5cGVzIG9mIGVsZW1lbnQgZGVjbGFyYXRpb25zLgoJCSovCgkJaWYgKChXWFNfRUxFTV9UWVBFREVGKGVsZW1EZWNsKSAhPSBOVUxMKSAmJgoJCSAgICAoV1hTX0lTX0NPTVBMRVgoV1hTX0VMRU1fVFlQRURFRihlbGVtRGVjbCkpKSAmJgoJCSAgICAoV1hTX1RZUEVfSVNfTE9DQUwoV1hTX0VMRU1fVFlQRURFRihlbGVtRGVjbCkpKSkKCQl7CgkJICAgIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb25zaXN0ZW50KHBjdHh0LAoJCQlXWFNfQkFTSUNfQ0FTVCBlbGVtRGVjbCwKCQkJV1hTX1RZUEVfUEFSVElDTEUoV1hTX0VMRU1fVFlQRURFRihlbGVtRGVjbCkpLAoJCQlOVUxMLCBOVUxMLCAwKTsKCQl9CiNlbmRpZgoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CiAKICAgIC8qCiAgICAqIEZpbmFsbHkgd2UgY2FuIGJ1aWxkIHRoZSBhdXRvbWF0b24gZnJvbSB0aGUgY29udGVudCBtb2RlbCBvZgogICAgKiBjb21wbGV4IHR5cGVzLgogICAgKi8KCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBwY3R4dCk7CgkJLyogRklYSEZBSUxVUkU7ICovCgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIC8qCiAgICAqIFVSR0VOVCBUT0RPOiBjb3MtZWxlbWVudC1jb25zaXN0ZW50CiAgICAqLyAgICAgICAgCiAgICBnb3RvIGV4aXQ7ICAgIAoKZXhpdF9lcnJvcjogICAgCiAgICByZXQgPSBwY3R4dC0+ZXJyOwogICAgZ290byBleGl0OwoKZXhpdF9mYWlsdXJlOgogICAgcmV0ID0gLTE7CgpleGl0OgogICAgLyoKICAgICogUmVzZXQgdGhlIGNvbnN0cnVjdG9yLiBUaGlzIGlzIG5lZWRlZCBmb3IgWFNJIGFjcXVpc2l0aW9uLCBzaW5jZQogICAgKiB0aG9zZSBpdGVtcyB3aWxsIGJlIHByb2Nlc3NlZCBvdmVyIGFuZCBvdmVyIGFnYWluIGZvciBldmVyeSBYU0kKICAgICogaWYgbm90IGNsZWFyZWQgaGVyZS4KICAgICovCiAgICBjb24tPmJ1Y2tldCA9IG9sZGJ1Y2tldDsKICAgIGNvbi0+cGVuZGluZy0+bmJJdGVtcyA9IDA7ICAgIAogICAgaWYgKGNvbi0+c3Vic3RHcm91cHMgIT0gTlVMTCkgewoJeG1sSGFzaEZyZWUoY29uLT5zdWJzdEdyb3VwcywKCSAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFTdWJzdEdyb3VwRnJlZSk7Cgljb24tPnN1YnN0R3JvdXBzID0gTlVMTDsKICAgIH0gICAgCiAgICBpZiAoY29uLT5yZWRlZnMgIT0gTlVMTCkgewoJeG1sU2NoZW1hUmVkZWZMaXN0RnJlZShjb24tPnJlZGVmcyk7Cgljb24tPnJlZGVmcyA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4ocmV0KTsKfQovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFQdHIgbWFpblNjaGVtYSA9IE5VTEw7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0ID0gTlVMTDsKICAgIGludCByZXM7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYQogICAgKiB0aGUgQVBJOyBpLmUuIG5vdCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgZG9jdW1lbnQuCiAgICAqLwoKICAgIHhtbFNjaGVtYUluaXRUeXBlcygpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICAvKiBUT0RPOiBJbml0IHRoZSBjb250ZXh0LiBJcyB0aGlzIGFsbCB3ZSBuZWVkPyovCiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5lcnIgPSAwOwogICAgY3R4dC0+Y291bnRlciA9IDA7CgogICAgLyogQ3JlYXRlIHRoZSAqbWFpbiogc2NoZW1hLiAqLwogICAgbWFpblNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0KTsKICAgIGlmIChtYWluU2NoZW1hID09IE5VTEwpCglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIC8qCiAgICAqIENyZWF0ZSB0aGUgc2NoZW1hIGNvbnN0cnVjdG9yLgogICAgKi8KICAgIGlmIChjdHh0LT5jb25zdHJ1Y3RvciA9PSBOVUxMKSB7CgljdHh0LT5jb25zdHJ1Y3RvciA9IHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRDcmVhdGUoY3R4dC0+ZGljdCk7CglpZiAoY3R4dC0+Y29uc3RydWN0b3IgPT0gTlVMTCkKCSAgICByZXR1cm4oTlVMTCk7CgkvKiBUYWtlIG93bmVyc2hpcCBvZiB0aGUgY29uc3RydWN0b3IgdG8gYmUgYWJsZSB0byBmcmVlIGl0LiAqLwoJY3R4dC0+b3duc0NvbnN0cnVjdG9yID0gMTsKICAgIH0KICAgIGN0eHQtPmNvbnN0cnVjdG9yLT5tYWluU2NoZW1hID0gbWFpblNjaGVtYTsKICAgIC8qCiAgICAqIExvY2F0ZSBhbmQgYWRkIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hQWRkU2NoZW1hRG9jKGN0eHQsIFhNTF9TQ0hFTUFfU0NIRU1BX01BSU4sCgljdHh0LT5VUkwsIGN0eHQtPmRvYywgY3R4dC0+YnVmZmVyLCBjdHh0LT5zaXplLCBOVUxMLAoJTlVMTCwgTlVMTCwgJmJ1Y2tldCk7CiAgICBpZiAocmVzID09IC0xKQoJZ290byBleGl0X2ZhaWx1cmU7CiAgICBpZiAocmVzICE9IDApCglnb3RvIGV4aXQ7ICAgCgogICAgaWYgKGJ1Y2tldCA9PSBOVUxMKSB7CgkvKiBUT0RPOiBFcnJvciBjb2RlLCBhY3R1YWxseSB3ZSBmYWlsZWQgdG8gKmxvY2F0ZSogdGhlIHNjaGVtYS4gKi8KCWlmIChjdHh0LT5VUkwpIAoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAoJCU5VTEwsIE5VTEwsCgkJIkZhaWxlZCB0byBsb2NhdGUgdGhlIG1haW4gc2NoZW1hIHJlc291cmNlIGF0ICclcyciLAoJCWN0eHQtPlVSTCwgTlVMTCk7CgllbHNlCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCgkJTlVMTCwgTlVMTCwKCQkiRmFpbGVkIHRvIGxvY2F0ZSB0aGUgbWFpbiBzY2hlbWEgcmVzb3VyY2UiLAoJCSAgICBOVUxMLCBOVUxMKTsKCWdvdG8gZXhpdDsKICAgIH0gICAgICAgIAogICAgLyogVGhlbiBkbyB0aGUgcGFyc2luZyBmb3IgZ29vZC4gKi8KICAgIGlmICh4bWxTY2hlbWFQYXJzZU5ld0RvY1dpdGhDb250ZXh0KGN0eHQsIG1haW5TY2hlbWEsIGJ1Y2tldCkgPT0gLTEpCglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0OwogICAgCiAgICBtYWluU2NoZW1hLT5kb2MgPSBidWNrZXQtPmRvYzsKICAgIG1haW5TY2hlbWEtPnByZXNlcnZlID0gY3R4dC0+cHJlc2VydmU7CiAgICAKICAgIGN0eHQtPnNjaGVtYSA9IG1haW5TY2hlbWE7CgogICAgaWYgKHhtbFNjaGVtYUZpeHVwQ29tcG9uZW50cyhjdHh0LCBXWFNfQ09OU1RSVUNUT1IoY3R4dCktPm1haW5CdWNrZXQpID09IC0xKQoJZ290byBleGl0X2ZhaWx1cmU7CgogICAgLyoKICAgICogVE9ETzogVGhpcyBpcyBub3QgbmljZSwgc2luY2Ugd2UgY2Fubm90IGRpc3Rpbmd1aXNoIGZyb20gdGhlCiAgICAqIHJlc3VsdCBpZiB0aGVyZSB3YXMgYW4gaW50ZXJuYWwgZXJyb3Igb3Igbm90LgogICAgKi8KZXhpdDogICAgICAgCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewkKCWlmIChtYWluU2NoZW1hKSB7CgkgICAgeG1sU2NoZW1hRnJlZShtYWluU2NoZW1hKTsKCSAgICBtYWluU2NoZW1hID0gTlVMTDsKCX0KCWlmIChjdHh0LT5jb25zdHJ1Y3RvcikgewoJICAgIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRGcmVlKGN0eHQtPmNvbnN0cnVjdG9yKTsKCSAgICBjdHh0LT5jb25zdHJ1Y3RvciA9IE5VTEw7CgkgICAgY3R4dC0+b3duc0NvbnN0cnVjdG9yID0gMDsKCX0KICAgIH0KICAgIGN0eHQtPnNjaGVtYSA9IE5VTEw7CiAgICByZXR1cm4obWFpblNjaGVtYSk7CmV4aXRfZmFpbHVyZToKICAgIC8qIAogICAgKiBRdWl0ZSB2ZXJib3NlLCBidXQgc2hvdWxkIGNhdGNoIGludGVybmFsIGVycm9ycywgd2hpY2ggd2VyZQogICAgKiBub3QgY29tbXVuaXRhdGVkLgogICAgKi8KICAgIGlmIChtYWluU2NoZW1hKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZShtYWluU2NoZW1hKTsKCW1haW5TY2hlbWEgPSBOVUxMOwogICAgfQogICAgaWYgKGN0eHQtPmNvbnN0cnVjdG9yKSB7Cgl4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0RnJlZShjdHh0LT5jb25zdHJ1Y3Rvcik7CgljdHh0LT5jb25zdHJ1Y3RvciA9IE5VTEw7CgljdHh0LT5vd25zQ29uc3RydWN0b3IgPSAwOwogICAgfQogICAgUEVSUk9SX0lOVDIoInhtbFNjaGVtYVBhcnNlIiwKCSJBbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkIik7ICAgIAogICAgY3R4dC0+c2NoZW1hID0gTlVMTDsKICAgIHJldHVybihOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBjYWxsYmFjawogKiBAd2FybjogIHRoZSB3YXJuaW5nIGNhbGxiYWNrCiAqIEBjdHg6ICBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MKICoKICogU2V0IHRoZSBjYWxsYmFjayBmdW5jdGlvbnMgdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPmVyckN0eHQgPSBjdHg7CiAgICBpZiAoY3R4dC0+dmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKGN0eHQtPnZjdHh0LCBlcnIsIHdhcm4sIGN0eCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRQYXJzZXJTdHJ1Y3R1cmVkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzZXJyb3I6ICB0aGUgc3RydWN0dXJlZCBlcnJvciBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBzdHJ1Y3R1cmVkIGVycm9yIGNhbGxiYWNrCiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlclN0cnVjdHVyZWRFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3IsCgkJCQkgICB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm47CiAgICBjdHh0LT5zZXJyb3IgPSBzZXJyb3I7CiAgICBjdHh0LT5lcnJDdHh0ID0gY3R4OwogICAgaWYgKGN0eHQtPnZjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRWYWxpZFN0cnVjdHVyZWRFcnJvcnMoY3R4dC0+dmN0eHQsIHNlcnJvciwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIFhNbC1TY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGNhbGxiYWNrIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgY2FsbGJhY2sgcmVzdWx0CiAqIEBjdHg6IGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcyByZXN1bHQKICoKICogR2V0IHRoZSBjYWxsYmFjayBpbmZvcm1hdGlvbiB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGZhaWx1cmUsIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+ZXJyQ3R4dDsKCXJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nOgogKiBAdHlwZTogIHRoZSBmYWNldCB0eXBlCiAqCiAqIENvbnZlcnQgdGhlIHhtbFNjaGVtYVR5cGVUeXBlIHRvIGEgY2hhciBzdHJpbmcuCiAqCiAqIFJldHVybnMgdGhlIGNoYXIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmYWNldCB0eXBlIGlmIHRoZQogKiAgICAgdHlwZSBpcyBhIGZhY2V0IGFuZCBhbiAiSW50ZXJuYWwgRXJyb3IiIHN0cmluZyBvdGhlcndpc2UuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpCnsKICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJwYXR0ZXJuIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4RXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4SW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluRXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluSW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIndoaXRlU3BhY2UiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImVudW1lcmF0aW9uIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4TGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluTGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJ0b3RhbERpZ2l0cyIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAiZnJhY3Rpb25EaWdpdHMiKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoQkFEX0NBU1QgIkludGVybmFsIEVycm9yIik7Cn0KCnN0YXRpYyB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlCnhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgLyoKICAgICogVGhlIG5vcm1hbGl6YXRpb24gdHlwZSBjYW4gYmUgY2hhbmdlZCBvbmx5IGZvciB0eXBlcyB3aGljaCBhcmUgZGVyaXZlZAogICAgKiBmcm9tIHhzZDpzdHJpbmcuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkvKgoJKiBOb3RlIHRoYXQgd2UgYXNzdW1lIGEgd2hpdGVzcGFjZSBvZiBwcmVzZXJ2ZSBmb3IgYW55U2ltcGxlVHlwZS4KCSovCglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgfHwKCSAgICAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSk7CgllbHNlIGlmICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19OT1JNU1RSSU5HKQoJICAgIHJldHVybihYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUkVQTEFDRSk7CgllbHNlIHsKCSAgICAvKgoJICAgICogRm9yIGFsbCC3YXRvbWljtyBkYXRhdHlwZXMgb3RoZXIgdGhhbiBzdHJpbmcgKGFuZCB0eXBlcyC3ZGVyaXZlZLcKCSAgICAqIGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBpdCkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2UgaXMgZml4ZWQgdG8KCSAgICAqIGNvbGxhcHNlCgkgICAgKiBOb3RlIHRoYXQgdGhpcyBpbmNsdWRlcyBidWlsdC1pbiBsaXN0IGRhdGF0eXBlcy4KCSAgICAqLwoJICAgIHJldHVybihYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0UpOwoJfQogICAgfSBlbHNlIGlmIChXWFNfSVNfTElTVCh0eXBlKSkgewoJLyoKCSogRm9yIGxpc3QgdHlwZXMgdGhlIGZhY2V0ICJ3aGl0ZVNwYWNlIiBpcyBmaXhlZCB0byAiY29sbGFwc2UiLgoJKi8KCXJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKTsKICAgIH0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUpKSB7CglyZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9VTktOT1dOKTsKICAgIH0gZWxzZSBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkgewoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1BSRVNFUlZFKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX1BSRVNFUlZFKTsKCWVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1JFUExBQ0UpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUkVQTEFDRSk7CgllbHNlCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0UpOwogICAgfQogICAgcmV0dXJuICgtMSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTaW1wbGUgdHlwZSB2YWxpZGF0aW9uCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlET00gVmFsaWRhdGlvbiBjb2RlCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbjoKICogQHBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHZjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBleGlzdGluZyBzY2hlbWEKICogQG5vZGU6IHRoZSBub2RlIHRoYXQgZmlyZWQgdGhlIGFzc2VtYmxpbmcKICogQG5zTmFtZTogdGhlIG5hbWVzcGFjZSBuYW1lIG9mIHRoZSBuZXcgc2NoZW1hCiAqIEBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICoKICogRXhwYW5kcyBhbiBleGlzdGluZyBzY2hlbWEgYnkgYW4gYWRkaXRpb25hbCBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbG9jYXRpb24pCnsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQgPSBOVUxMOwoKICAgIGlmICgodmN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwoKICAgIGlmICh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uIiwKCSAgICAibm8gcGFyc2VyIGNvbnRleHQgYXZhaWxhYmxlIik7CglyZXR1cm4oLTEpOwogICAgfQogICAgcGN0eHQgPSB2Y3R4dC0+cGN0eHQ7CiAgICBpZiAocGN0eHQtPmNvbnN0cnVjdG9yID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiIsCgkgICAgIm5vIGNvbnN0cnVjdG9yIik7CglyZXR1cm4oLTEpOwogICAgfQogICAgLyoKICAgICogQWNxdWlyZSB0aGUgc2NoZW1hIGRvY3VtZW50LgogICAgKi8KICAgIGxvY2F0aW9uID0geG1sU2NoZW1hQnVpbGRBYnNvbHV0ZVVSSShwY3R4dC0+ZGljdCwKCWxvY2F0aW9uLCBub2RlKTsKICAgIC8qCiAgICAqIE5vdGUgdGhhdCB3ZSBwYXNzIFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCBoZXJlOwogICAgKiB0aGUgcHJvY2VzcyB3aWxsIGF1dG9tYXRpY2FsbHkgY2hhbmdlIHRoaXMgdG8KICAgICogWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTiBpZiBpdCBpcyB0aGUgZmlyc3Qgc2NoZW1hIGRvY3VtZW50LgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYUFkZFNjaGVtYURvYyhwY3R4dCwgWE1MX1NDSEVNQV9TQ0hFTUFfSU1QT1JULAoJbG9jYXRpb24sIE5VTEwsIE5VTEwsIDAsIG5vZGUsIE5VTEwsIG5zTmFtZSwgCgkmYnVja2V0KTsKICAgIGlmIChyZXQgIT0gMCkKCXJldHVybihyZXQpOyAgICAKICAgIGlmIChidWNrZXQgPT0gTlVMTCkgewkKCS8qCgkqIEdlbmVyYXRlIGEgd2FybmluZyB0aGF0IHRoZSBkb2N1bWVudCBjb3VsZCBub3QgYmUgbG9jYXRlZC4KCSovCgl4bWxTY2hlbWFDdXN0b21XYXJuaW5nKEFDVFhUX0NBU1QgdmN0eHQsIFhNTF9TQ0hFTUFWX01JU0MsCgkgICAgbm9kZSwgTlVMTCwKCSAgICAiVGhlIGRvY3VtZW50IGF0IGxvY2F0aW9uICclcycgY291bGQgbm90IGJlIGFjcXVpcmVkIiwKCSAgICBsb2NhdGlvbiwgTlVMTCwgTlVMTCk7CglyZXR1cm4ocmV0KTsKICAgIH0KICAgIC8qCiAgICAqIFRoZSBmaXJzdCBsb2NhdGVkIHNjaGVtYSB3aWxsIGJlIGhhbmRsZWQgYXMgaWYgYWxsIG90aGVyCiAgICAqIHNjaGVtYXMgaW1wb3J0ZWQgYnkgWFNJIHdlcmUgaW1wb3J0ZWQgYnkgdGhpcyBmaXJzdCBzY2hlbWEuCiAgICAqLwogICAgaWYgKChidWNrZXQgIT0gTlVMTCkgJiYKCShXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXQgPT0gTlVMTCkpCglXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXQgPSBidWNrZXQ7CiAgICAvKgogICAgKiBUT0RPOiBJcyB0aGlzIGhhbmRsZWQgbGlrZSBhbiBpbXBvcnQ/IEkuZS4gaXMgaXQgbm90IGFuIGVycm9yCiAgICAqIGlmIHRoZSBzY2hlbWEgY2Fubm90IGJlIGxvY2F0ZWQ/CiAgICAqLwogICAgaWYgKChidWNrZXQgPT0gTlVMTCkgfHwgKCEgQ0FOX1BBUlNFX1NDSEVNQShidWNrZXQpKSkKCXJldHVybigwKTsKICAgIC8qCiAgICAqIFdlIHdpbGwgcmV1c2UgdGhlIHBhcnNlciBjb250ZXh0IGZvciBldmVyeSBzY2hlbWEgaW1wb3J0ZWQKICAgICogZGlyZWN0bHkgdmlhIFhTSS4gU28gcmVzZXQgdGhlIGNvbnRleHQuCiAgICAqLwogICAgcGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIHBjdHh0LT5lcnIgPSAwOwogICAgcGN0eHQtPmRvYyA9IGJ1Y2tldC0+ZG9jOwogICAgCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZU5ld0RvY1dpdGhDb250ZXh0KHBjdHh0LCBzY2hlbWEsIGJ1Y2tldCk7ICAgICAgICAKICAgIGlmIChyZXQgPT0gLTEpIHsKCXBjdHh0LT5kb2MgPSBOVUxMOwoJZ290byBleGl0X2ZhaWx1cmU7CiAgICB9CiAgICAvKiBQYXJhbm9pZCBlcnJvciBjaGFubmVsbGluZy4gKi8KICAgIGlmICgocmV0ID09IDApICYmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkpCglyZXQgPSBwY3R4dC0+ZXJyOyAgICAKICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgPT0gMCkgewkKCS8qIAoJKiBPbmx5IGJvdGhlciB0byBmaXh1cCBwZW5kaW5nIGNvbXBvbmVudHMsIGlmIHRoZXJlIHdhcwoJKiBubyBlcnJvciB5ZXQuCgkqIEZvciBldmVyeSBYU0kgYWNxdWlyZWQgc2NoZW1hIChhbmQgaXRzIHN1Yi1zY2hlbWF0YSkgd2Ugd2lsbAoJKiBmaXh1cCB0aGUgY29tcG9uZW50cy4KCSovCgl4bWxTY2hlbWFGaXh1cENvbXBvbmVudHMocGN0eHQsIGJ1Y2tldCk7CglyZXQgPSBwY3R4dC0+ZXJyOwoJLyoKCSogTm90IG5pY2UsIGJ1dCB3ZSBuZWVkIHNvbWVob3cgdG8gY2hhbm5lbCB0aGUgc2NoZW1hIHBhcnNlcgoJKiBlcnJvciB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0LgoJKi8KCWlmICgocmV0ICE9IDApICYmICh2Y3R4dC0+ZXJyID09IDApKQoJICAgIHZjdHh0LT5lcnIgPSByZXQ7Cgl2Y3R4dC0+bmJlcnJvcnMgKz0gcGN0eHQtPm5iZXJyb3JzOwogICAgfSBlbHNlIHsKCS8qIEFkZCB0byB2YWxpZGF0aW9uIGVycm9yIHN1bS4gKi8gCgl2Y3R4dC0+bmJlcnJvcnMgKz0gcGN0eHQtPm5iZXJyb3JzOwogICAgfQogICAgcGN0eHQtPmRvYyA9IE5VTEw7CiAgICByZXR1cm4ocmV0KTsKZXhpdF9mYWlsdXJlOgogICAgcGN0eHQtPmRvYyA9IE5VTEw7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIHhtbFNjaGVtYUF0dHJJbmZvUHRyCnhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCQkgICAgICAKCQkJIGludCBtZXRhVHlwZSkKewogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuIChOVUxMKTsKICAgIHsKCWludCBpOwoJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgoJZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CgkgICAgaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIGlmIChpYXR0ci0+bWV0YVR5cGUgPT0gbWV0YVR5cGUpCgkJcmV0dXJuIChpYXR0cik7Cgl9CgogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlYU0k6CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZQogKiBvZiBhbiBpbnN0YW5jZS4gSWYgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gaXMgdXNlZCwgQG5vTmFtZXNwYWNlCiAqIG11c3QgYmUgc2V0IHRvIDEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlYU0koeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBjb25zdCB4bWxDaGFyICpuc25hbWUgPSBOVUxMLCAqbG9jYXRpb247CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCiAgICAvKgogICAgKiBQYXJzZSB0aGUgdmFsdWU7IHdlIHdpbGwgYXNzdW1lIGFuIGV2ZW4gbnVtYmVyIG9mIHZhbHVlcwogICAgKiB0byBiZSBnaXZlbiAodGhpcyBpcyBob3cgWGVyY2VzIGFuZCBYU1Ygd29yaykuCiAgICAqCiAgICAqIFVSR0VOVCBUT0RPOiAhISBUaGlzIG5lZWRzIHRvIHdvcmsgZm9yIGJvdGgKICAgICogQG5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gQU5EIEBzY2hlbWFMb2NhdGlvbiBvbiB0aGUgc2FtZQogICAgKiBlbGVtZW50ICEhCiAgICAqLwogICAgaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCglYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DKTsKICAgIGlmIChpYXR0ciA9PSBOVUxMKQoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCglYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DKTsKICAgIGlmIChpYXR0ciA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGN1ciA9IGlhdHRyLT52YWx1ZTsKICAgIGRvIHsKCS8qCgkqIFRPRE86IE1vdmUgdGhlIHN0cmluZyBwYXJzaW5nIG1lY2hhbmlzbSBhd2F5IGZyb20gaGVyZS4KCSovCglpZiAoaWF0dHItPm1ldGFUeXBlID09IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1NDSEVNQV9MT0MpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgY291bnQrKzsgLyogVE9ETzogRG9uJ3QgdXNlIHRoZSBzY2hlbWEncyBkaWN0LiAqLwoJICAgIG5zbmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwoJICAgIGN1ciA9IGVuZDsKCX0KCS8qCgkqIEdldCB0aGUgVVJJLgoJKi8KCXdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCSAgICBjdXIrKzsKCWVuZCA9IGN1cjsKCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJICAgIGVuZCsrOwoJaWYgKGVuZCA9PSBjdXIpIHsKCSAgICBpZiAoaWF0dHItPm1ldGFUeXBlID09CgkJWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfU0NIRU1BX0xPQykKCSAgICB7CgkJLyoKCQkqIElmIHVzaW5nIEBzY2hlbWFMb2NhdGlvbiB0aGVuIHR1cGxlcyBhcmUgZXhwZWN0ZWQuCgkJKiBJLmUuIHRoZSBuYW1lc3BhY2UgbmFtZSAqYW5kKiB0aGUgZG9jdW1lbnQncyBVUkkuCgkJKi8JCQoJCXhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoQUNUWFRfQ0FTVCB2Y3R4dCwgWE1MX1NDSEVNQVZfTUlTQywKCQkgICAgaWF0dHItPm5vZGUsIE5VTEwsCgkJICAgICJUaGUgdmFsdWUgbXVzdCBjb25zaXN0IG9mIHR1cGxlczogdGhlIHRhcmdldCBuYW1lc3BhY2UgIgoJCSAgICAibmFtZSBhbmQgdGhlIGRvY3VtZW50J3MgVVJJIiwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIGJyZWFrOwoJfQoJY291bnQrKzsgLyogVE9ETzogRG9uJ3QgdXNlIHRoZSBzY2hlbWEncyBkaWN0LiAqLwoJbG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsKCWN1ciA9IGVuZDsKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbih2Y3R4dCwgdmN0eHQtPnNjaGVtYSwKCSAgICBpYXR0ci0+bm9kZSwgbnNuYW1lLCBsb2NhdGlvbik7CglpZiAocmV0ID09IC0xKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hQXNzZW1ibGVCeVhTSSIsCgkJImFzc2VtYmxpbmcgc2NoZW1hdGEiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJIGNvbnN0IHhtbENoYXIgKnByZWZpeCkKewogICAgaWYgKHZjdHh0LT5zYXggIT0gTlVMTCkgewoJaW50IGksIGo7Cgl4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZTsKCQoJZm9yIChpID0gdmN0eHQtPmRlcHRoOyBpID49IDA7IGktLSkgewoJICAgIGlmICh2Y3R4dC0+ZWxlbUluZm9zW2ldLT5uYk5zQmluZGluZ3MgIT0gMCkgewoJCWlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1tpXTsKCQlmb3IgKGogPSAwOyBqIDwgaW5vZGUtPm5iTnNCaW5kaW5ncyAqIDI7IGogKz0gMikgewoJCSAgICBpZiAoKChwcmVmaXggPT0gTlVMTCkgJiYKCQkJICAgIChpbm9kZS0+bnNCaW5kaW5nc1tqXSA9PSBOVUxMKSkgfHwKCQkJKChwcmVmaXggIT0gTlVMTCkgJiYgeG1sU3RyRXF1YWwocHJlZml4LAoJCQkgICAgaW5vZGUtPm5zQmluZGluZ3Nbal0pKSkgewoKCQkJLyoKCQkJKiBOb3RlIHRoYXQgdGhlIG5hbWVzcGFjZSBiaW5kaW5ncyBhcmUgYWxyZWFkeQoJCQkqIGluIGEgc3RyaW5nIGRpY3QuCgkJCSovCgkJCXJldHVybiAoaW5vZGUtPm5zQmluZGluZ3NbaisxXSk7CQkJCgkJICAgIH0KCQl9CgkgICAgfQoJfQoJcmV0dXJuIChOVUxMKTsKI2lmZGVmIExJQlhNTF9XUklURVJfRU5BQkxFRAogICAgfSBlbHNlIGlmICh2Y3R4dC0+cmVhZGVyICE9IE5VTEwpIHsKCXhtbENoYXIgKm5zTmFtZTsKCQoJbnNOYW1lID0geG1sVGV4dFJlYWRlckxvb2t1cE5hbWVzcGFjZSh2Y3R4dC0+cmVhZGVyLCBwcmVmaXgpOwoJaWYgKG5zTmFtZSAhPSBOVUxMKSB7CgkgICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKCSAgICByZXQgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5kaWN0LCBuc05hbWUsIC0xKTsKCSAgICB4bWxGcmVlKG5zTmFtZSk7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0dXJuIChOVUxMKTsKI2VuZGlmCiAgICB9IGVsc2UgewoJeG1sTnNQdHIgbnM7CgoJaWYgKCh2Y3R4dC0+aW5vZGUtPm5vZGUgPT0gTlVMTCkgfHwKCSAgICAodmN0eHQtPmlub2RlLT5ub2RlLT5kb2MgPT0gTlVMTCkpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UiLAoJCSJubyBub2RlIG9yIG5vZGUncyBkb2MgYXZhbGlhYmxlIik7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCW5zID0geG1sU2VhcmNoTnModmN0eHQtPmlub2RlLT5ub2RlLT5kb2MsCgkgICAgdmN0eHQtPmlub2RlLT5ub2RlLCBwcmVmaXgpOwoJaWYgKG5zICE9IE5VTEwpCgkgICAgcmV0dXJuIChucy0+aHJlZik7CglyZXR1cm4gKE5VTEwpOwogICAgfQp9CgovKgoqIFRoaXMgb25lIHdvcmtzIG9uIHRoZSBzY2hlbWEgb2YgdGhlIHZhbGlkYXRpb24gY29udGV4dC4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwgCQkJICAKCQkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICB4bWxTY2hlbWFWYWxQdHIgKnZhbCwKCQkJICBpbnQgdmFsTmVlZGVkKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICh2Y3R4dCAmJiAodmN0eHQtPnNjaGVtYSA9PSBOVUxMKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbiIsCgkgICAgImEgc2NoZW1hIGlzIG5lZWRlZCBvbiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Iik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCAhPSAwKQoJcmV0dXJuIChyZXQpOwogICAgewoJeG1sQ2hhciAqbG9jYWxOYW1lID0gTlVMTDsKCXhtbENoYXIgKnByZWZpeCA9IE5VTEw7CgoJbG9jYWxOYW1lID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwoJaWYgKHByZWZpeCAhPSBOVUxMKSB7CgkgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lID0gTlVMTDsKCgkgICAgaWYgKHZjdHh0ICE9IE5VTEwpIAoJCW5zTmFtZSA9IHhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh2Y3R4dCwgQkFEX0NBU1QgcHJlZml4KTsKCSAgICBlbHNlIGlmIChub2RlICE9IE5VTEwpIHsKCQl4bWxOc1B0ciBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKCQlpZiAobnMgIT0gTlVMTCkKCQkgICAgbnNOYW1lID0gbnMtPmhyZWY7CgkgICAgfSBlbHNlIHsKCQl4bWxGcmVlKHByZWZpeCk7CgkJeG1sRnJlZShsb2NhbE5hbWUpOwoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIGlmIChuc05hbWUgPT0gTlVMTCkgewoJCXhtbEZyZWUocHJlZml4KTsKCQl4bWxGcmVlKGxvY2FsTmFtZSk7CgkJcmV0dXJuICgxKTsKCSAgICB9CgkgICAgaWYgKHhtbFNjaGVtYUdldE5vdGF0aW9uKHNjaGVtYSwgbG9jYWxOYW1lLCBuc05hbWUpICE9IE5VTEwpIHsKCQlpZiAodmFsTmVlZGVkICYmICh2YWwgIT0gTlVMTCkpIHsKCQkgICAgKCp2YWwpID0geG1sU2NoZW1hTmV3Tk9UQVRJT05WYWx1ZShCQURfQ0FTVCBsb2NhbE5hbWUsCgkJCUJBRF9DQVNUIHhtbFN0cmR1cChuc05hbWUpKTsKCQkgICAgaWYgKCp2YWwgPT0gTlVMTCkKCQkJcmV0ID0gLTE7CgkJfQoJICAgIH0gZWxzZQoJCXJldCA9IDE7CgkgICAgeG1sRnJlZShwcmVmaXgpOwoJICAgIHhtbEZyZWUobG9jYWxOYW1lKTsKCX0gZWxzZSB7CgkgICAgaWYgKHhtbFNjaGVtYUdldE5vdGF0aW9uKHNjaGVtYSwgdmFsdWUsIE5VTEwpICE9IE5VTEwpIHsKCQlpZiAodmFsTmVlZGVkICYmICh2YWwgIT0gTlVMTCkpIHsKCQkgICAgKCp2YWwpID0geG1sU2NoZW1hTmV3Tk9UQVRJT05WYWx1ZSgKCQkJQkFEX0NBU1QgeG1sU3RyZHVwKHZhbHVlKSwgTlVMTCk7CgkJICAgIGlmICgqdmFsID09IE5VTEwpCgkJCXJldCA9IC0xOwoJCX0KCSAgICB9IGVsc2UKCQlyZXR1cm4gKDEpOwoJfQogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZBZGROb2RlUU5hbWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgICAgICBjb25zdCB4bWxDaGFyKiBsbmFtZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciogbnNuYW1lKQp7CiAgICBpbnQgaTsKCiAgICBsbmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIGxuYW1lLCAtMSk7CiAgICBpZiAobG5hbWUgPT0gTlVMTCkKCXJldHVybigtMSk7CiAgICBpZiAobnNuYW1lICE9IE5VTEwpIHsKCW5zbmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIG5zbmFtZSwgLTEpOwoJaWYgKG5zbmFtZSA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPm5vZGVRTmFtZXMtPm5iSXRlbXM7IGkgKz0gMikgewoJaWYgKCh2Y3R4dC0+bm9kZVFOYW1lcy0+aXRlbXMgW2ldID09IGxuYW1lKSAmJgoJICAgICh2Y3R4dC0+bm9kZVFOYW1lcy0+aXRlbXNbaSArMV0gPT0gbnNuYW1lKSkKCSAgICAvKiBBbHJlYWR5IHRoZXJlICovCgkgICAgcmV0dXJuKGkpOwogICAgfQogICAgLyogQWRkIG5ldyBlbnRyeS4gKi8KICAgIGkgPSB2Y3R4dC0+bm9kZVFOYW1lcy0+bmJJdGVtczsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0QWRkKHZjdHh0LT5ub2RlUU5hbWVzLCAodm9pZCAqKSBsbmFtZSk7CiAgICB4bWxTY2hlbWFJdGVtTGlzdEFkZCh2Y3R4dC0+bm9kZVFOYW1lcywgKHZvaWQgKikgbnNuYW1lKTsKICAgIHJldHVybihpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqICBWYWxpZGF0aW9uIG9mIGlkZW50aXR5LWNvbnN0cmFpbnRzIChJREMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUF1Z21lbnRJREM6CiAqIEBpZGNEZWY6IHRoZSBJREMgZGVmaW5pdGlvbgogKgogKiBDcmVhdGVzIGFuIGF1Z21lbnRlZCBJREMgZGVmaW5pdGlvbiBpdGVtLgogKgogKiBSZXR1cm5zIHRoZSBpdGVtLCBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF1Z21lbnRJREMoeG1sU2NoZW1hSURDUHRyIGlkY0RlZiwKCQkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKCiAgICBhaWRjID0gKHhtbFNjaGVtYUlEQ0F1Z1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENBdWcpKTsKICAgIGlmIChhaWRjID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkgICAgInhtbFNjaGVtYUF1Z21lbnRJREM6IGFsbG9jYXRpbmcgYW4gYXVnbWVudGVkIElEQyBkZWZpbml0aW9uIiwKCSAgICBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIGFpZGMtPmtleXJlZkRlcHRoID0gLTE7CiAgICBhaWRjLT5kZWYgPSBpZGNEZWY7CiAgICBhaWRjLT5uZXh0ID0gTlVMTDsKICAgIGlmICh2Y3R4dC0+YWlkY3MgPT0gTlVMTCkKCXZjdHh0LT5haWRjcyA9IGFpZGM7CiAgICBlbHNlIHsKCWFpZGMtPm5leHQgPSB2Y3R4dC0+YWlkY3M7Cgl2Y3R4dC0+YWlkY3MgPSBhaWRjOwogICAgfQogICAgLyoKICAgICogU2F2ZSBpZiB3ZSBoYXZlIGtleXJlZnMgYXQgYWxsLgogICAgKi8KICAgIGlmICgodmN0eHQtPmhhc0tleXJlZnMgPT0gMCkgJiYKCShpZGNEZWYtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpKQoJdmN0eHQtPmhhc0tleXJlZnMgPSAxOwp9CgovKioKICogeG1sU2NoZW1hSURDTmV3QmluZGluZzoKICogQGlkY0RlZjogdGhlIElEQyBkZWZpbml0aW9uIG9mIHRoaXMgYmluZGluZwogKgogKiBDcmVhdGVzIGEgbmV3IElEQyBiaW5kaW5nLgogKgogKiBSZXR1cm5zIHRoZSBuZXcgSURDIGJpbmRpbmcsIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyCnhtbFNjaGVtYUlEQ05ld0JpbmRpbmcoeG1sU2NoZW1hSURDUHRyIGlkY0RlZikKewogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cikgeG1sTWFsbG9jKAoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDQmluZGluZykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgYSBQU1ZJIElEQyBiaW5kaW5nIGl0ZW0iLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcpKTsKICAgIHJldC0+ZGVmaW5pdGlvbiA9IGlkY0RlZjsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1N0b3JlTm9kZVRhYmxlSXRlbToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAaXRlbTogdGhlIElEQyBub2RlIHRhYmxlIGl0ZW0KICoKICogVGhlIHZhbGlkYXRpb24gY29udGV4dCBpcyB1c2VkIHRvIHN0b3JlIElEQyBub2RlIHRhYmxlIGl0ZW1zLgogKiBUaGV5IGFyZSBzdG9yZWQgdG8gYXZvaWQgY29weWluZyB0aGVtIGlmIElEQyBub2RlLXRhYmxlcyBhcmUgbWVyZ2VkCiAqIHdpdGggY29ycmVzcG9uZGluZyBwYXJlbnQgSURDIG5vZGUtdGFibGVzIChidWJibGluZykuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNjZWVkZWQsIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW0pCnsKICAgIC8qCiAgICAqIEFkZCB0byBnb2JhbCBsaXN0LgogICAgKi8KICAgIGlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJdmN0eHQtPmlkY05vZGVzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopCgkgICAgeG1sTWFsbG9jKDIwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXZjdHh0LT5zaXplSWRjTm9kZXMgPSAyMDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVJZGNOb2RlcyA8PSB2Y3R4dC0+bmJJZGNOb2RlcykgewoJdmN0eHQtPnNpemVJZGNOb2RlcyAqPSAyOwoJdmN0eHQtPmlkY05vZGVzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+aWRjTm9kZXMsIHZjdHh0LT5zaXplSWRjTm9kZXMgKgoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKHZjdHh0LT5pZGNOb2RlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyB0aGUgSURDIG5vZGUgdGFibGUgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICB2Y3R4dC0+aWRjTm9kZXNbdmN0eHQtPm5iSWRjTm9kZXMrK10gPSBpdGVtOwoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENTdG9yZUtleToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAaXRlbTogdGhlIElEQyBrZXkKICoKICogVGhlIHZhbGlkYXRpb24gY29udGV4dCBpcyB1c2VkIHRvIHN0b3JlIGFuIElEQyBrZXkuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNjZWVkZWQsIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDU3RvcmVLZXkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkpCnsKICAgIC8qCiAgICAqIEFkZCB0byBnb2JhbCBsaXN0LgogICAgKi8KICAgIGlmICh2Y3R4dC0+aWRjS2V5cyA9PSBOVUxMKSB7Cgl2Y3R4dC0+aWRjS2V5cyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopCgkgICAgeG1sTWFsbG9jKDQwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCWlmICh2Y3R4dC0+aWRjS2V5cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyB0aGUgSURDIGtleSBzdG9yYWdlIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXZjdHh0LT5zaXplSWRjS2V5cyA9IDQwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUlkY0tleXMgPD0gdmN0eHQtPm5iSWRjS2V5cykgewoJdmN0eHQtPnNpemVJZGNLZXlzICo9IDI7Cgl2Y3R4dC0+aWRjS2V5cyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+aWRjS2V5cywgdmN0eHQtPnNpemVJZGNLZXlzICoKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBJREMga2V5IHN0b3JhZ2UgbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgdmN0eHQtPmlkY0tleXNbdmN0eHQtPm5iSWRjS2V5cysrXSA9IGtleTsKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbToKICogQGJpbmQ6IHRoZSBJREMgYmluZGluZwogKiBAbnRJdGVtOiB0aGUgbm9kZS10YWJsZSBpdGVtCiAqCiAqIEFwcGVuZHMgdGhlIElEQyBub2RlLXRhYmxlIGl0ZW0gdG8gdGhlIGJpbmRpbmcuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ0FwcGVuZE5vZGVUYWJsZUl0ZW0oeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCwKCQkJCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG50SXRlbSkKewogICAgaWYgKGJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgliaW5kLT5zaXplTm9kZXMgPSAxMDsKCWJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKQoJICAgIHhtbE1hbGxvYygxMCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKGJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCSJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0gZWxzZSBpZiAoYmluZC0+c2l6ZU5vZGVzIDw9IGJpbmQtPm5iTm9kZXMpIHsKCWJpbmQtPnNpemVOb2RlcyAqPSAyOwoJYmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopCgkgICAgeG1sUmVhbGxvYyhiaW5kLT5ub2RlVGFibGUsIGJpbmQtPnNpemVOb2RlcyAqCgkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJInJlLWFsbG9jYXRpbmcgYW4gYXJyYXkgb2YgSURDIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfQogICAgYmluZC0+bm9kZVRhYmxlW2JpbmQtPm5iTm9kZXMrK10gPSBudEl0ZW07CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENBY3F1aXJlQmluZGluZzoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAbWF0Y2hlcjogdGhlIElEQyBtYXRjaGVyCiAqCiAqIExvb2tzIHVwIGFuIFBTVkkgSURDIGJpbmRpbmcsIGZvciB0aGUgSURDIGRlZmluaXRpb24gYW5kCiAqIG9mIHRoZSBnaXZlbiBtYXRjaGVyLiBJZiBub25lIGZvdW5kLCBhIG5ldyBvbmUgaXMgY3JlYXRlZAogKiBhbmQgYWRkZWQgdG8gdGhlIElEQyB0YWJsZS4KICoKICogUmV0dXJucyBhbiBJREMgYmluZGluZyBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cgp4bWxTY2hlbWFJRENBY3F1aXJlQmluZGluZyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbTsKCiAgICBpZWxlbSA9IHZjdHh0LT5lbGVtSW5mb3NbbWF0Y2hlci0+ZGVwdGhdOwoKICAgIGlmIChpZWxlbS0+aWRjVGFibGUgPT0gTlVMTCkgewoJaWVsZW0tPmlkY1RhYmxlID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhtYXRjaGVyLT5haWRjLT5kZWYpOwoJaWYgKGllbGVtLT5pZGNUYWJsZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXR1cm4oaWVsZW0tPmlkY1RhYmxlKTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kID0gTlVMTDsKCgliaW5kID0gaWVsZW0tPmlkY1RhYmxlOwoJZG8gewoJICAgIGlmIChiaW5kLT5kZWZpbml0aW9uID09IG1hdGNoZXItPmFpZGMtPmRlZikKCQlyZXR1cm4oYmluZCk7CgkgICAgaWYgKGJpbmQtPm5leHQgPT0gTlVMTCkgewoJCWJpbmQtPm5leHQgPSB4bWxTY2hlbWFJRENOZXdCaW5kaW5nKG1hdGNoZXItPmFpZGMtPmRlZik7CgkJaWYgKGJpbmQtPm5leHQgPT0gTlVMTCkKCQkgICAgcmV0dXJuIChOVUxMKTsKCQlyZXR1cm4oYmluZC0+bmV4dCk7CgkgICAgfQoJICAgIGJpbmQgPSBiaW5kLT5uZXh0OwoJfSB3aGlsZSAoYmluZCAhPSBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJdGVtTGlzdFB0cgp4bWxTY2hlbWFJRENBY3F1aXJlVGFyZ2V0TGlzdCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIpCnsKICAgIGlmIChtYXRjaGVyLT50YXJnZXRzID09IE5VTEwpCgltYXRjaGVyLT50YXJnZXRzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIHJldHVybihtYXRjaGVyLT50YXJnZXRzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVLZXk6CiAqIEBrZXk6IHRoZSBJREMga2V5CiAqCiAqIEZyZWVzIGFuIElEQyBrZXkgdG9nZXRoZXIgd2l0aCBpdHMgY29tcGlsZWQgdmFsdWUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlS2V5KHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5KQp7CiAgICBpZiAoa2V5LT52YWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShrZXktPnZhbCk7CiAgICB4bWxGcmVlKGtleSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlQmluZGluZzoKICoKICogRnJlZXMgYW4gSURDIGJpbmRpbmcuIE5vdGUgdGhhdCB0aGUgbm9kZSB0YWJsZS1pdGVtcwogKiBhcmUgbm90IGZyZWVkLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgaWYgKGJpbmQtPm5vZGVUYWJsZSAhPSBOVUxMKQoJeG1sRnJlZShiaW5kLT5ub2RlVGFibGUpOwogICAgaWYgKGJpbmQtPmR1cGxzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoYmluZC0+ZHVwbHMpOwkKICAgIHhtbEZyZWUoYmluZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlSURDVGFibGU6CiAqIEBiaW5kOiB0aGUgZmlyc3QgSURDIGJpbmRpbmcgaW4gdGhlIGxpc3QKICoKICogRnJlZXMgYW4gSURDIHRhYmxlLCBpLmUuIGFsbCB0aGUgSURDIGJpbmRpbmdzIGluIHRoZSBsaXN0LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHByZXY7CgogICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJcHJldiA9IGJpbmQ7CgliaW5kID0gYmluZC0+bmV4dDsKCXhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nKHByZXYpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0OgogKiBAbWF0Y2hlcjogdGhlIGZpcnN0IElEQyBtYXRjaGVyIGluIHRoZSBsaXN0CiAqCiAqIEZyZWVzIGEgbGlzdCBvZiBJREMgbWF0Y2hlcnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlTWF0Y2hlckxpc3QoeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7CgogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJbmV4dCA9IG1hdGNoZXItPm5leHQ7CglpZiAobWF0Y2hlci0+a2V5U2VxcyAhPSBOVUxMKSB7CSAgICAKCSAgICBpbnQgaTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgbWF0Y2hlci0+c2l6ZUtleVNlcXM7IGkrKykKCQlpZiAobWF0Y2hlci0+a2V5U2Vxc1tpXSAhPSBOVUxMKQoJCSAgICB4bWxGcmVlKG1hdGNoZXItPmtleVNlcXNbaV0pOwoJICAgIHhtbEZyZWUobWF0Y2hlci0+a2V5U2Vxcyk7CSAgICAKCX0KCWlmIChtYXRjaGVyLT50YXJnZXRzICE9IE5VTEwpIHsKCSAgICBpZiAobWF0Y2hlci0+aWRjVHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJCWludCBpOwoJCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGlkY05vZGU7CgkJLyoKCQkqIE5vZGUtdGFibGUgaXRlbXMgZm9yIGtleXJlZnMgYXJlIG5vdCBzdG9yZWQgZ2xvYmFsbHkKCQkqIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQsIHNpbmNlIHRoZXkgYXJlIG5vdCBidWJibGVkLgoJCSogV2UgbmVlZCB0byBmcmVlIHRoZW0gaGVyZS4KCQkqLwoJCWZvciAoaSA9IDA7IGkgPCBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zOyBpKyspIHsKCQkgICAgaWRjTm9kZSA9CgkJCSh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgbWF0Y2hlci0+dGFyZ2V0cy0+aXRlbXNbaV07CgkJICAgIHhtbEZyZWUoaWRjTm9kZS0+a2V5cyk7CgkJICAgIHhtbEZyZWUoaWRjTm9kZSk7CgkJfQoJICAgIH0KCSAgICB4bWxTY2hlbWFJdGVtTGlzdEZyZWUobWF0Y2hlci0+dGFyZ2V0cyk7Cgl9Cgl4bWxGcmVlKG1hdGNoZXIpOwoJbWF0Y2hlciA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENSZWxlYXNlTWF0Y2hlckxpc3Q6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG1hdGNoZXI6IHRoZSBmaXJzdCBJREMgbWF0Y2hlciBpbiB0aGUgbGlzdAogKgogKiBDYWNoZXMgYSBsaXN0IG9mIElEQyBtYXRjaGVycyBmb3IgcmV1c2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENSZWxlYXNlTWF0Y2hlckxpc3QoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7CgogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJbmV4dCA9IG1hdGNoZXItPm5leHQ7CglpZiAobWF0Y2hlci0+a2V5U2VxcyAhPSBOVUxMKSB7CSAgICAKCSAgICBpbnQgaTsKCSAgICAvKgoJICAgICogRG9uJ3QgZnJlZSB0aGUgYXJyYXksIGJ1dCBvbmx5IHRoZSBjb250ZW50LgoJICAgICovCgkgICAgZm9yIChpID0gMDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspCgkJaWYgKG1hdGNoZXItPmtleVNlcXNbaV0gIT0gTlVMTCkgewoJCSAgICB4bWxGcmVlKG1hdGNoZXItPmtleVNlcXNbaV0pOwoJCSAgICBtYXRjaGVyLT5rZXlTZXFzW2ldID0gTlVMTDsKCQl9Cgl9CglpZiAobWF0Y2hlci0+dGFyZ2V0cykgewoJICAgIGlmIChtYXRjaGVyLT5pZGNUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkJaW50IGk7CgkJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaWRjTm9kZTsKCQkvKgoJCSogTm9kZS10YWJsZSBpdGVtcyBmb3Iga2V5cmVmcyBhcmUgbm90IHN0b3JlZCBnbG9iYWxseQoJCSogdG8gdGhlIHZhbGlkYXRpb24gY29udGV4dCwgc2luY2UgdGhleSBhcmUgbm90IGJ1YmJsZWQuCgkJKiBXZSBuZWVkIHRvIGZyZWUgdGhlbSBoZXJlLgoJCSovCgkJZm9yIChpID0gMDsgaSA8IG1hdGNoZXItPnRhcmdldHMtPm5iSXRlbXM7IGkrKykgewoJCSAgICBpZGNOb2RlID0KCQkJKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSBtYXRjaGVyLT50YXJnZXRzLT5pdGVtc1tpXTsKCQkgICAgeG1sRnJlZShpZGNOb2RlLT5rZXlzKTsKCQkgICAgeG1sRnJlZShpZGNOb2RlKTsKCQl9CgkgICAgfQoJICAgIHhtbFNjaGVtYUl0ZW1MaXN0RnJlZShtYXRjaGVyLT50YXJnZXRzKTsKCSAgICBtYXRjaGVyLT50YXJnZXRzID0gTlVMTDsKCX0JCgltYXRjaGVyLT5uZXh0ID0gTlVMTDsKCS8qCgkqIENhY2hlIHRoZSBtYXRjaGVyLgoJKi8KCWlmICh2Y3R4dC0+aWRjTWF0Y2hlckNhY2hlICE9IE5VTEwpCgkgICAgbWF0Y2hlci0+bmV4dENhY2hlZCA9IHZjdHh0LT5pZGNNYXRjaGVyQ2FjaGU7Cgl2Y3R4dC0+aWRjTWF0Y2hlckNhY2hlID0gbWF0Y2hlcjsKCgltYXRjaGVyID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBtYXRjaGVyOiB0aGUgSURDIG1hdGNoZXIKICogQHNlbDogdGhlIFhQYXRoIGluZm9ybWF0aW9uCiAqIEBwYXJlbnQ6IHRoZSBwYXJlbnQgInNlbGVjdG9yIiBzdGF0ZSBvYmplY3QgaWYgYW55CiAqIEB0eXBlOiAic2VsZWN0b3IiIG9yICJmaWVsZCIKICoKICogQ3JlYXRlcy9yZXVzZXMgYW5kIGFjdGl2YXRlcyBzdGF0ZSBvYmplY3RzIGZvciB0aGUgZ2l2ZW4KICogWFBhdGggaW5mb3JtYXRpb247IGlmIHRoZSBYUGF0aCBleHByZXNzaW9uIGNvbnNpc3RzIG9mIHVuaW9ucywKICogbXVsdGlwbGUgc3RhdGUgb2JqZWN0cyBhcmUgY3JlYXRlZCBmb3IgZXZlcnkgdW5pb25lZCBleHByZXNzaW9uLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCXhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciwKCQkJeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbCwKCQkJaW50IHR5cGUpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bzsKCiAgICAvKgogICAgKiBSZXVzZSB0aGUgc3RhdGUgb2JqZWN0cyBmcm9tIHRoZSBwb29sLgogICAgKi8KICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkgewoJc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVQb29sOwoJdmN0eHQtPnhwYXRoU3RhdGVQb29sID0gc3RvLT5uZXh0OwoJc3RvLT5uZXh0ID0gTlVMTDsKICAgIH0gZWxzZSB7CQoJLyoKCSogQ3JlYXRlIGEgbmV3IHN0YXRlIG9iamVjdC4KCSovCglzdG8gPSAoeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDU3RhdGVPYmopKTsKCWlmIChzdG8gPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkiYWxsb2NhdGluZyBhbiBJREMgc3RhdGUgb2JqZWN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgltZW1zZXQoc3RvLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDU3RhdGVPYmopKTsKICAgIH0JCiAgICAvKgogICAgKiBBZGQgdG8gZ2xvYmFsIGxpc3QuIAogICAgKi8JCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpCglzdG8tPm5leHQgPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CiAgICB2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBzdG87CgogICAgLyoKICAgICogRnJlZSB0aGUgb2xkIHhwYXRoIHZhbGlkYXRpb24gY29udGV4dC4KICAgICovCiAgICBpZiAoc3RvLT54cGF0aEN0eHQgIT0gTlVMTCkKCXhtbEZyZWVTdHJlYW1DdHh0KCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7CgogICAgLyoKICAgICogQ3JlYXRlIGEgbmV3IFhQYXRoIChwYXR0ZXJuKSB2YWxpZGF0aW9uIGNvbnRleHQuCiAgICAqLwogICAgc3RvLT54cGF0aEN0eHQgPSAodm9pZCAqKSB4bWxQYXR0ZXJuR2V0U3RyZWFtQ3R4dCgKCSh4bWxQYXR0ZXJuUHRyKSBzZWwtPnhwYXRoQ29tcCk7CiAgICBpZiAoc3RvLT54cGF0aEN0eHQgPT0gTlVMTCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3QiLAoJICAgICJmYWlsZWQgdG8gY3JlYXRlIGFuIFhQYXRoIHZhbGlkYXRpb24gY29udGV4dCIpOwoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgc3RvLT50eXBlID0gdHlwZTsKICAgIHN0by0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICBzdG8tPm1hdGNoZXIgPSBtYXRjaGVyOwogICAgc3RvLT5zZWwgPSBzZWw7CiAgICBzdG8tPm5iSGlzdG9yeSA9IDA7CiAgICAKI2lmZGVmIERFQlVHX0lEQwogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgU1RPIHB1c2ggJyVzJ1xuIiwKCXN0by0+c2VsLT54cGF0aCk7CiNlbmRpZgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVhQYXRoRXZhbHVhdGU6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGVUeXBlOiB0aGUgbm9kZVR5cGUgb2YgdGhlIGN1cnJlbnQgbm9kZQogKgogKiBFdmFsdWF0ZXMgYWxsIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgogKgogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgSUMgImZpZWxkIiBzdGF0ZSBvYmplY3RzIHdoaWNoIHJlc29sdmVkIHRvCiAqIHRoaXMgbm9kZSwgMCBpZiBub25lIHJlc29sdmVkIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgICAgICB4bWxFbGVtZW50VHlwZSBub2RlVHlwZSkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvLCBoZWFkID0gTlVMTCwgZmlyc3Q7CiAgICBpbnQgcmVzLCByZXNvbHZlZCA9IDAsIGRlcHRoID0gdmN0eHQtPmRlcHRoOwogICAgICAgIAogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKCiAgICBpZiAobm9kZVR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJZGVwdGgrKzsKI2lmZGVmIERFQlVHX0lEQwogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAKCSAgICAiSURDOiBFVkFMIG9uICVzLCBkZXB0aCAlZCwgdHlwZSAlZFxuIiwJICAgIAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSwgZGVwdGgsIG5vZGVUeXBlKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYKICAgIC8qCiAgICAqIFByb2Nlc3MgYWxsIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgogICAgKi8KICAgIGZpcnN0ID0gdmN0eHQtPnhwYXRoU3RhdGVzOwogICAgc3RvID0gZmlyc3Q7CiAgICB3aGlsZSAoc3RvICE9IGhlYWQpIHsKI2lmZGVmIERFQlVHX0lEQwoJaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgWyclcyddIHNlbGVjdG9yICclcydcbiIsIAoJCXN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5uYW1lLCBzdG8tPnNlbC0+eHBhdGgpOwoJZWxzZQoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFsnJXMnXSBmaWVsZCAnJXMnXG4iLCAKCQlzdG8tPm1hdGNoZXItPmFpZGMtPmRlZi0+bmFtZSwgc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICByZXMgPSB4bWxTdHJlYW1QdXNoKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoJZWxzZQoJICAgIHJlcyA9IHhtbFN0cmVhbVB1c2hBdHRyKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoKCWlmIChyZXMgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aEV2YWx1YXRlIiwKCQkiY2FsbGluZyB4bWxTdHJlYW1QdXNoKCkiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWlmIChyZXMgPT0gMCkKCSAgICBnb3RvIG5leHRfc3RvOwoJLyoKCSogRnVsbCBtYXRjaC4KCSovCiNpZmRlZiBERUJVR19JREMKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgICAgIgoJICAgICJNQVRDSFxuIik7CiNlbmRpZgoJLyoKCSogUmVnaXN0ZXIgYSBtYXRjaCBpbiB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkuCgkqLwoJaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkgICAgc3RvLT5oaXN0b3J5ID0gKGludCAqKSB4bWxNYWxsb2MoNSAqIHNpemVvZihpbnQpKTsKCSAgICBpZiAoc3RvLT5oaXN0b3J5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAiYWxsb2NhdGluZyB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkiLCBOVUxMKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICBzdG8tPnNpemVIaXN0b3J5ID0gNTsKCX0gZWxzZSBpZiAoc3RvLT5zaXplSGlzdG9yeSA8PSBzdG8tPm5iSGlzdG9yeSkgewoJICAgIHN0by0+c2l6ZUhpc3RvcnkgKj0gMjsKCSAgICBzdG8tPmhpc3RvcnkgPSAoaW50ICopIHhtbFJlYWxsb2Moc3RvLT5oaXN0b3J5LAoJCXN0by0+c2l6ZUhpc3RvcnkgKiBzaXplb2YoaW50KSk7CgkgICAgaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgInJlLWFsbG9jYXRpbmcgdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5IiwgTlVMTCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9Cgl9CQkKCXN0by0+aGlzdG9yeVtzdG8tPm5iSGlzdG9yeSsrXSA9IGRlcHRoOwoKI2lmZGVmIERFQlVHX0lEQwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgICAgIHB1c2ggbWF0Y2ggJyVkJ1xuIiwKCSAgICB2Y3R4dC0+ZGVwdGgpOwojZW5kaWYKCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikgewoJICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWw7CgkgICAgLyoKCSAgICAqIEFjdGl2YXRlIHN0YXRlIG9iamVjdHMgZm9yIHRoZSBJREMgZmllbGRzIG9mCgkgICAgKiB0aGUgSURDIHNlbGVjdG9yLgoJICAgICovCiNpZmRlZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICIKCQkiYWN0aXZhdGluZyBmaWVsZCBzdGF0ZXNcbiIpOwojZW5kaWYKCSAgICBzZWwgPSBzdG8tPm1hdGNoZXItPmFpZGMtPmRlZi0+ZmllbGRzOwoJICAgIHdoaWxlIChzZWwgIT0gTlVMTCkgewoJCWlmICh4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh2Y3R4dCwgc3RvLT5tYXRjaGVyLAoJCSAgICBzZWwsIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgPT0gLTEpCgkJICAgIHJldHVybiAoLTEpOwoJCXNlbCA9IHNlbC0+bmV4dDsKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQpIHsKCSAgICAvKgoJICAgICogQW4gSURDIGtleSBub2RlIHdhcyBmb3VuZCBieSB0aGUgSURDIGZpZWxkLgoJICAgICovCiNpZmRlZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiSURDOiAgICAga2V5IGZvdW5kXG4iKTsKI2VuZGlmCgkgICAgLyoKCSAgICAqIE5vdGlmeSB0aGF0IHRoZSBjaGFyYWN0ZXIgdmFsdWUgb2YgdGhpcyBub2RlIGlzCgkgICAgKiBuZWVkZWQuCgkgICAgKi8KCSAgICBpZiAocmVzb2x2ZWQgPT0gMCkgewoJCWlmICgodmN0eHQtPmlub2RlLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRCkgPT0gMCkKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRDsKCSAgICB9CgkgICAgcmVzb2x2ZWQrKzsKCX0KbmV4dF9zdG86CglpZiAoc3RvLT5uZXh0ID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogRXZhbHVhdGUgZmllbGQgc3RhdGUgb2JqZWN0cyBjcmVhdGVkIG9uIHRoaXMgbm9kZSBhcyB3ZWxsLgoJICAgICovCgkgICAgaGVhZCA9IGZpcnN0OwoJICAgIHN0byA9IHZjdHh0LT54cGF0aFN0YXRlczsKCX0gZWxzZQoJICAgIHN0byA9IHN0by0+bmV4dDsKICAgIH0KICAgIHJldHVybiAocmVzb2x2ZWQpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdElEQ0tleVNlcXVlbmNlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgeG1sQ2hhciAqKmJ1ZiwKCQkJICAgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqc2VxLAoJCQkgICAgICBpbnQgY291bnQpCnsKICAgIGludCBpLCByZXM7CiAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CgogICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiWyIpOwogICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCXJlcyA9IHhtbFNjaGVtYUdldENhbm9uVmFsdWVXaHRzcEV4dChzZXFbaV0tPnZhbCwgCgkgICAgeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoc2VxW2ldLT50eXBlKSwKCSAgICAmdmFsdWUpOwoJaWYgKHJlcyA9PSAwKQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgdmFsdWUpOwoJZWxzZSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UiLAoJCSJmYWlsZWQgdG8gY29tcHV0ZSBhIGNhbm9uaWNhbCB2YWx1ZSIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIj8/PyIpOwoJfQoJaWYgKGkgPCBjb3VudCAtMSkKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInLCAiKTsKCWVsc2UKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CglpZiAodmFsdWUgIT0gTlVMTCkgewoJICAgIHhtbEZyZWUodmFsdWUpOwoJICAgIHZhbHVlID0gTlVMTDsKCX0KICAgIH0KICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIl0iKTsKCiAgICByZXR1cm4gKEJBRF9DQVNUICpidWYpOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhQb3A6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogUG9wcyBhbGwgWFBhdGggc3RhdGVzLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFYUGF0aFBvcCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bzsKICAgIGludCByZXM7CgogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyA9PSBOVUxMKQoJcmV0dXJuKDApOwogICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwogICAgZG8gewoJcmVzID0geG1sU3RyZWFtUG9wKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7CglpZiAocmVzID09IC0xKQoJICAgIHJldHVybiAoLTEpOwoJc3RvID0gc3RvLT5uZXh0OwogICAgfSB3aGlsZSAoc3RvICE9IE5VTEwpOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogdGhlIHNpbXBsZS9jb21wbGV4IHR5cGUgb2YgdGhlIGN1cnJlbnQgbm9kZSBpZiBhbnkgYXQgYWxsCiAqIEB2YWw6IHRoZSBwcmVjb21waWxlZCB2YWx1ZQogKgogKiBQcm9jZXNzZXMgYW5kIHBvcHMgdGhlIGhpc3RvcnkgaXRlbXMgb2YgdGhlIElEQyBzdGF0ZSBvYmplY3RzLgogKiBJREMga2V5LXNlcXVlbmNlcyBhcmUgdmFsaWRhdGVkL2NyZWF0ZWQgb24gSURDIGJpbmRpbmdzLgogKiAKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgaW50IGRlcHRoKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8sIG5leHRzdG87CiAgICBpbnQgcmVzLCBtYXRjaERlcHRoOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkgPSBOVUxMOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlID0gdmN0eHQtPmlub2RlLT50eXBlRGVmLCBzaW1wbGVUeXBlID0gTlVMTDsKCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwoKI2lmZGVmIERFQlVHX0lEQwogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAKCSAgICAiSURDOiBCQUNLIG9uICVzLCBkZXB0aCAlZFxuIiwKCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSksIHZjdHh0LT5kZXB0aCk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmICAgIAogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIHN0YXRlIG9iamVjdHMuCiAgICAqLwogICAgd2hpbGUgKHN0byAhPSBOVUxMKSB7CglyZXMgPSB4bWxTdHJlYW1Qb3AoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCWlmIChyZXMgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5IiwKCQkiY2FsbGluZyB4bWxTdHJlYW1Qb3AoKSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQojaWZkZWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBzdHJlYW0gcG9wICclcydcbiIsCgkgICAgc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCglpZiAoc3RvLT5uYkhpc3RvcnkgPT0gMCkKCSAgICBnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgoJbWF0Y2hEZXB0aCA9IHN0by0+aGlzdG9yeVtzdG8tPm5iSGlzdG9yeSAtMV07CgoJLyoKCSogT25seSBtYXRjaGVzIGF0IHRoZSBjdXJyZW50IGRlcHRoIGFyZSBvZiBpbnRlcmVzdC4KCSovCglpZiAobWF0Y2hEZXB0aCAhPSBkZXB0aCkgewoJICAgIHN0byA9IHN0by0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0JCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgewoJICAgIC8qCgkgICAgKiBOT1RFOiBBY2NvcmRpbmcgdG8KCSAgICAqICAgaHR0cDovL3d3dy53My5vcmcvQnVncy9QdWJsaWMvc2hvd19idWcuY2dpP2lkPTIxOTgKCSAgICAqICAgLi4uIHRoZSBzaW1wbGUtY29udGVudCBvZiBjb21wbGV4IHR5cGVzIGlzIGFsc28gYWxsb3dlZC4KCSAgICAqLwoJICAgIAoJICAgIGlmIChXWFNfSVNfQ09NUExFWCh0eXBlKSkgewoJCWlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKSB7CgkJICAgIC8qCgkJICAgICogU2FuaXR5IGNoZWNrIGZvciBjb21wbGV4IHR5cGVzIHdpdGggc2ltcGxlIGNvbnRlbnQuCgkJICAgICovCgkJICAgIHNpbXBsZVR5cGUgPSB0eXBlLT5jb250ZW50VHlwZURlZjsKCQkgICAgaWYgKHNpbXBsZVR5cGUgPT0gTlVMTCkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5IiwKCQkJICAgICJmaWVsZCByZXNvbHZlcyB0byBhIENUIHdpdGggc2ltcGxlIGNvbnRlbnQgIgoJCQkgICAgImJ1dCB0aGUgQ1QgaXMgbWlzc2luZyB0aGUgU1QgZGVmaW5pdGlvbiIpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0gZWxzZQoJCSAgICBzaW1wbGVUeXBlID0gTlVMTDsKCSAgICB9IGVsc2UgCgkJc2ltcGxlVHlwZSA9IHR5cGU7CgkgICAgaWYgKHNpbXBsZVR5cGUgPT0gTlVMTCkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkKCQkvKgoJCSogTm90IHF1YWxpZmllZCBpZiB0aGUgZmllbGQgcmVzb2x2ZXMgdG8gYSBub2RlIG9mIG5vbgoJCSogc2ltcGxlIHR5cGUuCgkJKi8JCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCQkgICAgCgkJICAgIFdYU19CQVNJQ19DQVNUIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLAoJCSAgICAiVGhlIFhQYXRoICclcycgb2YgYSBmaWVsZCBvZiAlcyBkb2VzIGV2YWx1YXRlIHRvIGEgbm9kZSBvZiAiCgkJICAgICJub24tc2ltcGxlIHR5cGUiLAoJCSAgICBzdG8tPnNlbC0+eHBhdGgsCgkJICAgIHhtbFNjaGVtYUdldElEQ0Rlc2lnbmF0aW9uKCZzdHIsIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0KCSAgICAKCSAgICBpZiAoKGtleSA9PSBOVUxMKSAmJiAodmN0eHQtPmlub2RlLT52YWwgPT0gTlVMTCkpIHsKCQkvKgoJCSogRmFpbGVkIHRvIHByb3ZpZGUgdGhlIG5vcm1hbGl6ZWQgdmFsdWU7IG1heWJlCgkJKiB0aGUgdmFsdWUgd2FzIGludmFsaWQuCgkJKi8KCQlWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0lEQywKCQkgICAgV1hTX0JBU0lDX0NBU1Qgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYsCgkJICAgICJXYXJuaW5nOiBObyBwcmVjb21wdXRlZCB2YWx1ZSBhdmFpbGFibGUsIHRoZSB2YWx1ZSAiCgkJICAgICJ3YXMgZWl0aGVyIGludmFsaWQgb3Igc29tZXRoaW5nIHN0cmFuZ2UgaGFwcGVuZCIpOwoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyID0gc3RvLT5tYXRjaGVyOwoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmtleVNlcTsKCQlpbnQgcG9zLCBpZHg7CgkJCgkJLyoKCQkqIFRoZSBrZXkgd2lsbCBiZSBhbmNob3JlZCBvbiB0aGUgbWF0Y2hlcidzIGxpc3Qgb2YKCQkqIGtleS1zZXF1ZW5jZXMuIFRoZSBwb3NpdGlvbiBpbiB0aGlzIGxpc3QgaXMgZGV0ZXJtaW5lZAoJCSogYnkgdGhlIHRhcmdldCBub2RlJ3MgZGVwdGggcmVsYXRpdmUgdG8gdGhlIG1hdGNoZXIncwoJCSogZGVwdGggb2YgY3JlYXRpb24gKGkuZS4gdGhlIGRlcHRoIG9mIHRoZSBzY29wZSBlbGVtZW50KS4KCQkqIAoJCSogRWxlbWVudCAgICAgICAgRGVwdGggICAgUG9zICAgTGlzdC1lbnRyaWVzCgkJKiA8c2NvcGU+ICAgICAgICAgIDAgICAgICAgICAgICAgIE5VTEwKCQkqICAgPGJhcj4gICAgICAgICAgMSAgICAgICAgICAgICAgTlVMTAoJCSogICAgIDx0YXJnZXQvPiAgICAyICAgICAgIDIgICAgICB0YXJnZXQKCQkqICAgPGJhcj4KICAgICAgICAgICAgICAgICogPC9zY29wZT4KCQkqCgkJKiBUaGUgc2l6ZSBvZiB0aGUgbGlzdCBpcyBvbmx5IGRlcGVuZGFudCBvbiB0aGUgZGVwdGggb2YKCQkqIHRoZSB0cmVlLgoJCSogQW4gZW50cnkgd2lsbCBiZSBOVUxMZWQgaW4gc2VsZWN0b3JfbGVhdmUsIGkuZS4gd2hlbgoJCSogd2UgaGl0IHRoZSB0YXJnZXQncyAKCQkqLwkJICAgIAoJCXBvcyA9IHN0by0+ZGVwdGggLSBtYXRjaGVyLT5kZXB0aDsKCQlpZHggPSBzdG8tPnNlbC0+aW5kZXg7CgkJCgkJLyoKCQkqIENyZWF0ZS9ncm93IHRoZSBhcnJheSBvZiBrZXktc2VxdWVuY2VzLgoJCSovCgkJaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCSAgICBpZiAocG9zID4gOSkgCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzID0gcG9zICogMjsKCQkgICAgZWxzZQoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyA9IDEwOwoJCSAgICBtYXRjaGVyLT5rZXlTZXFzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiopIAoJCQl4bWxNYWxsb2MobWF0Y2hlci0+c2l6ZUtleVNlcXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSk7CQkJCgkJICAgIGlmIChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHsJCQoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBrZXktc2VxdWVuY2VzIiwKCQkJICAgIE5VTEwpOwoJCQlyZXR1cm4oLTEpOwoJCSAgICB9CgkJICAgIG1lbXNldChtYXRjaGVyLT5rZXlTZXFzLCAwLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQl9IGVsc2UgaWYgKHBvcyA+PSBtYXRjaGVyLT5zaXplS2V5U2VxcykgewkKCQkgICAgaW50IGkgPSBtYXRjaGVyLT5zaXplS2V5U2VxczsKCQkgICAgCgkJICAgIG1hdGNoZXItPnNpemVLZXlTZXFzICo9IDI7CgkJICAgIG1hdGNoZXItPmtleVNlcXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKikKCQkJeG1sUmVhbGxvYyhtYXRjaGVyLT5rZXlTZXFzLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQkgICAgaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAicmVhbGxvY2F0aW5nIGFuIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogVGhlIGFycmF5IG5lZWRzIHRvIGJlIE5VTExlZC4KCQkgICAgKiBUT0RPOiBVc2UgbWVtc2V0PwoJCSAgICAqLwoJCSAgICBmb3IgKDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspIAoJCQltYXRjaGVyLT5rZXlTZXFzW2ldID0gTlVMTDsJCQkKCQl9CgkJCgkJLyoKCQkqIEdldC9jcmVhdGUgdGhlIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9IG1hdGNoZXItPmtleVNlcXNbcG9zXTsJCSAgICAKCQlpZiAoa2V5U2VxID09IE5VTEwpIHsJCgkJICAgIGdvdG8gY3JlYXRlX3NlcXVlbmNlOwoJCX0gZWxzZSBpZiAoa2V5U2VxW2lkeF0gIT0gTlVMTCkgewoJCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJCSAgICAvKgoJCSAgICAqIGN2Yy1pZGVudGl0eS1jb25zdHJhaW50OgoJCSAgICAqIDMgRm9yIGVhY2ggbm9kZSBpbiB0aGUgt3RhcmdldCBub2RlIHNldLcgYWxsCgkJICAgICogb2YgdGhlIHtmaWVsZHN9LCB3aXRoIHRoYXQgbm9kZSBhcyB0aGUgY29udGV4dAoJCSAgICAqIG5vZGUsIGV2YWx1YXRlIHRvIGVpdGhlciBhbiBlbXB0eSBub2RlLXNldCBvcgoJCSAgICAqIGEgbm9kZS1zZXQgd2l0aCBleGFjdGx5IG9uZSBtZW1iZXIsIHdoaWNoIG11c3QKCQkgICAgKiBoYXZlIGEgc2ltcGxlIHR5cGUuCgkJICAgICogCgkJICAgICogVGhlIGtleSB3YXMgYWxyZWFkeSBzZXQ7IHJlcG9ydCBhbiBlcnJvci4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAoJCQlXWFNfQkFTSUNfQ0FTVCBtYXRjaGVyLT5haWRjLT5kZWYsCgkJCSJUaGUgWFBhdGggJyVzJyBvZiBhIGZpZWxkIG9mICVzIGV2YWx1YXRlcyB0byBhICIKCQkJIm5vZGUtc2V0IHdpdGggbW9yZSB0aGFuIG9uZSBtZW1iZXIiLAoJCQlzdG8tPnNlbC0+eHBhdGgsCgkJCXhtbFNjaGVtYUdldElEQ0Rlc2lnbmF0aW9uKCZzdHIsIG1hdGNoZXItPmFpZGMtPmRlZikpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkJICAgIHN0by0+bmJIaXN0b3J5LS07CgkJICAgIGdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCQl9IGVsc2UKCQkgICAgZ290byBjcmVhdGVfa2V5OwkJCgkJCmNyZWF0ZV9zZXF1ZW5jZToKCQkvKgoJCSogQ3JlYXRlIGEga2V5LXNlcXVlbmNlLgoJCSovCgkJa2V5U2VxID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikgeG1sTWFsbG9jKAoJCSAgICBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzICogCgkJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CgkJaWYgKGtleVNlcSA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCSJhbGxvY2F0aW5nIGFuIElEQyBrZXktc2VxdWVuY2UiLCBOVUxMKTsKCQkgICAgcmV0dXJuKC0xKTsJCQkKCQl9CQoJCW1lbXNldChrZXlTZXEsIDAsIG1hdGNoZXItPmFpZGMtPmRlZi0+bmJGaWVsZHMgKiAKCQkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCQltYXRjaGVyLT5rZXlTZXFzW3Bvc10gPSBrZXlTZXE7CmNyZWF0ZV9rZXk6CgkJLyoKCQkqIENyZWF0ZSBhIGtleSBvbmNlIHBlciBub2RlIG9ubHkuCgkJKi8gIAoJCWlmIChrZXkgPT0gTlVMTCkgewoJCSAgICBrZXkgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikgeG1sTWFsbG9jKAoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleSkpOwoJCSAgICBpZiAoa2V5ID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCQkgICAgImFsbG9jYXRpbmcgYSBJREMga2V5IiwgTlVMTCk7CgkJCXhtbEZyZWUoa2V5U2VxKTsKCQkJbWF0Y2hlci0+a2V5U2Vxc1twb3NdID0gTlVMTDsKCQkJcmV0dXJuKC0xKTsJCQkKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIENvbnN1bWUgdGhlIGNvbXBpbGVkIHZhbHVlLgoJCSAgICAqLwoJCSAgICBrZXktPnR5cGUgPSBzaW1wbGVUeXBlOwoJCSAgICBrZXktPnZhbCA9IHZjdHh0LT5pbm9kZS0+dmFsOwoJCSAgICB2Y3R4dC0+aW5vZGUtPnZhbCA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogU3RvcmUgdGhlIGtleSBpbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hSURDU3RvcmVLZXkodmN0eHQsIGtleSkgPT0gLTEpIHsKCQkJeG1sU2NoZW1hSURDRnJlZUtleShrZXkpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0KCQlrZXlTZXFbaWR4XSA9IGtleTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpIHsKCQkKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxID0gTlVMTDsKCSAgICAvKiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOyAqLwoJICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG50SXRlbTsKCSAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7CgkgICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKCSAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciB0YXJnZXRzOwoJICAgIGludCBwb3MsIGksIGosIG5iS2V5czsKCSAgICAvKgoJICAgICogSGVyZSB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgc2NlbmFyaW86CgkgICAgKiBBbiBJREMgJ3NlbGVjdG9yJyBzdGF0ZSBvYmplY3QgcmVzb2x2ZWQgdG8gYSB0YXJnZXQgbm9kZSwKCSAgICAqIGR1cmluZyB0aGUgdGltZSB0aGlzIHRhcmdldCBub2RlIHdhcyBpbiB0aGUgCgkgICAgKiBhbmNlc3Rvci1vci1zZWxmIGF4aXMsIHRoZSAnZmllbGQnIHN0YXRlIG9iamVjdChzKSBsb29rZWQgCgkgICAgKiBvdXQgZm9yIG1hdGNoaW5nIG5vZGVzIHRvIGNyZWF0ZSBhIGtleS1zZXF1ZW5jZSBmb3IgdGhpcyAKCSAgICAqIHRhcmdldCBub2RlLiBOb3cgd2UgYXJlIGJhY2sgdG8gdGhpcyB0YXJnZXQgbm9kZSBhbmQgbmVlZAoJICAgICogdG8gcHV0IHRoZSBrZXktc2VxdWVuY2UsIHRvZ2V0aGVyIHdpdGggdGhlIHRhcmdldCBub2RlIAoJICAgICogaXRzZWxmLCBpbnRvIHRoZSBub2RlLXRhYmxlIG9mIHRoZSBjb3JyZXNwb25kaW5nIElEQyAKCSAgICAqIGJpbmRpbmcuCgkgICAgKi8KCSAgICBtYXRjaGVyID0gc3RvLT5tYXRjaGVyOwoJICAgIGlkYyA9IG1hdGNoZXItPmFpZGMtPmRlZjsKCSAgICBuYktleXMgPSBpZGMtPm5iRmllbGRzOwoJICAgIHBvcyA9IGRlcHRoIC0gbWF0Y2hlci0+ZGVwdGg7CQkKCSAgICAvKgoJICAgICogQ2hlY2sgaWYgdGhlIG1hdGNoZXIgaGFzIGFueSBrZXktc2VxdWVuY2VzIGF0IGFsbCwgcGx1cwoJICAgICogaWYgaXQgaGFzIGEga2V5LXNlcXVlbmNlIGZvciB0aGUgY3VycmVudCB0YXJnZXQgbm9kZS4KCSAgICAqLwkJCgkgICAgaWYgKChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHx8CgkJKG1hdGNoZXItPnNpemVLZXlTZXFzIDw9IHBvcykpIHsKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKQoJCSAgICBnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQllbHNlCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkgICAgfQoJICAgIAoJICAgIGtleVNlcSA9ICYobWF0Y2hlci0+a2V5U2Vxc1twb3NdKTsJCQoJICAgIGlmICgqa2V5U2VxID09IE5VTEwpIHsKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKQoJCSAgICBnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQllbHNlCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkgICAgfQoJICAgIAoJICAgIGZvciAoaSA9IDA7IGkgPCBuYktleXM7IGkrKykgewoJCWlmICgoKmtleVNlcSlbaV0gPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIE5vdCBxdWFsaWZpZWQsIGlmIG5vdCBhbGwgZmllbGRzIGRpZCByZXNvbHZlLgoJCSAgICAqLwoJCSAgICBpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKSB7CgkJCS8qCgkJCSogQWxsIGZpZWxkcyBvZiBhICJrZXkiIElEQyBtdXN0IHJlc29sdmUuCgkJCSovCgkJCWdvdG8gc2VsZWN0b3Jfa2V5X2Vycm9yOwoJCSAgICB9CQkgICAgCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogQWxsIGZpZWxkcyBkaWQgcmVzb2x2ZS4KCSAgICAqLwoJICAgIAoJICAgIC8qCgkgICAgKiA0LjEgSWYgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyB1bmlxdWUoL2tleSksCgkgICAgKiB0aGVuIG5vIHR3byBtZW1iZXJzIG9mIHRoZSC3cXVhbGlmaWVkIG5vZGUgc2V0tyBoYXZlCgkgICAgKiC3a2V5LXNlcXVlbmNlc7cgd2hvc2UgbWVtYmVycyBhcmUgcGFpcndpc2UgZXF1YWwsIGFzCgkgICAgKiBkZWZpbmVkIGJ5IEVxdWFsIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KCSAgICAqCgkgICAgKiBHZXQgdGhlIElEQyBiaW5kaW5nIGZyb20gdGhlIG1hdGNoZXIgYW5kIGNoZWNrIGZvcgoJICAgICogZHVwbGljYXRlIGtleS1zZXF1ZW5jZXMuCgkgICAgKi8KI2lmIDAKCSAgICBiaW5kID0geG1sU2NoZW1hSURDQWNxdWlyZUJpbmRpbmcodmN0eHQsIG1hdGNoZXIpOwojZW5kaWYKCSAgICB0YXJnZXRzID0geG1sU2NoZW1hSURDQWNxdWlyZVRhcmdldExpc3QodmN0eHQsIG1hdGNoZXIpOwoJICAgIGlmICgoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSAmJiAKCQkodGFyZ2V0cy0+bmJJdGVtcyAhPSAwKSkgewoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgY2tleSwgYmtleSwgKmJrZXlTZXE7CgkJCgkJaSA9IDA7CgkJcmVzID0gMDsKCQkvKgoJCSogQ29tcGFyZSB0aGUga2V5LXNlcXVlbmNlcywga2V5IGJ5IGtleS4KCQkqLwoJCWRvIHsKCQkgICAgYmtleVNlcSA9CgkJCSgoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpIHRhcmdldHMtPml0ZW1zW2ldKS0+a2V5czsKCQkgICAgZm9yIChqID0gMDsgaiA8IG5iS2V5czsgaisrKSB7CgkJCWNrZXkgPSAoKmtleVNlcSlbal07CgkJCWJrZXkgPSBia2V5U2VxW2pdOwkJCQkJCQkKCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoY2tleS0+dmFsLCBia2V5LT52YWwpOwoJCQlpZiAocmVzID09IC0xKSB7CgkJCSAgICByZXR1cm4gKC0xKTsKCQkJfSBlbHNlIGlmIChyZXMgPT0gMCkgewoJCQkgICAgLyoKCQkJICAgICogT25lIG9mIHRoZSBrZXlzIGRpZmZlcnMsIHNvIHRoZSBrZXktc2VxdWVuY2UKCQkJICAgICogd29uJ3QgYmUgZXF1YWw7IGdldCBvdXQuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCX0KCQkgICAgfQoJCSAgICBpZiAocmVzID09IDEpIHsKCQkJLyoKCQkJKiBEdXBsaWNhdGUga2V5LXNlcXVlbmNlIGZvdW5kLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBpKys7CgkJfSB3aGlsZSAoaSA8IHRhcmdldHMtPm5iSXRlbXMpOwoJCWlmIChpICE9IHRhcmdldHMtPm5iSXRlbXMpIHsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoJCSAgICAvKiAgIAoJCSAgICAqIFRPRE86IFRyeSB0byByZXBvcnQgdGhlIGtleS1zZXF1ZW5jZS4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAoJCQlXWFNfQkFTSUNfQ0FTVCBpZGMsCgkJCSJEdXBsaWNhdGUga2V5LXNlcXVlbmNlICVzIGluICVzIiwKCQkJeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UodmN0eHQsICZzdHIsCgkJCSAgICAoKmtleVNlcSksIG5iS2V5cyksCgkJCXhtbFNjaGVtYUdldElEQ0Rlc2lnbmF0aW9uKCZzdHJCLCBpZGMpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckIpOwoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEFkZCBhIG5vZGUtdGFibGUgaXRlbSB0byB0aGUgSURDIGJpbmRpbmcuCgkgICAgKi8KCSAgICBudEl0ZW0gPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpIHhtbE1hbGxvYygKCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGUpKTsKCSAgICBpZiAobnRJdGVtID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAiYWxsb2NhdGluZyBhbiBJREMgbm9kZS10YWJsZSBpdGVtIiwgTlVMTCk7CgkJeG1sRnJlZSgqa2V5U2VxKTsKCQkqa2V5U2VxID0gTlVMTDsKCQlyZXR1cm4oLTEpOwoJICAgIH0JCgkgICAgbWVtc2V0KG50SXRlbSwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlKSk7CgkgICAgCgkgICAgLyogCgkgICAgKiBTdG9yZSB0aGUgbm9kZS10YWJsZSBpdGVtIGluIGEgZ2xvYmFsIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkJaWYgKHhtbFNjaGVtYUlEQ1N0b3JlTm9kZVRhYmxlSXRlbSh2Y3R4dCwgbnRJdGVtKSA9PSAtMSkgewoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJICAgIHhtbEZyZWUoKmtleVNlcSk7CgkJICAgICprZXlTZXEgPSBOVUxMOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJbnRJdGVtLT5ub2RlUU5hbWVJRCA9IC0xOwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIFNhdmUgYSBjYWNoZWQgUU5hbWUgZm9yIHRoaXMgbm9kZSBvbiB0aGUgSURDIG5vZGUsIHRvIGJlCgkJKiBhYmxlIHRvIHJlcG9ydCBpdCwgZXZlbiBpZiB0aGUgbm9kZSBpcyBub3Qgc2F2ZWQuCgkJKi8KCQludEl0ZW0tPm5vZGVRTmFtZUlEID0geG1sU2NoZW1hVkFkZE5vZGVRTmFtZSh2Y3R4dCwKCQkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsKCQlpZiAobnRJdGVtLT5ub2RlUU5hbWVJRCA9PSAtMSkgewoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJICAgIHhtbEZyZWUoKmtleVNlcSk7CgkJICAgICprZXlTZXEgPSBOVUxMOwoJCSAgICByZXR1cm4gKC0xKTsJCSAgICAKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBJbml0IHRoZSBub2RlLXRhYmxlIGl0ZW06IFNhdmUgdGhlIG5vZGUsIHBvc2l0aW9uIGFuZAoJICAgICogY29uc3VtZSB0aGUga2V5LXNlcXVlbmNlLgoJICAgICovCgkgICAgbnRJdGVtLT5ub2RlID0gdmN0eHQtPm5vZGU7CgkgICAgbnRJdGVtLT5ub2RlTGluZSA9IHZjdHh0LT5pbm9kZS0+bm9kZUxpbmU7CgkgICAgbnRJdGVtLT5rZXlzID0gKmtleVNlcTsKCSAgICAqa2V5U2VxID0gTlVMTDsKI2lmIDAKCSAgICBpZiAoeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbShiaW5kLCBudEl0ZW0pID09IC0xKSB7CiNlbmRpZgoJICAgIGlmICh4bWxTY2hlbWFJdGVtTGlzdEFkZCh0YXJnZXRzLCBudEl0ZW0pID09IC0xKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJCSAgICAvKiAKCQkgICAgKiBGcmVlIHRoZSBpdGVtLCBzaW5jZSBrZXlyZWYgaXRlbXMgd29uJ3QgYmUKCQkgICAgKiBwdXQgb24gYSBnbG9iYWwgbGlzdC4KCQkgICAgKi8KCQkgICAgeG1sRnJlZShudEl0ZW0tPmtleXMpOwoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJfQoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAKCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwpzZWxlY3Rvcl9rZXlfZXJyb3I6CgkgICAgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJLyoKCQkqIDQuMi4xIChLRVkpIFRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbmQgdGhlIAoJCSogt3F1YWxpZmllZCBub2RlIHNldLcgYXJlIGVxdWFsLCB0aGF0IGlzLCBldmVyeSAKCQkqIG1lbWJlciBvZiB0aGUgt3RhcmdldCBub2RlIHNldLcgaXMgYWxzbyBhIG1lbWJlcgoJCSogb2YgdGhlILdxdWFsaWZpZWQgbm9kZSBzZXS3IGFuZCB2aWNlIHZlcnNhLgoJCSovCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCBpZGMsCgkJICAgICJOb3QgYWxsIGZpZWxkcyBvZiAlcyBldmFsdWF0ZSB0byBhIG5vZGUiLAoJCSAgICB4bWxTY2hlbWFHZXRJRENEZXNpZ25hdGlvbigmc3RyLCBpZGMpLCBOVUxMKTsKCQlGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgfQpzZWxlY3Rvcl9sZWF2ZToKCSAgICAvKgoJICAgICogRnJlZSB0aGUga2V5LXNlcXVlbmNlIGlmIG5vdCBhZGRlZCB0byB0aGUgSURDIHRhYmxlLgoJICAgICovCgkgICAgaWYgKChrZXlTZXEgIT0gTlVMTCkgJiYgKCprZXlTZXEgIT0gTlVMTCkpIHsKCQl4bWxGcmVlKCprZXlTZXEpOwoJCSprZXlTZXEgPSBOVUxMOwoJICAgIH0KCX0gLyogaWYgc2VsZWN0b3IgKi8KCQoJc3RvLT5uYkhpc3RvcnktLTsKCmRlcmVnaXN0ZXJfY2hlY2s6CgkvKgoJKiBEZXJlZ2lzdGVyIHN0YXRlIG9iamVjdHMgaWYgdGhleSByZWFjaCB0aGUgZGVwdGggb2YgY3JlYXRpb24uCgkqLwoJaWYgKChzdG8tPm5iSGlzdG9yeSA9PSAwKSAmJiAoc3RvLT5kZXB0aCA9PSBkZXB0aCkpIHsKI2lmZGVmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFNUTyBwb3AgJyVzJ1xuIiwKCQlzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCSAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IHN0bykgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkiLAoJCSAgICAiVGhlIHN0YXRlIG9iamVjdCB0byBiZSByZW1vdmVkIGlzIG5vdCB0aGUgZmlyc3QgIgoJCSAgICAiaW4gdGhlIGxpc3QiKTsKCSAgICB9CgkgICAgbmV4dHN0byA9IHN0by0+bmV4dDsKCSAgICAvKgoJICAgICogVW5saW5rIGZyb20gdGhlIGxpc3Qgb2YgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBzdG8tPm5leHQ7CgkgICAgc3RvLT5uZXh0ID0gdmN0eHQtPnhwYXRoU3RhdGVQb29sOwoJICAgIC8qCgkgICAgKiBMaW5rIGl0IHRvIHRoZSBwb29sIG9mIHJldXNhYmxlIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgPSBzdG87CgkgICAgc3RvID0gbmV4dHN0bzsKCX0gZWxzZQoJICAgIHN0byA9IHN0by0+bmV4dDsKICAgIH0gLyogd2hpbGUgKHN0byAhPSBOVUxMKSAqLwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW1EZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKgogKiBDcmVhdGVzIGhlbHBlciBvYmplY3RzIHRvIGV2YWx1YXRlIElEQyBzZWxlY3RvcnMvZmllbGRzCiAqIHN1Y2Nlc3NpdmVseS4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciwgbGFzdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFJRENQdHIgaWRjLCByZWZJZGM7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKICAgICAgICAKICAgIGlkYyA9ICh4bWxTY2hlbWFJRENQdHIpIGVsZW1EZWNsLT5pZGNzOwogICAgaWYgKGlkYyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIAojaWZkZWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IFJFR0lTVEVSIG9uICVzLCBkZXB0aCAlZFxuIiwKCSAgICAoY2hhciAqKSB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSksIHZjdHh0LT5kZXB0aCk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCiAgICBpZiAodmN0eHQtPmlub2RlLT5pZGNNYXRjaGVycyAhPSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzIiwKCSAgICAiVGhlIGNoYWluIG9mIElEQyBtYXRjaGVycyBpcyBleHBlY3RlZCB0byBiZSBlbXB0eSIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBkbyB7CglpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgLyoKCSAgICAqIFNpbmNlIElEQ3MgYnViYmxlcyBhcmUgZXhwZW5zaXZlIHdlIG5lZWQgdG8ga25vdyB0aGUKCSAgICAqIGRlcHRoIGF0IHdoaWNoIHRoZSBidWJibGVzIHNob3VsZCBzdG9wOyB0aGlzIHdpbGwgYmUKCSAgICAqIHRoZSBkZXB0aCBvZiB0aGUgdG9wLW1vc3Qga2V5cmVmIElEQy4gSWYgbm8ga2V5cmVmCgkgICAgKiByZWZlcmVuY2VzIGEga2V5L3VuaXF1ZSBJREMsIHRoZSBrZXlyZWZEZXB0aCB3aWxsCgkgICAgKiBiZSAtMSwgaW5kaWNhdGluZyB0aGF0IG5vIGJ1YmJsZXMgYXJlIG5lZWRlZC4KCSAgICAqLwoJICAgIHJlZklkYyA9ICh4bWxTY2hlbWFJRENQdHIpIGlkYy0+cmVmLT5pdGVtOwoJICAgIGlmIChyZWZJZGMgIT0gTlVMTCkgewoJCS8qCgkJKiBSZW1lbWJlciB0aGF0IHdlIGhhdmUga2V5cmVmcyBvbiB0aGlzIG5vZGUuCgkJKi8KCQl2Y3R4dC0+aW5vZGUtPmhhc0tleXJlZnMgPSAxOwoJCS8qCgkJKiBMb29rdXAgdGhlIHJlZmVyZW5jZWQgYXVnbWVudGVkIElEQyBpbmZvLgoJCSovCgkJYWlkYyA9IHZjdHh0LT5haWRjczsKCQl3aGlsZSAoYWlkYyAhPSBOVUxMKSB7CgkJICAgIGlmIChhaWRjLT5kZWYgPT0gcmVmSWRjKQoJCQlicmVhazsKCQkgICAgYWlkYyA9IGFpZGMtPm5leHQ7CgkJfQoJCWlmIChhaWRjID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyIsCgkJCSJDb3VsZCBub3QgZmluZCBhbiBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIGFuIElEQyAiCgkJCSJkZWZpbml0aW9uIik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJCWlmICgoYWlkYy0+a2V5cmVmRGVwdGggPT0gLTEpIHx8CgkJICAgICh2Y3R4dC0+ZGVwdGggPCBhaWRjLT5rZXlyZWZEZXB0aCkpCgkJICAgIGFpZGMtPmtleXJlZkRlcHRoID0gdmN0eHQtPmRlcHRoOwoJICAgIH0KCX0KCS8qCgkqIExvb2t1cCB0aGUgYXVnbWVudGVkIElEQyBpdGVtIGZvciB0aGUgSURDIGRlZmluaXRpb24uCgkqLwoJYWlkYyA9IHZjdHh0LT5haWRjczsKCXdoaWxlIChhaWRjICE9IE5VTEwpIHsKCSAgICBpZiAoYWlkYy0+ZGVmID09IGlkYykKCQlicmVhazsKCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0KCWlmIChhaWRjID09IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzIiwKCQkiQ291bGQgbm90IGZpbmQgYW4gYXVnbWVudGVkIElEQyBpdGVtIGZvciBhbiBJREMgZGVmaW5pdGlvbiIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogQ3JlYXRlIGFuIElEQyBtYXRjaGVyIGZvciBldmVyeSBJREMgZGVmaW5pdGlvbi4KCSovCglpZiAodmN0eHQtPmlkY01hdGNoZXJDYWNoZSAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFJldXNlIGEgY2FjaGVkIG1hdGNoZXIuCgkgICAgKi8KCSAgICBtYXRjaGVyID0gdmN0eHQtPmlkY01hdGNoZXJDYWNoZTsKCSAgICB2Y3R4dC0+aWRjTWF0Y2hlckNhY2hlID0gbWF0Y2hlci0+bmV4dENhY2hlZDsKCSAgICBtYXRjaGVyLT5uZXh0Q2FjaGVkID0gTlVMTDsKCX0gZWxzZSB7CgkgICAgbWF0Y2hlciA9ICh4bWxTY2hlbWFJRENNYXRjaGVyUHRyKSAKCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ01hdGNoZXIpKTsKCSAgICBpZiAobWF0Y2hlciA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIElEQyBtYXRjaGVyIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIG1lbXNldChtYXRjaGVyLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDTWF0Y2hlcikpOwoJfQoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICB2Y3R4dC0+aW5vZGUtPmlkY01hdGNoZXJzID0gbWF0Y2hlcjsKCWVsc2UKCSAgICBsYXN0LT5uZXh0ID0gbWF0Y2hlcjsKCWxhc3QgPSBtYXRjaGVyOwoKCW1hdGNoZXItPnR5cGUgPSBJRENfTUFUQ0hFUjsKCW1hdGNoZXItPmRlcHRoID0gdmN0eHQtPmRlcHRoOwkKCW1hdGNoZXItPmFpZGMgPSBhaWRjOwoJbWF0Y2hlci0+aWRjVHlwZSA9IGFpZGMtPmRlZi0+dHlwZTsKI2lmZGVmIERFQlVHX0lEQwkKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIHJlZ2lzdGVyIG1hdGNoZXJcbiIpOwojZW5kaWYgCgkvKgoJKiBJbml0IHRoZSBhdXRvbWF0b24gc3RhdGUgb2JqZWN0LiAKCSovCglpZiAoeG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3QodmN0eHQsIG1hdGNoZXIsIAoJICAgIGlkYy0+c2VsZWN0b3IsIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikgPT0gLTEpCgkgICAgcmV0dXJuICgtMSk7CgoJaWRjID0gaWRjLT5uZXh0OwogICAgfSB3aGlsZSAoaWRjICE9IE5VTEwpOwogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJRENGaWxsTm9kZVRhYmxlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtKQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOwogICAgaW50IHJlcywgaSwgaiwgaywgbmJUYXJnZXRzLCBuYkZpZWxkcywgbmJEdXBscywgbmJOb2RlVGFibGU7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICprZXlzLCAqbnRrZXlzOwogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKnRhcmdldHMsICpkdXBsczsKICAgIAogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyID0gaWVsZW0tPmlkY01hdGNoZXJzOwogICAgLyogdmN0eHQtPmNyZWF0ZUlEQ05vZGVUYWJsZXMgKi8KICAgIHdoaWxlIChtYXRjaGVyICE9IE5VTEwpIHsKCS8qCgkqIFNraXAga2V5cmVmIElEQ3MgYW5kIGVtcHR5IElEQyB0YXJnZXQtbGlzdHMuCgkqLwoJaWYgKChtYXRjaGVyLT5haWRjLT5kZWYtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHx8CgkgICAgV1hTX0lMSVNUX0lTX0VNUFRZKG1hdGNoZXItPnRhcmdldHMpKQoJewoJICAgIG1hdGNoZXIgPSBtYXRjaGVyLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQoJLyoKCSogSWYgd2UgX3dhbnRfIHRoZSBJREMgbm9kZS10YWJsZSB0byBiZSBjcmVhdGVkIGluIGFueSBjYXNlCgkqIHRoZW4gZG8gc28uIE90aGVyd2lzZSBjcmVhdGUgdGhlbSBvbmx5IGlmIGtleXJlZnMgbmVlZCB0aGVtLgoJKi8KCWlmICgoISB2Y3R4dC0+Y3JlYXRlSURDTm9kZVRhYmxlcykgJiYKCSAgICAoKG1hdGNoZXItPmFpZGMtPmtleXJlZkRlcHRoID09IC0xKSB8fAoJICAgICAobWF0Y2hlci0+YWlkYy0+a2V5cmVmRGVwdGggPiB2Y3R4dC0+ZGVwdGgpKSkKCXsKCSAgICBtYXRjaGVyID0gbWF0Y2hlci0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0KCS8qCgkqIEdldC9jcmVhdGUgdGhlIElEQyBiaW5kaW5nIG9uIHRoaXMgZWxlbWVudCBmb3IgdGhlIElEQyBkZWZpbml0aW9uLgoJKi8KCWJpbmQgPSB4bWxTY2hlbWFJRENBY3F1aXJlQmluZGluZyh2Y3R4dCwgbWF0Y2hlcik7CgoJaWYgKCEgV1hTX0lMSVNUX0lTX0VNUFRZKGJpbmQtPmR1cGxzKSkgewoJICAgIGR1cGxzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIGJpbmQtPmR1cGxzLT5pdGVtczsKCSAgICBuYkR1cGxzID0gYmluZC0+ZHVwbHMtPm5iSXRlbXM7Cgl9IGVsc2UgewoJICAgIGR1cGxzID0gTlVMTDsKCSAgICBuYkR1cGxzID0gMDsJICAgIAoJfQoJaWYgKGJpbmQtPm5vZGVUYWJsZSAhPSBOVUxMKSB7CgkgICAgbmJOb2RlVGFibGUgPSBiaW5kLT5uYk5vZGVzOwoJfSBlbHNlIHsKCSAgICBuYk5vZGVUYWJsZSA9IDA7Cgl9CgoJaWYgKChuYk5vZGVUYWJsZSA9PSAwKSAmJiAobmJEdXBscyA9PSAwKSkgewoJICAgIC8qCgkgICAgKiBUcmFuc2ZlciBhbGwgSURDIHRhcmdldC1ub2RlcyB0byB0aGUgSURDIG5vZGUtdGFibGUuCgkgICAgKi8KCSAgICBiaW5kLT5ub2RlVGFibGUgPQoJCSh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSBtYXRjaGVyLT50YXJnZXRzLT5pdGVtczsJCQoJICAgIGJpbmQtPnNpemVOb2RlcyA9IG1hdGNoZXItPnRhcmdldHMtPnNpemVJdGVtczsKCSAgICBiaW5kLT5uYk5vZGVzID0gbWF0Y2hlci0+dGFyZ2V0cy0+bmJJdGVtczsKCgkgICAgbWF0Y2hlci0+dGFyZ2V0cy0+aXRlbXMgPSBOVUxMOwoJICAgIG1hdGNoZXItPnRhcmdldHMtPnNpemVJdGVtcyA9IDA7CgkgICAgbWF0Y2hlci0+dGFyZ2V0cy0+bmJJdGVtcyA9IDA7CSAgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIENvbXBhcmUgdGhlIGtleS1zZXF1ZW5jZXMgYW5kIGFkZCB0byB0aGUgSURDIG5vZGUtdGFibGUuCgkgICAgKi8KCSAgICBuYlRhcmdldHMgPSBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zOwoJICAgIHRhcmdldHMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgbWF0Y2hlci0+dGFyZ2V0cy0+aXRlbXM7CQoJICAgIG5iRmllbGRzID0gbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkczsKCSAgICBpID0gMDsKCSAgICBkbyB7CgkJa2V5cyA9IHRhcmdldHNbaV0tPmtleXM7CgkJaWYgKG5iRHVwbHMpIHsJCQkKCQkgICAgLyoKCQkgICAgKiBTZWFyY2ggaW4gYWxyZWFkeSBmb3VuZCBkdXBsaWNhdGVzIGZpcnN0LgoJCSAgICAqLwoJCSAgICBqID0gMDsKCQkgICAgZG8gewkJCQkJCQoJCQlpZiAobmJGaWVsZHMgPT0gMSkgewoJCQkgICAgcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5c1swXS0+dmFsLAoJCQkJZHVwbHNbal0tPmtleXNbMF0tPnZhbCk7CgkJCSAgICBpZiAocmVzID09IC0xKQoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIGlmIChyZXMgPT0gMSkgewoJCQkJLyoKCQkJCSogRXF1YWwga2V5LXNlcXVlbmNlLgoJCQkJKi8KCQkJCWdvdG8gbmV4dF90YXJnZXQ7CgkJCSAgICB9CgkJCX0gZWxzZSB7CgkJCSAgICByZXMgPSAwOwoJCQkgICAgbnRrZXlzID0gZHVwbHNbal0tPmtleXM7CgkJCSAgICBmb3IgKGsgPSAwOyBrIDwgbmJGaWVsZHM7IGsrKykgewoJCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5c1trXS0+dmFsLAoJCQkJICAgIG50a2V5c1trXS0+dmFsKTsKCQkJCWlmIChyZXMgPT0gLTEpCgkJCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJCWlmIChyZXMgPT0gMCkgewoJCQkJICAgIC8qCgkJCQkgICAgKiBPbmUgb2YgdGhlIGtleXMgZGlmZmVycy4KCQkJCSAgICAqLwoJCQkJICAgIGJyZWFrOwoJCQkJfQoJCQkgICAgfQoJCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCQkvKgoJCQkJKiBFcXVhbCBrZXktc2VxdWVuY2UgZm91bmQuCgkJCQkqLwoJCQkJZ290byBuZXh0X3RhcmdldDsKCQkJICAgIH0KCQkJfQoJCQlqKys7CgkJICAgIH0gd2hpbGUgKGogPCBuYkR1cGxzKTsJCSAgICAKCQl9CgkJaWYgKG5iTm9kZVRhYmxlKSB7CgkJICAgIGogPSAwOwoJCSAgICBkbyB7CQkJCQkJCgkJCWlmIChuYkZpZWxkcyA9PSAxKSB7CgkJCSAgICByZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzWzBdLT52YWwsCgkJCQliaW5kLT5ub2RlVGFibGVbal0tPmtleXNbMF0tPnZhbCk7CgkJCSAgICBpZiAocmVzID09IC0xKQoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIGlmIChyZXMgPT0gMCkgewoJCQkJLyoKCQkJCSogVGhlIGtleS1zZXF1ZW5jZSBkaWZmZXJzLgoJCQkJKi8KCQkJCWdvdG8gbmV4dF9ub2RlX3RhYmxlX2VudHJ5OwoJCQkgICAgfQoJCQl9IGVsc2UgewoJCQkgICAgcmVzID0gMDsKCQkJICAgIG50a2V5cyA9IGJpbmQtPm5vZGVUYWJsZVtqXS0+a2V5czsKCQkJICAgIGZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCQlyZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzW2tdLT52YWwsCgkJCQkgICAgbnRrZXlzW2tdLT52YWwpOwoJCQkJaWYgKHJlcyA9PSAtMSkKCQkJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCQkJaWYgKHJlcyA9PSAwKSB7CgkJCQkgICAgLyoKCQkJCSAgICAqIE9uZSBvZiB0aGUga2V5cyBkaWZmZXJzLgoJCQkJICAgICovCgkJCQkgICAgZ290byBuZXh0X25vZGVfdGFibGVfZW50cnk7CgkJCQl9CgkJCSAgICB9CgkJCX0JCQkKCQkJLyoKCQkJKiBBZGQgdGhlIGR1cGxpY2F0ZSB0byB0aGUgbGlzdCBvZiBkdXBsaWNhdGVzLgoJCQkqLwoJCQlpZiAoYmluZC0+ZHVwbHMgPT0gTlVMTCkgewoJCQkgICAgYmluZC0+ZHVwbHMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwoJCQkgICAgaWYgKGJpbmQtPmR1cGxzID09IE5VTEwpCgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQl9CQkgICAgCgkJCWlmICh4bWxTY2hlbWFJdGVtTGlzdEFkZChiaW5kLT5kdXBscywgYmluZC0+bm9kZVRhYmxlW2pdKSA9PSAtMSkKCQkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCS8qCgkJCSogUmVtb3ZlIHRoZSBkdXBsaWNhdGUgZW50cnkgZnJvbSB0aGUgSURDIG5vZGUtdGFibGUuCgkJCSovCgkJCWJpbmQtPm5vZGVUYWJsZVtqXSA9IGJpbmQtPm5vZGVUYWJsZVtiaW5kLT5uYk5vZGVzIC0xXTsKCQkJYmluZC0+bmJOb2Rlcy0tOwoKCQkJZ290byBuZXh0X3RhcmdldDsKCm5leHRfbm9kZV90YWJsZV9lbnRyeToKCQkJaisrOwoJCSAgICB9IHdoaWxlIChqIDwgbmJOb2RlVGFibGUpOwoJCX0KCQkvKgoJCSogSWYgZXZlcnl0aGluZyBpcyBmaW5lLCB0aGVuIGFkZCB0aGUgSURDIHRhcmdldC1ub2RlIHRvCgkJKiB0aGUgSURDIG5vZGUtdGFibGUuCgkJKi8KCQlpZiAoeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbShiaW5kLCB0YXJnZXRzW2ldKSA9PSAtMSkKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCm5leHRfdGFyZ2V0OgoJCWkrKzsKCSAgICB9IHdoaWxlIChpIDwgbmJUYXJnZXRzKTsKCX0KCW1hdGNoZXIgPSBtYXRjaGVyLT5uZXh0OwogICAgfQogICAgcmV0dXJuKDApOwoKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4oLTEpOwp9CgovKioKICogeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlczogCiAqIEBkZXB0aDogdGhlIGN1cnJlbnQgdHJlZSBkZXB0aAogKgogKiBNZXJnZXMgSURDIGJpbmRpbmdzIG9mIGFuIGVsZW1lbnQgYXQgQGRlcHRoIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgSURDIAogKiBiaW5kaW5ncyBvZiBpdHMgcGFyZW50IGVsZW1lbnQuIElmIGEgZHVwbGljYXRlIG5vdGUtdGFibGUgZW50cnkgaXMgZm91bmQsIAogKiBib3RoLCB0aGUgcGFyZW50IG5vZGUtdGFibGUgZW50cnkgYW5kIGNoaWxkIGVudHJ5IGFyZSBkaXNjYXJkZWQgZnJvbSB0aGUgCiAqIG5vZGUtdGFibGUgb2YgdGhlIHBhcmVudC4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1YmJsZUlEQ05vZGVUYWJsZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOyAvKiBJREMgYmluZGluZ3Mgb2YgdGhlIGN1cnJlbnQgbm9kZS4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyICpwYXJUYWJsZSwgcGFyQmluZCA9IE5VTEw7IC8qIHBhcmVudCBJREMgYmluZGluZ3MuICovCiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBub2RlLCBwYXJOb2RlID0gTlVMTCwgKmR1cGxzLCAqcGFyTm9kZXM7IC8qIG5vZGUtdGFibGUgZW50cmllcy4gKi8KICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOwogICAgaW50IGksIGosIGssIHJldCA9IDAsIG5iRmllbGRzLCBvbGROdW0sIG9sZER1cGxzOwoKICAgIGJpbmQgPSB2Y3R4dC0+aW5vZGUtPmlkY1RhYmxlOyAgICAgICAgCiAgICBpZiAoYmluZCA9PSBOVUxMKSB7CgkvKiBGaW5lLCBubyB0YWJsZSwgbm8gYnViYmxlcy4gKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICAKICAgIHBhclRhYmxlID0gJih2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aCAtMV0tPmlkY1RhYmxlKTsKICAgIC8qCiAgICAqIFdhbGsgYWxsIGJpbmRpbmdzOyBjcmVhdGUgbmV3IG9yIGFkZCB0byBleGlzdGluZyBiaW5kaW5ncy4KICAgICogUmVtb3ZlIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2VzLgogICAgKi8KICAgIHdoaWxlIChiaW5kICE9IE5VTEwpIHsKCQoJaWYgKChiaW5kLT5uYk5vZGVzID09IDApICYmIFdYU19JTElTVF9JU19FTVBUWShiaW5kLT5kdXBscykpCgkgICAgZ290byBuZXh0X2JpbmRpbmc7CgkvKgoJKiBDaGVjayBpZiB0aGUga2V5L3VuaXF1ZSBJREMgdGFibGUgbmVlZHMgdG8gYmUgYnViYmxlZC4KCSovCglpZiAoISB2Y3R4dC0+Y3JlYXRlSURDTm9kZVRhYmxlcykgewoJICAgIGFpZGMgPSB2Y3R4dC0+YWlkY3M7CgkgICAgZG8gewoJCWlmIChhaWRjLT5kZWYgPT0gYmluZC0+ZGVmaW5pdGlvbikgewoJCSAgICBpZiAoKGFpZGMtPmtleXJlZkRlcHRoID09IC0xKSB8fCAKCQkJKGFpZGMtPmtleXJlZkRlcHRoID49IHZjdHh0LT5kZXB0aCkpIHsKCQkJZ290byBuZXh0X2JpbmRpbmc7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJfQoJCWFpZGMgPSBhaWRjLT5uZXh0OwoJICAgIH0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7Cgl9CgoJaWYgKHBhclRhYmxlICE9IE5VTEwpCgkgICAgcGFyQmluZCA9ICpwYXJUYWJsZTsKCS8qCgkqIFNlYXJjaCBhIG1hdGNoaW5nIHBhcmVudCBiaW5kaW5nIGZvciB0aGUKCSogSURDIGRlZmluaXRpb24uCgkqLwoJd2hpbGUgKHBhckJpbmQgIT0gTlVMTCkgewkgICAgCgkgICAgaWYgKHBhckJpbmQtPmRlZmluaXRpb24gPT0gYmluZC0+ZGVmaW5pdGlvbikKCQlicmVhazsKCSAgICBwYXJCaW5kID0gcGFyQmluZC0+bmV4dDsKCX0KCglpZiAocGFyQmluZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIENvbXBhcmUgZXZlcnkgbm9kZS10YWJsZSBlbnRyeSBvZiB0aGUgY2hpbGQgbm9kZSwgCgkgICAgKiBpLmUuIHRoZSBrZXktc2VxdWVuY2Ugd2l0aGluLCAuLi4KCSAgICAqLwoJICAgIG9sZE51bSA9IHBhckJpbmQtPm5iTm9kZXM7IC8qIFNraXAgbmV3bHkgYWRkZWQgaXRlbXMuICovCgoJICAgIGlmICghIFdYU19JTElTVF9JU19FTVBUWShwYXJCaW5kLT5kdXBscykpIHsKCQlvbGREdXBscyA9IHBhckJpbmQtPmR1cGxzLT5uYkl0ZW1zOwoJCWR1cGxzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIHBhckJpbmQtPmR1cGxzLT5pdGVtczsKCSAgICB9IGVsc2UgewoJCWR1cGxzID0gTlVMTDsKCQlvbGREdXBscyA9IDA7CQkKCSAgICB9CgkgICAgCgkgICAgcGFyTm9kZXMgPSBwYXJCaW5kLT5ub2RlVGFibGU7CgkgICAgbmJGaWVsZHMgPSBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsKCSAgICAKCSAgICBmb3IgKGkgPSAwOyBpIDwgYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJbm9kZSA9IGJpbmQtPm5vZGVUYWJsZVtpXTsKCQlpZiAobm9kZSA9PSBOVUxMKQoJCSAgICBjb250aW51ZTsKCQkvKgoJCSogLi4ud2l0aCBldmVyeSBrZXktc2VxdWVuY2Ugb2YgdGhlIHBhcmVudCBub2RlLCBhbHJlYWR5CgkJKiBldmFsdWF0ZWQgdG8gYmUgYSBkdXBsaWNhdGUga2V5LXNlcXVlbmNlLgoJCSovCgkJaWYgKG9sZER1cGxzKSB7CgkJICAgIGogPSAwOyAKCQkgICAgd2hpbGUgKGogPCBvbGREdXBscykgewoJCQlpZiAobmJGaWVsZHMgPT0gMSkgewoJCQkgICAgcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoCgkJCQlub2RlLT5rZXlzWzBdLT52YWwsCgkJCQlkdXBsc1tqXS0+a2V5c1swXS0+dmFsKTsKCQkJICAgIGlmIChyZXQgPT0gLTEpCgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgaWYgKHJldCA9PSAwKSB7CgkJCQlqKys7CgkJCQljb250aW51ZTsKCQkJICAgIH0KCQkJfSBlbHNlIHsKCQkJICAgIHBhck5vZGUgPSBkdXBsc1tqXTsKCQkJICAgIGZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCQlyZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCgKCQkJCSAgICBub2RlLT5rZXlzW2tdLT52YWwsCgkJCQkgICAgcGFyTm9kZS0+a2V5c1trXS0+dmFsKTsKCQkJCWlmIChyZXQgPT0gLTEpCgkJCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJCWlmIChyZXQgPT0gMCkKCQkJCSAgICBicmVhazsKCQkJICAgIH0KCQkJfQoJCQlpZiAocmV0ID09IDEpCgkJCSAgICAvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCSAgICBicmVhazsKCQkJaisrOwoJCSAgICB9CgkJICAgIGlmIChqICE9IG9sZER1cGxzKSB7CgkJCS8qIER1cGxpY2F0ZSBmb3VuZC4gU2tpcCB0aGlzIGVudHJ5LiAqLwoJCQljb250aW51ZTsKCQkgICAgfQoJCX0JCSAgICAKCQkvKgoJCSogLi4uIGFuZCB3aXRoIGV2ZXJ5IGtleS1zZXF1ZW5jZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkJKi8KCQlpZiAob2xkTnVtKSB7CgkJICAgIGogPSAwOyAKCQkgICAgd2hpbGUgKGogPCBvbGROdW0pIHsKCQkJcGFyTm9kZSA9IHBhck5vZGVzW2pdOwoJCQlpZiAobmJGaWVsZHMgPT0gMSkgewoJCQkgICAgcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoCgkJCQlub2RlLT5rZXlzWzBdLT52YWwsCgkJCQlwYXJOb2RlLT5rZXlzWzBdLT52YWwpOwoJCQkgICAgaWYgKHJldCA9PSAtMSkKCQkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCSAgICBpZiAocmV0ID09IDApIHsKCQkJCWorKzsKCQkJCWNvbnRpbnVlOwoJCQkgICAgfQoJCQl9IGVsc2UgewkJCSAgICAKCQkJICAgIGZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCQlyZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCgKCQkJCSAgICBub2RlLT5rZXlzW2tdLT52YWwsCgkJCQkgICAgcGFyTm9kZS0+a2V5c1trXS0+dmFsKTsKCQkJCWlmIChyZXQgPT0gLTEpCgkJCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJCWlmIChyZXQgPT0gMCkKCQkJCSAgICBicmVhazsKCQkJICAgIH0KCQkJfQoJCQlpZiAocmV0ID09IDEpCgkJCSAgICAvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCSAgICBicmVhazsKCQkJaisrOwoJCSAgICB9CgkJICAgIGlmIChqICE9IG9sZE51bSkgewoJCQkvKgoJCQkqIEhhbmRsZSBkdXBsaWNhdGVzLiBNb3ZlIHRoZSBkdXBsaWNhdGUgaW4KCQkJKiB0aGUgcGFyZW50J3Mgbm9kZS10YWJsZSB0byB0aGUgbGlzdCBvZgoJCQkqIGR1cGxpY2F0ZXMuCgkJCSovCQkJCgkJCW9sZE51bS0tOwoJCQlwYXJCaW5kLT5uYk5vZGVzLS07CgkJCS8qCgkJCSogTW92ZSBsYXN0IG9sZCBpdGVtIHRvIHBvcyBvZiBkdXBsaWNhdGUuCgkJCSovCgkJCXBhck5vZGVzW2pdID0gcGFyTm9kZXNbb2xkTnVtXTsKCQkJCgkJCWlmIChwYXJCaW5kLT5uYk5vZGVzICE9IG9sZE51bSkgewoJCQkgICAgLyoKCQkJICAgICogSWYgbmV3IGl0ZW1zIGV4aXN0LCBtb3ZlIGxhc3QgbmV3IGl0ZW0gdG8gCgkJCSAgICAqIGxhc3Qgb2Ygb2xkIGl0ZW1zLgoJCQkgICAgKi8KCQkJICAgIHBhck5vZGVzW29sZE51bV0gPSAKCQkJCXBhck5vZGVzW3BhckJpbmQtPm5iTm9kZXNdOwoJCQl9CgkJCWlmIChwYXJCaW5kLT5kdXBscyA9PSBOVUxMKSB7CgkJCSAgICBwYXJCaW5kLT5kdXBscyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkJCSAgICBpZiAocGFyQmluZC0+ZHVwbHMgPT0gTlVMTCkKCQkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCX0KCQkJeG1sU2NoZW1hSXRlbUxpc3RBZGQocGFyQmluZC0+ZHVwbHMsIHBhck5vZGUpOwkJCQoJCSAgICB9IGVsc2UgewoJCQkvKgoJCQkqIEFkZCB0aGUgbm9kZS10YWJsZSBlbnRyeSAobm9kZSBhbmQga2V5LXNlcXVlbmNlKSBvZiAKCQkJKiB0aGUgY2hpbGQgbm9kZSB0byB0aGUgbm9kZSB0YWJsZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkJCSovCgkJCWlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewkJCQoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCQkJeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgImFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIH0KCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcyA9IDE7CgkJCX0gZWxzZSBpZiAocGFyQmluZC0+bmJOb2RlcyA+PSBwYXJCaW5kLT5zaXplTm9kZXMpIHsKCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcyAqPSAyOwoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCQkJeG1sUmVhbGxvYyhwYXJCaW5kLT5ub2RlVGFibGUsIHBhckJpbmQtPnNpemVOb2RlcyAqIAoJCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgInJlLWFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIH0JCQkgICAgCgkJCX0KCQkJcGFyTm9kZXMgPSBwYXJCaW5kLT5ub2RlVGFibGU7CgkJCS8qCgkJCSogQXBwZW5kIHRoZSBuZXcgbm9kZS10YWJsZSBlbnRyeSB0byB0aGUgJ25ldyBub2RlLXRhYmxlCgkJCSogZW50cmllcycgc2VjdGlvbi4KCQkJKi8KCQkJcGFyTm9kZXNbcGFyQmluZC0+bmJOb2RlcysrXSA9IG5vZGU7CgkJICAgIH0KCgkJfQkKCQkKCSAgICB9CQoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogTm8gYmluZGluZyBmb3IgdGhlIElEQyB3YXMgZm91bmQ6IGNyZWF0ZSBhIG5ldyBvbmUgYW5kCgkgICAgKiBjb3B5IGFsbCBub2RlLXRhYmxlcy4KCSAgICAqLwoJICAgIHBhckJpbmQgPSB4bWxTY2hlbWFJRENOZXdCaW5kaW5nKGJpbmQtPmRlZmluaXRpb24pOwoJICAgIGlmIChwYXJCaW5kID09IE5VTEwpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICAKCSAgICAvKgoJICAgICogVE9ETzogSG1tLCBob3cgdG8gb3B0aW1pemUgdGhlIGluaXRpYWwgbnVtYmVyIG9mCgkgICAgKiBhbGxvY2F0ZWQgZW50cmllcz8KCSAgICAqLwoJICAgIGlmIChiaW5kLT5uYk5vZGVzICE9IDApIHsKCQkvKgoJCSogQWRkIGFsbCBJREMgbm9kZS10YWJsZSBlbnRyaWVzLgoJCSovCgkJaWYgKCEgdmN0eHQtPnBzdmlFeHBvc2VJRENOb2RlVGFibGVzKSB7CgkJICAgIC8qCgkJICAgICogSnVzdCBtb3ZlIHRoZSBlbnRyaWVzLgoJCSAgICAqIE5PVEU6IHRoaXMgaXMgcXVpdGUgc2F2ZSBoZXJlLCBzaW5jZQoJCSAgICAqIGFsbCB0aGUga2V5cmVmIGxvb2t1cHMgaGF2ZSBhbHJlYWR5IGJlZW4KCQkgICAgKiBwZXJmb3JtZWQuCgkJICAgICovCgkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9IGJpbmQtPm5vZGVUYWJsZTsKCQkgICAgYmluZC0+bm9kZVRhYmxlID0gTlVMTDsKCQkgICAgcGFyQmluZC0+c2l6ZU5vZGVzID0gYmluZC0+c2l6ZU5vZGVzOwoJCSAgICBiaW5kLT5zaXplTm9kZXMgPSAwOwoJCSAgICBwYXJCaW5kLT5uYk5vZGVzID0gYmluZC0+bmJOb2RlczsKCQkgICAgYmluZC0+bmJOb2RlcyA9IDA7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBDb3B5IHRoZSBlbnRyaWVzLgoJCSAgICAqLwoJCSAgICBwYXJCaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkJCXhtbE1hbGxvYyhiaW5kLT5uYk5vZGVzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJICAgIGlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkgICAgImFsbG9jYXRpbmcgYW4gYXJyYXkgb2YgSURDIG5vZGUtdGFibGUgIgoJCQkgICAgIml0ZW1zIiwgTlVMTCk7CgkJCXhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nKHBhckJpbmQpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIHBhckJpbmQtPnNpemVOb2RlcyA9IGJpbmQtPm5iTm9kZXM7CgkJICAgIHBhckJpbmQtPm5iTm9kZXMgPSBiaW5kLT5uYk5vZGVzOwoJCSAgICBtZW1jcHkocGFyQmluZC0+bm9kZVRhYmxlLCBiaW5kLT5ub2RlVGFibGUsCgkJCWJpbmQtPm5iTm9kZXMgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCQl9CgkgICAgfQoJICAgIGlmIChiaW5kLT5kdXBscykgewoJCS8qCgkJKiBNb3ZlIHRoZSBkdXBsaWNhdGVzLgoJCSovCgkJaWYgKHBhckJpbmQtPmR1cGxzICE9IE5VTEwpCgkJICAgIHhtbFNjaGVtYUl0ZW1MaXN0RnJlZShwYXJCaW5kLT5kdXBscyk7CgkJcGFyQmluZC0+ZHVwbHMgPSBiaW5kLT5kdXBsczsKCQliaW5kLT5kdXBscyA9IE5VTEw7CQkKCSAgICB9CgkgICAgaWYgKCpwYXJUYWJsZSA9PSBOVUxMKQoJCSpwYXJUYWJsZSA9IHBhckJpbmQ7CgkgICAgZWxzZSB7CgkJcGFyQmluZC0+bmV4dCA9ICpwYXJUYWJsZTsKCQkqcGFyVGFibGUgPSBwYXJCaW5kOwoJICAgIH0JICAgCgl9CQoKbmV4dF9iaW5kaW5nOgoJYmluZCA9IGJpbmQtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwoKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4oLTEpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWY6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW1EZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKgogKiBDaGVjayB0aGUgY3ZjLWlkYy1rZXlyZWYgY29uc3RyYWludHMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyOwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZDsKICAgIAogICAgbWF0Y2hlciA9IHZjdHh0LT5pbm9kZS0+aWRjTWF0Y2hlcnM7CiAgICAvKgogICAgKiBGaW5kIGEga2V5cmVmLgogICAgKi8KICAgIHdoaWxlIChtYXRjaGVyICE9IE5VTEwpIHsKCWlmICgobWF0Y2hlci0+aWRjVHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgJiYKCSAgICBtYXRjaGVyLT50YXJnZXRzICYmCgkgICAgbWF0Y2hlci0+dGFyZ2V0cy0+bmJJdGVtcykKCXsKCSAgICBpbnQgaSwgaiwgaywgcmVzLCBuYkZpZWxkcywgaGFzRHVwbHM7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqcmVmS2V5cywgKmtleXM7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgcmVmTm9kZSA9IE5VTEw7CgoJICAgIG5iRmllbGRzID0gbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkczsKCgkgICAgLyoKCSAgICAqIEZpbmQgdGhlIElEQyBub2RlLXRhYmxlIGZvciB0aGUgcmVmZXJlbmNlZCBJREMga2V5L3VuaXF1ZS4KCSAgICAqLwoJICAgIGJpbmQgPSB2Y3R4dC0+aW5vZGUtPmlkY1RhYmxlOwoJICAgIHdoaWxlIChiaW5kICE9IE5VTEwpIHsKCQlpZiAoKHhtbFNjaGVtYUlEQ1B0cikgbWF0Y2hlci0+YWlkYy0+ZGVmLT5yZWYtPml0ZW0gPT0gCgkJICAgIGJpbmQtPmRlZmluaXRpb24pCgkJICAgIGJyZWFrOwoJCWJpbmQgPSBiaW5kLT5uZXh0OwoJICAgIH0KCSAgICBoYXNEdXBscyA9IChiaW5kICYmIGJpbmQtPmR1cGxzICYmIGJpbmQtPmR1cGxzLT5uYkl0ZW1zKSA/IDEgOiAwOwoJICAgIC8qCgkgICAgKiBTZWFyY2ggZm9yIGEgbWF0Y2hpbmcga2V5LXNlcXVlbmNlcy4KCSAgICAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zOyBpKyspIHsKCQlyZXMgPSAwOwoJCXJlZk5vZGUgPSBtYXRjaGVyLT50YXJnZXRzLT5pdGVtc1tpXTsKCQlpZiAoYmluZCAhPSBOVUxMKSB7CgkJICAgIHJlZktleXMgPSByZWZOb2RlLT5rZXlzOwoJCSAgICBmb3IgKGogPSAwOyBqIDwgYmluZC0+bmJOb2RlczsgaisrKSB7CgkJCWtleXMgPSBiaW5kLT5ub2RlVGFibGVbal0tPmtleXM7CgkJCWZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCSAgICByZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzW2tdLT52YWwsCgkJCQlyZWZLZXlzW2tdLT52YWwpOwoJCQkgICAgaWYgKHJlcyA9PSAwKQoJCQkJYnJlYWs7CgkJCSAgICBlbHNlIGlmIChyZXMgPT0gLTEpIHsKCQkJCXJldHVybiAoLTEpOwoJCQkgICAgfQoJCQl9CgkJCWlmIChyZXMgPT0gMSkgewoJCQkgICAgLyoKCQkJICAgICogTWF0Y2ggZm91bmQuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCX0KCQkgICAgfQoJCSAgICBpZiAoKHJlcyA9PSAwKSAmJiBoYXNEdXBscykgewoJCQkvKgoJCQkqIFNlYXJjaCBpbiBkdXBsaWNhdGVzCgkJCSovCgkJCWZvciAoaiA9IDA7IGogPCBiaW5kLT5kdXBscy0+bmJJdGVtczsgaisrKSB7CgkJCSAgICBrZXlzID0gKCh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikKCQkJCWJpbmQtPmR1cGxzLT5pdGVtc1tqXSktPmtleXM7CgkJCSAgICBmb3IgKGsgPSAwOyBrIDwgbmJGaWVsZHM7IGsrKykgewoJCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5c1trXS0+dmFsLAoJCQkJICAgIHJlZktleXNba10tPnZhbCk7CgkJCQlpZiAocmVzID09IDApCgkJCQkgICAgYnJlYWs7CgkJCQllbHNlIGlmIChyZXMgPT0gLTEpIHsKCQkJCSAgICByZXR1cm4gKC0xKTsKCQkJCX0KCQkJICAgIH0KCQkJICAgIGlmIChyZXMgPT0gMSkgewoJCQkJLyoKCQkJCSogTWF0Y2ggaW4gZHVwbGljYXRlcyBmb3VuZC4KCQkJCSovCgkJCQl4bWxDaGFyICpzdHIgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgkJCQl4bWxTY2hlbWFLZXlyZWZFcnIodmN0eHQsCgkJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0lEQywgcmVmTm9kZSwKCQkJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgbWF0Y2hlci0+YWlkYy0+ZGVmLAoJCQkJICAgICJNb3JlIHRoYW4gb25lIG1hdGNoIGZvdW5kIGZvciAiCgkJCQkgICAgImtleS1zZXF1ZW5jZSAlcyBvZiBrZXlyZWYgJyVzJyIsCgkJCQkgICAgeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UodmN0eHQsICZzdHIsCgkJCQkJcmVmTm9kZS0+a2V5cywgbmJGaWVsZHMpLAoJCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCLAoJCQkJCW1hdGNoZXItPmFpZGMtPmRlZikpOwoJCQkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCQkJRlJFRV9BTkRfTlVMTChzdHJCKTsKCQkJCWJyZWFrOwoJCQkgICAgfQoJCQl9CgkJICAgIH0KCQl9CgkJCgkJaWYgKHJlcyA9PSAwKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICpzdHJCID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hS2V5cmVmRXJyKHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLCByZWZOb2RlLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgbWF0Y2hlci0+YWlkYy0+ZGVmLAoJCQkiTm8gbWF0Y2ggZm91bmQgZm9yIGtleS1zZXF1ZW5jZSAlcyBvZiBrZXlyZWYgJyVzJyIsCgkJCXhtbFNjaGVtYUZvcm1hdElEQ0tleVNlcXVlbmNlKHZjdHh0LCAmc3RyLAoJCQkgICAgcmVmTm9kZS0+a2V5cywgbmJGaWVsZHMpLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQiwgbWF0Y2hlci0+YWlkYy0+ZGVmKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCKTsKCQl9CgkgICAgfQoJfQoJbWF0Y2hlciA9IG1hdGNoZXItPm5leHQ7CiAgICB9CiAgICAvKiBUT0RPOiBSZXR1cm4gYW4gZXJyb3IgaWYgYW55IGVycm9yIGVuY291bnRlcmVkLiAqLwogICAgcmV0dXJuICgwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVhNTCBSZWFkZXIgdmFsaWRhdGlvbiBjb2RlICAgICAgICAgICAgICAgICAgICAgICoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHhtbFNjaGVtYUF0dHJJbmZvUHRyCnhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKICAgIC8qCiAgICAqIEdyb3cvY3JlYXRlIGxpc3Qgb2YgYXR0cmlidXRlIGluZm9zLgogICAgKi8KICAgIGlmICh2Y3R4dC0+YXR0ckluZm9zID09IE5VTEwpIHsKCXZjdHh0LT5hdHRySW5mb3MgPSAoeG1sU2NoZW1hQXR0ckluZm9QdHIgKikKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvUHRyKSk7Cgl2Y3R4dC0+c2l6ZUF0dHJJbmZvcyA9IDE7CglpZiAodmN0eHQtPmF0dHJJbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyBhdHRyaWJ1dGUgaW5mbyBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVBdHRySW5mb3MgPD0gdmN0eHQtPm5iQXR0ckluZm9zKSB7Cgl2Y3R4dC0+c2l6ZUF0dHJJbmZvcysrOwoJdmN0eHQtPmF0dHJJbmZvcyA9ICh4bWxTY2hlbWFBdHRySW5mb1B0ciAqKQoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmF0dHJJbmZvcywKCQl2Y3R4dC0+c2l6ZUF0dHJJbmZvcyAqIHNpemVvZih4bWxTY2hlbWFBdHRySW5mb1B0cikpOwoJaWYgKHZjdHh0LT5hdHRySW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgYXR0cmlidXRlIGluZm8gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW3ZjdHh0LT5uYkF0dHJJbmZvcysrXTsKCWlmIChpYXR0ci0+bG9jYWxOYW1lICE9IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvIiwKCQkiYXR0ciBpbmZvIG5vdCBjbGVhcmVkIik7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCWlhdHRyLT5ub2RlVHlwZSA9IFhNTF9BVFRSSUJVVEVfTk9ERTsKCXJldHVybiAoaWF0dHIpOwogICAgfQogICAgLyoKICAgICogQ3JlYXRlIGFuIGF0dHJpYnV0ZSBpbmZvLgogICAgKi8KICAgIGlhdHRyID0gKHhtbFNjaGVtYUF0dHJJbmZvUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRySW5mbykpOwogICAgaWYgKGlhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsICJjcmVhdGluZyBuZXcgYXR0cmlidXRlIGluZm8iLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQoaWF0dHIsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRySW5mbykpOwogICAgaWF0dHItPm5vZGVUeXBlID0gWE1MX0FUVFJJQlVURV9OT0RFOwogICAgdmN0eHQtPmF0dHJJbmZvc1t2Y3R4dC0+bmJBdHRySW5mb3MrK10gPSBpYXR0cjsKCiAgICByZXR1cm4gKGlhdHRyKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sTm9kZVB0ciBhdHRyTm9kZSwKCQkJaW50IG5vZGVMaW5lLAoJCQljb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsCgkJCWNvbnN0IHhtbENoYXIgKm5zTmFtZSwJCQkKCQkJaW50IG93bmVkTmFtZXMsCgkJCXhtbENoYXIgKnZhbHVlLAoJCQlpbnQgb3duZWRWYWx1ZSkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFQdXNoQXR0cmlidXRlIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKCkiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgYXR0ci0+bm9kZSA9IGF0dHJOb2RlOwogICAgYXR0ci0+bm9kZUxpbmUgPSBub2RlTGluZTsKICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOwogICAgYXR0ci0+bG9jYWxOYW1lID0gbG9jYWxOYW1lOwogICAgYXR0ci0+bnNOYW1lID0gbnNOYW1lOwogICAgaWYgKG93bmVkTmFtZXMpCglhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTOwogICAgLyoKICAgICogRXZhbHVhdGUgaWYgaXQncyBhbiBYU0kgYXR0cmlidXRlLgogICAgKi8KICAgIGlmIChuc05hbWUgIT0gTlVMTCkgewoJaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgIm5pbCIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX05JTDsJCQoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobG9jYWxOYW1lLCBCQURfQ0FTVCAidHlwZSIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1RZUEU7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1NDSEVNQV9MT0M7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTk9fTlNfU0NIRU1BX0xPQzsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sTmFtZXNwYWNlTnMpKSB7CgkgICAgYXR0ci0+bWV0YVR5cGUgPSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TOwoJfQogICAgfQogICAgYXR0ci0+dmFsdWUgPSB2YWx1ZTsKICAgIGlmIChvd25lZFZhbHVlKQoJYXR0ci0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7CiAgICBpZiAoYXR0ci0+bWV0YVR5cGUgIT0gMCkKCWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NRVRBOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFyRWxlbUluZm86CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGllbGVtOiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhckVsZW1JbmZvKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICAgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW0pCnsKICAgIGllbGVtLT5oYXNLZXlyZWZzID0gMDsKICAgIGllbGVtLT5hcHBsaWVkWFBhdGggPSAwOwogICAgaWYgKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVMpIHsKCUZSRUVfQU5EX05VTEwoaWVsZW0tPmxvY2FsTmFtZSk7CglGUkVFX0FORF9OVUxMKGllbGVtLT5uc05hbWUpOwogICAgfSBlbHNlIHsKCWllbGVtLT5sb2NhbE5hbWUgPSBOVUxMOwoJaWVsZW0tPm5zTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCUZSRUVfQU5EX05VTEwoaWVsZW0tPnZhbHVlKTsKICAgIH0gZWxzZSB7CglpZWxlbS0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT52YWwgIT0gTlVMTCkgewoJLyoKCSogUFNWSSBUT0RPOiBCZSBjYXJlZnVsIG5vdCB0byBmcmVlIGl0IHdoZW4gdGhlIHZhbHVlIGlzCgkqIGV4cG9zZWQgdmlhIFBTVkkuCgkqLwoJeG1sU2NoZW1hRnJlZVZhbHVlKGllbGVtLT52YWwpOwoJaWVsZW0tPnZhbCA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPmlkY01hdGNoZXJzICE9IE5VTEwpIHsKCS8qCgkqIFJFVklTSVQgT1BUSU1JWkUgVE9ETzogVXNlIGEgcG9vbCBvZiBJREMgbWF0Y2hlcnMuCgkqICAgRG9lcyBpdCB3b3JrPwoJKi8KCXhtbFNjaGVtYUlEQ1JlbGVhc2VNYXRjaGVyTGlzdCh2Y3R4dCwgaWVsZW0tPmlkY01hdGNoZXJzKTsKI2lmIDAKCXhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdChpZWxlbS0+aWRjTWF0Y2hlcnMpOwojZW5kaWYKCWllbGVtLT5pZGNNYXRjaGVycyA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPmlkY1RhYmxlICE9IE5VTEwpIHsKCS8qCgkqIE9QVElNSVpFIFRPRE86IFVzZSBhIHBvb2wgb2YgSURDIHRhYmxlcz8/LgoJKi8KCXhtbFNjaGVtYUlEQ0ZyZWVJRENUYWJsZShpZWxlbS0+aWRjVGFibGUpOwoJaWVsZW0tPmlkY1RhYmxlID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+cmVnZXhDdHh0ICE9IE5VTEwpIHsKCXhtbFJlZ0ZyZWVFeGVjQ3R4dChpZWxlbS0+cmVnZXhDdHh0KTsKCWllbGVtLT5yZWdleEN0eHQgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5uc0JpbmRpbmdzICE9IE5VTEwpIHsKCXhtbEZyZWUoKHhtbENoYXIgKiopaWVsZW0tPm5zQmluZGluZ3MpOwoJaWVsZW0tPm5zQmluZGluZ3MgPSBOVUxMOwoJaWVsZW0tPm5iTnNCaW5kaW5ncyA9IDA7CglpZWxlbS0+c2l6ZU5zQmluZGluZ3MgPSAwOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbzoKICogQHZjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDcmVhdGVzL3JldXNlcyBhbmQgaW5pdGlhbGl6ZXMgdGhlIGVsZW1lbnQgaW5mbyBpdGVtIGZvcgogKiB0aGUgY3VycmVjdCB0cmVlIGRlcHRoLgogKgogKiBSZXR1cm5zIHRoZSBlbGVtZW50IGluZm8gaXRlbSBvciBOVUxMIG9uIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm9kZUluZm9QdHIKeG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGluZm8gPSBOVUxMOwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPiB2Y3R4dC0+c2l6ZUVsZW1JbmZvcykgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyIsCgkgICAgImluY29uc2lzdGVudCBkZXB0aCBlbmNvdW50ZXJlZCIpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+ZWxlbUluZm9zID09IE5VTEwpIHsKCXZjdHh0LT5lbGVtSW5mb3MgPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIgKikKCSAgICB4bWxNYWxsb2MoMTAgKiBzaXplb2YoeG1sU2NoZW1hTm9kZUluZm9QdHIpKTsKCWlmICh2Y3R4dC0+ZWxlbUluZm9zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIHRoZSBlbGVtZW50IGluZm8gYXJyYXkiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbWVtc2V0KHZjdHh0LT5lbGVtSW5mb3MsIDAsIDEwICogc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7Cgl2Y3R4dC0+c2l6ZUVsZW1JbmZvcyA9IDEwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUVsZW1JbmZvcyA8PSB2Y3R4dC0+ZGVwdGgpIHsKCWludCBpID0gdmN0eHQtPnNpemVFbGVtSW5mb3M7CgoJdmN0eHQtPnNpemVFbGVtSW5mb3MgKj0gMjsKCXZjdHh0LT5lbGVtSW5mb3MgPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIgKikKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5lbGVtSW5mb3MsIHZjdHh0LT5zaXplRWxlbUluZm9zICoKCSAgICBzaXplb2YoeG1sU2NoZW1hTm9kZUluZm9QdHIpKTsKCWlmICh2Y3R4dC0+ZWxlbUluZm9zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBlbGVtZW50IGluZm8gYXJyYXkiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJLyoKCSogV2UgbmVlZCB0aGUgbmV3IG1lbW9yeSB0byBiZSBOVUxMZWQuCgkqIFRPRE86IFVzZSBtZW1zZXQgaW5zdGVhZD8KCSovCglmb3IgKDsgaSA8IHZjdHh0LT5zaXplRWxlbUluZm9zOyBpKyspCgkgICAgdmN0eHQtPmVsZW1JbmZvc1tpXSA9IE5VTEw7CiAgICB9IGVsc2UKCWluZm8gPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CgogICAgaWYgKGluZm8gPT0gTlVMTCkgewoJaW5mbyA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0cikKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CglpZiAoaW5mbyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyBhbiBlbGVtZW50IGluZm8iLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdID0gaW5mbzsKICAgIH0gZWxzZSB7CglpZiAoaW5mby0+bG9jYWxOYW1lICE9IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvIiwKCQkiZWxlbSBpbmZvIGhhcyBub3QgYmVlbiBjbGVhcmVkIik7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KICAgIG1lbXNldChpbmZvLCAwLCBzaXplb2YoeG1sU2NoZW1hTm9kZUluZm8pKTsKICAgIGluZm8tPm5vZGVUeXBlID0gWE1MX0VMRU1FTlRfTk9ERTsKICAgIGluZm8tPmRlcHRoID0gdmN0eHQtPmRlcHRoOwoKICAgIHJldHVybiAoaW5mbyk7Cn0KCiNkZWZpbmUgQUNUSVZBVEVfQVRUUklCVVRFKGl0ZW0pIHZjdHh0LT5pbm9kZSA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgaXRlbTsKI2RlZmluZSBBQ1RJVkFURV9FTEVNIHZjdHh0LT5pbm9kZSA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKI2RlZmluZSBBQ1RJVkFURV9QQVJFTlRfRUxFTSB2Y3R4dC0+aW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aCAtMV07CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJeG1sTm9kZVB0ciBub2RlLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCXhtbFNjaGVtYVZhbFR5cGUgdmFsVHlwZSwKCQkJY29uc3QgeG1sQ2hhciAqIHZhbHVlLAoJCQl4bWxTY2hlbWFWYWxQdHIgdmFsLAoJCQl1bnNpZ25lZCBsb25nIGxlbmd0aCwKCQkJaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQsIGVycm9yID0gMDsKCiAgICB4bWxTY2hlbWFUeXBlUHRyIHRtcFR5cGU7CiAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rOwogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB1bnNpZ25lZCBsb25nIGxlbiA9IDA7CiAgICB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlIHdzOwoKICAgIC8qCiAgICAqIEluIExpYnhtbDIsIGRlcml2ZWQgYnVpbHQtaW4gdHlwZXMgaGF2ZSBjdXJyZW50bHkgbm8gZXhwbGljaXQgZmFjZXRzLgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCXJldHVybiAoMCk7CgogICAgLyoKICAgICogTk9URTogRG8gbm90IGp1bXAgYXdheSwgaWYgdGhlIGZhY2V0U2V0IG9mIHRoZSBnaXZlbiB0eXBlIGlzCiAgICAqIGVtcHR5OiB1bnRpbCBub3csICJwYXR0ZXJuIiBhbmQgImVudW1lcmF0aW9uIiBmYWNldHMgb2YgdGhlCiAgICAqICpiYXNlIHR5cGVzKiBuZWVkIHRvIGJlIGNoZWNrZWQgYXMgd2VsbC4KICAgICovCiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgPT0gTlVMTCkKCWdvdG8gcGF0dGVybl9hbmRfZW51bTsKCiAgICBpZiAoISBXWFNfSVNfQVRPTUlDKHR5cGUpKSB7CglpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgkgICAgZ290byBXWFNfSVNfTElTVDsKCWVsc2UKCSAgICBnb3RvIHBhdHRlcm5fYW5kX2VudW07CiAgICB9CiAgICAvKgogICAgKiBXaGl0ZXNwYWNlIGhhbmRsaW5nIGlzIG9ubHkgb2YgaW1wb3J0YW5jZSBmb3Igc3RyaW5nLWJhc2VkCiAgICAqIHR5cGVzLgogICAgKi8KICAgIHRtcFR5cGUgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5cGUpOwogICAgaWYgKCh0bXBUeXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHx8CglXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKHRtcFR5cGUpKSB7Cgl3cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwogICAgfSBlbHNlCgl3cyA9IFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRTsKICAgIC8qCiAgICAqIElmIHRoZSB2YWx1ZSB3YXMgbm90IGNvbXB1dGVkIChmb3Igc3RyaW5nIG9yCiAgICAqIGFueVNpbXBsZVR5cGUgYmFzZWQgdHlwZXMpLCB0aGVuIHVzZSB0aGUgcHJvdmlkZWQKICAgICogdHlwZS4KICAgICovCiAgICBpZiAodmFsID09IE5VTEwpCgl2YWxUeXBlID0gdmFsVHlwZTsKICAgIGVsc2UKCXZhbFR5cGUgPSB4bWxTY2hlbWFHZXRWYWxUeXBlKHZhbCk7CiAgICAKICAgIHJldCA9IDA7CiAgICBmb3IgKGZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJLyoKCSogU2tpcCB0aGUgcGF0dGVybiAid2hpdGVTcGFjZSI6IGl0IGlzIHVzZWQgdG8KCSogZm9ybWF0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBiZWZvcmVoYW5kLgoJKi8KCXN3aXRjaCAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQljb250aW51ZTsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxlbmd0aEZhY2V0V2h0c3AoZmFjZXRMaW5rLT5mYWNldCwKCQkgICAgdmFsVHlwZSwgdmFsdWUsIHZhbCwgJmxlbiwgd3MpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldFdodHNwKGZhY2V0TGluay0+ZmFjZXQsIHdzLAoJCSAgICB2YWxUeXBlLCB2YWx1ZSwgdmFsLCB3cyk7CgkJYnJlYWs7Cgl9CglpZiAocmV0IDwgMCkgewoJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkidmFsaWRhdGluZyBhZ2FpbnN0IGEgYXRvbWljIHR5cGUgZmFjZXQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYUZhY2V0RXJyKGFjdHh0LCByZXQsIG5vZGUsCgkJdmFsdWUsIGxlbiwgdHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgZWxzZQoJCXJldHVybiAocmV0KTsKCSAgICBpZiAoZXJyb3IgPT0gMCkKCQllcnJvciA9IHJldDsKCX0KCXJldCA9IDA7CiAgICB9CgpXWFNfSVNfTElTVDoKICAgIGlmICghIFdYU19JU19MSVNUKHR5cGUpKQoJZ290byBwYXR0ZXJuX2FuZF9lbnVtOwogICAgLyoKICAgICogImxlbmd0aCIsICJtaW5MZW5ndGgiIGFuZCAibWF4TGVuZ3RoIiBvZiBsaXN0IHR5cGVzLgogICAgKi8KICAgIHJldCA9IDA7CiAgICBmb3IgKGZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCglzd2l0Y2ggKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoJCSAgICAKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxpc3RTaW1wbGVUeXBlRmFjZXQoZmFjZXRMaW5rLT5mYWNldCwKCQkgICAgdmFsdWUsIGxlbmd0aCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQljb250aW51ZTsKCX0KCWlmIChyZXQgPCAwKSB7CgkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVGYWNldHMiLAoJCSJ2YWxpZGF0aW5nIGFnYWluc3QgYSBsaXN0IHR5cGUgZmFjZXQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewoJICAgIGlmIChmaXJlRXJyb3JzKQkJCgkJeG1sU2NoZW1hRmFjZXRFcnIoYWN0eHQsIHJldCwgbm9kZSwKCQl2YWx1ZSwgbGVuZ3RoLCB0eXBlLCBmYWNldExpbmstPmZhY2V0LCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICBlbHNlCgkJcmV0dXJuIChyZXQpOwoJICAgIGlmIChlcnJvciA9PSAwKQoJCWVycm9yID0gcmV0OwoJfQoJcmV0ID0gMDsKICAgIH0KCnBhdHRlcm5fYW5kX2VudW06CiAgICBpZiAoZXJyb3IgPj0gMCkgewoJaW50IGZvdW5kID0gMDsKCS8qCgkqIFByb2Nlc3MgZW51bWVyYXRpb25zLiBGYWNldCB2YWx1ZXMgYXJlIGluIHRoZSB2YWx1ZSBzcGFjZQoJKiBvZiB0aGUgZGVmaW5pbmcgdHlwZSdzIGJhc2UgdHlwZS4gVGhpcyBzZWVtcyB0byBiZSBhIGJ1ZyBpbiB0aGUKCSogWE1MIFNjaGVtYSAxLjAgc3BlYy4gVXNlIHRoZSB3aGl0ZXNwYWNlIHR5cGUgb2YgdGhlIGJhc2UgdHlwZS4KCSogT25seSB0aGUgZmlyc3Qgc2V0IG9mIGVudW1lcmF0aW9ucyBpbiB0aGUgYW5jZXN0b3Itb3Itc2VsZiBheGlzCgkqIGlzIHVzZWQgZm9yIHZhbGlkYXRpb24uCgkqLwoJcmV0ID0gMDsKCXRtcFR5cGUgPSB0eXBlOwoJZG8gewoJICAgIGZvciAoZmFjZXQgPSB0bXBUeXBlLT5mYWNldHM7IGZhY2V0ICE9IE5VTEw7IGZhY2V0ID0gZmFjZXQtPm5leHQpIHsKCQlpZiAoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikKCQkgICAgY29udGludWU7CgkJZm91bmQgPSAxOwoJCXJldCA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGZhY2V0LT52YWwsIHZhbCk7CgkJaWYgKHJldCA9PSAxKQoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkJInZhbGlkYXRpbmcgYWdhaW5zdCBhbiBlbnVtZXJhdGlvbiBmYWNldCIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIGlmIChyZXQgIT0gMCkKCQlicmVhazsKCSAgICAvKgoJICAgICogQnJlYWsgb24gdGhlIGZpcnN0IHNldCBvZiBlbnVtZXJhdGlvbnMuIEFueSBhZGRpdGlvbmFsCgkgICAgKiAgZW51bWVyYXRpb25zIHdoaWNoIG1pZ2h0IGJlIGV4aXN0ZW50IG9uIHRoZSBhbmNlc3RvcnMKCSAgICAqICBvZiB0aGUgY3VycmVudCB0eXBlIGFyZSByZXN0cmljdGVkIGJ5IHRoaXMgc2V0OyB0aHVzCgkgICAgKiAgKm11c3QqICpub3QqIGJlIHRha2VuIGludG8gYWNjb3VudC4KCSAgICAqLwoJICAgIGlmIChmb3VuZCkKCQlicmVhazsKCSAgICB0bXBUeXBlID0gdG1wVHlwZS0+YmFzZVR5cGU7Cgl9IHdoaWxlICgodG1wVHlwZSAhPSBOVUxMKSAmJgoJICAgICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJaWYgKGZvdW5kICYmIChyZXQgPT0gMCkpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQ7CgkgICAgaWYgKGZpcmVFcnJvcnMpIHsKCQl4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCSAgICB2YWx1ZSwgMCwgdHlwZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuIChyZXQpOwoJICAgIGlmIChlcnJvciA9PSAwKQoJCWVycm9yID0gcmV0OwoJfQogICAgfQoKICAgIGlmIChlcnJvciA+PSAwKSB7CglpbnQgZm91bmQ7CgkvKgoJKiBQcm9jZXNzIHBhdHRlcnMuIFBhdHRlcm4gZmFjZXRzIGFyZSBPUmVkIGF0IHR5cGUgbGV2ZWwKCSogYW5kIEFORGVkIGlmIGRlcml2ZWQuIFdhbGsgdGhlIGJhc2UgdHlwZSBheGlzLgoJKi8KCXRtcFR5cGUgPSB0eXBlOwoJZmFjZXQgPSBOVUxMOwoJZG8gewoJICAgIGZvdW5kID0gMDsKCSAgICBmb3IgKGZhY2V0TGluayA9IHRtcFR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCQlmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCQlpZiAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pCgkJICAgIGNvbnRpbnVlOwoJCWZvdW5kID0gMTsKCQkvKiAKCQkqIE5PVEUgdGhhdCBmb3IgcGF0dGVybnMsIEB2YWx1ZSBuZWVkcyB0byBiZSB0aGUKCQkqIG5vcm1hbGl6ZWQgdmF1bGUuCgkJKi8KCQlyZXQgPSB4bWxSZWdleHBFeGVjKGZhY2V0TGluay0+ZmFjZXQtPnJlZ2V4cCwgdmFsdWUpOwoJCWlmIChyZXQgPT0gMSkKCQkgICAgYnJlYWs7CgkJZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJCSJ2YWxpZGF0aW5nIGFnYWluc3QgYSBwYXR0ZXJuIGZhY2V0Iik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0gZWxzZSB7CgkJICAgIC8qIAoJCSAgICAqIFNhdmUgdGhlIGxhc3Qgbm9uLXZhbGlkYXRpbmcgZmFjZXQuCgkJICAgICovCgkJICAgIGZhY2V0ID0gZmFjZXRMaW5rLT5mYWNldDsKCQl9CgkgICAgfQoJICAgIGlmIChmb3VuZCAmJiAocmV0ICE9IDEpKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1BBVFRFUk5fVkFMSUQ7CgkJaWYgKGZpcmVFcnJvcnMpIHsKCQkgICAgeG1sU2NoZW1hRmFjZXRFcnIoYWN0eHQsIHJldCwgbm9kZSwKCQkJdmFsdWUsIDAsIHR5cGUsIGZhY2V0LCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9IGVsc2UKCQkgICAgcmV0dXJuIChyZXQpOwoJCWlmIChlcnJvciA9PSAwKQoJCSAgICBlcnJvciA9IHJldDsKCQlicmVhazsKCSAgICB9CgkgICAgdG1wVHlwZSA9IHRtcFR5cGUtPmJhc2VUeXBlOwoJfSB3aGlsZSAoKHRtcFR5cGUgIT0gTlVMTCkgJiYgKHRtcFR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSk7CiAgICB9CgogICAgcmV0dXJuIChlcnJvcik7Cn0KIApzdGF0aWMgeG1sQ2hhciAqCnhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUpCnsKICAgIHN3aXRjaCAoeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSkpIHsJCgljYXNlIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRToKCSAgICByZXR1cm4gKHhtbFNjaGVtYUNvbGxhcHNlU3RyaW5nKHZhbHVlKSk7CgljYXNlIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFOgoJICAgIHJldHVybiAoeG1sU2NoZW1hV2hpdGVTcGFjZVJlcGxhY2UodmFsdWUpKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVFOYW1lKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsLAoJCSAgICAgICBpbnQgdmFsTmVlZGVkKQp7CiAgICBpbnQgcmV0OwogICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lOwogICAgeG1sQ2hhciAqbG9jYWwsICpwcmVmaXggPSBOVUxMOwogICAgCiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKHJldCA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlUU5hbWUiLAoJCSJjYWxsaW5nIHhtbFZhbGlkYXRlUU5hbWUoKSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJcmV0dXJuKCBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEpOwogICAgfQogICAgLyoKICAgICogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCBhbHdheXMgcmV0dXJuIGEgZHVwbGljYXRlZAogICAgKiBzdHJpbmdzLgogICAgKi8KICAgIGxvY2FsID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwogICAgaWYgKGxvY2FsID09IE5VTEwpCglsb2NhbCA9IHhtbFN0cmR1cCh2YWx1ZSk7CiAgICAvKgogICAgKiBPUFRJTUlaRSBUT0RPOiBVc2UgZmxhZ3MgZm9yOgogICAgKiAgLSBpcyB0aGVyZSBhbnkgbmFtZXNwYWNlIGJpbmRpbmc/CiAgICAqICAtIGlzIHRoZXJlIGEgZGVmYXVsdCBuYW1lc3BhY2U/CiAgICAqLwogICAgbnNOYW1lID0geG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHZjdHh0LCBwcmVmaXgpOwogICAgCiAgICBpZiAocHJlZml4ICE9IE5VTEwpIHsKCXhtbEZyZWUocHJlZml4KTsKCS8qCgkqIEEgbmFtZXNwYWNlIG11c3QgYmUgZm91bmQgaWYgdGhlIHByZWZpeCBpcwoJKiBOT1QgTlVMTC4KCSovCglpZiAobnNOYW1lID09IE5VTEwpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsIHJldCwgTlVMTCwKCQlXWFNfQkFTSUNfQ0FTVCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyAiCgkJImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluICIKCQkic2NvcGUiLCB2YWx1ZSwgTlVMTCk7CgkgICAgaWYgKGxvY2FsICE9IE5VTEwpCgkJeG1sRnJlZShsb2NhbCk7CgkgICAgcmV0dXJuIChyZXQpOwoJfQogICAgfQogICAgaWYgKHZhbE5lZWRlZCAmJiB2YWwpIHsKCWlmIChuc05hbWUgIT0gTlVMTCkKCSAgICAqdmFsID0geG1sU2NoZW1hTmV3UU5hbWVWYWx1ZSgKCQlCQURfQ0FTVCB4bWxTdHJkdXAobnNOYW1lKSwgQkFEX0NBU1QgbG9jYWwpOwoJZWxzZQoJICAgICp2YWwgPSB4bWxTY2hlbWFOZXdRTmFtZVZhbHVlKE5VTEwsCgkJQkFEX0NBU1QgbG9jYWwpOwogICAgfSBlbHNlCgl4bWxGcmVlKGxvY2FsKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qCiogY3ZjLXNpbXBsZS10eXBlCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCSAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICB4bWxTY2hlbWFWYWxQdHIgKnJldFZhbCwKCQkJICAgICBpbnQgZmlyZUVycm9ycywKCQkJICAgICBpbnQgbm9ybWFsaXplLAoJCQkgICAgIGludCBpc05vcm1hbGl6ZWQpCnsKICAgIGludCByZXQgPSAwLCB2YWxOZWVkZWQgPSAocmV0VmFsKSA/IDEgOiAwOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbCA9IE5VTEw7CiAgICAvKiB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlIHdzOyAqLwogICAgeG1sQ2hhciAqbm9ybVZhbHVlID0gTlVMTDsKCiNkZWZpbmUgTk9STUFMSVpFKGF0eXBlKSBcCiAgICBpZiAoKCEgaXNOb3JtYWxpemVkKSAmJiBcCiAgICAobm9ybWFsaXplIHx8ICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEKSkpIHsgXAoJbm9ybVZhbHVlID0geG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoYXR5cGUsIHZhbHVlKTsgXAoJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSBcCgkgICAgdmFsdWUgPSBub3JtVmFsdWU7IFwKCWlzTm9ybWFsaXplZCA9IDE7IFwKICAgIH0KICAgIAogICAgaWYgKChyZXRWYWwgIT0gTlVMTCkgJiYgKCpyZXRWYWwgIT0gTlVMTCkpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSgqcmV0VmFsKTsKCSpyZXRWYWwgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogMy4xNC40IFNpbXBsZSBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwogICAgKiBWYWxpZGF0aW9uIFJ1bGU6IFN0cmluZyBWYWxpZAogICAgKi8KICAgIC8qCiAgICAqIDEgSXQgaXMgc2NoZW1hLXZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZAogICAgKiBieSBEYXRhdHlwZSBWYWxpZCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCiAgICAqLwogICAgLyoKICAgICogMi4xIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUWSBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVFkgZ2l2ZW4KICAgICogdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLCB0aGVuCiAgICAqIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZCBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4yIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUSUVTIG9yIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEVOVElUSUVTCiAgICAqIGdpdmVuIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwKICAgICogdGhlbiBldmVyeSB3aGl0ZXNwYWNlLWRlbGltaXRlZCBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkCiAgICAqIGVudGl0eSBuYW1lty4KICAgICovCiAgICAvKgogICAgKiAyLjMgb3RoZXJ3aXNlIG5vIGZ1cnRoZXIgY29uZGl0aW9uIGFwcGxpZXMuCiAgICAqLwogICAgaWYgKCghIHZhbE5lZWRlZCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUUpKQoJdmFsTmVlZGVkID0gMTsKICAgIGlmICh2YWx1ZSA9PSBOVUxMKQoJdmFsdWUgPSBCQURfQ0FTVCAiIjsKICAgIGlmIChXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKHR5cGUpIHx8IFdYU19JU19BVE9NSUModHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgYmlUeXBlOyAvKiBUaGUgYnVpbHQtaW4gdHlwZS4gKi8KCS8qCgkqIFNQRUMgKDEuMi4xKSAiaWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcKCSogYSBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSIKCSovCgkvKgoJKiBXaGl0ZXNwYWNlLW5vcm1hbGl6ZS4KCSovCglOT1JNQUxJWkUodHlwZSk7CglpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBidWlsdC1pbiB0eXBlLgoJICAgICovCgkgICAgYmlUeXBlID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgd2hpbGUgKChiaVR5cGUgIT0gTlVMTCkgJiYKCQkoYmlUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpCgkJYmlUeXBlID0gYmlUeXBlLT5iYXNlVHlwZTsKCgkgICAgaWYgKGJpVHlwZSA9PSBOVUxMKSB7CgkJQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJICAgICJjb3VsZCBub3QgZ2V0IHRoZSBidWlsdC1pbiB0eXBlIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UKCSAgICBiaVR5cGUgPSB0eXBlOwoJLyoKCSogTk9UQVRJT05zIG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGhlcmUsIHNpbmNlIHRoZXkgbmVlZAoJKiB0byBsb29rdXAgaW4gdGhlIGhhc2h0YWJsZSBvZiBOT1RBVElPTiBkZWNsYXJhdGlvbnMgb2YgdGhlIHNjaGVtYS4KCSovCglpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgewkgICAgCgkgICAgc3dpdGNoIChiaVR5cGUtPmJ1aWx0SW5UeXBlKSB7CQkKCQljYXNlIFhNTF9TQ0hFTUFTX05PVEFUSU9OOgkJICAgIAoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uKAoJCQkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCwKCQkJKCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0KS0+c2NoZW1hLAoJCQlOVUxMLCB2YWx1ZSwgJnZhbCwgdmFsTmVlZGVkKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BU19RTkFNRToKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVRTmFtZSgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCwKCQkJdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIC8qIHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSk7ICovCgkJICAgIGlmICh2YWxOZWVkZWQpCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCAmdmFsLCBOVUxMKTsKCQkgICAgZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgTlVMTCwgTlVMTCk7CgkJICAgIGJyZWFrOwoJICAgIH0KCX0gZWxzZSBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikgewkgICAgCgkgICAgc3dpdGNoIChiaVR5cGUtPmJ1aWx0SW5UeXBlKSB7CQkgICAgCgkJY2FzZSBYTUxfU0NIRU1BU19OT1RBVElPTjoKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbihOVUxMLAoJCQkoKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIGFjdHh0KS0+c2NoZW1hLCBub2RlLAoJCQl2YWx1ZSwgJnZhbCwgdmFsTmVlZGVkKTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgLyogd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKTsgKi8KCQkgICAgaWYgKHZhbE5lZWRlZCkKCQkJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGVOb05vcm0oYmlUeXBlLAoJCQkgICAgdmFsdWUsICZ2YWwsIG5vZGUpOwoJCSAgICBlbHNlCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCBOVUxMLCBub2RlKTsKCQkgICAgYnJlYWs7CgkgICAgfQkgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIFZhbGlkYXRpb24gdmlhIGEgcHVibGljIEFQSSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LgoJICAgICovCgkgICAgVE9ETwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAidmFsaWRhdGluZyBhZ2FpbnN0IGEgYnVpbHQtaW4gdHlwZSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGlmIChXWFNfSVNfTElTVCh0eXBlKSkKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgZWxzZQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsJICAgIAoJfQoJaWYgKChyZXQgPT0gMCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTKSkgewoJICAgIC8qCgkgICAgKiBDaGVjayBmYWNldHMuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyhhY3R4dCwgbm9kZSwgdHlwZSwKCQkoeG1sU2NoZW1hVmFsVHlwZSkgYmlUeXBlLT5idWlsdEluVHlwZSwgdmFsdWUsIHZhbCwKCQkwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgZmFjZXRzIG9mIGF0b21pYyBzaW1wbGUgdHlwZSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlpZiAoV1hTX0lTX0xJU1QodHlwZSkpIAoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJZWxzZQoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CQkKCSAgICB9Cgl9CglpZiAoZmlyZUVycm9ycyAmJiAocmV0ID4gMCkpCgkgICAgeG1sU2NoZW1hU2ltcGxlVHlwZUVycihhY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSwgMSk7CiAgICB9IGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGUpKSB7CgoJeG1sU2NoZW1hVHlwZVB0ciBpdGVtVHlwZTsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcFZhbHVlID0gTlVMTDsKCXVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCXhtbFNjaGVtYVZhbFB0ciBwcmV2VmFsID0gTlVMTCwgY3VyVmFsID0gTlVMTDsKCS8qIDEuMi4yIGlmIHt2YXJpZXR5fSBpcyC3bGlzdLcgdGhlbiB0aGUgc3RyaW5nIG11c3QgYmUgYSBzZXF1ZW5jZQoJKiBvZiB3aGl0ZSBzcGFjZSBzZXBhcmF0ZWQgdG9rZW5zLCBlYWNoIG9mIHdoaWNoILdtYXRjaLdlcyBhIGxpdGVyYWwKCSogaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7aXRlbSB0eXBlIGRlZmluaXRpb259CgkqLwoJLyoKCSogTm90ZSB0aGF0IFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEIHdpbGwgYmUgc2V0IGlmCgkqIHRoZSBsaXN0IHR5cGUgaGFzIGFuIGVudW0gb3IgcGF0dGVybiBmYWNldC4KCSovCglOT1JNQUxJWkUodHlwZSk7CgkvKgoJKiBWQUwgVE9ETzogT3B0aW1pemUgdmFsaWRhdGlvbiBvZiBlbXB0eSB2YWx1ZXMuCgkqIFZBTCBUT0RPOiBXZSBkbyBub3QgaGF2ZSBjb21wdXRlZCB2YWx1ZXMgZm9yIGxpc3RzLgoJKi8KCWl0ZW1UeXBlID0gV1hTX0xJU1RfSVRFTVRZUEUodHlwZSk7CQoJY3VyID0gdmFsdWU7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICB0bXBWYWx1ZSA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIGxlbisrOwoKCSAgICBpZiAodmFsTmVlZGVkKQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoYWN0eHQsIG5vZGUsIGl0ZW1UeXBlLAoJCSAgICB0bXBWYWx1ZSwgJmN1clZhbCwgZmlyZUVycm9ycywgMCwgMSk7CgkgICAgZWxzZQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoYWN0eHQsIG5vZGUsIGl0ZW1UeXBlLAoJCSAgICB0bXBWYWx1ZSwgTlVMTCwgZmlyZUVycm9ycywgMCwgMSk7CgkgICAgRlJFRV9BTkRfTlVMTCh0bXBWYWx1ZSk7CgkgICAgaWYgKGN1clZhbCAhPSBOVUxMKSB7CgkJLyoKCQkqIEFkZCB0byBsaXN0IG9mIGNvbXB1dGVkIHZhbHVlcy4KCQkqLwoJCWlmICh2YWwgPT0gTlVMTCkKCQkgICAgdmFsID0gY3VyVmFsOwoJCWVsc2UKCQkgICAgeG1sU2NoZW1hVmFsdWVBcHBlbmQocHJldlZhbCwgY3VyVmFsKTsKCQlwcmV2VmFsID0gY3VyVmFsOwoJCWN1clZhbCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCQkidmFsaWRhdGluZyBhbiBpdGVtIG9mIGxpc3Qgc2ltcGxlIHR5cGUiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCWJyZWFrOwoJICAgIH0JICAgIAoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CglGUkVFX0FORF9OVUxMKHRtcFZhbHVlKTsKCWlmICgocmV0ID09IDApICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUykpIHsKCSAgICAvKgoJICAgICogQXBwbHkgZmFjZXRzIChwYXR0ZXJuLCBlbnVtZXJhdGlvbikuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyhhY3R4dCwgbm9kZSwgdHlwZSwKCQlYTUxfU0NIRU1BU19VTktOT1dOLCB2YWx1ZSwgdmFsLAoJCWxlbiwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJCSJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBsaXN0IHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCSAgICB9Cgl9CglpZiAoZmlyZUVycm9ycyAmJiAocmV0ID4gMCkpIHsKCSAgICAvKiAKCSAgICAqIFJlcG9ydCB0aGUgbm9ybWFsaXplZCB2YWx1ZS4KCSAgICAqLwoJICAgIG5vcm1hbGl6ZSA9IDE7CgkgICAgTk9STUFMSVpFKHR5cGUpOwoJICAgIHhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoYWN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUsIDEpOwoJfQogICAgfSBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlckxpbms7CgkvKgoJKiBUT0RPOiBGb3IgYWxsIGRhdGF0eXBlcyC3ZGVyaXZlZLcgYnkgt3VuaW9utyAgd2hpdGVTcGFjZSBkb2VzCgkqIG5vdCBhcHBseSBkaXJlY3RseTsgaG93ZXZlciwgdGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utwoJKiB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZQoJKiC3bWVtYmVyVHlwZXO3IGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4KCSoKCSogVGhpcyBtZWFucyB0aGF0IHRoZSB2YWx1ZSBpcyBub3JtYWxpemVkIGJ5IHRoZSBmaXJzdCB2YWxpZGF0aW5nCgkqIG1lbWJlciB0eXBlLCB0aGVuIHRoZSBmYWNldHMgb2YgdGhlIHVuaW9uIHR5cGUgYXJlIGFwcGxpZWQuIFRoaXMKCSogbmVlZHMgY2hhbmdpbmcgb2YgdGhlIHZhbHVlIQoJKi8KCgkvKgoJKiAxLjIuMyBpZiB7dmFyaWV0eX0gaXMgt3VuaW9utyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IGEKCSogbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIGF0IGxlYXN0IG9uZSBtZW1iZXIgb2YKCSoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfQoJKi8KCW1lbWJlckxpbmsgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlKTsKCWlmIChtZW1iZXJMaW5rID09IE5VTEwpIHsKCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkidW5pb24gc2ltcGxlIHR5cGUgaGFzIG5vIG1lbWJlciB0eXBlcyIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CQoJLyoKCSogQWx3YXlzIG5vcm1hbGl6ZSB1bmlvbiB0eXBlIHZhbHVlcywgc2luY2Ugd2UgY3VycmVudGx5CgkqIGNhbm5vdCBzdG9yZSB0aGUgd2hpdGVzcGFjZSBpbmZvcm1hdGlvbiB3aXRoIHRoZSB2YWx1ZQoJKiBpdHNlbGY7IG90aGVyd2lzZSBhIGxhdGVyIHZhbHVlLWNvbXBhcmlzb24gd291bGQgYmUKCSogbm90IHBvc3NpYmxlLgoJKi8KCXdoaWxlIChtZW1iZXJMaW5rICE9IE5VTEwpIHsKCSAgICBpZiAodmFsTmVlZGVkKSAKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLAoJCSAgICBtZW1iZXJMaW5rLT50eXBlLCB2YWx1ZSwgJnZhbCwgMCwgMSwgMCk7CgkgICAgZWxzZQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoYWN0eHQsIG5vZGUsCgkJICAgIG1lbWJlckxpbmstPnR5cGUsIHZhbHVlLCBOVUxMLCAwLCAxLCAwKTsKCSAgICBpZiAocmV0IDw9IDApCgkJYnJlYWs7CgkgICAgbWVtYmVyTGluayA9IG1lbWJlckxpbmstPm5leHQ7Cgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAidmFsaWRhdGluZyBtZW1iZXJzIG9mIHVuaW9uIHNpbXBsZSB0eXBlIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJfQoJLyoKCSogQXBwbHkgZmFjZXRzIChwYXR0ZXJuLCBlbnVtZXJhdGlvbikuCgkqLwoJaWYgKChyZXQgPT0gMCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTKSkgewoJICAgIC8qCgkgICAgKiBUaGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkKCSAgICAqIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZSC3bWVtYmVyVHlwZXO3CgkgICAgKiBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuCgkgICAgKi8KCSAgICBOT1JNQUxJWkUobWVtYmVyTGluay0+dHlwZSk7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJWE1MX1NDSEVNQVNfVU5LTk9XTiwgdmFsdWUsIHZhbCwKCQkwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgZmFjZXRzIG9mIHVuaW9uIHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsJCQoJICAgIH0KCX0KCWlmIChmaXJlRXJyb3JzICYmIChyZXQgPiAwKSkKCSAgICB4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKGFjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlLCAxKTsKICAgIH0KCiAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKG5vcm1WYWx1ZSk7CiAgICBpZiAocmV0ID09IDApIHsKCWlmIChyZXRWYWwgIT0gTlVMTCkKCSAgICAqcmV0VmFsID0gdmFsOwoJZWxzZSBpZiAodmFsICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICB9IGVsc2UgaWYgKHZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZShub3JtVmFsdWUpOwogICAgaWYgKHZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWRXhwYW5kUU5hbWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqKm5zTmFtZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsTmFtZSkKewogICAgaW50IHJldCA9IDA7CgogICAgaWYgKChuc05hbWUgPT0gTlVMTCkgfHwgKGxvY2FsTmFtZSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgKm5zTmFtZSA9IE5VTEw7CiAgICAqbG9jYWxOYW1lID0gTlVMTDsKCiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gLTEpCglyZXR1cm4gKC0xKTsKICAgIGlmIChyZXQgPiAwKSB7Cgl4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLCBOVUxMLAoJICAgIHZhbHVlLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIDEpOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHsKCXhtbENoYXIgKmxvY2FsID0gTlVMTDsKCXhtbENoYXIgKnByZWZpeDsKCgkvKgoJKiBOT1RFOiB4bWxTcGxpdFFOYW1lMiB3aWxsIHJldHVybiBhIGR1cGxpY2F0ZWQKCSogc3RyaW5nLgoJKi8KCWxvY2FsID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwoJaWYgKGxvY2FsID09IE5VTEwpCgkgICAgKmxvY2FsTmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIHZhbHVlLCAtMSk7CgllbHNlIHsKCSAgICAqbG9jYWxOYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbG9jYWwsIC0xKTsKCSAgICB4bWxGcmVlKGxvY2FsKTsKCX0KCgkqbnNOYW1lID0geG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHZjdHh0LCBwcmVmaXgpOwoKCWlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIHhtbEZyZWUocHJlZml4KTsKCSAgICAvKgoJICAgICogQSBuYW1lc3BhY2UgbXVzdCBiZSBmb3VuZCBpZiB0aGUgcHJlZml4IGlzIE5PVCBOVUxMLgoJICAgICovCgkgICAgaWYgKCpuc05hbWUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsIE5VTEwsCgkJICAgIFdYU19CQVNJQ19DQVNUIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkgICAgIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyAiCgkJICAgICJjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiBzY29wZSIsCgkJICAgIHZhbHVlLCBOVUxMKTsKCQlyZXR1cm4gKDIpOwoJICAgIH0KCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQl4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0ciwKCQkJeG1sU2NoZW1hVHlwZVB0ciAqbG9jYWxUeXBlLAoJCQl4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6ICg0KQogICAgKiBBTkQKICAgICogU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEVsZW1lbnQpIChjdmMtYXNzZXNzLWVsdCkKICAgICogICAoMS4yLjEuMi4xKSAtICgxLjIuMS4yLjQpCiAgICAqIEhhbmRsZSAneHNpOnR5cGUnLgogICAgKi8KICAgIGlmIChsb2NhbFR5cGUgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgKmxvY2FsVHlwZSA9IE5VTEw7CiAgICBpZiAoaWF0dHIgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKm5zTmFtZSA9IE5VTEwsICpsb2NhbCA9IE5VTEw7CgkvKgoJKiBUT0RPOiBXZSBzaG91bGQgcmVwb3J0IGEgKndhcm5pbmcqIHRoYXQgdGhlIHR5cGUgd2FzIG92ZXJyaWRlbgoJKiBieSB0aGUgaW5zdGFuY2UuCgkqLwoJQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKTsKCS8qCgkqIChjdmMtZWx0KSAoMy4zLjQpIDogKDQuMSkKCSogKGN2Yy1hc3Nlc3MtZWx0KSAoMS4yLjEuMi4yKQoJKi8KCXJldCA9IHhtbFNjaGVtYVZFeHBhbmRRTmFtZSh2Y3R4dCwgaWF0dHItPnZhbHVlLAoJICAgICZuc05hbWUsICZsb2NhbCk7CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFRTmFtZUV4cGFuZCgpIHRvIHZhbGlkYXRlIHRoZSAiCgkJICAgICJhdHRyaWJ1dGUgJ3hzaTp0eXBlJyIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZXhpdDsKCX0KCS8qCgkqIChjdmMtZWx0KSAoMy4zLjQpIDogKDQuMikKCSogKGN2Yy1hc3Nlc3MtZWx0KSAoMS4yLjEuMi4zKQoJKi8KCSpsb2NhbFR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKHZjdHh0LT5zY2hlbWEsIGxvY2FsLCBuc05hbWUpOwoJaWYgKCpsb2NhbFR5cGUgPT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8yLCBOVUxMLAoJCVdYU19CQVNJQ19DQVNUIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkiVGhlIFFOYW1lIHZhbHVlICclcycgb2YgdGhlIHhzaTp0eXBlIGF0dHJpYnV0ZSBkb2VzIG5vdCAiCgkJInJlc29sdmUgdG8gYSB0eXBlIGRlZmluaXRpb24iLAoJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIG5zTmFtZSwgbG9jYWwpLCBOVUxMKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgcmV0ID0gdmN0eHQtPmVycjsKCSAgICBnb3RvIGV4aXQ7Cgl9CglpZiAoZWxlbURlY2wgIT0gTlVMTCkgewoJICAgIGludCBzZXQgPSAwOwoKCSAgICAvKgoJICAgICogU1BFQyBjdmMtZWx0ICgzLjMuNCkgOiAoNC4zKSAoVHlwZSBEZXJpdmF0aW9uIE9LKQoJICAgICogIlRoZSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utyBtdXN0IGJlIHZhbGlkbHkKCSAgICAqIGRlcml2ZWQgZnJvbSB0aGUge3R5cGUgZGVmaW5pdGlvbn0gZ2l2ZW4gdGhlIHVuaW9uIG9mCgkgICAgKiB0aGUge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYW5kIHRoZSB7dHlwZSBkZWZpbml0aW9ufSdzCgkgICAgKiB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSwgYXMgZGVmaW5lZCBpbgoJICAgICogVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAopzMuNC42KQoJICAgICogKGlmIGl0IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24pLAoJICAgICogb3IgZ2l2ZW4ge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYXMgZGVmaW5lZCBpbiBUeXBlCgkgICAgKiBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSAoaWYgaXQgaXMgYSBzaW1wbGUgdHlwZQoJICAgICogZGVmaW5pdGlvbikuIgoJICAgICoKCSAgICAqIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9OiB0aGUgImJsb2NrIiBvbiB0aGUgZWxlbWVudCBkZWNsLgoJICAgICoge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc306IHRoZSAiYmxvY2siIG9uIHRoZSB0eXBlIGRlZi4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBPUFRJTUlaRSBUT0RPOiBXZSBjb3VsZCBtYXAgdHlwZXMgYWxyZWFkeSBldmFsdWF0ZWQKCSAgICAqIHRvIGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIG90aGVyIHR5cGVzIHRvIGF2b2lkIGNoZWNraW5nCgkgICAgKiB0aGlzIG92ZXIgYW5kIG92ZXIgZm9yIHRoZSBzYW1lIHR5cGVzLgoJICAgICovCgkgICAgaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTikgfHwKCQkoZWxlbURlY2wtPnN1YnR5cGVzLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSkKCQlzZXQgfD0gU1VCU0VUX0VYVEVOU0lPTjsKCgkgICAgaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OKSB8fAoJCShlbGVtRGVjbC0+c3VidHlwZXMtPmZsYWdzICYKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikpCgkJc2V0IHw9IFNVQlNFVF9SRVNUUklDVElPTjsKCgkgICAgLyoKCSAgICAqIFJFTU9WRUQgYW5kIENIQU5HRUQgc2luY2UgdGhpcyBwcm9kdWNlZCBhIHBhcnNlciBjb250ZXh0CgkgICAgKiB3aGljaCBhZGRzIHRvIHRoZSBzdHJpbmcgZGljdCBvZiB0aGUgc2NoZW1hLiBTbyB0aGlzIHdvdWxkCgkgICAgKiBjaGFuZ2UgdGhlIHNjaGVtYSBhbmQgd2UgZG9uJ3Qgd2FudCB0aGlzLiBXZSBkb24ndCBuZWVkCgkgICAgKiB0aGUgcGFyc2VyIGNvbnRleHQgYW55bW9yZS4KCSAgICAqCgkgICAgKiBpZiAoKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSAmJgoJICAgICoJKHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh2Y3R4dCkgPT0gLTEpKQoJICAgICoJICAgIHJldHVybiAoLTEpOwoJICAgICovCgoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU0Rlcml2ZWRPSyhBQ1RYVF9DQVNUIHZjdHh0LCAqbG9jYWxUeXBlLAoJCWVsZW1EZWNsLT5zdWJ0eXBlcywgc2V0KSAhPSAwKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8zLCBOVUxMLCBOVUxMLAoJCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiAnJXMnLCBzcGVjaWZpZWQgYnkgeHNpOnR5cGUsIGlzICIKCQkgICAgImJsb2NrZWQgb3Igbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSAgICAib2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24iLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkoKmxvY2FsVHlwZSktPnRhcmdldE5hbWVzcGFjZSwKCQkJKCpsb2NhbFR5cGUpLT5uYW1lKSwKCQkgICAgTlVMTCk7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCXJldCA9IHZjdHh0LT5lcnI7CgkJKmxvY2FsVHlwZSA9IE5VTEw7CgkgICAgfQoJfQogICAgfQpleGl0OgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICBBQ1RJVkFURV9FTEVNOwogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtRGVjbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wgPSB2Y3R4dC0+aW5vZGUtPmRlY2w7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFjdHVhbFR5cGU7CgogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMQogICAgKi8KICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xLCBOVUxMLAoJICAgICJObyBtYXRjaGluZyBkZWNsYXJhdGlvbiBhdmFpbGFibGUiKTsKICAgICAgICByZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQogICAgYWN0dWFsVHlwZSA9IFdYU19FTEVNX1RZUEVERUYoZWxlbURlY2wpOwogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMgogICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7CglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8yLCBOVUxMLAoJICAgICJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCIpOwogICAgICAgIHJldHVybiAodmN0eHQtPmVycik7CiAgICB9CiAgICBpZiAoYWN0dWFsVHlwZSA9PSBOVUxMKSB7CiAgICAJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIpOwogICAgCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSk7CiAgICB9CiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCWludCByZXQ7Cgl4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDMKCSogSGFuZGxlICd4c2k6bmlsJy4KCSovCglpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCSAgICBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OSUwpOwoJaWYgKGlhdHRyKSB7CgkgICAgQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKTsKCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQlBQ1RYVF9DQVNUIHZjdHh0LCBOVUxMLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJCWlhdHRyLT52YWx1ZSwgJihpYXR0ci0+dmFsKSwgMSwgMCwgMCk7CgkgICAgQUNUSVZBVEVfRUxFTTsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2wiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkgdG8gIgoJCSAgICAidmFsaWRhdGUgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSB7CgkJICAgIC8qCgkJICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMy4xCgkJICAgICovCgkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMSwgTlVMTCwKCQkJIlRoZSBlbGVtZW50IGlzIG5vdCAnbmlsbGFibGUnIik7CgkJICAgIC8qIERvZXMgbm90IHJldHVybiBhbiBlcnJvciBvbiBwdXJwb3NlLiAqLwoJCX0gZWxzZSB7CgkJICAgIGlmICh4bWxTY2hlbWFWYWx1ZUdldEFzQm9vbGVhbihpYXR0ci0+dmFsKSkgewoJCQkvKgoJCQkqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMi4yCgkJCSovCgkJCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCQkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCBOVUxMLAoJCQkJIlRoZSBlbGVtZW50IGNhbm5vdCBiZSAnbmlsbGVkJyBiZWNhdXNlICIKCQkJCSJ0aGVyZSBpcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQgZGVmaW5lZCAiCgkJCQkiZm9yIGl0Iik7CgkJCSAgICAgLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkJCX0gZWxzZQoJCQkgICAgdmN0eHQtPmlub2RlLT5mbGFncyB8PQoJCQkJWE1MX1NDSEVNQV9FTEVNX0lORk9fTklMTEVEOwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDQKCSogSGFuZGxlICd4c2k6dHlwZScuCgkqLwoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkgICAgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CglpZiAoaWF0dHIpIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIGxvY2FsVHlwZSA9IE5VTEw7CgoJICAgIHJldCA9IHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHZjdHh0LCBpYXR0ciwgJmxvY2FsVHlwZSwKCQllbGVtRGVjbCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJCSJwcm9jZXNzIHRoZSBhdHRyaWJ1dGUgJ3hzaTp0eXBlJyIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkgICAgfQoJICAgIGlmIChsb2NhbFR5cGUgIT0gTlVMTCkgewoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fTE9DQUxfVFlQRTsKCQlhY3R1YWxUeXBlID0gbG9jYWxUeXBlOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIElEQzogUmVnaXN0ZXIgaWRlbnRpdHktY29uc3RyYWludCBYUGF0aCBtYXRjaGVycy4KICAgICovCiAgICBpZiAoKGVsZW1EZWNsLT5pZGNzICE9IE5VTEwpICYmCgkoeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyh2Y3R4dCwgZWxlbURlY2wpID09IC0xKSkKCSAgICByZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIE5vIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgLyoKICAgICogUmVtZW1iZXIgdGhlIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgdmN0eHQtPmlub2RlLT50eXBlRGVmID0gYWN0dWFsVHlwZTsKCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZBdHRyaWJ1dGVzU2ltcGxlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CiAgICBpbnQgcmV0ID0gMCwgaTsKCiAgICAvKgogICAgKiBTUEVDIGN2Yy10eXBlICgzLjEuMSkKICAgICogIlRoZSBhdHRyaWJ1dGVzIG9mIG11c3QgYmUgZW1wdHksIGV4Y2VwdGluZyB0aG9zZSB3aG9zZSBuYW1lc3BhY2UKICAgICogbmFtZSBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kCiAgICAqIHdob3NlIGxvY2FsIG5hbWUgaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3IKICAgICogbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbi4iCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJaWYgKCEgaWF0dHItPm1ldGFUeXBlKSB7CgkgICAgQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKQoJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGlhdHRyLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMTsKICAgICAgICB9CiAgICB9CiAgICBBQ1RJVkFURV9FTEVNCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qCiogQ2xlYW51cCBjdXJyZW50bHkgdXNlZCBhdHRyaWJ1dGUgaW5mb3MuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IGk7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBhdHRyOwoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybjsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTKSB7CgkgICAgaWYgKGF0dHItPmxvY2FsTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUoKHhtbENoYXIgKikgYXR0ci0+bG9jYWxOYW1lKTsKCSAgICBpZiAoYXR0ci0+bnNOYW1lICE9IE5VTEwpCgkJeG1sRnJlZSgoeG1sQ2hhciAqKSBhdHRyLT5uc05hbWUpOwoJfQoJaWYgKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCSAgICBpZiAoYXR0ci0+dmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKCh4bWxDaGFyICopIGF0dHItPnZhbHVlKTsKCX0KCWlmIChhdHRyLT52YWwgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShhdHRyLT52YWwpOwoJICAgIGF0dHItPnZhbCA9IE5VTEw7Cgl9CgltZW1zZXQoYXR0ciwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICB9CiAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwp9CgovKgoqIDMuNC40IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKKiAgIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKSAoY3ZjLWNvbXBsZXgtdHlwZSkKKiAzLjIuNCBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gVmFsaWRhdGlvbiBSdWxlcwoqICAgVmFsaWRhdGlvbiBSdWxlOiBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoY3ZjLWF0dHJpYnV0ZSkKKiAgIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpIChjdmMtYXUpCioKKiBPbmx5ICJhc3Nlc3NlZCIgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIHdpbGwgYmUgdmlzaWJsZSB0bwoqIElEQ3MuIEkuZS4gbm90ICJsYXgiICh3aXRob3V0IGRlY2xhcmF0aW9uKSBhbmQgInNraXAiIHdpbGQgYXR0cmlidXRlcy4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSB2Y3R4dC0+aW5vZGUtPnR5cGVEZWY7ICAgIAogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgYXR0clVzZUxpc3Q7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgYXR0clVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2wgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHIsIHRtcGlhdHRyOyAgICAKICAgIGludCBpLCBqLCBmb3VuZCwgbmJBdHRycywgbmJVc2VzOwogICAgaW50IHhwYXRoUmVzID0gMCwgcmVzLCB3aWxkSURzID0gMCwgZml4ZWQ7CiAgICB4bWxOb2RlUHRyIGRlZkF0dHJPd25lckVsZW0gPSBOVUxMOwoKICAgIC8qCiAgICAqIFNQRUMgKGN2Yy1hdHRyaWJ1dGUpCiAgICAqICgxKSAiVGhlIGRlY2xhcmF0aW9uIG11c3Qgbm90IGJlILdhYnNlbnS3IChzZWUgTWlzc2luZwogICAgKiBTdWItY29tcG9uZW50cyAopzUuMykgZm9yIGhvdyB0aGlzIGNhbiBmYWlsIHRvIGJlCiAgICAqIHRoZSBjYXNlKS4iCiAgICAqICgyKSAiSXRzIHt0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGJlIGFic2VudC4iCiAgICAqCiAgICAqIE5PVEUgKDEpICsgKDIpOiBUaGlzIGlzIG5vdCBoYW5kbGVkIGhlcmUsIHNpbmNlIHdlIGN1cnJlbnRseSBkbyBub3QKICAgICogYWxsb3cgdmFsaWRhdGlvbiBhZ2FpbnN0IHNjaGVtYXMgd2hpY2ggaGF2ZSBtaXNzaW5nIHN1Yi1jb21wb25lbnRzLgogICAgKgogICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQogICAgKiAoMykgIkZvciBlYWNoIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uCiAgICAqIGl0ZW0ncyBbYXR0cmlidXRlc10gZXhjZXB0aW5nIHRob3NlIHdob3NlIFtuYW1lc3BhY2UgbmFtZV0gaXMKICAgICogaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZQogICAgKiBbbG9jYWwgbmFtZV0gaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3IKICAgICogbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiwgdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZwogICAgKiBtdXN0IGJlIHRydWU6CiAgICAqCiAgICAqLwogICAgYXR0clVzZUxpc3QgPSAoeG1sU2NoZW1hSXRlbUxpc3RQdHIpIHR5cGUtPmF0dHJVc2VzOwogICAgLyoKICAgICogQG5iQXR0cnMgaXMgdGhlIG51bWJlciBvZiBhdHRyaWJ1dGVzIHByZXNlbnQgaW4gdGhlIGluc3RhbmNlLgogICAgKi8KICAgIG5iQXR0cnMgPSB2Y3R4dC0+bmJBdHRySW5mb3M7CiAgICBpZiAoYXR0clVzZUxpc3QgIT0gTlVMTCkKCW5iVXNlcyA9IGF0dHJVc2VMaXN0LT5uYkl0ZW1zOwogICAgZWxzZQoJbmJVc2VzID0gMDsKICAgIGZvciAoaSA9IDA7IGkgPCBuYlVzZXM7IGkrKykgewogICAgICAgIGZvdW5kID0gMDsKCWF0dHJVc2UgPSBhdHRyVXNlTGlzdC0+aXRlbXNbaV07CglhdHRyRGVjbCA9IFdYU19BVFRSVVNFX0RFQ0woYXR0clVzZSk7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IG5iQXR0cnM7IGorKykgewoJICAgIGlhdHRyID0gdmN0eHQtPmF0dHJJbmZvc1tqXTsKCSAgICAvKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkgKDMpCgkgICAgKiBTa2lwIG1ldGEgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChpYXR0ci0+bWV0YVR5cGUpCgkJY29udGludWU7CgkgICAgaWYgKGlhdHRyLT5sb2NhbE5hbWVbMF0gIT0gYXR0ckRlY2wtPm5hbWVbMF0pCgkJY29udGludWU7CgkgICAgaWYgKCF4bWxTdHJFcXVhbChpYXR0ci0+bG9jYWxOYW1lLCBhdHRyRGVjbC0+bmFtZSkpCgkJY29udGludWU7CgkgICAgaWYgKCF4bWxTdHJFcXVhbChpYXR0ci0+bnNOYW1lLCBhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlKSkKCQljb250aW51ZTsKCSAgICBmb3VuZCA9IDE7CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkgICAgKiAoMy4xKSAiSWYgdGhlcmUgaXMgYW1vbmcgdGhlIHthdHRyaWJ1dGUgdXNlc30gYW4gYXR0cmlidXRlCgkgICAgKiB1c2Ugd2l0aCBhbiB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSB3aG9zZSB7bmFtZX0gbWF0Y2hlcwoJICAgICogdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtJ3MgW2xvY2FsIG5hbWVdIGFuZCB3aG9zZQoJICAgICoge3RhcmdldCBuYW1lc3BhY2V9IGlzIGlkZW50aWNhbCB0byB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uCgkgICAgKiBpdGVtJ3MgW25hbWVzcGFjZSBuYW1lXSAod2hlcmUgYW4gt2Fic2VudLcge3RhcmdldCBuYW1lc3BhY2V9CgkgICAgKiBpcyB0YWtlbiB0byBiZSBpZGVudGljYWwgdG8gYSBbbmFtZXNwYWNlIG5hbWVdIHdpdGggbm8gdmFsdWUpLAoJICAgICogdGhlbiB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QKCSAgICAqIHRvIHRoYXQgYXR0cmlidXRlIHVzZSBhcyBwZXIgQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKFVzZSkKCSAgICAqICinMy41LjQpLiBJbiB0aGlzIGNhc2UgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IG9mIHRoYXQKCSAgICAqIGF0dHJpYnV0ZSB1c2UgaXMgdGhlILdjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb263IGZvciB0aGUKCSAgICAqIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHdpdGggcmVzcGVjdCB0byBTY2hlbWEtVmFsaWRpdHkKCSAgICAqIEFzc2Vzc21lbnQgKEF0dHJpYnV0ZSkgKKczLjIuNCkgYW5kCgkgICAgKiBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkgKKczLjIuNSkuCgkgICAgKi8KCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEOwoJICAgIGlhdHRyLT51c2UgPSBhdHRyVXNlOwoJICAgIC8qCgkgICAgKiBDb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24uCgkgICAgKi8KCSAgICBpYXR0ci0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIGlhdHRyLT50eXBlRGVmID0gYXR0ckRlY2wtPnN1YnR5cGVzOwoJICAgIGJyZWFrOwoJfQoKCWlmIChmb3VuZCkKCSAgICBjb250aW51ZTsKCglpZiAoYXR0clVzZS0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSB7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBub24tZXhpc3RlbnQsIHJlcXVpcmVkIGF0dHJpYnV0ZXMuCgkgICAgKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSAgICAqICg0KSAiVGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IG9mIGVhY2ggYXR0cmlidXRlIHVzZSBpbgoJICAgICogdGhlIHthdHRyaWJ1dGUgdXNlc30gd2hvc2Uge3JlcXVpcmVkfSBpcyB0cnVlIG1hdGNoZXMgb25lCgkgICAgKiBvZiB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIGluIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uCgkgICAgKiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIGFzIHBlciBjbGF1c2UgMy4xIGFib3ZlLiIKCSAgICAqLwoJICAgIHRtcGlhdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CgkgICAgaWYgKHRtcGlhdHRyID09IE5VTEwpIHsKCQlWRVJST1JfSU5UKAoJCSAgICAieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbygpIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkc7CgkgICAgdG1waWF0dHItPnVzZSA9IGF0dHJVc2U7CgkgICAgdG1waWF0dHItPmRlY2wgPSBhdHRyRGVjbDsJICAgIAoJfSBlbHNlIGlmICgoYXR0clVzZS0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJICAgICgoYXR0clVzZS0+ZGVmVmFsdWUgIT0gTlVMTCkgfHwKCSAgICAgKGF0dHJEZWNsLT5kZWZWYWx1ZSAhPSBOVUxMKSkpIHsKCSAgICAvKgoJICAgICogSGFuZGxlIG5vbi1leGlzdGVudCwgb3B0aW9uYWwsIGRlZmF1bHQvZml4ZWQgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIHRtcGlhdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CgkgICAgaWYgKHRtcGlhdHRyID09IE5VTEwpIHsKCQlWRVJST1JfSU5UKAoJCSAgICAieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbygpIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVDsKCSAgICB0bXBpYXR0ci0+dXNlID0gYXR0clVzZTsKCSAgICB0bXBpYXR0ci0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIHRtcGlhdHRyLT50eXBlRGVmID0gYXR0ckRlY2wtPnN1YnR5cGVzOwoJICAgIHRtcGlhdHRyLT5sb2NhbE5hbWUgPSBhdHRyRGVjbC0+bmFtZTsKCSAgICB0bXBpYXR0ci0+bnNOYW1lID0gYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZTsKCX0KICAgIH0KCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zID09IDApCglyZXR1cm4gKDApOwogICAgbmJVc2VzID0gdmN0eHQtPm5iQXR0ckluZm9zOwogICAgLyoKICAgICogVmFsaWRhdGUgYWdhaW5zdCB0aGUgd2lsZGNhcmQuCiAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCS8qCgkqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkqICgzLjIuMSkgIlRoZXJlIG11c3QgYmUgYW4ge2F0dHJpYnV0ZSB3aWxkY2FyZH0uIgoJKi8KCWZvciAoaSA9IDA7IGkgPCBuYkF0dHJzOyBpKyspIHsKCSAgICBpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgzKQoJICAgICogU2tpcCBtZXRhIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAoaWF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikKCQljb250aW51ZTsKCSAgICAvKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSAgICAqICgzLjIuMikgIlRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aAoJICAgICogcmVzcGVjdCB0byBpdCBhcyBkZWZpbmVkIGluIEl0ZW0gVmFsaWQgKFdpbGRjYXJkKSAopzMuMTAuNCkuIgoJICAgICoKCSAgICAqIFNQRUMgSXRlbSBWYWxpZCAoV2lsZGNhcmQpIChjdmMtd2lsZGNhcmQpCgkgICAgKiAiLi4uIGl0cyBbbmFtZXNwYWNlIG5hbWVdIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8KCSAgICAqIHRoZSB3aWxkY2FyZCBjb25zdHJhaW50LCBhcyBkZWZpbmVkIGluIFdpbGRjYXJkIGFsbG93cwoJICAgICogTmFtZXNwYWNlIE5hbWUgKKczLjEwLjQpLiIKCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCSAgICBpYXR0ci0+bnNOYW1lKSA9PSAwKSB7CgkJLyoKCQkqIEhhbmRsZSBwcm9jZXNzQ29udGVudHMuCgkJKgoJCSogU1BFQyAoY3ZjLXdpbGRjYXJkKToKCQkqIHByb2Nlc3NDb250ZW50cyB8IGNvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbjoKCQkqICJzdHJpY3QiICAgICAgICAgICJtdXN0RmluZCIKCQkqICJsYXgiICAgICAgICAgICAgICJub25lIgoJCSogInNraXAiICAgICAgICAgICAgInNraXAiCgkJKi8KCQlpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PQoJCSAgICBYTUxfU0NIRU1BU19BTllfU0tJUCkgewoJCSAgICAgLyoKCQkgICAgKiBjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24gPSAic2tpcCIKCQkgICAgKgoJCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCQkgICAgKiBbdmFsaWRpdHldID0gIm5vdEtub3duIgoJCSAgICAqIFt2YWxpZGF0aW9uIGF0dGVtcHRlZF0gPSAibm9uZSIKCQkgICAgKi8KCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVA7CgkJICAgIGNvbnRpbnVlOwoJCX0KCQkvKgoJCSogRmluZCBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCgkJKi8KCQlpYXR0ci0+ZGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2wodmN0eHQtPnNjaGVtYSwKCQkgICAgaWF0dHItPmxvY2FsTmFtZSwgaWF0dHItPm5zTmFtZSk7CgkJaWYgKGlhdHRyLT5kZWNsICE9IE5VTEwpIHsKCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRDsKCQkgICAgLyoKCQkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJCSAgICAqICg1KSAiTGV0IFtEZWZpbml0aW9uOl0gIHRoZSB3aWxkIElEcyBiZSB0aGUgc2V0IG9mCgkJICAgICogYWxsIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIHdoaWNoIGNsYXVzZSAzLjIKCQkgICAgKiBhcHBsaWVkIGFuZCB3aG9zZSC3dmFsaWRhdGlvbrcgcmVzdWx0ZWQgaW4gYQoJCSAgICAqILdjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb263IG9mIG11c3RGaW5kIG9yIG5vCgkJICAgICogt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgYXQgYWxsLCBhbmQgd2hvc2UKCQkgICAgKiBbbG9jYWwgbmFtZV0gYW5kIFtuYW1lc3BhY2UgbmFtZV0gcmVzb2x2ZSAoYXMKCQkgICAgKiBkZWZpbmVkIGJ5IFFOYW1lIHJlc29sdXRpb24gKEluc3RhbmNlKSAopzMuMTUuNCkpIHRvCgkJICAgICogYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdob3NlIHt0eXBlIGRlZmluaXRpb259IGlzCgkJICAgICogb3IgaXMgZGVyaXZlZCBmcm9tIElELiBUaGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nCgkJICAgICogbXVzdCBiZSB0cnVlOiIKCQkgICAgKi8KCQkgICAgaWF0dHItPnR5cGVEZWYgPSBXWFNfQVRUUl9UWVBFREVGKGlhdHRyLT5kZWNsKTsKCQkgICAgaWYgKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSgKCQkJaWF0dHItPnR5cGVEZWYsIFhNTF9TQ0hFTUFTX0lEKSkgewoJCQkvKgoJCQkqIFNQRUMgKDUuMSkgIlRoZXJlIG11c3QgYmUgbm8gbW9yZSB0aGFuIG9uZQoJCQkqIGl0ZW0gaW4gt3dpbGQgSURzty4iCgkJCSovCgkJCWlmICh3aWxkSURzICE9IDApIHsKCQkJICAgIC8qIFZBTCBUT0RPICovCgkJCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0RVUExJQ0FURV9JRDsKCQkJICAgIFRPRE8KCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJCXdpbGRJRHMrKzsKCQkJLyoKCQkJKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJCQkqICg1LjIpICJJZiC3d2lsZCBJRHO3IGlzIG5vbi1lbXB0eSwgdGhlcmUgbXVzdCBub3QKCQkJKiBiZSBhbnkgYXR0cmlidXRlIHVzZXMgYW1vbmcgdGhlIHthdHRyaWJ1dGUgdXNlc30KCQkJKiB3aG9zZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzIHt0eXBlIGRlZmluaXRpb259CgkJCSogaXMgb3IgaXMgZGVyaXZlZCBmcm9tIElELiIKCQkJKi8KCQkJZm9yIChqID0gMDsgaiA8IGF0dHJVc2VMaXN0LT5uYkl0ZW1zOyBqKyspIHsKCQkJICAgIGlmICh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoCgkJCQlXWFNfQVRUUlVTRV9UWVBFREVGKGF0dHJVc2VMaXN0LT5pdGVtc1tqXSksCgkJCQlYTUxfU0NIRU1BU19JRCkpIHsKCQkJCS8qIFVSR0VOVCBWQUwgVE9ETzogaW1wbGVtZW50ICovCgkJCQlpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0FORF9VU0VfSUQ7CgkJCQlUT0RPCgkJCQlicmVhazsKCQkJICAgIH0KCQkJfQoJCSAgICB9CgkJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09CgkJICAgIFhNTF9TQ0hFTUFTX0FOWV9MQVgpIHsKCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX0xBWF9OT19ERUNMOwoJCSAgICAvKgoJCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCQkgICAgKiBbdmFsaWRpdHldID0gIm5vdEtub3duIgoJCSAgICAqIFt2YWxpZGF0aW9uIGF0dGVtcHRlZF0gPSAibm9uZSIKCQkgICAgKi8KCQl9IGVsc2UgewoJCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX1NUUklDVF9OT19ERUNMOwoJCX0KCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKCiAgICAvKgogICAgKiBHZXQgdGhlIG93bmVyIGVsZW1lbnQ7IG5lZWRlZCBmb3IgY3JlYXRpb24gb2YgZGVmYXVsdCBhdHRyaWJ1dGVzLgogICAgKiBUaGlzIGZpeGVzIGJ1ZyAjMzQxMzM3LCByZXBvcnRlZCBieSBEYXZpZCBHcm9obWFubi4KICAgICovCiAgICBpZiAodmN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgewoJeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW0gPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CglpZiAoaWVsZW0gJiYgaWVsZW0tPm5vZGUgJiYgaWVsZW0tPm5vZGUtPmRvYykKCSAgICBkZWZBdHRyT3duZXJFbGVtID0gaWVsZW0tPm5vZGU7CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSB2YWx1ZXMsIGNyZWF0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMsIGV2YWx1YXRlIElEQ3MuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CglpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CgkvKgoJKiBWQUwgVE9ETzogTm90ZSB0aGF0IHdlIHdvbid0IHRyeSB0byByZXNvbHZlIElEQ3MgdG8KCSogImxheCIgYW5kICJza2lwIiB2YWxpZGF0ZWQgYXR0cmlidXRlcy4gQ2hlY2sgd2hhdCB0bwoJKiBkbyBpbiB0aGlzIGNhc2UuCgkqLwoJaWYgKChpYXR0ci0+c3RhdGUgIT0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRCkgJiYKCSAgICAoaWF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCkpCgkgICAgY29udGludWU7CgkvKgoJKiBWQUwgVE9ETzogV2hhdCB0byBkbyBpZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIG1pc3Npbmc/CgkqLwoJaWYgKGlhdHRyLT50eXBlRGVmID09IE5VTEwpIHsKCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9OT19UWVBFOwoJICAgIGNvbnRpbnVlOwoJfQoKCUFDVElWQVRFX0FUVFJJQlVURShpYXR0cik7CglmaXhlZCA9IDA7Cgl4cGF0aFJlcyA9IDA7CgoJaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEV2YWx1YXRlIElEQ3MuCgkgICAgKi8KCSAgICB4cGF0aFJlcyA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUodmN0eHQsCgkJWE1MX0FUVFJJQlVURV9OT0RFKTsKCSAgICBpZiAoeHBhdGhSZXMgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0KCglpZiAoaWF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCkgewoJICAgIC8qCgkgICAgKiBEZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkgICAgKiBXZSBuZWVkIHRoZSB2YWx1ZSBvbmx5IGlmIHdlIG5lZWQgdG8gcmVzb2x2ZSBJRENzIG9yCgkgICAgKiB3aWxsIGNyZWF0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAoKHhwYXRoUmVzKSB8fCAoZGVmQXR0ck93bmVyRWxlbSkpIHsKCQlpZiAoaWF0dHItPnVzZS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJCSAgICBpYXR0ci0+dmFsdWUgPSAoeG1sQ2hhciAqKSBpYXR0ci0+dXNlLT5kZWZWYWx1ZTsKCQkgICAgaWF0dHItPnZhbCA9IGlhdHRyLT51c2UtPmRlZlZhbDsKCQl9IGVsc2UgewoJCSAgICBpYXR0ci0+dmFsdWUgPSAoeG1sQ2hhciAqKSBpYXR0ci0+ZGVjbC0+ZGVmVmFsdWU7CgkJICAgIGlhdHRyLT52YWwgPSBpYXR0ci0+ZGVjbC0+ZGVmVmFsOwoJCX0KCQkvKgoJCSogSURDcyB3aWxsIGNvbnN1bWUgdGhlIHByZWNvbXB1dGVkIGRlZmF1bHQgdmFsdWUsCgkJKiBzbyB3ZSBuZWVkIHRvIGNsb25lIGl0LgoJCSovCgkJaWYgKGlhdHRyLT52YWwgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkiZGVmYXVsdC9maXhlZCB2YWx1ZSBvbiBhbiBhdHRyaWJ1dGUgdXNlIHdhcyAiCgkJCSJub3QgcHJlY29tcHV0ZWQiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJaWF0dHItPnZhbCA9IHhtbFNjaGVtYUNvcHlWYWx1ZShpYXR0ci0+dmFsKTsKCQlpZiAoaWF0dHItPnZhbCA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYUNvcHlWYWx1ZSgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogUFNWSTogQWRkIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZSB0byB0aGUgY3VycmVudCBlbGVtZW50LgoJICAgICogVkFMIFRPRE86IFNob3VsZCB3ZSB1c2UgdGhlICpub3JtYWxpemVkKiB2YWx1ZT8gVGhpcyBjdXJyZW50bHkKCSAgICAqICAgdXNlcyB0aGUgKmluaXRpYWwqIHZhbHVlLgoJICAgICovCgkgICAgCgkgICAgaWYgKGRlZkF0dHJPd25lckVsZW0pIHsKCQl4bWxDaGFyICpub3JtVmFsdWU7CgkJY29uc3QgeG1sQ2hhciAqdmFsdWU7CgoJCXZhbHVlID0gaWF0dHItPnZhbHVlOwoJCS8qCgkJKiBOb3JtYWxpemUgdGhlIHZhbHVlLgoJCSovCgkJbm9ybVZhbHVlID0geG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoaWF0dHItPnR5cGVEZWYsCgkJICAgIGlhdHRyLT52YWx1ZSk7CgkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCSAgICB2YWx1ZSA9IEJBRF9DQVNUIG5vcm1WYWx1ZTsKCgkJaWYgKGlhdHRyLT5uc05hbWUgPT0gTlVMTCkgewoJCSAgICBpZiAoeG1sTmV3UHJvcChkZWZBdHRyT3duZXJFbGVtLAoJCQlpYXR0ci0+bG9jYWxOYW1lLCB2YWx1ZSkgPT0gTlVMTCkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkgICAgImNhbGxsaW5nIHhtbE5ld1Byb3AoKSIpOwoJCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJCSAgICB4bWxGcmVlKG5vcm1WYWx1ZSk7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICB4bWxOc1B0ciBuczsKCgkJICAgIG5zID0geG1sU2VhcmNoTnNCeUhyZWYoZGVmQXR0ck93bmVyRWxlbS0+ZG9jLAoJCQlkZWZBdHRyT3duZXJFbGVtLCBpYXR0ci0+bnNOYW1lKTsKCQkgICAgaWYgKG5zID09IE5VTEwpIHsKCQkJeG1sQ2hhciBwcmVmaXhbMTJdOwoJCQlpbnQgY291bnRlciA9IDA7CgoJCQkvKgoJCQkqIENyZWF0ZSBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBvbiB0aGUgdmFsaWRhdGlvbgoJCQkqIHJvb3Qgbm9kZSBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgaW4gc2NvcGUuCgkJCSovCgkJCWRvIHsKCQkJICAgIHNucHJpbnRmKChjaGFyICopIHByZWZpeCwgMTIsICJwJWQiLCBjb3VudGVyKyspOwoJCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhkZWZBdHRyT3duZXJFbGVtLT5kb2MsCgkJCQlkZWZBdHRyT3duZXJFbGVtLCBCQURfQ0FTVCBwcmVmaXgpOwoJCQkgICAgaWYgKGNvdW50ZXIgPiAxMDAwKSB7CgkJCQlWRVJST1JfSU5UKAoJCQkJICAgICJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkJICAgICJjb3VsZCBub3QgY29tcHV0ZSBhIG5zIHByZWZpeCBmb3IgYSAiCgkJCQkgICAgImRlZmF1bHQvZml4ZWQgYXR0cmlidXRlIik7CgkJCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJCQkgICAgeG1sRnJlZShub3JtVmFsdWUpOwoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIH0KCQkJfSB3aGlsZSAobnMgIT0gTlVMTCk7CgkJCW5zID0geG1sTmV3TnModmN0eHQtPnZhbGlkYXRpb25Sb290LAoJCQkgICAgaWF0dHItPm5zTmFtZSwgQkFEX0NBU1QgcHJlZml4KTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIFRPRE86CgkJICAgICogaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LXhtbC1zY2hlbWEtY29tbWVudHMvMjAwNUp1bFNlcC8wNDA2Lmh0bWwKCQkgICAgKiBJZiB3ZSBoYXZlIFFOYW1lczogZG8gd2UgbmVlZCB0byBlbnN1cmUgdGhlcmUncyBhCgkJICAgICogcHJlZml4IGRlZmluZWQgZm9yIHRoZSBRTmFtZT8KCQkgICAgKi8KCQkgICAgeG1sTmV3TnNQcm9wKGRlZkF0dHJPd25lckVsZW0sIG5zLCBpYXR0ci0+bG9jYWxOYW1lLCB2YWx1ZSk7CgkJfQoJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkgICAgeG1sRnJlZShub3JtVmFsdWUpOwoJICAgIH0KCSAgICAvKgoJICAgICogR28gZGlyZWN0bHkgdG8gSURDIGV2YWx1YXRpb24uCgkgICAgKi8KCSAgICBnb3RvIGV2YWxfaWRjczsKCX0KCS8qCgkqIFZhbGlkYXRlIHRoZSB2YWx1ZS4KCSovCglpZiAodmN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogRnJlZSBsYXN0IGNvbXB1dGVkIHZhbHVlOyBqdXN0IGZvciBzYWZldHkgcmVhc29ucy4KCSAgICAqLwoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+dmFsdWUpOwoJICAgIHZjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CgkvKgoJKiBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSAqdXNlKiBjYW4gYmUgdW5hdmFpbGFibGUsIGlmCgkqIHRoZSBhdHRyaWJ1dGUgd2FzIGEgd2lsZCBhdHRyaWJ1dGUuCgkqLwoJaWYgKChpYXR0ci0+ZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSB8fAoJICAgICgoaWF0dHItPnVzZSAhPSBOVUxMKSAmJgoJICAgICAoaWF0dHItPnVzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSkpCgkgICAgZml4ZWQgPSAxOwoJZWxzZQoJICAgIGZpeGVkID0gMDsKCS8qCgkqIFNQRUMgKGN2Yy1hdHRyaWJ1dGUpCgkqICgzKSAiVGhlIGl0ZW0ncyC3bm9ybWFsaXplZCB2YWx1ZbcgbXVzdCBiZSBsb2NhbGx5ILd2YWxpZLcKCSogd2l0aCByZXNwZWN0IHRvIHRoYXQge3R5cGUgZGVmaW5pdGlvbn0gYXMgcGVyIAoJKiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLiIKCSoKCSogVkFMIFRPRE86IERvIHdlIGFscmVhZHkgaGF2ZSB0aGUKCSogIm5vcm1hbGl6ZWQgYXR0cmlidXRlIHZhbHVlIiBoZXJlPwoJKi8KCWlmICh4cGF0aFJlcyB8fCBmaXhlZCkgewoJICAgIGlhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19WQUxVRV9ORUVERUQ7CgkgICAgLyoKCSAgICAqIFJlcXVlc3QgYSBjb21wdXRlZCB2YWx1ZS4KCSAgICAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkJQUNUWFRfQ0FTVCB2Y3R4dCwKCQlpYXR0ci0+bm9kZSwgaWF0dHItPnR5cGVEZWYsIGlhdHRyLT52YWx1ZSwgJihpYXR0ci0+dmFsKSwKCQkxLCAxLCAwKTsKCX0gZWxzZSB7CgkgICAgcmVzID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQlBQ1RYVF9DQVNUIHZjdHh0LAoJCWlhdHRyLT5ub2RlLCBpYXR0ci0+dHlwZURlZiwgaWF0dHItPnZhbHVlLCBOVUxMLAoJCTEsIDAsIDApOwoJfQoJICAgIAoJaWYgKHJlcyAhPSAwKSB7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVN0cmVhbVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUU7CgkgICAgLyoKCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCSAgICAqIFt2YWxpZGl0eV0gPSAiaW52YWxpZCIKCSAgICAqLwoJICAgIGdvdG8gZXZhbF9pZGNzOwoJfQoKCWlmIChmaXhlZCkgewkgICAgCgkgICAgLyoKCSAgICAqIFNQRUMgQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKFVzZSkgKGN2Yy1hdSkKCSAgICAqICJGb3IgYW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gdG8gYmW3dmFsaWS3CgkgICAgKiB3aXRoIHJlc3BlY3QgdG8gYW4gYXR0cmlidXRlIHVzZSBpdHMgKm5vcm1hbGl6ZWQqCgkgICAgKiB2YWx1ZbcgbXVzdCBtYXRjaCB0aGUgKmNhbm9uaWNhbCogbGV4aWNhbAoJICAgICogcmVwcmVzZW50YXRpb24gb2YgdGhlIGF0dHJpYnV0ZSB1c2UncyB7dmFsdWUKCSAgICAqIGNvbnN0cmFpbnR9dmFsdWUsIGlmIGl0IGlzIHByZXNlbnQgYW5kIGZpeGVkLiIKCSAgICAqCgkgICAgKiBWQUwgVE9ETzogVGhlIHJlcXVpcmVtZW50IGZvciB0aGUgKmNhbm9uaWNhbCogdmFsdWUKCSAgICAqIHdpbGwgYmUgcmVtb3ZlZCBpbiBYTUwgU2NoZW1hIDEuMS4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBTUEVDIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChjdmMtYXR0cmlidXRlKQoJICAgICogKDQpICJUaGUgaXRlbSdzICphY3R1YWwqIHZhbHVltyBtdXN0IG1hdGNoIHRoZSAqdmFsdWUqIG9mCgkgICAgKiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9LCBpZiBpdCBpcyBwcmVzZW50IGFuZCBmaXhlZC4iCgkgICAgKi8KCSAgICBpZiAoaWF0dHItPnZhbCA9PSBOVUxMKSB7CgkJLyogVkFMIFRPRE86IEEgdmFsdWUgd2FzIG5vdCBwcmVjb21wdXRlZC4gKi8KCQlUT0RPCgkJZ290byBldmFsX2lkY3M7CgkgICAgfQoJICAgIGlmICgoaWF0dHItPnVzZSAhPSBOVUxMKSAmJgoJCShpYXR0ci0+dXNlLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJCWlmIChpYXR0ci0+dXNlLT5kZWZWYWwgPT0gTlVMTCkgewoJCSAgICAvKiBWQUwgVE9ETzogQSBkZWZhdWx0IHZhbHVlIHdhcyBub3QgcHJlY29tcHV0ZWQuICovCgkJICAgIFRPRE8KCQkgICAgZ290byBldmFsX2lkY3M7CgkJfQoJCWlhdHRyLT52Y1ZhbHVlID0gaWF0dHItPnVzZS0+ZGVmVmFsdWU7CgkJLyoKCQlpZiAoeG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKGF0dHItPnZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzLAoJCSAgICBhdHRyLT51c2UtPmRlZlZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzKSAhPSAwKSB7CgkJKi8KCQlpZiAoISB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChpYXR0ci0+dmFsLCBpYXR0ci0+dXNlLT5kZWZWYWwpKQoJCSAgICBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRTsKCSAgICB9IGVsc2UgewoJCWlmIChpYXR0ci0+ZGVjbC0+ZGVmVmFsID09IE5VTEwpIHsKCQkgICAgLyogVkFMIFRPRE86IEEgZGVmYXVsdCB2YWx1ZSB3YXMgbm90IHByZWNvbXB1dGVkLiAqLwoJCSAgICBUT0RPCgkJICAgIGdvdG8gZXZhbF9pZGNzOwoJCX0KCQlpYXR0ci0+dmNWYWx1ZSA9IGlhdHRyLT5kZWNsLT5kZWZWYWx1ZTsKCQkvKgoJCWlmICh4bWxTY2hlbWFDb21wYXJlVmFsdWVzV2h0c3AoYXR0ci0+dmFsLAoJCSAgICAoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MsCgkJICAgIGF0dHJEZWNsLT5kZWZWYWwsCgkJICAgICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cykgIT0gMCkgewoJCSovCgkJaWYgKCEgeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoaWF0dHItPnZhbCwgaWF0dHItPmRlY2wtPmRlZlZhbCkpCgkJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX0ZJWEVEX1ZBTFVFOwoJICAgIH0KCSAgICAvKgoJICAgICogW3ZhbGlkaXR5XSA9ICJ2YWxpZCIKCSAgICAqLwoJfQpldmFsX2lkY3M6CgkvKgoJKiBFdmFsdWF0ZSBJRENzLgoJKi8KCWlmICh4cGF0aFJlcykgewoJICAgIGlmICh4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHZjdHh0LAoJCXZjdHh0LT5kZXB0aCArMSkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0gZWxzZSBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hWFBhdGhQb3AodmN0eHQpOwogICAgfQoKICAgIC8qCiAgICAqIFJlcG9ydCBlcnJvcnMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CglpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoKGlhdHRyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX01FVEEpIHx8CgkgICAgKGlhdHRyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEKSB8fAoJICAgIChpYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVApIHx8CgkgICAgKGlhdHRyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1dJTERfTEFYX05PX0RFQ0wpKQoJICAgIGNvbnRpbnVlOwoJQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKTsKCXN3aXRjaCAoaWF0dHItPnN0YXRlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HOiB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIEFDVElWQVRFX0VMRU07CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzQsIE5VTEwsIE5VTEwsCgkJCSJUaGUgYXR0cmlidXRlICclcycgaXMgcmVxdWlyZWQgYnV0IG1pc3NpbmciLAoJCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkgICAgaWF0dHItPmRlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgIGlhdHRyLT5kZWNsLT5uYW1lKSwKCQkJTlVMTCk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICBicmVhazsKCQl9CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9OT19UWVBFOgoJCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfQVRUUklCVVRFXzIsIE5VTEwsCgkJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUU6CgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19BVSwgTlVMTCwgTlVMTCwKCQkgICAgIlRoZSB2YWx1ZSAnJXMnIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCAiCgkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLCAKCQkgICAgaWF0dHItPnZhbHVlLCBpYXR0ci0+dmNWYWx1ZSk7CQkKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfU1RSSUNUX05PX0RFQ0w6CgkJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19XSUxEQ0FSRCwgTlVMTCwKCQkgICAgIk5vIG1hdGNoaW5nIGdsb2JhbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gYXZhaWxhYmxlLCBidXQgIgoJCSAgICAiZGVtYW5kZWQgYnkgdGhlIHN0cmljdCB3aWxkY2FyZCIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOgoJCWlmIChpYXR0ci0+bWV0YVR5cGUpCgkJICAgIGJyZWFrOwoJCS8qCgkJKiBNQVlCRSBWQUwgVE9ETzogT25lIG1pZ2h0IHJlcG9ydCBkaWZmZXJlbnQgZXJyb3IgbWVzc2FnZXMKCQkqIGZvciB0aGUgZm9sbG93aW5nIGVycm9ycy4KCQkqLwoJCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfM18yXzEsIGlhdHRyLCBOVUxMKTsKCQl9IGVsc2UgewoJCSAgICB4bWxTY2hlbWFJbGxlZ2FsQXR0ckVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8yLCBpYXR0ciwgTlVMTCk7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgaW50ICpza2lwKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB2Y3R4dC0+aW5vZGUtPmRlY2w7CiAgICAvKgogICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IHdhcyBhbHJlYWR5IGlkZW50aWZpZWQgdG8gYmUKICAgICogbWF0Y2hpbmcgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmICgoc2tpcCA9PSBOVUxMKSB8fCAod2lsZCA9PSBOVUxMKSB8fAoJKHdpbGQtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkIiwKCSAgICAiYmFkIGFyZ3VtZW50cyIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAqc2tpcCA9IDA7CiAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7CgkvKgoJKiBVUkdFTlQgVkFMIFRPRE86IEVpdGhlciB3ZSBuZWVkIHRvIHBvc2l0aW9uIHRoZSBzdHJlYW0gdG8gdGhlCgkqIG5leHQgc2libGluZywgb3Igd2FsayB0aGUgd2hvbGUgc3VidHJlZS4KCSovCgkqc2tpcCA9IDE7CglyZXR1cm4gKDApOwogICAgfQogICAgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKCglkZWNsID0geG1sU2NoZW1hR2V0RWxlbSh2Y3R4dC0+c2NoZW1hLAoJICAgIHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CSAgICAKCWlmIChkZWNsICE9IE5VTEwpIHsKCSAgICB2Y3R4dC0+aW5vZGUtPmRlY2wgPSBkZWNsOwoJICAgIHJldHVybiAoMCk7Cgl9CiAgICB9CiAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpIHsKCS8qIFZBTCBUT0RPOiBDaGFuZ2UgdG8gcHJvcGVyIGVycm9yIGNvZGUuICovCglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xLCBOVUxMLCAvKiBXWFNfQkFTSUNfQ0FTVCB3aWxkICovCgkgICAgIk5vIG1hdGNoaW5nIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIGF2YWlsYWJsZSwgYnV0ICIKCSAgICAiZGVtYW5kZWQgYnkgdGhlIHN0cmljdCB3aWxkY2FyZCIpOwoJcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkgewoJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgkvKgoJKiBTUEVDIFZhbGlkYXRpb24gUnVsZTogU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEVsZW1lbnQpCgkqICgxLjIuMS4yLjEpIC0gKDEuMi4xLjIuMyApCgkqCgkqIFVzZSB0aGUgeHNpOnR5cGUgYXR0cmlidXRlIGZvciB0aGUgdHlwZSBkZWZpbml0aW9uLgoJKi8KCWlhdHRyID0geG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJICAgIFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1RZUEUpOwoJaWYgKGlhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUodmN0eHQsIGlhdHRyLAoJCSYodmN0eHQtPmlub2RlLT50eXBlRGVmKSwgTlVMTCkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1XaWxkY2FyZCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKCkgdG8gIgoJCSAgICAicHJvY2VzcyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAvKgoJICAgICogRG9uJ3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuCgkgICAgKi8KCSAgICByZXR1cm4gKDApOwoJfQogICAgfQogICAgLyoKICAgICogU1BFQyBWYWxpZGF0aW9uIFJ1bGU6IFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KQogICAgKgogICAgKiBGYWxsYmFjayB0byAiYW55VHlwZSIuCiAgICAqLwogICAgdmN0eHQtPmlub2RlLT50eXBlRGVmID0KCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgcmV0dXJuICgwKTsKfQoKLyoKKiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdDoKKgoqIFRoaXMgd2lsbCBiZSBjYWxsZWQgaWY6IG5vdCBuaWxsZWQsIG5vIGNvbnRlbnQgYW5kIGEgZGVmYXVsdC9maXhlZAoqIHZhbHVlIGlzIHByb3ZpZGVkLgoqLwoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKeyAgIAogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSA9IHZjdHh0LT5pbm9kZTsKCiAgICAvKgogICAgKiBjb3MtdmFsaWQtZGVmYXVsdDoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKICAgICogRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCB3aXRoIHJlc3BlY3QgdG8gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8gICAgCiAgICBpZiBXWFNfSVNfQ09NUExFWChpbm9kZS0+dHlwZURlZikgewoJLyoKCSogQ29tcGxleCB0eXBlLgoJKgoJKiBTUEVDICgyLjEpICJpdHMge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KCSogb3IgbWl4ZWQuIgoJKiBTUEVDICgyLjIuMikgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBtaXhlZCwgdGhlbiB0aGUge2NvbnRlbnQKCSogdHlwZX0ncyBwYXJ0aWNsZSBtdXN0IGJlILdlbXB0aWFibGW3IGFzIGRlZmluZWQgYnkgCgkqIFBhcnRpY2xlIEVtcHRpYWJsZSAopzMuOS42KS4iCgkqLwoJaWYgKCghIFdYU19IQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSAmJgoJICAgICgoISBXWFNfSEFTX01JWEVEX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB8fAoJICAgICAoISBXWFNfRU1QVElBQkxFKGlub2RlLT50eXBlRGVmKSkpKSB7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xOwoJICAgIC8qIE5PVEUgdGhhdCB0aGlzIGNvdmVycyAoMi4yLjIpIGFzIHdlbGwuICovCgkgICAgVkVSUk9SKHJldCwgTlVMTCwKCQkiRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCwgdGhlIHR5cGUgZGVmaW5pdGlvbiAiCgkJIm11c3QgYmUgYSBzaW1wbGUgdHlwZSBvciBhIGNvbXBsZXggdHlwZSB3aXRoIHNpbXBsZSBjb250ZW50ICIKCQkib3IgbWl4ZWQgY29udGVudCBhbmQgYSBwYXJ0aWNsZSBlbXB0aWFibGUiKTsKCSAgICByZXR1cm4ocmV0KTsKCX0KICAgIH0JCiAgICAvKgogICAgKiAxIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBzdHJpbmcgCiAgICAqIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIAogICAgKiBWYWxpZCAopzMuMTQuNCkuCiAgICAqCiAgICAqIEFORAogICAgKgogICAgKiAyLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSAKICAgICogc3RyaW5nIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIAogICAgKiBhcyBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAopzMuMTQuNCkuCiAgICAqLyAgCiAgICBpZiAoV1hTX0lTX1NJTVBMRShpbm9kZS0+dHlwZURlZikpIHsKCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKEFDVFhUX0NBU1QgdmN0eHQsCgkgICAgTlVMTCwgaW5vZGUtPnR5cGVEZWYsIHZhbHVlLCB2YWwsIDEsIDEsIDApOwoKICAgIH0gZWxzZSBpZiAoV1hTX0hBU19TSU1QTEVfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHsKCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKEFDVFhUX0NBU1QgdmN0eHQsCgkgICAgTlVMTCwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLCB2YWx1ZSwgdmFsLCAxLCAxLCAwKTsKICAgIH0KICAgIGlmIChyZXQgPCAwKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCIsCgkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CiAgICB9ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWQ29udGVudE1vZGVsQ2FsbGJhY2soeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0IEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBpdGVtLAoJCQkgICAgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGUpCnsKICAgIGlub2RlLT5kZWNsID0gaXRlbTsKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7CgoJaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHsKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIGNhbGxiYWNrIGZvciAnJXMnIFtkZWNsYXJhdGlvbl1cbiIsCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQlpbm9kZS0+bG9jYWxOYW1lLCBpbm9kZS0+bnNOYW1lKSk7Cgl9IGVsc2UgewoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAiQVVUT01BVE9OIGNhbGxiYWNrIGZvciAnJXMnIFt3aWxkY2FyZF1cbiIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGlub2RlLT5sb2NhbE5hbWUsIGlub2RlLT5uc05hbWUpKTsKCgl9CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7ICAgIAogICAgdmN0eHQtPmlub2RlID0geG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyh2Y3R4dCk7CiAgICBpZiAodmN0eHQtPmlub2RlID09IE5VTEwpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKCkiKTsKCXJldHVybiAoLTEpOwogICAgfSAgIAogICAgdmN0eHQtPm5iQXR0ckluZm9zID0gMDsKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlKQp7CiAgICBpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEKQoJcmV0dXJuICh4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJICAgIEFDVFhUX0NBU1QgdmN0eHQsIE5VTEwsCgkgICAgdHlwZSwgdmFsdWUsICYoaW5vZGUtPnZhbCksIDEsIDEsIDApKTsKICAgIGVsc2UKCXJldHVybiAoeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCSAgICBBQ1RYVF9DQVNUIHZjdHh0LCBOVUxMLAoJICAgIHR5cGUsIHZhbHVlLCBOVUxMLCAxLCAwLCAwKSk7Cn0KCgoKLyogCiogUHJvY2VzcyBFTkQgb2YgZWxlbWVudC4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSA9IHZjdHh0LT5pbm9kZTsKCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApCgl4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyh2Y3R4dCk7CiAgICBpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX05PVF9FWFBFQ1RFRCkgewoJLyoKCSogVGhpcyBlbGVtZW50IHdhcyBub3QgZXhwZWN0ZWQ7CgkqIHdlIHdpbGwgbm90IHZhbGlkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGJyb2tlbiBwYXJlbnRzLgoJKiBTa2lwIHZhbGlkYXRpb24gb2YgYWxsIGNvbnRlbnQgb2YgdGhlIHBhcmVudC4KCSovCgl2Y3R4dC0+c2tpcERlcHRoID0gdmN0eHQtPmRlcHRoIC0xOwoJZ290byBlbmRfZWxlbTsKICAgIH0gICAgCiAgICBpZiAoKGlub2RlLT50eXBlRGVmID09IE5VTEwpIHx8CgkoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFKSkgewoJLyoKCSogMS4gdGhlIHR5cGUgZGVmaW5pdGlvbiBtaWdodCBiZSBtaXNzaW5nIGlmIHRoZSBlbGVtZW50IHdhcwoJKiAgICBlcnJvciBwcm9uZQoJKiAyLiBpdCBtaWdodCBiZSBhYnN0cmFjdC4KCSovCglnb3RvIGVuZF9lbGVtOwogICAgfQogICAgLyoKICAgICogQ2hlY2sgdGhlIGNvbnRlbnQgbW9kZWwuCiAgICAqLwogICAgaWYgKChpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB8fAoJKGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKSB7CgoJLyoKCSogV29ya2Fyb3VuZCBmb3IgImFueVR5cGUiLgoJKi8KCWlmIChpbm9kZS0+dHlwZURlZi0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkKCSAgICBnb3RvIGNoYXJhY3Rlcl9jb250ZW50OwkJCQoJCglpZiAoKGlub2RlLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVCkgPT0gMCkgewoJICAgIHhtbENoYXIgKnZhbHVlc1sxMF07CgkgICAgaW50IHRlcm1pbmFsLCBuYnZhbCA9IDEwLCBuYm5lZzsKCgkgICAgaWYgKGlub2RlLT5yZWdleEN0eHQgPT0gTlVMTCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIHJlZ2V4IGNvbnRleHQuCgkJKi8KCQlpbm9kZS0+cmVnZXhDdHh0ID0KCQkgICAgeG1sUmVnTmV3RXhlY0N0eHQoaW5vZGUtPnR5cGVEZWYtPmNvbnRNb2RlbCwKCQkgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpIHhtbFNjaGVtYVZDb250ZW50TW9kZWxDYWxsYmFjaywKCQkgICAgdmN0eHQpOwoJCWlmIChpbm9kZS0+cmVnZXhDdHh0ID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJCSJmYWlsZWQgdG8gY3JlYXRlIGEgcmVnZXggY29udGV4dCIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gY3JlYXRlIG9uICclcydcbiIsIGlub2RlLT5sb2NhbE5hbWUpOwojZW5kaWYJICAgIAoJICAgIH0KCSAgICAvKgoJICAgICogR2V0IGhvbGQgb2YgdGhlIHN0aWxsIGV4cGVjdGVkIGNvbnRlbnQsIHNpbmNlIGEgZnVydGhlcgoJICAgICogY2FsbCB0byB4bWxSZWdFeGVjUHVzaFN0cmluZygpIHdpbGwgbG9vc2UgdGhpcyBpbmZvcm1hdGlvbi4KCSAgICAqLyAKCSAgICB4bWxSZWdFeGVjTmV4dFZhbHVlcyhpbm9kZS0+cmVnZXhDdHh0LAoJCSZuYnZhbCwgJm5ibmVnLCAmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKGlub2RlLT5yZWdleEN0eHQsIE5VTEwsIE5VTEwpOwoJICAgIGlmIChyZXQgPD0gMCkgewkJCgkJLyoKCQkqIFN0aWxsIG1pc3Npbmcgc29tZXRoaW5nLgoJCSovCgkJcmV0ID0gMTsKCQlpbm9kZS0+ZmxhZ3MgfD0KCQkgICAgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UOwoJCXhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwgTlVMTCwgTlVMTCwKCQkgICAgIk1pc3NpbmcgY2hpbGQgZWxlbWVudChzKSIsCgkJICAgIG5idmFsLCBuYm5lZywgdmFsdWVzKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gbWlzc2luZyBFUlJPUiBvbiAnJXMnXG4iLAoJCSAgICBpbm9kZS0+bG9jYWxOYW1lKTsKI2VuZGlmCgkgICAgfSBlbHNlIHsKCQkvKgoJCSogQ29udGVudCBtb2RlbCBpcyBzYXRpc2ZpZWQuCgkJKi8KCQlyZXQgPSAwOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBzdWNjZWVkZWQgb24gJyVzJ1xuIiwKCQkgICAgaW5vZGUtPmxvY2FsTmFtZSk7CiNlbmRpZgoJICAgIH0KCgl9CiAgICB9CiAgICBpZiAoaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykKCWdvdG8gZW5kX2VsZW07CgpjaGFyYWN0ZXJfY29udGVudDoKCiAgICBpZiAodmN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+dmFsdWUpOwoJdmN0eHQtPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGNoYXJhY3RlciBjb250ZW50LgogICAgKi8KICAgIGlmIChpbm9kZS0+ZGVjbCA9PSBOVUxMKSB7CgkvKgoJKiBTcGVlZHVwIGlmIG5vIGRlY2xhcmF0aW9uIGV4aXN0cy4KCSovCglpZiAoV1hTX0lTX1NJTVBMRShpbm9kZS0+dHlwZURlZikpIHsJICAgIAoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLCBpbm9kZS0+dmFsdWUpOwoJfSBlbHNlIGlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZURlZiwKCQlpbm9kZS0+dmFsdWUpOwoJfQkJCglpZiAocmV0IDwgMCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGVuZF9lbGVtOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNSAKICAgICogVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNS4xIAogICAgKiBJZiB0aGUgZGVjbGFyYXRpb24gaGFzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCAKICAgICogdGhlIGl0ZW0gaGFzIG5laXRoZXIgZWxlbWVudCBub3IgY2hhcmFjdGVyIFtjaGlsZHJlbl0gYW5kIAogICAgKiBjbGF1c2UgMy4yIGhhcyBub3QgYXBwbGllZCwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgaWYgKChpbm9kZS0+ZGVjbC0+dmFsdWUgIT0gTlVMTCkgJiYKCShpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkgJiYgCgkoISBJTk9ERV9OSUxMRUQoaW5vZGUpKSkgewoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjEgCgkqIElmIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgaXMgYSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utwoJKiB0aGVuIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9CgkqIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBkZWZhdWx0IGZvciB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIAoJKiBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4gCgkqLwoJLyogCgkqIE5PVEU6ICdsb2NhbCcgYWJvdmUgbWVhbnMgdHlwZXMgYWNxdWlyZWQgYnkgeHNpOnR5cGUuCgkqIE5PVEU6IEFsdGhvdWdoIHRoZSAqY2Fub25pY2FsKiB2YWx1ZSBpcyBzdGF0ZWQsIGl0IGlzIG5vdAoJKiByZWxldmFudCBpZiBjYW5vbmljYWwgb3Igbm90LiBBZGRpdGlvbmFsbHkgWE1MIFNjaGVtYSAxLjEKCSogd2lsbCByZW1vdmVkIHRoaXMgcmVxdWlyZW1lbnQgYXMgd2VsbC4KCSovCglpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fTE9DQUxfVFlQRSkgewoKCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh2Y3R4dCwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUsICYoaW5vZGUtPnZhbCkpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWdvdG8gZW5kX2VsZW07CgkgICAgfQoJICAgIC8qCgkgICAgKiBTdG9wIGhlcmUsIHRvIGF2b2lkIHJlZHVuZGFudCB2YWxpZGF0aW9uIG9mIHRoZSB2YWx1ZQoJICAgICogKHNlZSBmb2xsb3dpbmcpLgoJICAgICovCgkgICAgZ290byBkZWZhdWx0X3Bzdmk7Cgl9CQoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjIgCgkqIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gd2l0aCB0aGUgY2Fub25pY2FsIGxleGljYWwgCgkqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgdXNlZCBhcyBpdHMgCgkqILdub3JtYWxpemVkIHZhbHVltyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSAKCSogt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKQoJKiAopzMuMy40KS4KCSovCSAgICAKCWlmIChXWFNfSVNfU0lNUExFKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLCBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJfSBlbHNlIGlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZURlZiwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUpOwkgICAgCgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGVuZF9lbGVtOwoJfQoKZGVmYXVsdF9wc3ZpOgoJLyoKCSogUFNWSTogQ3JlYXRlIGEgdGV4dCBub2RlIG9uIHRoZSBpbnN0YW5jZSBlbGVtZW50LgoJKi8KCWlmICgodmN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgJiYKCSAgICAoaW5vZGUtPm5vZGUgIT0gTlVMTCkpIHsKCSAgICB4bWxOb2RlUHRyIHRleHRDaGlsZDsKCSAgICB4bWxDaGFyICpub3JtVmFsdWU7CgkgICAgLyoKCSAgICAqIFZBTCBUT0RPOiBOb3JtYWxpemUgdGhlIHZhbHVlLgoJICAgICovCSAgICAKCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFOb3JtYWxpemVWYWx1ZShpbm9kZS0+dHlwZURlZiwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkgewoJCXRleHRDaGlsZCA9IHhtbE5ld1RleHQoQkFEX0NBU1Qgbm9ybVZhbHVlKTsKCQl4bWxGcmVlKG5vcm1WYWx1ZSk7CgkgICAgfSBlbHNlCgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJICAgIGlmICh0ZXh0Q2hpbGQgPT0gTlVMTCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxOZXdUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0gZWxzZQoJCXhtbEFkZENoaWxkKGlub2RlLT5ub2RlLCB0ZXh0Q2hpbGQpOwkgICAgCgl9CgkKICAgIH0gZWxzZSBpZiAoISBJTk9ERV9OSUxMRUQoaW5vZGUpKSB7CQoJLyoKCSogNS4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IAoJKiB0byB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IAoJKiBWYWxpZCAoVHlwZSkgKKczLjMuNCkuCgkqLwkKCWlmIChXWFNfSVNfU0lNUExFKGlub2RlLT50eXBlRGVmKSkgewoJICAgICAvKgoJICAgICogU1BFQyAoY3ZjLXR5cGUpICgzLjEpCgkgICAgKiAiSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIC4uLiIKCSAgICAqICgzLjEuMykgIklmIGNsYXVzZSAzLjIgb2YgRWxlbWVudCBMb2NhbGx5IFZhbGlkCgkgICAgKiAoRWxlbWVudCkgKKczLjMuNCkgZGlkIG5vdCBhcHBseSwgdGhlbiB0aGUgt25vcm1hbGl6ZWQgdmFsdWW3CgkgICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgZGVmaW5lZAoJICAgICogYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KCSAgICAqLwkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQkgICAgaW5vZGUsIGlub2RlLT50eXBlRGVmLCBpbm9kZS0+dmFsdWUpOwoJfSBlbHNlIGlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtdHlwZSkgKDMuMikgIklmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBjb21wbGV4IHR5cGUKCSAgICAqIGRlZmluaXRpb24sIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlCgkgICAgKiC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUgdHlwZSBkZWZpbml0aW9uIGFzIHBlcgoJICAgICogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpICinMy40LjQpOyIKCSAgICAqCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMi4yKQoJICAgICogIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIC4uLiAKCSAgICAqIHRoZSC3bm9ybWFsaXplZCB2YWx1Zbcgb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcwoJICAgICogt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGFzCgkgICAgKiBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLCBpbm9kZS0+dmFsdWUpOwoJfQkKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZW5kX2VsZW07Cgl9CgkvKgoJKiA1LjIuMiBJZiB0aGVyZSBpcyBhIGZpeGVkIHt2YWx1ZSBjb25zdHJhaW50fSBhbmQgY2xhdXNlIDMuMiBoYXMgCgkqIG5vdCBhcHBsaWVkLCBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJaWYgKChpbm9kZS0+ZGVjbC0+dmFsdWUgIT0gTlVMTCkgJiYKCSAgICAoaW5vZGUtPmRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkpIHsKCgkgICAgLyoKCSAgICAqIFRPRE86IFdlIHdpbGwgbmVlZCBhIGNvbXB1dGVkIHZhbHVlLCB3aGVuIGNvbXBhcmlzb24gaXMKCSAgICAqIGRvbmUgb24gY29tcHV0ZWQgdmFsdWVzLgoJICAgICovCgkgICAgLyoKCSAgICAqIDUuMi4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqLwoJICAgIGlmIChpbm9kZS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfRUxFTV9DT05URU5UKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8xOwoJCVZFUlJPUihyZXQsIE5VTEwsCgkJICAgICJUaGUgY29udGVudCBtdXN0IG5vdCBjb250YWludCBlbGVtZW50IG5vZGVzIHNpbmNlICIKCQkgICAgInRoZXJlIGlzIGEgZml4ZWQgdmFsdWUgY29uc3RyYWludCIpOwoJCWdvdG8gZW5kX2VsZW07CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogNS4yLjIuMiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgCgkJKiBiZSB0cnVlOgoJCSovCQkKCQlpZiAoV1hTX0hBU19NSVhFRF9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJCSAgICAvKgoJCSAgICAqIDUuMi4yLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlILdhY3R1YWwgdHlwZSAKCQkgICAgKiBkZWZpbml0aW9utyBpcyBtaXhlZCwgdGhlbiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIHRoZSAKCQkgICAgKiBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIAoJCSAgICAqIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCgkJICAgICoKCQkgICAgKiAuLi4gdGhlICppbml0aWFsIHZhbHVlKiBvZiBhbiBlbGVtZW50IGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gaXMgdGhlIHN0cmluZyBjb21wb3NlZCBvZiwgaW4gb3JkZXIsIHRoZSAKCQkgICAgKiBbY2hhcmFjdGVyIGNvZGVdIG9mIGVhY2ggY2hhcmFjdGVyIGluZm9ybWF0aW9uIGl0ZW0gaW4gCgkJICAgICogdGhlIFtjaGlsZHJlbl0gb2YgdGhhdCBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0uCgkJICAgICovCQkgICAKCQkgICAgaWYgKCEgeG1sU3RyRXF1YWwoaW5vZGUtPnZhbHVlLCBpbm9kZS0+ZGVjbC0+dmFsdWUpKXsKCQkJLyogCgkJCSogVkFMIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJCSogVkFMIFRPRE86IEltcGxlbWVudCB0aGUgY2Fub25pY2FsIHN0dWZmLgoJCQkqLwoJCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMTsKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsIAoJCQkgICAgcmV0LCBOVUxMLCBOVUxMLAoJCQkgICAgIlRoZSBpbml0aWFsIHZhbHVlICclcycgZG9lcyBub3QgbWF0Y2ggdGhlIGZpeGVkICIKCQkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLAoJCQkgICAgaW5vZGUtPnZhbHVlLCBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJCQlnb3RvIGVuZF9lbGVtOwoJCSAgICB9CgkJfSBlbHNlIGlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJCSAgICAvKgoJCSAgICAqIDUuMi4yLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlILdhY3R1YWwgdHlwZSAKCQkgICAgKiBkZWZpbml0aW9utyBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIAoJCSAgICAqICphY3R1YWwgdmFsdWUqIG9mIHRoZSBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCAKCQkgICAgKiBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCgkJICAgICovCgkJICAgIC8qCgkJICAgICogVkFMIFRPRE86ICphY3R1YWwgdmFsdWUqIGlzIHRoZSBub3JtYWxpemVkIHZhbHVlLCBpbXBsLgoJCSAgICAqICAgICAgICAgICB0aGlzLgoJCSAgICAqIFZBTCBUT0RPOiBSZXBvcnQgaW52YWxpZCAmIGV4cGVjdGVkIHZhbHVlcyBhcyB3ZWxsLgoJCSAgICAqIFZBTCBUT0RPOiBJbXBsZW1lbnQgYSBjb21wYXJpc29uIHdpdGggdGhlIGNvbXB1dGVkIHZhbHVlcy4KCQkgICAgKi8KCQkgICAgaWYgKCEgeG1sU3RyRXF1YWwoaW5vZGUtPnZhbHVlLAoJCQkgICAgaW5vZGUtPmRlY2wtPnZhbHVlKSkgewoJCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMjsKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJCSAgICByZXQsIE5VTEwsIE5VTEwsCgkJCSAgICAiVGhlIGFjdHVhbCB2YWx1ZSAnJXMnIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCAiCgkJCSAgICAidmFsdWUgY29uc3RyYWludCAnJXMnIiwgCgkJCSAgICBpbm9kZS0+dmFsdWUsCgkJCSAgICBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJCQlnb3RvIGVuZF9lbGVtOwoJCSAgICB9CQkgICAgCgkJfQoJICAgIH0JICAgIAoJfQogICAgfQogICAgCmVuZF9lbGVtOgogICAgaWYgKHZjdHh0LT5kZXB0aCA8IDApIHsKCS8qIFRPRE86IHJhaXNlIGVycm9yPyAqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+ZGVwdGggPT0gdmN0eHQtPnNraXBEZXB0aCkKCXZjdHh0LT5za2lwRGVwdGggPSAtMTsKICAgIC8qCiAgICAqIEV2YWx1YXRlIHRoZSBoaXN0b3J5IG9mIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAgICAqLyAgICAKICAgIGlmIChpbm9kZS0+YXBwbGllZFhQYXRoICYmCgkoeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSh2Y3R4dCwgdmN0eHQtPmRlcHRoKSA9PSAtMSkpCglnb3RvIGludGVybmFsX2Vycm9yOwogICAgLyoKICAgICogTUFZQkUgVE9ETzoKICAgICogU1BFQyAoNikgIlRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSC3dmFsaWS3IHdpdGgKICAgICogcmVzcGVjdCB0byBlYWNoIG9mIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uc30gYXMgcGVyCiAgICAqIElkZW50aXR5LWNvbnN0cmFpbnQgU2F0aXNmaWVkICinMy4xMS40KS4iCiAgICAqLwogICAgLyoKICAgICogUFNWSSBUT0RPOiBJZiB3ZSBleHBvc2UgSURDIG5vZGUtdGFibGVzIHZpYSBQU1ZJIHRoZW4gdGhlIHRhYmxlcwogICAgKiAgIG5lZWQgdG8gYmUgYnVpbHQgaW4gYW55IGNhc2UuCiAgICAqICAgV2Ugd2lsbCBjdXJyZW50bHkgYnVpbGQgSURDIG5vZGUtdGFibGVzIGFuZCBidWJibGUgdGhlbSBvbmx5IGlmCiAgICAqICAga2V5cmVmcyBkbyBleGlzdC4KICAgICovCiAgICAKICAgIC8qCiAgICAqIEFkZCB0aGUgY3VycmVudCBJREMgdGFyZ2V0LW5vZGVzIHRvIHRoZSBJREMgbm9kZS10YWJsZXMuCiAgICAqLwogICAgaWYgKChpbm9kZS0+aWRjTWF0Y2hlcnMgIT0gTlVMTCkgJiYKCSh2Y3R4dC0+aGFzS2V5cmVmcyB8fCB2Y3R4dC0+Y3JlYXRlSURDTm9kZVRhYmxlcykpCiAgICB7CglpZiAoeG1sU2NoZW1hSURDRmlsbE5vZGVUYWJsZXModmN0eHQsIGlub2RlKSA9PSAtMSkKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgLyoKICAgICogVmFsaWRhdGUgSURDIGtleXJlZnMuCiAgICAqLwogICAgaWYgKHZjdHh0LT5pbm9kZS0+aGFzS2V5cmVmcykKCWlmICh4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZih2Y3R4dCkgPT0gLTEpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIC8qCiAgICAqIE1lcmdlL2ZyZWUgdGhlIElEQyB0YWJsZS4KICAgICovCiAgICBpZiAoaW5vZGUtPmlkY1RhYmxlICE9IE5VTEwpIHsKI2lmZGVmIERFQlVHX0lEQ19OT0RFX1RBQkxFCgl4bWxTY2hlbWFEZWJ1Z0R1bXBJRENUYWJsZShzdGRvdXQsCgkgICAgaW5vZGUtPm5zTmFtZSwKCSAgICBpbm9kZS0+bG9jYWxOYW1lLAoJICAgIGlub2RlLT5pZGNUYWJsZSk7CiNlbmRpZgoJaWYgKCh2Y3R4dC0+ZGVwdGggPiAwKSAmJgoJICAgICh2Y3R4dC0+aGFzS2V5cmVmcyB8fCB2Y3R4dC0+Y3JlYXRlSURDTm9kZVRhYmxlcykpCgl7CgkgICAgLyoKCSAgICAqIE1lcmdlIHRoZSBJREMgbm9kZSB0YWJsZSB3aXRoIHRoZSB0YWJsZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh2Y3R4dCkgPT0gLTEpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCX0JCiAgICB9CiAgICAvKgogICAgKiBDbGVhciB0aGUgY3VycmVudCBpZWxlbS4KICAgICogVkFMIFRPRE86IERvbid0IGZyZWUgdGhlIFBTVkkgSURDIHRhYmxlcyBpZiB0aGV5IGFyZQogICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBQU1ZJLgogICAgKi8KICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8odmN0eHQsIGlub2RlKTsKICAgIC8qCiAgICAqIFNraXAgZnVydGhlciBwcm9jZXNzaW5nIGlmIHdlIGFyZSBvbiB0aGUgdmFsaWRhdGlvbiByb290LgogICAgKi8KICAgIGlmICh2Y3R4dC0+ZGVwdGggPT0gMCkgewoJdmN0eHQtPmRlcHRoLS07Cgl2Y3R4dC0+aW5vZGUgPSBOVUxMOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIFJlc2V0IHRoZSBrZXlyZWZEZXB0aCBpZiBuZWVkZWQuCiAgICAqLwogICAgaWYgKHZjdHh0LT5haWRjcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENBdWdQdHIgYWlkYyA9IHZjdHh0LT5haWRjczsKCWRvIHsKCSAgICBpZiAoYWlkYy0+a2V5cmVmRGVwdGggPT0gdmN0eHQtPmRlcHRoKSB7CgkJLyoKCQkqIEEgJ2tleXJlZkRlcHRoJyBvZiBhIGtleS91bmlxdWUgSURDIG1hdGNoZXMgdGhlIGN1cnJlbnQKCQkqIGRlcHRoLCB0aGlzIG1lYW5zIHRoYXQgd2UgYXJlIGxlYXZpbmcgdGhlIHNjb3BlIG9mIHRoZQoJCSogdG9wLW1vc3Qga2V5cmVmIElEQyB3aGljaCByZWZlcnMgdG8gdGhpcyBJREMuCgkJKi8KCQlhaWRjLT5rZXlyZWZEZXB0aCA9IC0xOwoJICAgIH0KCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7CiAgICB9CiAgICB2Y3R4dC0+ZGVwdGgtLTsgICAgICAgIAogICAgdmN0eHQtPmlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwogICAgLyoKICAgICogVkFMIFRPRE86IDcgSWYgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyB0aGUgt3ZhbGlkYXRpb24gcm9vdLcsIGl0IG11c3QgYmUgCiAgICAqILd2YWxpZLcgcGVyIFZhbGlkYXRpb24gUm9vdCBWYWxpZCAoSUQvSURSRUYpICinMy4zLjQpLgogICAgKi8KICAgIHJldHVybiAocmV0KTsKCmludGVybmFsX2Vycm9yOgogICAgdmN0eHQtPmVyciA9IC0xOwogICAgcmV0dXJuICgtMSk7Cn0KCi8qCiogMy40LjQgQ29tcGxleCBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwoqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpIChjdmMtY29tcGxleC10eXBlKQoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgcGllbGVtOwogICAgeG1sU2NoZW1hVHlwZVB0ciBwdHlwZTsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPD0gMCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJICAgICJub3QgaW50ZW5kZWQgZm9yIHRoZSB2YWxpZGF0aW9uIHJvb3QiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgcGllbGVtID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdOwogICAgaWYgKHBpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXBpZWxlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICAvKgogICAgKiBIYW5kbGUgJ25pbGxlZCcgZWxlbWVudHMuCiAgICAqLwogICAgaWYgKElOT0RFX05JTExFRChwaWVsZW0pKSB7CgkvKgoJKiBTUEVDIChjdmMtZWx0KSAoMy4zLjQpIDogKDMuMi4xKQoJKi8KCUFDVElWQVRFX1BBUkVOVF9FTEVNOwoJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMTsKCVZFUlJPUihyZXQsIE5VTEwsCgkgICAgIk5laXRoZXIgY2hhcmFjdGVyIG5vciBlbGVtZW50IGNvbnRlbnQgaXMgYWxsb3dlZCwgIgoJICAgICJiZWNhdXNlIHRoZSBlbGVtZW50IHdhcyAnbmlsbGVkJyIpOwoJQUNUSVZBVEVfRUxFTTsKCWdvdG8gdW5leHBlY3RlZF9lbGVtOwogICAgfQoKICAgIHB0eXBlID0gcGllbGVtLT50eXBlRGVmOwoKICAgIGlmIChwdHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkgewoJLyoKCSogV29ya2Fyb3VuZCBmb3IgImFueVR5cGUiOiB3ZSBoYXZlIGN1cnJlbnRseSBubyBjb250ZW50IG1vZGVsCgkqIGFzc2lnbmVkIGZvciAiYW55VHlwZSIsIHNvIGhhbmRsZSBpdCBleHBsaWNpdGVseS4KCSogImFueVR5cGUiIGhhcyBhbiB1bmJvdW5kZWQsIGxheCAiYW55IiB3aWxkY2FyZC4KCSovCgl2Y3R4dC0+aW5vZGUtPmRlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKHZjdHh0LT5zY2hlbWEsCgkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsCgkgICAgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoKCWlmICh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoJICAgIC8qCgkgICAgKiBQcm9jZXNzICJ4c2k6dHlwZSIuCgkgICAgKiBTUEVDIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMSkgLSAoMS4yLjEuMi4zKQoJICAgICovCgkgICAgaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkJWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CgkgICAgaWYgKGlhdHRyICE9IE5VTEwpIHsKCQlyZXQgPSB4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSh2Y3R4dCwgaWF0dHIsCgkJICAgICYodmN0eHQtPmlub2RlLT50eXBlRGVmKSwgTlVMTCk7CgkJaWYgKHJldCAhPSAwKSB7CgkJICAgIGlmIChyZXQgPT0gLTEpIHsKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJCSAgICAicHJvY2VzcyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICByZXR1cm4gKHJldCk7CgkJfQoJICAgIH0gZWxzZSB7CgkJIC8qCgkJICogRmFsbGJhY2sgdG8gImFueVR5cGUiLgoJCSAqCgkJICogU1BFQyAoY3ZjLWFzc2Vzcy1lbHQpCgkJICogIklmIHRoZSBpdGVtIGNhbm5vdCBiZSC3c3RyaWN0bHkgYXNzZXNzZWS3LCBbLi4uXQoJCSAqIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHNjaGVtYSB2YWxpZGl0eSBtYXkgYmUgbGF4bHkKCQkgKiBhc3Nlc3NlZCBpZiBpdHMgt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgaXMgbm90CgkJICogc2tpcCBieSC3dmFsaWRhdGluZ7cgd2l0aCByZXNwZWN0IHRvIHRoZSC3dXItdHlwZQoJCSAqIGRlZmluaXRpb263IGFzIHBlciBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpICinMy4zLjQpLiIKCQkqLwoJCXZjdHh0LT5pbm9kZS0+dHlwZURlZiA9CgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CgogICAgc3dpdGNoIChwdHlwZS0+Y29udGVudFR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgoJICAgIC8qCgkgICAgKiBTUEVDICgyLjEpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlCgkgICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBvciBlbGVtZW50CgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgoJICAgICovCgkgICAgQUNUSVZBVEVfUEFSRU5UX0VMRU0KCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMTsKCSAgICBWRVJST1IocmV0LCBOVUxMLAoJCSJFbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVtcHR5Iik7CgkgICAgQUNUSVZBVEVfRUxFTQoJICAgIGdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIGJyZWFrOwoKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOiB7CgkgICAgeG1sUmVnRXhlY0N0eHRQdHIgcmVnZXhDdHh0OwoJICAgIHhtbENoYXIgKnZhbHVlc1sxMF07CgkgICAgaW50IHRlcm1pbmFsLCBuYnZhbCA9IDEwLCBuYm5lZzsKCgkgICAgLyogVkFMIFRPRE86IE9wdGltaXplZCAiYW55VHlwZSIgdmFsaWRhdGlvbi4qLwoKCSAgICBpZiAocHR5cGUtPmNvbnRNb2RlbCA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCSAgICAidHlwZSBoYXMgZWxlbSBjb250ZW50IGJ1dCBubyBjb250ZW50IG1vZGVsIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBTYWZldHkgYmVsZiBmb3IgZXZhbHVhdGlvbiBpZiB0aGUgY29udC4gbW9kZWwgd2FzIGFscmVhZHkKCSAgICAqIGV4YW1pbmVkIHRvIGJlIGludmFsaWQuCgkgICAgKi8KCSAgICBpZiAocGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkgICAgInZhbGlkYXRpbmcgZWxlbSwgYnV0IGVsZW0gY29udGVudCBpcyBhbHJlYWR5IGludmFsaWQiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgoJICAgIHJlZ2V4Q3R4dCA9IHBpZWxlbS0+cmVnZXhDdHh0OwoJICAgIGlmIChyZWdleEN0eHQgPT0gTlVMTCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIHJlZ2V4IGNvbnRleHQuCgkJKi8KCQlyZWdleEN0eHQgPSB4bWxSZWdOZXdFeGVjQ3R4dChwdHlwZS0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykgeG1sU2NoZW1hVkNvbnRlbnRNb2RlbENhbGxiYWNrLAoJCSAgICB2Y3R4dCk7CgkJaWYgKHJlZ2V4Q3R4dCA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkJImZhaWxlZCB0byBjcmVhdGUgYSByZWdleCBjb250ZXh0Iik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlwaWVsZW0tPnJlZ2V4Q3R4dCA9IHJlZ2V4Q3R4dDsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJBVVRPTUFUQSBjcmVhdGUgb24gJyVzJ1xuIiwKCQkgICAgcGllbGVtLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICB9CgoJICAgIC8qCgkgICAgKiBTUEVDICgyLjQpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZWxlbWVudC1vbmx5IG9yIG1peGVkLAoJICAgICogdGhlbiB0aGUgc2VxdWVuY2Ugb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzCgkgICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgaWYgYW55LCB0YWtlbiBpbgoJICAgICogb3JkZXIsIGlzILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB7Y29udGVudCB0eXBlfSdzCgkgICAgKiBwYXJ0aWNsZSwgYXMgZGVmaW5lZCBpbiBFbGVtZW50IFNlcXVlbmNlIExvY2FsbHkgVmFsaWQKCSAgICAqIChQYXJ0aWNsZSkgKKczLjkuNCkuIgoJICAgICovCgkgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcyKHJlZ2V4Q3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCSAgICBpZiAocmV0IDwgMCkKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIHB1c2ggRVJST1IgZm9yICclcycgb24gJyVzJ1xuIiwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgcGllbGVtLT5sb2NhbE5hbWUpOwoJICAgIGVsc2UKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIHB1c2ggT0sgZm9yICclcycgb24gJyVzJ1xuIiwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgcGllbGVtLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICBpZiAodmN0eHQtPmVyciA9PSBYTUxfU0NIRU1BVl9JTlRFUk5BTCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sUmVnRXhlY1B1c2hTdHJpbmcyKCkiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxSZWdFeGVjRXJySW5mbyhyZWdleEN0eHQsIE5VTEwsICZuYnZhbCwgJm5ibmVnLAoJCSAgICAmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJCXhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwgTlVMTCxOVUxMLAoJCSAgICAiVGhpcyBlbGVtZW50IGlzIG5vdCBleHBlY3RlZCIsCgkJICAgIG5idmFsLCBuYm5lZywgdmFsdWVzKTsKCQlyZXQgPSB2Y3R4dC0+ZXJyOwoJCWdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIH0gZWxzZQoJCXJldCA9IDA7Cgl9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKCSAgICBBQ1RJVkFURV9QQVJFTlRfRUxFTQoJICAgIGlmIChXWFNfSVNfQ09NUExFWChwdHlwZSkpIHsKCQkvKgoJCSogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkgKDIuMikKCQkqICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuCgkJKiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBlbGVtZW50IGluZm9ybWF0aW9uCgkJKiBpdGVtIFtjaGlsZHJlbl0sIC4uLiIKCQkqLwoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCVZFUlJPUihyZXQsIE5VTEwsICJFbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkgICAgImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24iKTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiBTUEVDIChjdmMtdHlwZSkgKDMuMS4yKSAiVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0CgkJKiBoYXZlIG5vIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLiIKCQkqLwoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8yOwoJCVZFUlJPUihyZXQsIE5VTEwsICJFbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkgICAgImJlY2F1c2UgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBzaW1wbGUiKTsKCSAgICB9CgkgICAgQUNUSVZBVEVfRUxFTQoJICAgIHJldCA9IHZjdHh0LT5lcnI7CgkgICAgZ290byB1bmV4cGVjdGVkX2VsZW07CgkgICAgYnJlYWs7CgoJZGVmYXVsdDoKCSAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAocmV0KTsKdW5leHBlY3RlZF9lbGVtOgogICAgLyoKICAgICogUG9wIHRoaXMgZWxlbWVudCBhbmQgc2V0IHRoZSBza2lwRGVwdGggdG8gc2tpcAogICAgKiBhbGwgZnVydGhlciBjb250ZW50IG9mIHRoZSBwYXJlbnQgZWxlbWVudC4KICAgICovCiAgICB2Y3R4dC0+c2tpcERlcHRoID0gdmN0eHQtPmRlcHRoOwogICAgdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEOwogICAgcGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQ7CiAgICByZXR1cm4gKHJldCk7Cn0KCiNkZWZpbmUgWE1MX1NDSEVNQV9QVVNIX1RFWFRfUEVSU0lTVCAxCiNkZWZpbmUgWE1MX1NDSEVNQV9QVVNIX1RFWFRfQ1JFQVRFRCAyCiNkZWZpbmUgWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEUgMwoKc3RhdGljIGludAp4bWxTY2hlbWFWUHVzaFRleHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgaW50IG5vZGVUeXBlLCBjb25zdCB4bWxDaGFyICp2YWx1ZSwgaW50IGxlbiwKCQkgIGludCBtb2RlLCBpbnQgKmNvbnN1bWVkKQp7CiAgICAvKgogICAgKiBVbmZvcnR1bmF0ZWx5IHdlIGhhdmUgdG8gZHVwbGljYXRlIHRoZSB0ZXh0IHNvbWV0aW1lcy4KICAgICogT1BUSU1JWkU6IE1heWJlIHdlIGNvdWxkIHNraXAgaXQsIGlmOgogICAgKiAgIDEuIGNvbnRlbnQgdHlwZSBpcyBzaW1wbGUKICAgICogICAyLiB3aGl0ZXNwYWNlIGlzICJjb2xsYXBzZSIKICAgICogICAzLiBpdCBjb25zaXN0cyBvZiB3aGl0ZXNwYWNlIG9ubHkKICAgICoKICAgICogUHJvY2VzcyBjaGFyYWN0ZXIgY29udGVudC4KICAgICovCiAgICBpZiAoY29uc3VtZWQgIT0gTlVMTCkKCSpjb25zdW1lZCA9IDA7CiAgICBpZiAoSU5PREVfTklMTEVEKHZjdHh0LT5pbm9kZSkpIHsKCS8qIAoJKiBTUEVDIGN2Yy1lbHQgKDMuMy40IC0gMy4yLjEpCgkqICJUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBjaGFyYWN0ZXIgb3IKCSogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgoJKi8KCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8xLCBOVUxMLAoJICAgICJOZWl0aGVyIGNoYXJhY3RlciBub3IgZWxlbWVudCBjb250ZW50IGlzIGFsbG93ZWQgIgoJICAgICJiZWNhdXNlIHRoZSBlbGVtZW50IGlzICduaWxsZWQnIik7CglyZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogU1BFQyAoMi4xKSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVtcHR5LCB0aGVuIHRoZQogICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBvciBlbGVtZW50CiAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4iCiAgICAqLwogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0KCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsgICAgCglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzEsIE5VTEwsCgkgICAgIkNoYXJhY3RlciBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkgICAgImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbXB0eSIpOwoJcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KCiAgICBpZiAodmN0eHQtPmlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PQoJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgewoJaWYgKChub2RlVHlwZSAhPSBYTUxfVEVYVF9OT0RFKSB8fAoJICAgICghIHhtbFNjaGVtYUlzQmxhbmsoKHhtbENoYXIgKikgdmFsdWUsIGxlbikpKSB7CgkgICAgLyogCgkgICAgKiBTUEVDIGN2Yy1jb21wbGV4LXR5cGUgKDIuMykgCgkgICAgKiAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVsZW1lbnQtb25seSwgdGhlbiB0aGUgCgkgICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBpbmZvcm1hdGlvbiAKCSAgICAqIGl0ZW0gW2NoaWxkcmVuXSBvdGhlciB0aGFuIHRob3NlIHdob3NlIFtjaGFyYWN0ZXIgCgkgICAgKiBjb2RlXSBpcyBkZWZpbmVkIGFzIGEgd2hpdGUgc3BhY2UgaW4gW1hNTCAxLjAgKFNlY29uZCAKCSAgICAqIEVkaXRpb24pXS4iCgkgICAgKi8KCSAgICBWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzMsIE5VTEwsCgkJIkNoYXJhY3RlciBjb250ZW50IG90aGVyIHRoYW4gd2hpdGVzcGFjZSBpcyBub3QgYWxsb3dlZCAiCgkJImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyAnZWxlbWVudC1vbmx5JyIpOwoJICAgIHJldHVybiAodmN0eHQtPmVycik7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgCiAgICBpZiAoKHZhbHVlID09IE5VTEwpIHx8ICh2YWx1ZVswXSA9PSAwKSkKCXJldHVybiAoMCk7CiAgICAvKgogICAgKiBTYXZlIHRoZSB2YWx1ZS4KICAgICogTk9URSB0aGF0IGV2ZW4gaWYgdGhlIGNvbnRlbnQgdHlwZSBpcyAqbWl4ZWQqLCB3ZSBuZWVkIHRoZQogICAgKiAqaW5pdGlhbCB2YWx1ZSogZm9yIGRlZmF1bHQvZml4ZWQgdmFsdWUgY29uc3RyYWludHMuCiAgICAqLwogICAgaWYgKCh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCSgodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpIHx8CgkodmN0eHQtPmlub2RlLT5kZWNsLT52YWx1ZSA9PSBOVUxMKSkpCglyZXR1cm4gKDApOwogICAgCiAgICBpZiAodmN0eHQtPmlub2RlLT52YWx1ZSA9PSBOVUxMKSB7CgkvKgoJKiBTZXQgdGhlIHZhbHVlLgoJKi8KCXN3aXRjaCAobW9kZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9QVVNIX1RFWFRfUEVSU0lTVDoKCQkvKgoJCSogV2hlbiB3b3JraW5nIG9uIGEgdHJlZS4KCQkqLwoJCXZjdHh0LT5pbm9kZS0+dmFsdWUgPSB2YWx1ZTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfUFVTSF9URVhUX0NSRUFURUQ6CgkJLyoKCQkqIFdoZW4gd29ya2luZyB3aXRoIHRoZSByZWFkZXIuCgkJKiBUaGUgdmFsdWUgd2lsbCBiZSBmcmVlZCBieSB0aGUgZWxlbWVudCBpbmZvLgoJCSovCgkJdmN0eHQtPmlub2RlLT52YWx1ZSA9IHZhbHVlOwoJCWlmIChjb25zdW1lZCAhPSBOVUxMKQoJCSAgICAqY29uc3VtZWQgPSAxOwoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0KCQkgICAgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9WT0xBVElMRToKCQkvKgoJCSogV2hlbiB3b3JraW5nIHdpdGggU0FYLgoJCSogVGhlIHZhbHVlIHdpbGwgYmUgZnJlZWQgYnkgdGhlIGVsZW1lbnQgaW5mby4KCQkqLwoJCWlmIChsZW4gIT0gLTEpCgkJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPSBCQURfQ0FTVCB4bWxTdHJuZHVwKHZhbHVlLCBsZW4pOwoJCWVsc2UKCQkgICAgdmN0eHQtPmlub2RlLT52YWx1ZSA9IEJBRF9DQVNUIHhtbFN0cmR1cCh2YWx1ZSk7CgkJdmN0eHQtPmlub2RlLT5mbGFncyB8PQoJCSAgICBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUzsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfSBlbHNlIHsKCWlmIChsZW4gPCAwKQoJICAgIGxlbiA9IHhtbFN0cmxlbih2YWx1ZSk7CgkvKgoJKiBDb25jYXQgdGhlIHZhbHVlLgoJKi8JCglpZiAodmN0eHQtPmlub2RlLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTKSB7CgkgICAgdmN0eHQtPmlub2RlLT52YWx1ZSA9IEJBRF9DQVNUIHhtbFN0cm5jYXQoCgkJKHhtbENoYXIgKikgdmN0eHQtPmlub2RlLT52YWx1ZSwgdmFsdWUsIGxlbik7Cgl9IGVsc2UgewoJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPQoJCUJBRF9DQVNUIHhtbFN0cm5jYXROZXcodmN0eHQtPmlub2RlLT52YWx1ZSwgdmFsdWUsIGxlbik7CgkgICAgdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUzsKCX0KICAgIH0JCgogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmCgkodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJICAgICJpbiBza2lwLXN0YXRlIik7Cglnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgaWYgKHZjdHh0LT54c2lBc3NlbWJsZSkgewoJLyogCgkqIFdlIHdpbGwgc3RvcCB2YWxpZGF0aW9uIGlmIHRoZXJlIHdhcyBhbiBlcnJvciBkdXJpbmcKCSogZHluYW1pYyBzY2hlbWEgY29uc3RydWN0aW9uLgoJKiBOb3RlIHRoYXQgd2Ugc2ltcGx5IHNldCBAc2tpcERlcHRoIHRvIDAsIHRoaXMgY291bGQKCSogbWVhbiB0aGF0IGEgc3RyZWFtaW5nIGRvY3VtZW50IHZpYSBTQVggd291bGQgYmUKCSogc3RpbGwgcmVhZCB0byB0aGUgZW5kIGJ1dCBpdCB3b24ndCBiZSB2YWxpZGF0ZWQgYW55IG1vcmUuCgkqIFRPRE86IElmIHdlIGFyZSBzdXJlIGhvdyB0byBzdG9wIHRoZSB2YWxpZGF0aW9uIGF0IG9uY2UKCSogICBmb3IgYWxsIGlucHV0IHNjZW5hcmlvcywgdGhlbiB0aGlzIHNob3VsZCBiZSBjaGFuZ2VkIHRvCgkqICAgaW5zdGFudGx5IHN0b3AgdGhlIHZhbGlkYXRpb24uCgkqLwoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSSh2Y3R4dCk7CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0ID09IC0xKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgdmN0eHQtPnNraXBEZXB0aCA9IDA7CgkgICAgcmV0dXJuKHJldCk7Cgl9CiAgICB9CiAgICBpZiAodmN0eHQtPmRlcHRoID4gMCkgewoJLyoKCSogVmFsaWRhdGUgdGhpcyBlbGVtZW50IGFnYWluc3QgdGhlIGNvbnRlbnQgbW9kZWwKCSogb2YgdGhlIHBhcmVudC4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSh2Y3R4dCk7CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVN0cmVhbVZhbGlkYXRlQ2hpbGRFbGVtZW50KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGV4aXQ7Cgl9CglpZiAodmN0eHQtPmRlcHRoID09IHZjdHh0LT5za2lwRGVwdGgpCgkgICAgZ290byBleGl0OwoJaWYgKCh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkgJiYKCSAgICAodmN0eHQtPmlub2RlLT50eXBlRGVmID09IE5VTEwpKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCQkidGhlIGNoaWxkIGVsZW1lbnQgd2FzIHZhbGlkIGJ1dCBuZWl0aGVyIHRoZSAiCgkJImRlY2xhcmF0aW9uIG5vciB0aGUgdHlwZSB3YXMgc2V0Iik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBHZXQgdGhlIGRlY2xhcmF0aW9uIG9mIHRoZSB2YWxpZGF0aW9uIHJvb3QuCgkqLwoJdmN0eHQtPmlub2RlLT5kZWNsID0geG1sU2NoZW1hR2V0RWxlbSh2Y3R4dC0+c2NoZW1hLAoJICAgIHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLAoJICAgIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsKCWlmICh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfMTsKCSAgICBWRVJST1IocmV0LCBOVUxMLAoJCSJObyBtYXRjaGluZyBnbG9iYWwgZGVjbGFyYXRpb24gYXZhaWxhYmxlICIKCQkiZm9yIHRoZSB2YWxpZGF0aW9uIHJvb3QiKTsKCSAgICBnb3RvIGV4aXQ7Cgl9CiAgICB9CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKQoJZ290byB0eXBlX3ZhbGlkYXRpb247CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbC0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSB7CglpbnQgc2tpcDsKCS8qCgkqIFdpbGRjYXJkcy4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1XaWxkY2FyZCh2Y3R4dCwgJnNraXApOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1XaWxkY2FyZCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBleGl0OwoJfQoJaWYgKHNraXApIHsKCSAgICB2Y3R4dC0+c2tpcERlcHRoID0gdmN0eHQtPmRlcHRoOwoJICAgIGdvdG8gZXhpdDsKCX0KCS8qCgkqIFRoZSBkZWNsYXJhdGlvbiBtaWdodCBiZSBzZXQgYnkgdGhlIHdpbGRjYXJkIHZhbGlkYXRpb24sCgkqIHdoZW4gdGhlIHByb2Nlc3NDb250ZW50cyBpcyAibGF4IiBvciAic3RyaWN0Ii4KCSovCglpZiAodmN0eHQtPmlub2RlLT5kZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB7CgkgICAgLyoKCSAgICAqIENsZWFyIHRoZSAiZGVjbCIgZmllbGQgdG8gbm90IGNvbmZ1c2UgZnVydGhlciBwcm9jZXNzaW5nLgoJICAgICovCgkgICAgdmN0eHQtPmlub2RlLT5kZWNsID0gTlVMTDsKCSAgICBnb3RvIHR5cGVfdmFsaWRhdGlvbjsKCX0KICAgIH0KICAgIC8qCiAgICAqIFZhbGlkYXRlIGFnYWluc3QgdGhlIGRlY2xhcmF0aW9uLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2wodmN0eHQpOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAocmV0IDwgMCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtRGVjbCgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KCWdvdG8gZXhpdDsKICAgIH0KICAgIC8qCiAgICAqIFZhbGlkYXRlIGFnYWluc3QgdGhlIHR5cGUgZGVmaW5pdGlvbi4KICAgICovCnR5cGVfdmFsaWRhdGlvbjoKCiAgICBpZiAodmN0eHQtPmlub2RlLT50eXBlRGVmID09IE5VTEwpIHsKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFOwoJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMTsKICAgIAlWRVJST1IocmV0LCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKCWdvdG8gZXhpdDsKICAgIH0gICAgCiAgICBpZiAodmN0eHQtPmlub2RlLT50eXBlRGVmLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1QpIHsKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFOwoJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMjsKICAgIAkgICAgVkVSUk9SKHJldCwgTlVMTCwKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzdHJhY3QiKTsJCglnb3RvIGV4aXQ7CiAgICB9CiAgICAvKgogICAgKiBFdmFsdWF0ZSBJRENzLiBEbyBpdCBoZXJlLCBzaW5jZSBuZXcgSURDIG1hdGNoZXJzIGFyZSByZWdpc3RlcmVkCiAgICAqIGR1cmluZyB2YWxpZGF0aW9uIGFnYWluc3QgdGhlIGRlY2xhcmF0aW9uLiBUaGlzIG11c3QgYmUgZG9uZQogICAgKiBfYmVmb3JlXyBhdHRyaWJ1dGUgdmFsaWRhdGlvbi4KICAgICovCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUodmN0eHQsIFhNTF9FTEVNRU5UX05PREUpOwoJdmN0eHQtPmlub2RlLT5hcHBsaWVkWFBhdGggPSAxOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJImNhbGxpbmcgeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KICAgIH0KICAgIC8qCiAgICAqIFZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKFdYU19JU19DT01QTEVYKHZjdHh0LT5pbm9kZS0+dHlwZURlZikpIHsKCWlmICgodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHx8CgkgICAgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+YXR0clVzZXMgIT0gTlVMTCkpIHsKCgkgICAgcmV0ID0geG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4KHZjdHh0KTsKCX0KICAgIH0gZWxzZSBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCglyZXQgPSB4bWxTY2hlbWFWQXR0cmlidXRlc1NpbXBsZSh2Y3R4dCk7CiAgICB9CiAgICAvKgogICAgKiBDbGVhciByZWdpc3RlcmVkIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKQoJeG1sU2NoZW1hQ2xlYXJBdHRySW5mb3ModmN0eHQpOwogICAgaWYgKHJldCA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCSAgICAiY2FsbGluZyBhdHRyaWJ1dGVzIHZhbGlkYXRpb24iKTsKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBEb24ndCByZXR1cm4gYW4gZXJyb3IgaWYgYXR0cmlidXRlcyBhcmUgaW52YWxpZCBvbiBwdXJwb3NlLgogICAgKi8KICAgIHJldCA9IDA7CgpleGl0OgogICAgaWYgKHJldCAhPSAwKQoJdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4gKC0xKTsKfQoKI2lmZGVmIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQKc3RhdGljIGludAp4bWxTY2hlbWFWUmVhZGVyV2Fsayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGNvbnN0IGludCBXSFRTUCA9IDEzLCBTSUdOX1dIVFNQID0gMTQsIEVORF9FTEVNID0gMTU7CiAgICBpbnQgZGVwdGgsIG5vZGVUeXBlLCByZXQgPSAwLCBjb25zdW1lZDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtOwoKICAgIHZjdHh0LT5kZXB0aCA9IC0xOwogICAgcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CiAgICAvKgogICAgKiBNb3ZlIHRvIHRoZSBkb2N1bWVudCBlbGVtZW50LgogICAgKi8KICAgIHdoaWxlIChyZXQgPT0gMSkgewoJbm9kZVR5cGUgPSB4bWxUZXh0UmVhZGVyTm9kZVR5cGUodmN0eHQtPnJlYWRlcik7CglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICBnb3RvIHJvb3RfZm91bmQ7CglyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKICAgIH0KICAgIGdvdG8gZXhpdDsKCnJvb3RfZm91bmQ6CgogICAgZG8gewoJZGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7Cglub2RlVHlwZSA9IHhtbFRleHRSZWFkZXJOb2RlVHlwZSh2Y3R4dC0+cmVhZGVyKTsKCglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJICAgIAoJICAgIHZjdHh0LT5kZXB0aCsrOwoJICAgIGlmICh4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSh2Y3R4dCkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZWxlbSA9IHZjdHh0LT5pbm9kZTsKCSAgICBpZWxlbS0+bG9jYWxOYW1lID0geG1sVGV4dFJlYWRlckxvY2FsTmFtZSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZWxlbS0+bnNOYW1lID0geG1sVGV4dFJlYWRlck5hbWVzcGFjZVVyaSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZWxlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9OQU1FUzsKCSAgICAvKgoJICAgICogSXMgdGhlIGVsZW1lbnQgZW1wdHk/CgkgICAgKi8KCSAgICByZXQgPSB4bWxUZXh0UmVhZGVySXNFbXB0eUVsZW1lbnQodmN0eHQtPnJlYWRlcik7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sVGV4dFJlYWRlcklzRW1wdHlFbGVtZW50KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZiAocmV0KSB7CgkJaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVnaXN0ZXIgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIHZjdHh0LT5uYkF0dHJJbmZvcyA9IDA7CgkgICAgcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb0ZpcnN0QXR0cmlidXRlKHZjdHh0LT5yZWFkZXIpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWYgKHJldCA9PSAxKSB7CgkJZG8gewoJCSAgICAvKgoJCSAgICAqIFZBTCBUT0RPOiBIb3cgZG8gd2Uga25vdyB0aGF0IHRoZSByZWFkZXIgd29ya3Mgb24gYQoJCSAgICAqIG5vZGUgdHJlZSwgdG8gYmUgYWJsZSB0byBwYXNzIGEgbm9kZSBoZXJlPwoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwgTlVMTCwKCQkJKGNvbnN0IHhtbENoYXIgKikgeG1sVGV4dFJlYWRlckxvY2FsTmFtZSh2Y3R4dC0+cmVhZGVyKSwKCQkJeG1sVGV4dFJlYWRlck5hbWVzcGFjZVVyaSh2Y3R4dC0+cmVhZGVyKSwgMSwKCQkJeG1sVGV4dFJlYWRlclZhbHVlKHZjdHh0LT5yZWFkZXIpLCAxKSA9PSAtMSkgewoKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb05leHRBdHRyaWJ1dGUodmN0eHQtPnJlYWRlcik7CgkJICAgIGlmIChyZXQgPT0gLTEpIHsKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sVGV4dFJlYWRlck1vdmVUb0ZpcnN0QXR0cmlidXRlKCkiKTsKCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkgICAgfQoJCX0gd2hpbGUgKHJldCA9PSAxKTsKCQkvKgoJCSogQmFjayB0byBlbGVtZW50IHBvc2l0aW9uLgoJCSovCgkJcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb0VsZW1lbnQodmN0eHQtPnJlYWRlcik7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9FbGVtZW50KCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KCSAgICAqLwoJICAgIHJldD0geG1sU2NoZW1hVmFsaWRhdGVFbGVtKHZjdHh0KTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0ID09IC0xKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBleGl0OwoJICAgIH0KCSAgICBpZiAodmN0eHQtPmRlcHRoID09IHZjdHh0LT5za2lwRGVwdGgpIHsKCQlpbnQgY3VyRGVwdGg7CgkJLyoKCQkqIFNraXAgYWxsIGNvbnRlbnQuCgkJKi8KCQlpZiAoKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZKSA9PSAwKSB7CgkJICAgIHJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwoJCSAgICBjdXJEZXB0aCA9IHhtbFRleHRSZWFkZXJEZXB0aCh2Y3R4dC0+cmVhZGVyKTsKCQkgICAgd2hpbGUgKChyZXQgPT0gMSkgJiYgKGN1ckRlcHRoICE9IGRlcHRoKSkgewoJCQlyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKCQkJY3VyRGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7CgkJICAgIH0KCQkgICAgaWYgKHJldCA8IDApIHsKCQkJLyoKCQkJKiBWQUwgVE9ETzogQSByZWFkZXIgZXJyb3Igb2NjdXJlZDsgd2hhdCB0byBkbyBoZXJlPwoJCQkqLwoJCQlyZXQgPSAxOwoJCQlnb3RvIGV4aXQ7CgkJICAgIH0KCQl9CgkJZ290byBsZWF2ZV9lbGVtOwoJICAgIH0KCSAgICAvKgoJICAgICogUkVBREVSIFZBTCBUT0RPOiBJcyBhbiBFTkRfRUxFTSByZWFsbHkgbmV2ZXIgY2FsbGVkCgkgICAgKiBpZiB0aGUgZWxlbSBpcyBlbXB0eT8KCSAgICAqLwoJICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCQlnb3RvIGxlYXZlX2VsZW07Cgl9IGVsc2UgaWYgKG5vZGVUeXBlID09IEVORF9FTEVNKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgRU5EIG9mIGVsZW1lbnQuCgkgICAgKi8KbGVhdmVfZWxlbToKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHZjdHh0KTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oKSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlnb3RvIGV4aXQ7CgkgICAgfQoJICAgIGlmICh2Y3R4dC0+ZGVwdGggPj0gMCkKCQlpZWxlbSA9IHZjdHh0LT5pbm9kZTsKCSAgICBlbHNlCgkJaWVsZW0gPSBOVUxMOwoJfSBlbHNlIGlmICgobm9kZVR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gV0hUU1ApIHx8CgkgICAgKG5vZGVUeXBlID09IFNJR05fV0hUU1ApKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgY2hhcmFjdGVyIGNvbnRlbnQuCgkgICAgKi8KCSAgICB4bWxDaGFyICp2YWx1ZTsKCgkgICAgaWYgKChub2RlVHlwZSA9PSBXSFRTUCkgfHwgKG5vZGVUeXBlID09IFNJR05fV0hUU1ApKQoJCW5vZGVUeXBlID0gWE1MX1RFWFRfTk9ERTsKCgkgICAgdmFsdWUgPSB4bWxUZXh0UmVhZGVyVmFsdWUodmN0eHQtPnJlYWRlcik7CgkgICAgcmV0ID0geG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBub2RlVHlwZSwgQkFEX0NBU1QgdmFsdWUsCgkJLTEsIFhNTF9TQ0hFTUFfUFVTSF9URVhUX0NSRUFURUQsICZjb25zdW1lZCk7CgkgICAgaWYgKCEgY29uc3VtZWQpCgkJeG1sRnJlZSh2YWx1ZSk7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVlB1c2hUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0gZWxzZSBpZiAoKG5vZGVUeXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkpIHsKCSAgICAvKgoJICAgICogVkFMIFRPRE86IFdoYXQgdG8gZG8gd2l0aCBlbnRpdGllcz8KCSAgICAqLwoJICAgIFRPRE8KCX0KCS8qCgkqIFJlYWQgbmV4dCBub2RlLgoJKi8KCXJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwogICAgfSB3aGlsZSAocmV0ID09IDEpOwoKZXhpdDoKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4gKC0xKTsKfQojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTQVggdmFsaWRhdGlvbiBoYW5kbGVycwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qCiogUHJvY2VzcyB0ZXh0IGNvbnRlbnQuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVRleHQodm9pZCAqY3R4LCAKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIGNoLCAKCQkgICAgICAgaW50IGxlbikKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICBpZiAoeG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBYTUxfVEVYVF9OT0RFLCBjaCwgbGVuLAoJWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEUsIE5VTEwpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7Cgl2Y3R4dC0+ZXJyID0gLTE7Cgl4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIH0KfQoKLyoKKiBQcm9jZXNzIENEQVRBIGNvbnRlbnQuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbih2b2lkICpjdHgsIAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKiBjaCwgCgkJCSAgICAgaW50IGxlbikKeyAgIAogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICBpZiAoeG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFLCBjaCwgbGVuLAoJWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEUsIE5VTEwpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7Cgl2Y3R4dC0+ZXJyID0gLTE7Cgl4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIH0KfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hU0FYSGFuZGxlUmVmZXJlbmNlKHZvaWQgKmN0eCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgLyogU0FYIFZBTCBUT0RPOiBXaGF0IHRvIGRvIGhlcmU/ICovCiAgICBUT0RPCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zKHZvaWQgKmN0eCwKCQkJCSBjb25zdCB4bWxDaGFyICogbG9jYWxuYW1lLCAKCQkJCSBjb25zdCB4bWxDaGFyICogcHJlZml4IEFUVFJJQlVURV9VTlVTRUQsIAoJCQkJIGNvbnN0IHhtbENoYXIgKiBVUkksIAoJCQkJIGludCBuYl9uYW1lc3BhY2VzLCAKCQkJCSBjb25zdCB4bWxDaGFyICoqIG5hbWVzcGFjZXMsIAoJCQkJIGludCBuYl9hdHRyaWJ1dGVzLCAKCQkJCSBpbnQgbmJfZGVmYXVsdGVkIEFUVFJJQlVURV9VTlVTRUQsIAoJCQkJIGNvbnN0IHhtbENoYXIgKiogYXR0cmlidXRlcykKeyAgCiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHg7CiAgICBpbnQgcmV0OwogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW07CiAgICBpbnQgaSwgajsKICAgIAogICAgLyoKICAgICogU0FYIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggbmJfZGVmYXVsdGVkPwogICAgKi8KICAgIC8qCiAgICAqIFNraXAgZWxlbWVudHMgaWYgaW5zaWRlIGEgInNraXAiIHdpbGRjYXJkIG9yIGludmFsaWQuCiAgICAqLwogICAgdmN0eHQtPmRlcHRoKys7CiAgICBpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmICh2Y3R4dC0+ZGVwdGggPj0gdmN0eHQtPnNraXBEZXB0aCkpCglyZXR1cm47CiAgICAvKgogICAgKiBQdXNoIHRoZSBlbGVtZW50LgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSh2Y3R4dCkgPT0gLTEpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSgpIik7Cglnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CiAgICAvKgogICAgKiBUT0RPOiBJcyB0aGlzIE9LPwogICAgKi8KICAgIGllbGVtLT5ub2RlTGluZSA9IHhtbFNBWDJHZXRMaW5lTnVtYmVyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIGllbGVtLT5sb2NhbE5hbWUgPSBsb2NhbG5hbWU7CiAgICBpZWxlbS0+bnNOYW1lID0gVVJJOwogICAgaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgLyoKICAgICogUmVnaXN0ZXIgbmFtZXNwYWNlcyBvbiB0aGUgZWxlbSBpbmZvLgogICAgKi8gICAgCiAgICBpZiAobmJfbmFtZXNwYWNlcyAhPSAwKSB7CgkvKgoJKiBBbHRob3VnaCB0aGUgcGFyc2VyIGJ1aWxkcyBpdHMgb3duIG5hbWVzcGFjZSBsaXN0LAoJKiB3ZSBoYXZlIG5vIGFjY2VzcyB0byBpdCwgc28gd2UnbGwgdXNlIGFuIG93biBvbmUuCgkqLwogICAgICAgIGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbmJfbmFtZXNwYWNlczsgaSsrLCBqICs9IDIpIHsJICAgIAoJICAgIC8qCgkgICAgKiBTdG9yZSBwcmVmaXggYW5kIG5hbWVzcGFjZSBuYW1lLgoJICAgICovCSAgIAoJICAgIGlmIChpZWxlbS0+bnNCaW5kaW5ncyA9PSBOVUxMKSB7CgkJaWVsZW0tPm5zQmluZGluZ3MgPQoJCSAgICAoY29uc3QgeG1sQ2hhciAqKikgeG1sTWFsbG9jKDEwICoKCQkJc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJCWlmIChpZWxlbS0+bnNCaW5kaW5ncyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJCSJhbGxvY2F0aW5nIG5hbWVzcGFjZSBiaW5kaW5ncyBmb3IgU0FYIHZhbGlkYXRpb24iLAoJCQlOVUxMKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJaWVsZW0tPm5iTnNCaW5kaW5ncyA9IDA7CgkJaWVsZW0tPnNpemVOc0JpbmRpbmdzID0gNTsKCSAgICB9IGVsc2UgaWYgKGllbGVtLT5zaXplTnNCaW5kaW5ncyA8PSBpZWxlbS0+bmJOc0JpbmRpbmdzKSB7CgkJaWVsZW0tPnNpemVOc0JpbmRpbmdzICo9IDI7CgkJaWVsZW0tPm5zQmluZGluZ3MgPQoJCSAgICAoY29uc3QgeG1sQ2hhciAqKikgeG1sUmVhbGxvYygKCQkJKHZvaWQgKikgaWVsZW0tPm5zQmluZGluZ3MsCgkJCWllbGVtLT5zaXplTnNCaW5kaW5ncyAqIDIgKiBzaXplb2YoY29uc3QgeG1sQ2hhciAqKSk7CgkJaWYgKGllbGVtLT5uc0JpbmRpbmdzID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkJInJlLWFsbG9jYXRpbmcgbmFtZXNwYWNlIGJpbmRpbmdzIGZvciBTQVggdmFsaWRhdGlvbiIsCgkJCU5VTEwpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCSAgICB9CgoJICAgIGllbGVtLT5uc0JpbmRpbmdzW2llbGVtLT5uYk5zQmluZGluZ3MgKiAyXSA9IG5hbWVzcGFjZXNbal07CgkgICAgaWYgKG5hbWVzcGFjZXNbaisxXVswXSA9PSAwKSB7CgkJLyoKCQkqIEhhbmRsZSB4bWxucz0iIi4KCQkqLwoJCWllbGVtLT5uc0JpbmRpbmdzW2llbGVtLT5uYk5zQmluZGluZ3MgKiAyICsgMV0gPSBOVUxMOwoJICAgIH0gZWxzZQoJCWllbGVtLT5uc0JpbmRpbmdzW2llbGVtLT5uYk5zQmluZGluZ3MgKiAyICsgMV0gPQoJCSAgICBuYW1lc3BhY2VzW2orMV07CgkgICAgaWVsZW0tPm5iTnNCaW5kaW5ncysrOwkgICAgCSAgICAKCX0KICAgIH0KICAgIC8qCiAgICAqIFJlZ2lzdGVyIGF0dHJpYnV0ZXMuCiAgICAqIFNBWCBWQUwgVE9ETzogV2UgYXJlIG5vdCBhZGRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCiAgICAqIGF0dHJpYnV0ZXMgeWV0LgogICAgKi8KICAgIGlmIChuYl9hdHRyaWJ1dGVzICE9IDApIHsKCXhtbENoYXIgKnZhbHVlOwoKICAgICAgICBmb3IgKGogPSAwLCBpID0gMDsgaSA8IG5iX2F0dHJpYnV0ZXM7IGkrKywgaiArPSA1KSB7CgkgICAgLyoKCSAgICAqIER1cGxpY2F0ZSB0aGUgdmFsdWUuCgkgICAgKi8JIAoJICAgIHZhbHVlID0geG1sU3RybmR1cChhdHRyaWJ1dGVzW2orM10sCgkJYXR0cmlidXRlc1tqKzRdIC0gYXR0cmlidXRlc1tqKzNdKTsKCSAgICAvKgoJICAgICogVE9ETzogU2V0IHRoZSBub2RlIGxpbmUuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKHZjdHh0LAoJCU5VTEwsIGllbGVtLT5ub2RlTGluZSwgYXR0cmlidXRlc1tqXSwgYXR0cmlidXRlc1tqKzJdLCAwLAoJCXZhbHVlLCAxKTsKCSAgICBpZiAocmV0ID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlU3RhcnRFbGVtZW50TnMiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIFZhbGlkYXRlIHRoZSBlbGVtZW50LgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbSh2Y3R4dCk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyIsCgkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtKCkiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJZ290byBleGl0OwogICAgfSAgICAKCmV4aXQ6CiAgICByZXR1cm47CmludGVybmFsX2Vycm9yOgogICAgdmN0eHQtPmVyciA9IC0xOwogICAgeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZUVuZEVsZW1lbnROcyh2b2lkICpjdHgsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogbG9jYWxuYW1lIEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogcHJlZml4IEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogVVJJIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKICAgIGludCByZXM7CgogICAgLyoKICAgICogU2tpcCBlbGVtZW50cyBpZiBpbnNpZGUgYSAic2tpcCIgd2lsZGNhcmQgb3IgaWYgaW52YWxpZC4KICAgICovCiAgICBpZiAodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgewoJaWYgKHZjdHh0LT5kZXB0aCA+IHZjdHh0LT5za2lwRGVwdGgpIHsKCSAgICB2Y3R4dC0+ZGVwdGgtLTsKCSAgICByZXR1cm47Cgl9IGVsc2UKCSAgICB2Y3R4dC0+c2tpcERlcHRoID0gLTE7CiAgICB9CiAgICAvKgogICAgKiBTQVggVkFMIFRPRE86IEp1c3QgYSB0ZW1wb3JhcnkgY2hlY2suCiAgICAqLwogICAgaWYgKCgheG1sU3RyRXF1YWwodmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIGxvY2FsbmFtZSkpIHx8CgkoIXhtbFN0ckVxdWFsKHZjdHh0LT5pbm9kZS0+bnNOYW1lLCBVUkkpKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zIiwKCSAgICAiZWxlbSBwb3AgbWlzbWF0Y2giKTsKICAgIH0KICAgIHJlcyA9IHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0odmN0eHQpOwogICAgaWYgKHJlcyAhPSAwKSB7CglpZiAocmVzIDwgMCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZUVuZEVsZW1lbnROcyIsCgkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KCWdvdG8gZXhpdDsKICAgIH0KZXhpdDoKICAgIHJldHVybjsKaW50ZXJuYWxfZXJyb3I6CiAgICB2Y3R4dC0+ZXJyID0gLTE7CiAgICB4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpb24gaW50ZXJmYWNlcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFOZXdWYWxpZEN0eHQ6CiAqIEBzY2hlbWE6ICBhIHByZWNvbXBpbGVkIFhNTCBTY2hlbWFzCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQgYmFzZWQgb24gdGhlIGdpdmVuIHNjaGVtYS4KICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5ub2RlUU5hbWVzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKICAgIHJldC0+c2NoZW1hID0gc2NoZW1hOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2xlYXJWYWxpZEN0eHQ6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dDsKICogbGVhdmVzIHNvbWUgZmllbGRzIGFsaXZlIGludGVuZGVkIGZvciByZXVzZSBvZiB0aGUgY29udGV4dC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaWYgKHZjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qCiAgICAqIFRPRE86IFNob3VsZCB3ZSBjbGVhciB0aGUgZmxhZ3M/CiAgICAqICAgTWlnaHQgYmUgcHJvYmxlbWF0aWMgaWYgb25lIHJldXNlcyB0aGUgY29udGV4dAogICAgKiAgIGFuZCBhc3N1bWVzIHRoYXQgdGhlIG9wdGlvbnMgcmVtYWluIHRoZSBzYW1lLgogICAgKi8KICAgIHZjdHh0LT5mbGFncyA9IDA7CiAgICB2Y3R4dC0+dmFsaWRhdGlvblJvb3QgPSBOVUxMOwogICAgdmN0eHQtPmRvYyA9IE5VTEw7CiNpZmRlZiBMSUJYTUxfUkVBREVSX0VOQUJMRUQKICAgIHZjdHh0LT5yZWFkZXIgPSBOVUxMOwojZW5kaWYKICAgIHZjdHh0LT5oYXNLZXlyZWZzID0gMDsgICAgCgogICAgaWYgKHZjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKHZjdHh0LT52YWx1ZSk7Cgl2Y3R4dC0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogQXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbi4KICAgICovCiAgICBpZiAodmN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBjdXIgPSB2Y3R4dC0+YWlkY3MsIG5leHQ7CglkbyB7CgkgICAgbmV4dCA9IGN1ci0+bmV4dDsKCSAgICB4bWxGcmVlKGN1cik7CgkgICAgY3VyID0gbmV4dDsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKCXZjdHh0LT5haWRjcyA9IE5VTEw7CiAgICB9CiAgICBpZiAodmN0eHQtPmlkY01hdGNoZXJDYWNoZSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIgPSB2Y3R4dC0+aWRjTWF0Y2hlckNhY2hlLCB0bXA7CgoJd2hpbGUgKG1hdGNoZXIpIHsKCSAgICB0bXAgPSBtYXRjaGVyOwoJICAgIG1hdGNoZXIgPSBtYXRjaGVyLT5uZXh0Q2FjaGVkOwoJICAgIHhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdCh0bXApOwoJfQoJdmN0eHQtPmlkY01hdGNoZXJDYWNoZSA9IE5VTEw7CiAgICB9CgoKICAgIGlmICh2Y3R4dC0+aWRjTm9kZXMgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBpdGVtOwoKCWZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJJZGNOb2RlczsgaSsrKSB7CgkgICAgaXRlbSA9IHZjdHh0LT5pZGNOb2Rlc1tpXTsKCSAgICB4bWxGcmVlKGl0ZW0tPmtleXMpOwoJICAgIHhtbEZyZWUoaXRlbSk7Cgl9Cgl4bWxGcmVlKHZjdHh0LT5pZGNOb2Rlcyk7Cgl2Y3R4dC0+aWRjTm9kZXMgPSBOVUxMOwoJdmN0eHQtPm5iSWRjTm9kZXMgPSAwOwoJdmN0eHQtPnNpemVJZGNOb2RlcyA9IDA7CiAgICB9CiAgICAvKgogICAgKiBOb3RlIHRoYXQgd2Ugd29uJ3QgZGVsZXRlIHRoZSBYUGF0aCBzdGF0ZSBwb29sIGhlcmUuCiAgICAqLwogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlSURDU3RhdGVPYmpMaXN0KHZjdHh0LT54cGF0aFN0YXRlcyk7Cgl2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogQXR0cmlidXRlIGluZm8uCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7Cgl4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyh2Y3R4dCk7CiAgICB9CiAgICAvKgogICAgKiBFbGVtZW50IGluZm8uCiAgICAqLwogICAgaWYgKHZjdHh0LT5lbGVtSW5mb3MgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFOb2RlSW5mb1B0ciBlaTsKCglmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykgewoJICAgIGVpID0gdmN0eHQtPmVsZW1JbmZvc1tpXTsKCSAgICBpZiAoZWkgPT0gTlVMTCkKCQlicmVhazsKCSAgICB4bWxTY2hlbWFDbGVhckVsZW1JbmZvKHZjdHh0LCBlaSk7Cgl9CiAgICB9ICAgIAogICAgeG1sU2NoZW1hSXRlbUxpc3RDbGVhcih2Y3R4dC0+bm9kZVFOYW1lcyk7CiAgICAvKiBSZWNyZWF0ZSB0aGUgZGljdC4gKi8KICAgIHhtbERpY3RGcmVlKHZjdHh0LT5kaWN0KTsKICAgIC8qCiAgICAqIFRPRE86IElzIGlzIHNhdmUgdG8gcmVjcmVhdGUgaXQ/IERvIHdlIGhhdmUgYSBzY2VuYXJpbwogICAgKiB3aGVyZSB0aGUgdXNlciBwcm92aWRlcyB0aGUgZGljdD8KICAgICovCiAgICB2Y3R4dC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChjdHh0LT5wY3R4dCk7CiAgICBpZiAoY3R4dC0+aWRjTm9kZXMgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBpdGVtOwoKCWZvciAoaSA9IDA7IGkgPCBjdHh0LT5uYklkY05vZGVzOyBpKyspIHsKCSAgICBpdGVtID0gY3R4dC0+aWRjTm9kZXNbaV07CgkgICAgeG1sRnJlZShpdGVtLT5rZXlzKTsKCSAgICB4bWxGcmVlKGl0ZW0pOwoJfQoJeG1sRnJlZShjdHh0LT5pZGNOb2Rlcyk7CiAgICB9CiAgICBpZiAoY3R4dC0+aWRjS2V5cyAhPSBOVUxMKSB7CglpbnQgaTsKCWZvciAoaSA9IDA7IGkgPCBjdHh0LT5uYklkY0tleXM7IGkrKykKCSAgICB4bWxTY2hlbWFJRENGcmVlS2V5KGN0eHQtPmlkY0tleXNbaV0pOwoJeG1sRnJlZShjdHh0LT5pZGNLZXlzKTsKICAgIH0KCiAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlcyk7CgljdHh0LT54cGF0aFN0YXRlcyA9IE5VTEw7CiAgICB9CiAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlUG9vbCk7CgljdHh0LT54cGF0aFN0YXRlUG9vbCA9IE5VTEw7CiAgICB9CgogICAgLyoKICAgICogQXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbi4KICAgICovCiAgICBpZiAoY3R4dC0+YWlkY3MgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDQXVnUHRyIGN1ciA9IGN0eHQtPmFpZGNzLCBuZXh0OwoJZG8gewoJICAgIG5leHQgPSBjdXItPm5leHQ7CgkgICAgeG1sRnJlZShjdXIpOwoJICAgIGN1ciA9IG5leHQ7Cgl9IHdoaWxlIChjdXIgIT0gTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+YXR0ckluZm9zICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0cjsKCgkvKiBKdXN0IGEgcGFyYW5vaWQgY2FsbCB0byB0aGUgY2xlYW51cC4gKi8KCWlmIChjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKQoJICAgIHhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKGN0eHQpOwoJZm9yIChpID0gMDsgaSA8IGN0eHQtPnNpemVBdHRySW5mb3M7IGkrKykgewoJICAgIGF0dHIgPSBjdHh0LT5hdHRySW5mb3NbaV07CgkgICAgeG1sRnJlZShhdHRyKTsKCX0KCXhtbEZyZWUoY3R4dC0+YXR0ckluZm9zKTsKICAgIH0KICAgIGlmIChjdHh0LT5lbGVtSW5mb3MgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFOb2RlSW5mb1B0ciBlaTsKCglmb3IgKGkgPSAwOyBpIDwgY3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKSB7CgkgICAgZWkgPSBjdHh0LT5lbGVtSW5mb3NbaV07CgkgICAgaWYgKGVpID09IE5VTEwpCgkJYnJlYWs7CgkgICAgeG1sU2NoZW1hQ2xlYXJFbGVtSW5mbyhjdHh0LCBlaSk7CgkgICAgeG1sRnJlZShlaSk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmVsZW1JbmZvcyk7CiAgICB9CiAgICBpZiAoY3R4dC0+bm9kZVFOYW1lcyAhPSBOVUxMKQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGN0eHQtPm5vZGVRTmFtZXMpOwogICAgaWYgKGN0eHQtPmRpY3QgIT0gTlVMTCkKCXhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzVmFsaWQ6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDaGVjayBpZiBhbnkgZXJyb3Igd2FzIGRldGVjdGVkIGR1cmluZyB2YWxpZGF0aW9uLgogKiAKICogUmV0dXJucyAxIGlmIHZhbGlkIHNvIGZhciwgMCBpZiBlcnJvcnMgd2VyZSBkZXRlY3RlZCwgYW5kIC0xIGluIGNhc2UKICogICAgICAgICBvZiBpbnRlcm5hbCBlcnJvci4KICovCmludAp4bWxTY2hlbWFJc1ZhbGlkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybigtMSk7CiAgICByZXR1cm4oY3R4dC0+ZXJyID09IDApOwp9CgovKioKICogeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgZnVuY3Rpb24KICogQHdhcm46IHRoZSB3YXJuaW5nIGZ1bmN0aW9uCiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dAogKgogKiBTZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKi8Kdm9pZAp4bWxTY2hlbWFTZXRWYWxpZEVycm9ycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+ZXJyQ3R4dCA9IGN0eDsKICAgIGlmIChjdHh0LT5wY3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKGN0eHQtPnBjdHh0LCBlcnIsIHdhcm4sIGN0eCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRWYWxpZFN0cnVjdHVyZWRFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzZXJyb3I6ICB0aGUgc3RydWN0dXJlZCBlcnJvciBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBzdHJ1Y3R1cmVkIGVycm9yIGNhbGxiYWNrCiAqLwp2b2lkCnhtbFNjaGVtYVNldFZhbGlkU3RydWN0dXJlZEVycm9ycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3IsIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgljdHh0LT5zZXJyb3IgPSBzZXJyb3I7CiAgICBjdHh0LT5lcnJvciA9IE5VTEw7CiAgICBjdHh0LT53YXJuaW5nID0gTlVMTDsKICAgIGN0eHQtPmVyckN0eHQgPSBjdHg7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNldFBhcnNlclN0cnVjdHVyZWRFcnJvcnMoY3R4dC0+cGN0eHQsIHNlcnJvciwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFZhbGlkRXJyb3JzOgogKiBAY3R4dDoJYSBYTUwtU2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgZnVuY3Rpb24gcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbiByZXN1bHQKICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0IHJlc3VsdAogKgogKiBHZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCXhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQl4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+ZXJyQ3R4dDsKCXJldHVybiAoMCk7Cn0KCgovKioKICogeG1sU2NoZW1hU2V0VmFsaWRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvcHRpb25zOiBhIGNvbWJpbmF0aW9uIG9mIHhtbFNjaGVtYVZhbGlkT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24uCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVNldFZhbGlkT3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJIGludCBvcHRpb25zKQoKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVZhbGlkT3B0aW9uLgogICAgKiBUT0RPOiBJcyB0aGVyZSBhbiBvdGhlciwgbW9yZSBlYXN5IHRvIG1haW50YWluLAogICAgKiB3YXk/CiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgY3R4dC0+b3B0aW9ucyA9IG9wdGlvbnM7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBHZXQgdGhlIHZhbGlkYXRpb24gY29udGV4dCBvcHRpb25zLgogKgogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb3IgLTEgb24gZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkRvY1dhbGsoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgbm9kZSwgdmFsUm9vdDsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKCiAgICAvKiBET0MgVkFMIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgc3RhcnQgZnVuY3Rpb24uICovCiAgICB2YWxSb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQodmN0eHQtPmRvYyk7CiAgICBpZiAodmFsUm9vdCA9PSBOVUxMKSB7CgkvKiBWQUwgVE9ETzogRXJyb3IgY29kZT8gKi8KCVZFUlJPUigxLCBOVUxMLCAiVGhlIGRvY3VtZW50IGhhcyBubyBkb2N1bWVudCBlbGVtZW50Iik7CglyZXR1cm4gKDEpOwogICAgfQogICAgdmN0eHQtPmRlcHRoID0gLTE7CiAgICB2Y3R4dC0+dmFsaWRhdGlvblJvb3QgPSB2YWxSb290OwogICAgbm9kZSA9IHZhbFJvb3Q7CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7CglpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmICh2Y3R4dC0+ZGVwdGggPj0gdmN0eHQtPnNraXBEZXB0aCkpCgkgICAgZ290byBuZXh0X3NpYmxpbmc7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgoJICAgIC8qCgkgICAgKiBJbml0IHRoZSBub2RlLWluZm8uCgkgICAgKi8KCSAgICB2Y3R4dC0+ZGVwdGgrKzsKCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgaWVsZW0tPm5vZGUgPSBub2RlOwoJICAgIGllbGVtLT5ub2RlTGluZSA9IG5vZGUtPmxpbmU7CgkgICAgaWVsZW0tPmxvY2FsTmFtZSA9IG5vZGUtPm5hbWU7CgkgICAgaWYgKG5vZGUtPm5zICE9IE5VTEwpCgkJaWVsZW0tPm5zTmFtZSA9IG5vZGUtPm5zLT5ocmVmOwoJICAgIGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICAvKgoJICAgICogUmVnaXN0ZXIgYXR0cmlidXRlcy4KCSAgICAqIERPQyBWQUwgVE9ETzogV2UgZG8gbm90IHJlZ2lzdGVyIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgoJICAgICogYXR0cmlidXRlcyB5ZXQuCgkgICAgKi8KCSAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwoJICAgIGlmIChub2RlLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKCQlhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCQlkbyB7CgkJICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKQoJCQluc05hbWUgPSBhdHRyLT5ucy0+aHJlZjsKCQkgICAgZWxzZQoJCQluc05hbWUgPSBOVUxMOwoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKHZjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0ciwKCQkJLyogCgkJCSogTm90ZSB0aGF0IHdlIGdpdmUgaXQgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZQoJCQkqIHBhcmVudCBlbGVtZW50LgoJCQkqLwoJCQlpZWxlbS0+bm9kZUxpbmUsCgkJCWF0dHItPm5hbWUsIG5zTmFtZSwgMCwKCQkJeG1sTm9kZUxpc3RHZXRTdHJpbmcoYXR0ci0+ZG9jLCBhdHRyLT5jaGlsZHJlbiwgMSksIDEpOwoJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYURvY1dhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJfSB3aGlsZSAoYXR0cik7CgkgICAgfQoJICAgIC8qCgkgICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFEb2NXYWxrIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJLyoKCQkqIERvbid0IHN0b3AgdmFsaWRhdGlvbjsganVzdCBza2lwIHRoZSBjb250ZW50CgkJKiBvZiB0aGlzIGVsZW1lbnQuCgkJKi8KCQlnb3RvIGxlYXZlX25vZGU7CgkgICAgfQoJICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYKCQkodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJCWdvdG8gbGVhdmVfbm9kZTsKCX0gZWxzZSBpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIGNoYXJhY3RlciBjb250ZW50LgoJICAgICovCgkgICAgaWYgKChpZWxlbSAhPSBOVUxMKSAmJiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpKQoJCWllbGVtLT5mbGFncyBePSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICByZXQgPSB4bWxTY2hlbWFWUHVzaFRleHQodmN0eHQsIG5vZGUtPnR5cGUsIG5vZGUtPmNvbnRlbnQsCgkJLTEsIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1QsIE5VTEwpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkRvY1dhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIC8qCgkgICAgKiBET0MgVkFMIFRPRE86IFNob3VsZCB3ZSBza2lwIGZ1cnRoZXIgdmFsaWRhdGlvbiBvZiB0aGUKCSAgICAqIGVsZW1lbnQgY29udGVudCBoZXJlPwoJICAgICovCgl9IGVsc2UgaWYgKChub2RlLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwKCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSkgewoJICAgIC8qCgkgICAgKiBET0MgVkFMIFRPRE86IFdoYXQgdG8gZG8gd2l0aCBlbnRpdGllcz8KCSAgICAqLwkgICAgCgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkRvY1dhbGsiLAoJCSJ0aGVyZSBpcyBhdCBsZWFzdCBvbmUgZW50aXR5IHJlZmVyZW5jZSBpbiB0aGUgbm9kZS10cmVlICIKCQkiY3VycmVudGx5IGJlaW5nIHZhbGlkYXRlZC4gUHJvY2Vzc2luZyBvZiBlbnRpdGllcyB3aXRoICIKCQkidGhpcyBYTUwgU2NoZW1hIHByb2Nlc3NvciBpcyBub3Qgc3VwcG9ydGVkICh5ZXQpLiBQbGVhc2UgIgoJCSJzdWJzdGl0dXRlIGVudGl0aWVzIGJlZm9yZSB2YWxpZGF0aW9uLiIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9IGVsc2UgewoJICAgIGdvdG8gbGVhdmVfbm9kZTsKCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBYSW5jbHVkZSBub2RlcywgZXRjLgoJICAgICovCgl9CgkvKgoJKiBXYWxrIHRoZSBkb2MuCgkqLwoJaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsKCSAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CgkgICAgY29udGludWU7Cgl9CmxlYXZlX25vZGU6CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkgICAgLyoKCSAgICAqIExlYXZpbmcgdGhlIHNjb3BlIG9mIGFuIGVsZW1lbnQuCgkgICAgKi8KCSAgICBpZiAobm9kZSAhPSB2Y3R4dC0+aW5vZGUtPm5vZGUpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWRG9jV2FsayIsCgkJICAgICJlbGVtZW50IHBvc2l0aW9uIG1pc21hdGNoIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkRvY1dhbGsiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoJICAgIGlmIChub2RlID09IHZhbFJvb3QpCgkJZ290byBleGl0OwoJfQpuZXh0X3NpYmxpbmc6CglpZiAobm9kZS0+bmV4dCAhPSBOVUxMKQoJICAgIG5vZGUgPSBub2RlLT5uZXh0OwoJZWxzZSB7CgkgICAgbm9kZSA9IG5vZGUtPnBhcmVudDsKCSAgICBnb3RvIGxlYXZlX25vZGU7Cgl9CiAgICB9CgpleGl0OgogICAgcmV0dXJuIChyZXQpOwppbnRlcm5hbF9lcnJvcjoKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVByZVJ1bih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpIHsKICAgIC8qCiAgICAqIFNvbWUgaW5pdGlhbGl6YXRpb24uCiAgICAqLyAgICAKICAgIHZjdHh0LT5lcnIgPSAwOwogICAgdmN0eHQtPm5iZXJyb3JzID0gMDsKICAgIHZjdHh0LT5kZXB0aCA9IC0xOwogICAgdmN0eHQtPnNraXBEZXB0aCA9IC0xOwogICAgdmN0eHQtPnhzaUFzc2VtYmxlID0gMDsKICAgIHZjdHh0LT5oYXNLZXlyZWZzID0gMDsKI2lmZGVmIEVOQUJMRV9JRENfTk9ERV9UQUJMRVNfVEVTVAogICAgdmN0eHQtPmNyZWF0ZUlEQ05vZGVUYWJsZXMgPSAxOwojZWxzZQogICAgdmN0eHQtPmNyZWF0ZUlEQ05vZGVUYWJsZXMgPSAwOwojZW5kaWYKICAgIC8qCiAgICAqIENyZWF0ZSBhIHNjaGVtYSArIHBhcnNlciBpZiBuZWNlc3NhcnkuCiAgICAqLwogICAgaWYgKHZjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoJeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKCQoJdmN0eHQtPnhzaUFzc2VtYmxlID0gMTsKCS8qIAoJKiBJZiBub3Qgc2NoZW1hIHdhcyBnaXZlbiB0aGVuIHdlIHdpbGwgY3JlYXRlIGEgc2NoZW1hCgkqIGR5bmFtaWNhbGx5IHVzaW5nIFhTSSBzY2hlbWEgbG9jYXRpb25zLgoJKgoJKiBDcmVhdGUgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dC4KCSovCglpZiAoKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSAmJgoJICAgKHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh2Y3R4dCkgPT0gLTEpKQoJICAgcmV0dXJuICgtMSk7CglwY3R4dCA9IHZjdHh0LT5wY3R4dDsKCXBjdHh0LT54c2lBc3NlbWJsZSA9IDE7CgkvKgoJKiBDcmVhdGUgdGhlIHNjaGVtYS4KCSovCgl2Y3R4dC0+c2NoZW1hID0geG1sU2NoZW1hTmV3U2NoZW1hKHBjdHh0KTsKCWlmICh2Y3R4dC0+c2NoZW1hID09IE5VTEwpCgkgICAgcmV0dXJuICgtMSk7CQkKCS8qIAoJKiBDcmVhdGUgdGhlIHNjaGVtYSBjb25zdHJ1Y3Rpb24gY29udGV4dC4KCSovCglwY3R4dC0+Y29uc3RydWN0b3IgPSB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0Q3JlYXRlKHBjdHh0LT5kaWN0KTsKCWlmIChwY3R4dC0+Y29uc3RydWN0b3IgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJcGN0eHQtPmNvbnN0cnVjdG9yLT5tYWluU2NoZW1hID0gdmN0eHQtPnNjaGVtYTsKCS8qCgkqIFRha2Ugb3duZXJzaGlwIG9mIHRoZSBjb25zdHJ1Y3RvciB0byBiZSBhYmxlIHRvIGZyZWUgaXQuCgkqLwoJcGN0eHQtPm93bnNDb25zdHJ1Y3RvciA9IDE7CiAgICB9CQogICAgLyoKICAgICogQXVnbWVudCB0aGUgSURDIGRlZmluaXRpb25zLgogICAgKi8KICAgIGlmICh2Y3R4dC0+c2NoZW1hLT5pZGNEZWYgIT0gTlVMTCkgewoJeG1sSGFzaFNjYW4odmN0eHQtPnNjaGVtYS0+aWRjRGVmLAoJICAgICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXVnbWVudElEQywgdmN0eHQpOwogICAgfQogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQb3N0UnVuKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkgewogICAgaWYgKHZjdHh0LT54c2lBc3NlbWJsZSkgewoJaWYgKHZjdHh0LT5zY2hlbWEgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWUodmN0eHQtPnNjaGVtYSk7CgkgICAgdmN0eHQtPnNjaGVtYSA9IE5VTEw7Cgl9CiAgICB9CiAgICB4bWxTY2hlbWFDbGVhclZhbGlkQ3R4dCh2Y3R4dCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVlN0YXJ0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IHJldCA9IDA7CgogICAgaWYgKHhtbFNjaGVtYVByZVJ1bih2Y3R4dCkgPCAwKQogICAgICAgIHJldHVybigtMSk7CgogICAgaWYgKHZjdHh0LT5kb2MgIT0gTlVMTCkgewoJLyoKCSAqIFRyZWUgdmFsaWRhdGlvbi4KCSAqLwoJcmV0ID0geG1sU2NoZW1hVkRvY1dhbGsodmN0eHQpOwojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECiAgICB9IGVsc2UgaWYgKHZjdHh0LT5yZWFkZXIgIT0gTlVMTCkgewoJLyoKCSAqIFhNTCBSZWFkZXIgdmFsaWRhdGlvbi4KCSAqLwojaWZkZWYgWE1MX1NDSEVNQV9SRUFERVJfRU5BQkxFRAoJcmV0ID0geG1sU2NoZW1hVlJlYWRlcldhbGsodmN0eHQpOwojZW5kaWYKI2VuZGlmCiAgICB9IGVsc2UgaWYgKCh2Y3R4dC0+c2F4ICE9IE5VTEwpICYmICh2Y3R4dC0+cGFyc2VyQ3R4dCAhPSBOVUxMKSkgewoJLyoKCSAqIFNBWCB2YWxpZGF0aW9uLgoJICovCglyZXQgPSB4bWxQYXJzZURvY3VtZW50KHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIH0gZWxzZSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWU3RhcnQiLAoJICAgICJubyBpbnN0YW5jZSB0byB2YWxpZGF0ZSIpOwoJcmV0ID0gLTE7CiAgICB9CgogICAgeG1sU2NoZW1hUG9zdFJ1bih2Y3R4dCk7CiAgICBpZiAocmV0ID09IDApCglyZXQgPSB2Y3R4dC0+ZXJyOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQgbm9kZQogKgogKiBWYWxpZGF0ZSBhIGJyYW5jaCBvZiBhIHRyZWUsIHN0YXJ0aW5nIHdpdGggdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgYW5kIGl0cyBzdWJ0cmVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yCiAqIGNvZGUgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0pCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZWxlbSA9PSBOVUxMKSB8fCAoZWxlbS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSkKCXJldHVybiAoLTEpOwoKICAgIGlmIChjdHh0LT5zY2hlbWEgPT0gTlVMTCkKCXJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGVsZW0tPmRvYzsKICAgIGN0eHQtPm5vZGUgPSBlbGVtOwogICAgY3R4dC0+dmFsaWRhdGlvblJvb3QgPSBlbGVtOwogICAgcmV0dXJuKHhtbFNjaGVtYVZTdGFydChjdHh0KSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvYzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGRvYzogIGEgcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxEb2NQdHIgZG9jKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGRvYyA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICBjdHh0LT5kb2MgPSBkb2M7CiAgICBjdHh0LT5ub2RlID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChjdHh0LT5ub2RlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0RPQ1VNRU5UX0VMRU1FTlRfTUlTU0lORywKCSAgICAoeG1sTm9kZVB0cikgZG9jLCBOVUxMLAoJICAgICJUaGUgZG9jdW1lbnQgaGFzIG5vIGRvY3VtZW50IGVsZW1lbnQiLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGN0eHQtPm5vZGU7CiAgICByZXR1cm4gKHhtbFNjaGVtYVZTdGFydChjdHh0KSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQlGdW5jdGlvbiBhbmQgZGF0YSBmb3IgU0FYIHN0cmVhbWluZyBBUEkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVNwbGl0U0FYRGF0YSB4bWxTY2hlbWFTcGxpdFNBWERhdGE7CnR5cGVkZWYgeG1sU2NoZW1hU3BsaXRTQVhEYXRhICp4bWxTY2hlbWFTcGxpdFNBWERhdGFQdHI7CgpzdHJ1Y3QgX3htbFNjaGVtYVNwbGl0U0FYRGF0YSB7CiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAgdXNlcl9zYXg7CiAgICB2b2lkICAgICAgICAgICAgICAgICAqdXNlcl9kYXRhOwogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQ7CiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAgc2NoZW1hc19zYXg7Cn07CgojZGVmaW5lIFhNTF9TQVhfUExVR19NQUdJQyAweGRjNDNiYTIxCgpzdHJ1Y3QgX3htbFNjaGVtYVNBWFBsdWcgewogICAgdW5zaWduZWQgaW50IG1hZ2ljOwoKICAgIC8qIHRoZSBvcmlnaW5hbCBjYWxsYmFja3MgaW5mb3JtYXRpb25zICovCiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAqdXNlcl9zYXhfcHRyOwogICAgeG1sU0FYSGFuZGxlclB0ciAgICAgIHVzZXJfc2F4OwogICAgdm9pZCAgICAgICAgICAgICAgICAqKnVzZXJfZGF0YV9wdHI7CiAgICB2b2lkICAgICAgICAgICAgICAgICAqdXNlcl9kYXRhOwoKICAgIC8qIHRoZSBibG9jayBwbHVnZ2VkIGJhY2sgYW5kIHZhbGlkYXRpb24gaW5mb3JtYXRpb25zICovCiAgICB4bWxTQVhIYW5kbGVyICAgICAgICAgc2NoZW1hc19zYXg7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dDsKfTsKCi8qIEFsbCB0aG9zZSBmdW5jdGlvbnMganVzdCBib3VuY2VzIHRvIHRoZSB1c2VyIHByb3ZpZGVkIFNBWCBoYW5kbGVycyAqLwpzdGF0aWMgdm9pZAppbnRlcm5hbFN1YnNldFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSwKCSAgICAgICBjb25zdCB4bWxDaGFyICpFeHRlcm5hbElELCBjb25zdCB4bWxDaGFyICpTeXN0ZW1JRCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmludGVybmFsU3Vic2V0ICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmludGVybmFsU3Vic2V0KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSwgRXh0ZXJuYWxJRCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW1JRCk7Cn0KCnN0YXRpYyBpbnQKaXNTdGFuZGFsb25lU3BsaXQodm9pZCAqY3R4KQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aXNTdGFuZGFsb25lICE9IE5VTEwpKQoJcmV0dXJuKGN0eHQtPnVzZXJfc2F4LT5pc1N0YW5kYWxvbmUoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKaGFzSW50ZXJuYWxTdWJzZXRTcGxpdCh2b2lkICpjdHgpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5oYXNJbnRlcm5hbFN1YnNldCAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+aGFzSW50ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKaGFzRXh0ZXJuYWxTdWJzZXRTcGxpdCh2b2lkICpjdHgpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5oYXNFeHRlcm5hbFN1YnNldCAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+aGFzRXh0ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyB2b2lkCmV4dGVybmFsU3Vic2V0U3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpuYW1lLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKkV4dGVybmFsSUQsIGNvbnN0IHhtbENoYXIgKlN5c3RlbUlEKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aW50ZXJuYWxTdWJzZXQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+aW50ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBFeHRlcm5hbElELAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbUlEKTsKfQoKc3RhdGljIHhtbFBhcnNlcklucHV0UHRyCnJlc29sdmVFbnRpdHlTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKnB1YmxpY0lkLCBjb25zdCB4bWxDaGFyICpzeXN0ZW1JZCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnJlc29sdmVFbnRpdHkgIT0gTlVMTCkpCglyZXR1cm4oY3R4dC0+dXNlcl9zYXgtPnJlc29sdmVFbnRpdHkoY3R4dC0+dXNlcl9kYXRhLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgpzdGF0aWMgeG1sRW50aXR5UHRyCmdldEVudGl0eVNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmdldEVudGl0eSAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+Z2V0RW50aXR5KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgpzdGF0aWMgeG1sRW50aXR5UHRyCmdldFBhcmFtZXRlckVudGl0eVNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmdldFBhcmFtZXRlckVudGl0eSAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+Z2V0UGFyYW1ldGVyRW50aXR5KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgoKc3RhdGljIHZvaWQKZW50aXR5RGVjbFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSwgaW50IHR5cGUsCiAgICAgICAgICBjb25zdCB4bWxDaGFyICpwdWJsaWNJZCwgY29uc3QgeG1sQ2hhciAqc3lzdGVtSWQsIHhtbENoYXIgKmNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5lbnRpdHlEZWNsICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmVudGl0eURlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCB0eXBlLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkLCBjb250ZW50KTsKfQoKc3RhdGljIHZvaWQKYXR0cmlidXRlRGVjbFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqIGVsZW0sCiAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgaW50IHR5cGUsIGludCBkZWYsCiAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogZGVmYXVsdFZhbHVlLCB4bWxFbnVtZXJhdGlvblB0ciB0cmVlKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+YXR0cmlidXRlRGVjbCAhPSBOVUxMKSkgewoJY3R4dC0+dXNlcl9zYXgtPmF0dHJpYnV0ZURlY2woY3R4dC0+dXNlcl9kYXRhLCBlbGVtLCBuYW1lLCB0eXBlLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmLCBkZWZhdWx0VmFsdWUsIHRyZWUpOwogICAgfSBlbHNlIHsKCXhtbEZyZWVFbnVtZXJhdGlvbih0cmVlKTsKICAgIH0KfQoKc3RhdGljIHZvaWQKZWxlbWVudERlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsIGludCB0eXBlLAoJICAgIHhtbEVsZW1lbnRDb250ZW50UHRyIGNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5lbGVtZW50RGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5lbGVtZW50RGVjbChjdHh0LT51c2VyX2RhdGEsIG5hbWUsIHR5cGUsIGNvbnRlbnQpOwp9CgpzdGF0aWMgdm9pZApub3RhdGlvbkRlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkgICAgIGNvbnN0IHhtbENoYXIgKnB1YmxpY0lkLCBjb25zdCB4bWxDaGFyICpzeXN0ZW1JZCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPm5vdGF0aW9uRGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5ub3RhdGlvbkRlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwp9CgpzdGF0aWMgdm9pZAp1bnBhcnNlZEVudGl0eURlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJICAgY29uc3QgeG1sQ2hhciAqcHVibGljSWQsIGNvbnN0IHhtbENoYXIgKnN5c3RlbUlkLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5vdGF0aW9uTmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnVucGFyc2VkRW50aXR5RGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT51bnBhcnNlZEVudGl0eURlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQsIG5vdGF0aW9uTmFtZSk7Cn0KCnN0YXRpYyB2b2lkCnNldERvY3VtZW50TG9jYXRvclNwbGl0KHZvaWQgKmN0eCwgeG1sU0FYTG9jYXRvclB0ciBsb2MpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5zZXREb2N1bWVudExvY2F0b3IgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+c2V0RG9jdW1lbnRMb2NhdG9yKGN0eHQtPnVzZXJfZGF0YSwgbG9jKTsKfQoKc3RhdGljIHZvaWQKc3RhcnREb2N1bWVudFNwbGl0KHZvaWQgKmN0eCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnN0YXJ0RG9jdW1lbnQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+c3RhcnREb2N1bWVudChjdHh0LT51c2VyX2RhdGEpOwp9CgpzdGF0aWMgdm9pZAplbmREb2N1bWVudFNwbGl0KHZvaWQgKmN0eCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmVuZERvY3VtZW50ICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmVuZERvY3VtZW50KGN0eHQtPnVzZXJfZGF0YSk7Cn0KCnN0YXRpYyB2b2lkCnByb2Nlc3NpbmdJbnN0cnVjdGlvblNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqZGF0YSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnByb2Nlc3NpbmdJbnN0cnVjdGlvbiAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oY3R4dC0+dXNlcl9kYXRhLCB0YXJnZXQsIGRhdGEpOwp9CgpzdGF0aWMgdm9pZApjb21tZW50U3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICp2YWx1ZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmNvbW1lbnQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+Y29tbWVudChjdHh0LT51c2VyX2RhdGEsIHZhbHVlKTsKfQoKLyoKICogVmFyYXJncyBlcnJvciBjYWxsYmFja3MgdG8gdGhlIHVzZXIgYXBwbGljYXRpb24sIGhhcmRlciAuLi4KICovCgpzdGF0aWMgdm9pZCBYTUxDREVDTAp3YXJuaW5nU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+d2FybmluZyAhPSBOVUxMKSkgewoJVE9ETwogICAgfQp9CnN0YXRpYyB2b2lkIFhNTENERUNMCmVycm9yU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+ZXJyb3IgIT0gTlVMTCkpIHsKCVRPRE8KICAgIH0KfQpzdGF0aWMgdm9pZCBYTUxDREVDTApmYXRhbEVycm9yU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+ZmF0YWxFcnJvciAhPSBOVUxMKSkgewoJVE9ETwogICAgfQp9CgovKgogKiBUaG9zZSBhcmUgZnVuY3Rpb24gd2hlcmUgYm90aCB0aGUgdXNlciBoYW5kbGVyIGFuZCB0aGUgc2NoZW1hcyBoYW5kbGVyCiAqIG5lZWQgdG8gYmUgY2FsbGVkLgogKi8Kc3RhdGljIHZvaWQKY2hhcmFjdGVyc1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqY2gsIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4LT5jaGFyYWN0ZXJzICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmNoYXJhY3RlcnMoY3R4dC0+dXNlcl9kYXRhLCBjaCwgbGVuKTsKICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTQVhIYW5kbGVUZXh0KGN0eHQtPmN0eHQsIGNoLCBsZW4pOwp9CgpzdGF0aWMgdm9pZAppZ25vcmFibGVXaGl0ZXNwYWNlU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpjaCwgaW50IGxlbikKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aWdub3JhYmxlV2hpdGVzcGFjZSAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5pZ25vcmFibGVXaGl0ZXNwYWNlKGN0eHQtPnVzZXJfZGF0YSwgY2gsIGxlbik7CiAgICBpZiAoY3R4dC0+Y3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU0FYSGFuZGxlVGV4dChjdHh0LT5jdHh0LCBjaCwgbGVuKTsKfQoKc3RhdGljIHZvaWQKY2RhdGFCbG9ja1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqdmFsdWUsIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+aWdub3JhYmxlV2hpdGVzcGFjZShjdHh0LT51c2VyX2RhdGEsIHZhbHVlLCBsZW4pOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbihjdHh0LT5jdHh0LCB2YWx1ZSwgbGVuKTsKfQoKc3RhdGljIHZvaWQKcmVmZXJlbmNlU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5yZWZlcmVuY2UgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+cmVmZXJlbmNlKGN0eHQtPnVzZXJfZGF0YSwgbmFtZSk7CiAgICBpZiAoY3R4dC0+Y3R4dCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZShjdHh0LT51c2VyX2RhdGEsIG5hbWUpOwp9CgpzdGF0aWMgdm9pZApzdGFydEVsZW1lbnROc1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSwgCgkJICAgIGNvbnN0IHhtbENoYXIgKiBwcmVmaXgsIGNvbnN0IHhtbENoYXIgKiBVUkksIAoJCSAgICBpbnQgbmJfbmFtZXNwYWNlcywgY29uc3QgeG1sQ2hhciAqKiBuYW1lc3BhY2VzLCAKCQkgICAgaW50IG5iX2F0dHJpYnV0ZXMsIGludCBuYl9kZWZhdWx0ZWQsIAoJCSAgICBjb25zdCB4bWxDaGFyICoqIGF0dHJpYnV0ZXMpIHsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnN0YXJ0RWxlbWVudE5zICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPnN0YXJ0RWxlbWVudE5zKGN0eHQtPnVzZXJfZGF0YSwgbG9jYWxuYW1lLCBwcmVmaXgsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVJJLCBuYl9uYW1lc3BhY2VzLCBuYW1lc3BhY2VzLAoJCQkJICAgICAgIG5iX2F0dHJpYnV0ZXMsIG5iX2RlZmF1bHRlZCwKCQkJCSAgICAgICBhdHRyaWJ1dGVzKTsKICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyhjdHh0LT5jdHh0LCBsb2NhbG5hbWUsIHByZWZpeCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSwgbmJfbmFtZXNwYWNlcywgbmFtZXNwYWNlcywKCQkJCQkgbmJfYXR0cmlidXRlcywgbmJfZGVmYXVsdGVkLAoJCQkJCSBhdHRyaWJ1dGVzKTsKfQoKc3RhdGljIHZvaWQKZW5kRWxlbWVudE5zU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICogbG9jYWxuYW1lLCAKCQkgICAgY29uc3QgeG1sQ2hhciAqIHByZWZpeCwgY29uc3QgeG1sQ2hhciAqIFVSSSkgewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+ZW5kRWxlbWVudE5zICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmVuZEVsZW1lbnROcyhjdHh0LT51c2VyX2RhdGEsIGxvY2FsbmFtZSwgcHJlZml4LCBVUkkpOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNBWEhhbmRsZUVuZEVsZW1lbnROcyhjdHh0LT5jdHh0LCBsb2NhbG5hbWUsIHByZWZpeCwgVVJJKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNBWFBsdWc6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzYXg6ICBhIHBvaW50ZXIgdG8gdGhlIG9yaWdpbmFsIHhtbFNBWEhhbmRsZXJQdHIKICogQHVzZXJfZGF0YTogIGEgcG9pbnRlciB0byB0aGUgb3JpZ2luYWwgU0FYIHVzZXIgZGF0YSBwb2ludGVyCiAqCiAqIFBsdWcgYSBTQVggYmFzZWQgdmFsaWRhdGlvbiBsYXllciBpbiBhIFNBWCBwYXJzaW5nIGV2ZW50IGZsb3cuCiAqIFRoZSBvcmlnaW5hbCBAc2F4cHRyIGFuZCBAZGF0YXB0ciBkYXRhIGFyZSByZXBsYWNlZCBieSBuZXcgcG9pbnRlcnMKICogYnV0IHRoZSBjYWxscyB0byB0aGUgb3JpZ2luYWwgd2lsbCBiZSBtYWludGFpbmVkLgogKgogKiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIGRhdGEgc3RydWN0dXJlIG5lZWRlZCB0byB1bnBsdWcgdGhlIHZhbGlkYXRpb24gbGF5ZXIKICogICAgICAgICBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3JzLgogKi8KeG1sU2NoZW1hU0FYUGx1Z1B0cgp4bWxTY2hlbWFTQVhQbHVnKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCSB4bWxTQVhIYW5kbGVyUHRyICpzYXgsIHZvaWQgKip1c2VyX2RhdGEpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgcmV0OwogICAgeG1sU0FYSGFuZGxlclB0ciBvbGRfc2F4OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2F4ID09IE5VTEwpIHx8ICh1c2VyX2RhdGEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuKE5VTEwpOwoKICAgIC8qCiAgICAgKiBXZSBvbmx5IGFsbG93IHRvIHBsdWcgaW50byBTQVgyIGV2ZW50IHN0cmVhbXMKICAgICAqLwogICAgb2xkX3NheCA9ICpzYXg7CiAgICBpZiAoKG9sZF9zYXggIT0gTlVMTCkgJiYgKG9sZF9zYXgtPmluaXRpYWxpemVkICE9IFhNTF9TQVgyX01BR0lDKSkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICBpZiAoKG9sZF9zYXggIT0gTlVMTCkgJiYgCiAgICAgICAgKG9sZF9zYXgtPnN0YXJ0RWxlbWVudE5zID09IE5VTEwpICYmIChvbGRfc2F4LT5lbmRFbGVtZW50TnMgPT0gTlVMTCkgJiYKICAgICAgICAoKG9sZF9zYXgtPnN0YXJ0RWxlbWVudCAhPSBOVUxMKSB8fCAob2xkX3NheC0+ZW5kRWxlbWVudCAhPSBOVUxMKSkpCiAgICAgICAgcmV0dXJuKE5VTEwpOwoKICAgIC8qCiAgICAgKiBldmVyeXRoaW5nIHNlZW1zIHJpZ2h0IGFsbG9jYXRlIHRoZSBsb2NhbCBkYXRhIG5lZWRlZCBmb3IgdGhhdCBsYXllcgogICAgICovCiAgICByZXQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFTQVhQbHVnU3RydWN0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hU0FYUGx1Z1N0cnVjdCkpOwogICAgcmV0LT5tYWdpYyA9IFhNTF9TQVhfUExVR19NQUdJQzsKICAgIHJldC0+c2NoZW1hc19zYXguaW5pdGlhbGl6ZWQgPSBYTUxfU0FYMl9NQUdJQzsKICAgIHJldC0+Y3R4dCA9IGN0eHQ7CiAgICByZXQtPnVzZXJfc2F4X3B0ciA9IHNheDsKICAgIHJldC0+dXNlcl9zYXggPSBvbGRfc2F4OwogICAgaWYgKG9sZF9zYXggPT0gTlVMTCkgewkKICAgICAgICAvKgoJICogZ28gZGlyZWN0LCBubyBuZWVkIGZvciB0aGUgc3BsaXQgYmxvY2sgYW5kIGZ1bmN0aW9ucy4KCSAqLwoJcmV0LT5zY2hlbWFzX3NheC5zdGFydEVsZW1lbnROcyA9IHhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zOwoJcmV0LT5zY2hlbWFzX3NheC5lbmRFbGVtZW50TnMgPSB4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnM7CgkvKgoJICogTm90ZSB0aGF0IHdlIHVzZSB0aGUgc2FtZSB0ZXh0LWZ1bmN0aW9uIGZvciBib3RoLCB0byBwcmV2ZW50CgkgKiB0aGUgcGFyc2VyIGZyb20gdGVzdGluZyBmb3IgaWdub3JhYmxlIHdoaXRlc3BhY2UuCgkgKi8KCXJldC0+c2NoZW1hc19zYXguaWdub3JhYmxlV2hpdGVzcGFjZSA9IHhtbFNjaGVtYVNBWEhhbmRsZVRleHQ7CglyZXQtPnNjaGVtYXNfc2F4LmNoYXJhY3RlcnMgPSB4bWxTY2hlbWFTQVhIYW5kbGVUZXh0OwoKCXJldC0+c2NoZW1hc19zYXguY2RhdGFCbG9jayA9IHhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbjsKCXJldC0+c2NoZW1hc19zYXgucmVmZXJlbmNlID0geG1sU2NoZW1hU0FYSGFuZGxlUmVmZXJlbmNlOwoKCXJldC0+dXNlcl9kYXRhID0gY3R4dDsKCSp1c2VyX2RhdGEgPSBjdHh0OwogICAgfSBlbHNlIHsKICAgICAgIC8qCiAgICAgICAgKiBmb3IgZWFjaCBjYWxsYmFjayB1bnVzZWQgYnkgU2NoZW1hcyBpbml0aWFsaXplIGl0IHRvIHRoZSBTcGxpdAoJKiByb3V0aW5lIG9ubHkgaWYgbm9uIE5VTEwgaW4gdGhlIHVzZXIgYmxvY2ssIHRoaXMgY2FuIHNwZWVkIHVwIAoJKiB0aGluZ3MgYXQgdGhlIFNBWCBsZXZlbC4KCSovCiAgICAgICAgaWYgKG9sZF9zYXgtPmludGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaW50ZXJuYWxTdWJzZXQgPSBpbnRlcm5hbFN1YnNldFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5pc1N0YW5kYWxvbmUgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5pc1N0YW5kYWxvbmUgPSBpc1N0YW5kYWxvbmVTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+aGFzSW50ZXJuYWxTdWJzZXQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5oYXNJbnRlcm5hbFN1YnNldCA9IGhhc0ludGVybmFsU3Vic2V0U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmhhc0V4dGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaGFzRXh0ZXJuYWxTdWJzZXQgPSBoYXNFeHRlcm5hbFN1YnNldFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5yZXNvbHZlRW50aXR5ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgucmVzb2x2ZUVudGl0eSA9IHJlc29sdmVFbnRpdHlTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+Z2V0RW50aXR5ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZ2V0RW50aXR5ID0gZ2V0RW50aXR5U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmVudGl0eURlY2wgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5lbnRpdHlEZWNsID0gZW50aXR5RGVjbFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5ub3RhdGlvbkRlY2wgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5ub3RhdGlvbkRlY2wgPSBub3RhdGlvbkRlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+YXR0cmlidXRlRGVjbCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmF0dHJpYnV0ZURlY2wgPSBhdHRyaWJ1dGVEZWNsU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmVsZW1lbnREZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZWxlbWVudERlY2wgPSBlbGVtZW50RGVjbFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT51bnBhcnNlZEVudGl0eURlY2wgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC51bnBhcnNlZEVudGl0eURlY2wgPSB1bnBhcnNlZEVudGl0eURlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+c2V0RG9jdW1lbnRMb2NhdG9yICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguc2V0RG9jdW1lbnRMb2NhdG9yID0gc2V0RG9jdW1lbnRMb2NhdG9yU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPnN0YXJ0RG9jdW1lbnQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5zdGFydERvY3VtZW50ID0gc3RhcnREb2N1bWVudFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5lbmREb2N1bWVudCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmVuZERvY3VtZW50ID0gZW5kRG9jdW1lbnRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+cHJvY2Vzc2luZ0luc3RydWN0aW9uICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgucHJvY2Vzc2luZ0luc3RydWN0aW9uID0gcHJvY2Vzc2luZ0luc3RydWN0aW9uU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmNvbW1lbnQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5jb21tZW50ID0gY29tbWVudFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT53YXJuaW5nICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgud2FybmluZyA9IHdhcm5pbmdTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+ZXJyb3IgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5lcnJvciA9IGVycm9yU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmZhdGFsRXJyb3IgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5mYXRhbEVycm9yID0gZmF0YWxFcnJvclNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5nZXRQYXJhbWV0ZXJFbnRpdHkgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5nZXRQYXJhbWV0ZXJFbnRpdHkgPSBnZXRQYXJhbWV0ZXJFbnRpdHlTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+ZXh0ZXJuYWxTdWJzZXQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5leHRlcm5hbFN1YnNldCA9IGV4dGVybmFsU3Vic2V0U3BsaXQ7CgoJLyoKCSAqIHRoZSA2IHNjaGVtYXMgY2FsbGJhY2sgaGF2ZSB0byBnbyB0byB0aGUgc3BsaXR0ZXIgZnVuY3Rpb25zCgkgKiBOb3RlIHRoYXQgd2UgdXNlIHRoZSBzYW1lIHRleHQtZnVuY3Rpb24gZm9yIGlnbm9yYWJsZVdoaXRlc3BhY2UKCSAqIGlmIHBvc3NpYmxlLCB0byBwcmV2ZW50IHRoZSBwYXJzZXIgZnJvbSB0ZXN0aW5nIGZvciBpZ25vcmFibGUKCSAqIHdoaXRlc3BhY2UuCgkgKi8KICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmNoYXJhY3RlcnMgPSBjaGFyYWN0ZXJzU3BsaXQ7CglpZiAoKG9sZF9zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgIT0gTlVMTCkgJiYKCSAgICAob2xkX3NheC0+aWdub3JhYmxlV2hpdGVzcGFjZSAhPSBvbGRfc2F4LT5jaGFyYWN0ZXJzKSkKCSAgICByZXQtPnNjaGVtYXNfc2F4Lmlnbm9yYWJsZVdoaXRlc3BhY2UgPSBpZ25vcmFibGVXaGl0ZXNwYWNlU3BsaXQ7CgllbHNlCgkgICAgcmV0LT5zY2hlbWFzX3NheC5pZ25vcmFibGVXaGl0ZXNwYWNlID0gY2hhcmFjdGVyc1NwbGl0OwogICAgICAgIHJldC0+c2NoZW1hc19zYXguY2RhdGFCbG9jayA9IGNkYXRhQmxvY2tTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnJlZmVyZW5jZSA9IHJlZmVyZW5jZVNwbGl0OwogICAgICAgIHJldC0+c2NoZW1hc19zYXguc3RhcnRFbGVtZW50TnMgPSBzdGFydEVsZW1lbnROc1NwbGl0OwogICAgICAgIHJldC0+c2NoZW1hc19zYXguZW5kRWxlbWVudE5zID0gZW5kRWxlbWVudE5zU3BsaXQ7CgoJcmV0LT51c2VyX2RhdGFfcHRyID0gdXNlcl9kYXRhOwoJcmV0LT51c2VyX2RhdGEgPSAqdXNlcl9kYXRhOwoJKnVzZXJfZGF0YSA9IHJldDsKICAgIH0KCiAgICAvKgogICAgICogcGx1ZyB0aGUgcG9pbnRlcnMgYmFjay4KICAgICAqLwogICAgKnNheCA9ICYocmV0LT5zY2hlbWFzX3NheCk7CiAgICBjdHh0LT5zYXggPSAqc2F4OwogICAgY3R4dC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9WQUxJRF9DVFhUX0ZMQUdfU1RSRUFNOwogICAgeG1sU2NoZW1hUHJlUnVuKGN0eHQpOwogICAgcmV0dXJuKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTQVhVbnBsdWc6CiAqIEBwbHVnOiAgYSBkYXRhIHN0cnVjdHVyZSByZXR1cm5lZCBieSB4bWxTY2hlbWFTQVhQbHVnCiAqCiAqIFVucGx1ZyBhIFNBWCBiYXNlZCB2YWxpZGF0aW9uIGxheWVyIGluIGEgU0FYIHBhcnNpbmcgZXZlbnQgZmxvdy4KICogVGhlIG9yaWdpbmFsIHBvaW50ZXJzIHVzZWQgaW4gdGhlIGNhbGwgYXJlIHJlc3RvcmVkLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzIGFuZCAtMSBpbiBjYXNlIG9mIGZhaWx1cmUuCiAqLwppbnQKeG1sU2NoZW1hU0FYVW5wbHVnKHhtbFNjaGVtYVNBWFBsdWdQdHIgcGx1ZykKewogICAgeG1sU0FYSGFuZGxlclB0ciAqc2F4OwogICAgdm9pZCAqKnVzZXJfZGF0YTsKCiAgICBpZiAoKHBsdWcgPT0gTlVMTCkgfHwgKHBsdWctPm1hZ2ljICE9IFhNTF9TQVhfUExVR19NQUdJQykpCiAgICAgICAgcmV0dXJuKC0xKTsKICAgIHBsdWctPm1hZ2ljID0gMDsKCiAgICB4bWxTY2hlbWFQb3N0UnVuKHBsdWctPmN0eHQpOwogICAgLyogcmVzdG9yZSB0aGUgZGF0YSAqLwogICAgc2F4ID0gcGx1Zy0+dXNlcl9zYXhfcHRyOwogICAgKnNheCA9IHBsdWctPnVzZXJfc2F4OwogICAgaWYgKHBsdWctPnVzZXJfc2F4ICE9IE5VTEwpIHsKCXVzZXJfZGF0YSA9IHBsdWctPnVzZXJfZGF0YV9wdHI7CgkqdXNlcl9kYXRhID0gcGx1Zy0+dXNlcl9kYXRhOwogICAgfQoKICAgIC8qIGZyZWUgYW5kIHJldHVybiAqLwogICAgeG1sRnJlZShwbHVnKTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAaW5wdXQ6ICB0aGUgaW5wdXQgdG8gdXNlIGZvciByZWFkaW5nIHRoZSBkYXRhCiAqIEBlbmM6ICBhbiBvcHRpb25hbCBlbmNvZGluZyBpbmZvcm1hdGlvbgogKiBAc2F4OiAgYSBTQVggaGFuZGxlciBmb3IgdGhlIHJlc3VsdGluZyBldmVudHMKICogQHVzZXJfZGF0YTogIHRoZSBjb250ZXh0IHRvIHByb3ZpZGUgdG8gdGhlIFNBWCBoYW5kbGVyLgogKgogKiBWYWxpZGF0ZSBhbiBpbnB1dCBiYXNlZCBvbiBhIGZsb3cgb2YgU0FYIGV2ZW50IGZyb20gdGhlIHBhcnNlcgogKiBhbmQgZm9yd2FyZCB0aGUgZXZlbnRzIHRvIHRoZSBAc2F4IGhhbmRsZXIgd2l0aCB0aGUgcHJvdmlkZWQgQHVzZXJfZGF0YQogKiB0aGUgdXNlciBwcm92aWRlZCBAc2F4IGhhbmRsZXIgbXVzdCBiZSBhIFNBWDIgb25lLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0LCB4bWxDaGFyRW5jb2RpbmcgZW5jLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTQVhIYW5kbGVyUHRyIHNheCwgdm9pZCAqdXNlcl9kYXRhKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIHBsdWcgPSBOVUxMOwogICAgeG1sU0FYSGFuZGxlclB0ciBvbGRfc2F4ID0gTlVMTDsKICAgIHhtbFBhcnNlckN0eHRQdHIgcGN0eHQgPSBOVUxMOwogICAgeG1sUGFyc2VySW5wdXRQdHIgaW5wdXRTdHJlYW0gPSBOVUxMOwogICAgaW50IHJldDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGlucHV0ID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAgKiBwcmVwYXJlIHRoZSBwYXJzZXIKICAgICAqLwogICAgcGN0eHQgPSB4bWxOZXdQYXJzZXJDdHh0KCk7CiAgICBpZiAocGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIG9sZF9zYXggPSBwY3R4dC0+c2F4OwogICAgcGN0eHQtPnNheCA9IHNheDsKICAgIHBjdHh0LT51c2VyRGF0YSA9IHVzZXJfZGF0YTsKI2lmIDAKICAgIGlmIChvcHRpb25zKQogICAgICAgIHhtbEN0eHRVc2VPcHRpb25zKHBjdHh0LCBvcHRpb25zKTsKI2VuZGlmCiAgICBwY3R4dC0+bGluZW51bWJlcnMgPSAxOyAgICAKCiAgICBpbnB1dFN0cmVhbSA9IHhtbE5ld0lPSW5wdXRTdHJlYW0ocGN0eHQsIGlucHV0LCBlbmMpOzsKICAgIGlmIChpbnB1dFN0cmVhbSA9PSBOVUxMKSB7CiAgICAgICAgcmV0ID0gLTE7Cglnb3RvIGRvbmU7CiAgICB9CiAgICBpbnB1dFB1c2gocGN0eHQsIGlucHV0U3RyZWFtKTsKICAgIGN0eHQtPnBhcnNlckN0eHQgPSBwY3R4dDsKICAgIGN0eHQtPmlucHV0ID0gaW5wdXQ7CgogICAgLyoKICAgICAqIFBsdWcgdGhlIHZhbGlkYXRpb24gYW5kIGxhdW5jaCB0aGUgcGFyc2luZwogICAgICovCiAgICBwbHVnID0geG1sU2NoZW1hU0FYUGx1ZyhjdHh0LCAmKHBjdHh0LT5zYXgpLCAmKHBjdHh0LT51c2VyRGF0YSkpOwogICAgaWYgKHBsdWcgPT0gTlVMTCkgewogICAgICAgIHJldCA9IC0xOwoJZ290byBkb25lOwogICAgfQogICAgY3R4dC0+aW5wdXQgPSBpbnB1dDsKICAgIGN0eHQtPmVuYyA9IGVuYzsKICAgIGN0eHQtPnNheCA9IHBjdHh0LT5zYXg7CiAgICBjdHh0LT5mbGFncyB8PSBYTUxfU0NIRU1BX1ZBTElEX0NUWFRfRkxBR19TVFJFQU07CiAgICByZXQgPSB4bWxTY2hlbWFWU3RhcnQoY3R4dCk7CgogICAgaWYgKChyZXQgPT0gMCkgJiYgKCEgY3R4dC0+cGFyc2VyQ3R4dC0+d2VsbEZvcm1lZCkpIHsKCXJldCA9IGN0eHQtPnBhcnNlckN0eHQtPmVyck5vOwoJaWYgKHJldCA9PSAwKQoJICAgIHJldCA9IDE7CiAgICB9ICAgIAoKZG9uZToKICAgIGN0eHQtPnBhcnNlckN0eHQgPSBOVUxMOwogICAgY3R4dC0+c2F4ID0gTlVMTDsKICAgIGN0eHQtPmlucHV0ID0gTlVMTDsKICAgIGlmIChwbHVnICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFTQVhVbnBsdWcocGx1Zyk7CiAgICB9CiAgICAvKiBjbGVhbnVwICovCiAgICBpZiAocGN0eHQgIT0gTlVMTCkgewoJcGN0eHQtPnNheCA9IG9sZF9zYXg7Cgl4bWxGcmVlUGFyc2VyQ3R4dChwY3R4dCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZpbGU6CiAqIEBjdHh0OiBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGZpbGVuYW1lOiB0aGUgVVJJIG9mIHRoZSBpbnN0YW5jZQogKiBAb3B0aW9uczogYSBmdXR1cmUgc2V0IG9mIG9wdGlvbnMsIGN1cnJlbnRseSB1bnVzZWQKICoKICogRG8gYSBzY2hlbWFzIHZhbGlkYXRpb24gb2YgdGhlIGdpdmVuIHJlc291cmNlLCBpdCB3aWxsIHVzZSB0aGUKICogU0FYIHN0cmVhbWFibGUgdmFsaWRhdGlvbiBpbnRlcm5hbGx5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRmlsZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBmaWxlbmFtZSwKCQkgICAgICBpbnQgb3B0aW9ucyBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpbnQgcmV0OwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChmaWxlbmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIAogICAgaW5wdXQgPSB4bWxQYXJzZXJJbnB1dEJ1ZmZlckNyZWF0ZUZpbGVuYW1lKGZpbGVuYW1lLAoJWE1MX0NIQVJfRU5DT0RJTkdfTk9ORSk7CiAgICBpZiAoaW5wdXQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTdHJlYW0oY3R4dCwgaW5wdXQsIFhNTF9DSEFSX0VOQ09ESU5HX05PTkUsCglOVUxMLCBOVUxMKTsgICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCiNkZWZpbmUgYm90dG9tX3htbHNjaGVtYXMKI2luY2x1ZGUgImVsZmdjY2hhY2suaCIKI2VuZGlmIC8qIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQgKi8K