LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlCiAqICAgICBuZWVkIHRvIHZhbGlkYXRlIGFsbCBzY2hlbWEgYXR0cmlidXRlcyAocmVmLCB0eXBlLCBuYW1lKQogKiAgICAgYWdhaW5zdCB0aGVpciB0eXBlcy4KICogICAtIEVsaW1pbmF0ZSBpdGVtIGNyZWF0aW9uIGZvcjogPz8KICoKICogVVJHRU5UIFRPRE86CiAqICAgLSBGb3IgeHNpLWRyaXZlbiBzY2hlbWEgYWNxdWlzaXRpb24sIGF1Z21lbnQgdGhlIElEQ3MgYWZ0ZXIgZXZlcnkKICogICAgIGFjcXVpc2l0aW9uIGVwaXNvZGUgKHhtbFNjaGVtYUF1Z21lbnRJREMpLgogKgogKiBOT1RFUzoKICogICAtIEVsaW1hdGVkIGl0ZW0gY3JlYXRpb24gZm9yOiA8cmVzdHJpY3Rpb24+LCA8ZXh0ZW5zaW9uPiwKICogICAgIDxzaW1wbGVDb250ZW50PiwgPGNvbXBsZXhDb250ZW50PiwgPGxpc3Q+LCA8dW5pb24+CiAqCiAqIFBST0JMRU1TOgogKiAgIC0gaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvd3d3LXhtbC1zY2hlbWEtY29tbWVudHMvMjAwNUp1bFNlcC8wMzM3Lmh0bWwKICogICAgIElEQyBYUGF0aCBleHByZXNzaW9uIGFuZCBjaGFtZWxlb24gaW5jbHVkZXM6IHRoZSB0YXJnZXROYW1lc3BhY2UgaXMgY2hhbmdlZCwgc28KICogICAgIFhQYXRoIHdpbGwgaGF2ZSB0cm91YmxlIHRvIHJlc29sdmUgdG8gdGhpcyBuYW1lc3BhY2UsIHNpbmNlIG5vdCBrbm93bi4KICoKICoKICogQ09OU1RSQUlOVFM6CiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogICBBbGwgR3JvdXAgTGltaXRlZCAoY29zLWFsbC1saW1pdGVkKQogKiAgIFN0YXR1czogY29tcGxldGUKICogICAoMS4yKQogKiAgICAgSW4geG1sU2NoZW1hR3JvdXBEZWZSZWZlcmVuY2VUZXJtRml4dXAoKSBhbmQKICogICAoMikKICogICAgIEluIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cCgpCiAqICAgICBUT0RPOiBBY3R1YWxseSB0aGlzIHNob3VsZCBnbyB0byBjb21wb25lbnQtbGV2ZWwgY2hlY2tzLAogKiAgICAgYnV0IGlzIGRvbmUgaGVyZSBkdWUgdG8gcGVyZm9ybWFuY2UuIE1vdmUgaXQgdG8gYW4gb3RoZXIgbGF5ZXIKICogICAgIGlzIHNjaGVtYSBjb25zdHJ1Y3Rpb24gdmlhIGFuIEFQSSBpcyBpbXBsZW1lbnRlZC4KICovCiNkZWZpbmUgSU5fTElCWE1MCiNpbmNsdWRlICJsaWJ4bWwuaCIKCiNpZmRlZiBMSUJYTUxfU0NIRU1BU19FTkFCTEVECgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sbWVtb3J5Lmg+CiNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VyLmg+CiNpbmNsdWRlIDxsaWJ4bWwvcGFyc2VySW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwvaGFzaC5oPgojaW5jbHVkZSA8bGlieG1sL3VyaS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHNjaGVtYXMuaD4KI2luY2x1ZGUgPGxpYnhtbC9zY2hlbWFzSW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hc3R5cGVzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sYXV0b21hdGEuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxyZWdleHAuaD4KI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CiNpbmNsdWRlIDxsaWJ4bWwvZW5jb2RpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxJTy5oPgojaWZkZWYgTElCWE1MX1BBVFRFUk5fRU5BQkxFRAojaW5jbHVkZSA8bGlieG1sL3BhdHRlcm4uaD4KI2VuZGlmCiNpZmRlZiBMSUJYTUxfUkVBREVSX0VOQUJMRUQKI2luY2x1ZGUgPGxpYnhtbC94bWxyZWFkZXIuaD4KI2VuZGlmCgovKiAjZGVmaW5lIERFQlVHIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQ09OVEVOVCAxICovCgovKiAjZGVmaW5lIERFQlVHX1RZUEUgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UX1JFR0VYUCAxICovCgovKiAjZGVmaW5lIERFQlVHX0FVVE9NQVRBIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfSURDICovCgovKiAjZGVmaW5lIERFQlVHX0lEQ19OT0RFX1RBQkxFICovCgojaWZkZWYgREVCVUdfSURDCiAjaWZuZGVmIERFQlVHX0lEQ19OT0RFX1RBQkxFCiAgI2RlZmluZSBERUJVR19JRENfTk9ERV9UQUJMRQogI2VuZGlmCiNlbmRpZiAgIAoKLyogI2RlZmluZSBFTkFCTEVfUEFSVElDTEVfUkVTVFJJQ1RJT04gMSAqLwoKI2RlZmluZSBFTkFCTEVfUkVERUZJTkUKCi8qICNkZWZpbmUgRU5BQkxFX05BTUVEX0xPQ0FMUyAqLwoKLyogI2RlZmluZSBFTkFCTEVfSURDX05PREVfVEFCTEVTX1RFU1QgKi8KCiNkZWZpbmUgRFVNUF9DT05URU5UX01PREVMCgojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECi8qICNkZWZpbmUgWE1MX1NDSEVNQV9SRUFERVJfRU5BQkxFRCAqLwojZW5kaWYKCiNkZWZpbmUgVU5CT1VOREVEICgxIDw8IDMwKQojZGVmaW5lIFRPRE8gCQkJCQkJCQlcCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwJCQkJXAoJICAgICJVbmltcGxlbWVudGVkIGJsb2NrIGF0ICVzOiVkXG4iLAkJCQlcCiAgICAgICAgICAgIF9fRklMRV9fLCBfX0xJTkVfXyk7CgojZGVmaW5lIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSAoY29uc3QgeG1sQ2hhciAqKSAiIyMiCgovKgogKiBUaGUgWE1MIFNjaGVtYXMgbmFtZXNwYWNlcwogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hSW5zdGFuY2VOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbE5hbWVzcGFjZU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CgovKgoqIENvbWUgY2FzdGluZyBtYWNyb3MuCiovCiNkZWZpbmUgQUNUWFRfQ0FTVCAoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKQojZGVmaW5lIFBDVFhUX0NBU1QgKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpCiNkZWZpbmUgVkNUWFRfQ0FTVCAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKQojZGVmaW5lIFdYU19CQVNJQ19DQVNUICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpCiNkZWZpbmUgV1hTX1RSRUVfQ0FTVCAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCiNkZWZpbmUgV1hTX1BUQ19DQVNUICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKI2RlZmluZSBXWFNfVFlQRV9DQVNUICh4bWxTY2hlbWFUeXBlUHRyKQojZGVmaW5lIFdYU19FTEVNX0NBU1QgKHhtbFNjaGVtYUVsZW1lbnRQdHIpCiNkZWZpbmUgV1hTX0FUVFJfR1JPVVBfQ0FTVCAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpCiNkZWZpbmUgV1hTX0FUVFJfQ0FTVCAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKQojZGVmaW5lIFdYU19BVFRSX1VTRV9DQVNUICh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIpCiNkZWZpbmUgV1hTX0FUVFJfUFJPSElCX0NBU1QgKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cikKI2RlZmluZSBXWFNfTU9ERUxfR1JPVVBERUZfQ0FTVCAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikKI2RlZmluZSBXWFNfTU9ERUxfR1JPVVBfQ0FTVCAoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikKI2RlZmluZSBXWFNfSURDX0NBU1QgKHhtbFNjaGVtYUlEQ1B0cikKI2RlZmluZSBXWFNfUU5BTUVfQ0FTVCAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpCiNkZWZpbmUgV1hTX0xJU1RfQ0FTVCAoeG1sU2NoZW1hSXRlbUxpc3RQdHIpCgovKgoqIE1hY3JvcyB0byBxdWVyeSBjb21tb24gcHJvcGVydGllcyBvZiBjb21wb25lbnRzLgoqLwojZGVmaW5lIFdYU19JVEVNX05PREUoaSkgeG1sU2NoZW1hR2V0Q29tcG9uZW50Tm9kZShXWFNfQkFTSUNfQ0FTVCAoaSkpCgojZGVmaW5lIFdYU19JVEVNX1RZUEVfTkFNRShpKSB4bWxTY2hlbWFHZXRDb21wb25lbnRUeXBlU3RyKFdYU19CQVNJQ19DQVNUIChpKSkKLyoKKiBNYWNyb3MgZm9yIGVsZW1lbnQgZGVjbGFyYXRpb25zLgoqLwojZGVmaW5lIFdYU19FTEVNX1RZUEVERUYoZSkgKGUpLT5zdWJ0eXBlcwoKI2RlZmluZSBXWFNfU1VCU1RfSEVBRChpdGVtKSAoaXRlbSktPnJlZkRlY2wKLyoKKiBNYWNyb3MgZm9yIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMuCiovCiNkZWZpbmUgV1hTX0FUVFJfVFlQRURFRihhKSAoYSktPnN1YnR5cGVzCi8qCiogTWFjcm9zIGZvciBhdHRyaWJ1dGUgdXNlcy4KKi8KI2RlZmluZSBXWFNfQVRUUlVTRV9ERUNMKGF1KSBXWFNfQVRUUl9DQVNUIChXWFNfQVRUUl9VU0VfQ0FTVCAoYXUpKS0+YXR0ckRlY2wKCiNkZWZpbmUgV1hTX0FUVFJVU0VfVFlQRURFRihhdSkgV1hTX0FUVFJfVFlQRURFRihXWFNfQVRUUlVTRV9ERUNMKCBXWFNfQVRUUl9VU0VfQ0FTVCBhdSkpCgojZGVmaW5lIFdYU19BVFRSVVNFX0RFQ0xfTkFNRShhdSkgKFdYU19BVFRSVVNFX0RFQ0woYXUpKS0+bmFtZQoKI2RlZmluZSBXWFNfQVRUUlVTRV9ERUNMX1ROUyhhdSkgKFdYU19BVFRSVVNFX0RFQ0woYXUpKS0+dGFyZ2V0TmFtZXNwYWNlCi8qCiogTWFjcm9zIGZvciBhdHRyaWJ1dGUgZ3JvdXBzLgoqLwojZGVmaW5lIFdYU19BVFRSX0dST1VQX0hBU19SRUZTKGFnKSAoKFdYU19BVFRSX0dST1VQX0NBU1QgKGFnKSktPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0hBU19SRUZTKQojZGVmaW5lIFdYU19BVFRSX0dST1VQX0VYUEFOREVEKGFnKSAoKFdYU19BVFRSX0dST1VQX0NBU1QgKGFnKSktPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQpCi8qCiogTWFjcm9zIGZvciBwYXJ0aWNsZXMuCiovCiNkZWZpbmUgV1hTX1BBUlRJQ0xFKHApIFdYU19QVENfQ0FTVCAocCkKCiNkZWZpbmUgV1hTX1BBUlRJQ0xFX1RFUk0ocCkgKFdYU19QQVJUSUNMRShwKSktPmNoaWxkcmVuCgojZGVmaW5lIFdYU19QQVJUSUNMRV9NT0RFTChwKSBXWFNfTU9ERUxfR1JPVVBfQ0FTVCBXWFNfUEFSVElDTEUocCktPmNoaWxkcmVuCi8qCiogTWFjcm9zIGZvciBtb2RlbCBncm91cHMgZGVmaW5pdGlvbnMuCiovCiNkZWZpbmUgV1hTX01PREVMR1JPVVBERUZfTU9ERUwobWdkKSAoV1hTX01PREVMX0dST1VQX0NBU1QgKG1nZCkpLT5jaGlsZHJlbgovKgoqIE1hY3JvcyBmb3IgbW9kZWwgZ3JvdXBzLgoqLwojZGVmaW5lIFdYU19JU19NT0RFTF9HUk9VUChpKSBcCiAgICAoKChpKS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8IFwKICAgICAoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHx8IFwKICAgICAoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpKQoKI2RlZmluZSBXWFNfTU9ERUxHUk9VUF9QQVJUSUNMRShtZykgV1hTX1BUQ19DQVNUIChtZyktPmNoaWxkcmVuCi8qCiogTWFjcm9zIGZvciBzY2hlbWEgYnVja2V0cy4KKi8KI2RlZmluZSBXWFNfSVNfQlVDS0VUX0lOQ1JFREVGKHQpICgoKHQpID09IFhNTF9TQ0hFTUFfU0NIRU1BX0lOQ0xVREUpIHx8IFwKICAgICgodCkgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpKQoKI2RlZmluZSBXWFNfSVNfQlVDS0VUX0lNUE1BSU4odCkgKCgodCkgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTikgfHwgXAogICAgKCh0KSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQpKQoKI2RlZmluZSBXWFNfSU1QQlVDS0VUKGIpICgoeG1sU2NoZW1hSW1wb3J0UHRyKSAoYikpCgojZGVmaW5lIFdYU19JTkNCVUNLRVQoYikgKCh4bWxTY2hlbWFJbmNsdWRlUHRyKSAoYikpCi8qCiogTWFjcm9zIGZvciBjb21wbGV4L3NpbXBsZSB0eXBlcy4KKi8KI2RlZmluZSBXWFNfSVNfQU5ZVFlQRShpKSBcCiAgICAgKCggKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoIChXWFNfVFlQRV9DQVNUIChpKSktPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBXWFNfSVNfQ09NUExFWChpKSBcCiAgICAoKChpKS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwgXAogICAgICgoaSktPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBXWFNfSVNfU0lNUExFKGl0ZW0pIFwKICAgICgoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB8fCBcCiAgICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpKQoKI2RlZmluZSBXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKGkpIFwKICAgICgoKGkpLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICAoKGkpLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkKCiNkZWZpbmUgV1hTX0lTX1JFU1RSSUNUSU9OKHQpIFwKICAgICgodCktPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikKCiNkZWZpbmUgV1hTX0lTX0VYVEVOU0lPTih0KSBcCiAgICAoKHQpLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKQoKI2RlZmluZSBXWFNfSVNfVFlQRV9OT1RfRklYRUQoaSkgXAogICAgKCgoaSktPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiBcCiAgICAgKCgoaSktPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9SRVNPTFZFRCkgPT0gMCkpCgojZGVmaW5lIFdYU19JU19UWVBFX05PVF9GSVhFRF8xKGl0ZW0pIFwKICAgICgoKGl0ZW0pLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgXAogICAgICgoKGl0ZW0pLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklYVVBfMSkgPT0gMCkpCi8qCiogTWFjcm9zIGZvciBleGNsdXNpdmVseSBmb3IgY29tcGxleCB0eXBlcy4KKi8KI2RlZmluZSBXWFNfSEFTX0NPTVBMRVhfQ09OVEVOVChpdGVtKSBcCiAgICAoKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgfHwgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHx8IFwKICAgICAoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSkKCiNkZWZpbmUgV1hTX0hBU19TSU1QTEVfQ09OVEVOVChpdGVtKSBcCiAgICAoKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8IFwKICAgICAoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkKCiNkZWZpbmUgV1hTX0hBU19NSVhFRF9DT05URU5UKGl0ZW0pIFwKICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpCgojZGVmaW5lIFdYU19FTVBUSUFCTEUodCkgXAogICAgKHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoV1hTX1BUQ19DQVNUICh0KS0+c3VidHlwZXMpKQoKI2RlZmluZSBXWFNfVFlQRV9DT05URU5UVFlQRSh0KSAodCktPnN1YnR5cGVzCgojZGVmaW5lIFdYU19UWVBFX1BBUlRJQ0xFKHQpIFdYU19QVENfQ0FTVCAodCktPnN1YnR5cGVzCgojZGVmaW5lIFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odCkgV1hTX1BBUlRJQ0xFX1RFUk0oV1hTX1RZUEVfUEFSVElDTEUodCkpCi8qCiogTWFjcm9zIGZvciBleGNsdXNpdmVseSBmb3Igc2ltcGxlIHR5cGVzLgoqLwojZGVmaW5lIFdYU19MSVNUX0lURU1UWVBFKHQpICh0KS0+c3VidHlwZXMKCiNkZWZpbmUgV1hTX0lTX0FUT01JQyh0KSAodC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKQoKI2RlZmluZSBXWFNfSVNfTElTVCh0KSAodC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkKCiNkZWZpbmUgV1hTX0lTX1VOSU9OKHQpICh0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikKLyoKKiBNaXNjIHBhcnNlciBjb250ZXh0IG1hY3Jvcy4KKi8KI2RlZmluZSBXWFNfQ09OU1RSVUNUT1IoY3R4KSAoY3R4KS0+Y29uc3RydWN0b3IKCiNkZWZpbmUgV1hTX0hBU19CVUNLRVRTKGN0eCkgXAooIChXWFNfQ09OU1RSVUNUT1IoKGN0eCkpLT5idWNrZXRzICE9IE5VTEwpICYmIFwKKFdYU19DT05TVFJVQ1RPUigoY3R4KSktPmJ1Y2tldHMtPm5iSXRlbXMgPiAwKSApCgojZGVmaW5lIFdYU19TVUJTVF9HUk9VUFMoY3R4KSBXWFNfQ09OU1RSVUNUT1IoKGN0eCkpLT5zdWJzdEdyb3VwcwoKI2RlZmluZSBXWFNfQlVDS0VUKGN0eCkgV1hTX0NPTlNUUlVDVE9SKChjdHgpKS0+YnVja2V0CgojZGVmaW5lIFdYU19TQ0hFTUEoY3R4KSAoY3R4KS0+c2NoZW1hCgojZGVmaW5lIFdYU19BRERfTE9DQUwoY3R4LCBpdGVtKSBcCiAgICB4bWxTY2hlbWFBZGRJdGVtU2l6ZSgmKFdYU19CVUNLRVQoY3R4KS0+bG9jYWxzKSwgMTAsIGl0ZW0pCgojZGVmaW5lIFdYU19BRERfR0xPQkFMKGN0eCwgaXRlbSkgXAogICAgeG1sU2NoZW1hQWRkSXRlbVNpemUoJihXWFNfQlVDS0VUKGN0eCktPmdsb2JhbHMpLCA1LCBpdGVtKQoKI2RlZmluZSBXWFNfQUREX1BFTkRJTkcoY3R4LCBpdGVtKSBcCiAgICB4bWxTY2hlbWFBZGRJdGVtU2l6ZSgmKChjdHgpLT5jb25zdHJ1Y3Rvci0+cGVuZGluZyksIDEwLCBpdGVtKQovKgoqIHhtbFNjaGVtYUl0ZW1MaXN0IG1hY3Jvcy4KKi8KI2RlZmluZSBXWFNfSUxJU1RfSVNfRU1QVFkobCkgKChsID09IE5VTEwpIHx8ICgobCktPm5iSXRlbXMgPT0gMCkpCi8qCiogTWlzYyBtYWNyb3MuCiovCiNkZWZpbmUgSVNfU0NIRU1BKG5vZGUsIHR5cGUpIFwKICAgKChub2RlICE9IE5VTEwpICYmIChub2RlLT5ucyAhPSBOVUxMKSAmJiBcCiAgICAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgdHlwZSkpICYmIFwKICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkKCiNkZWZpbmUgRlJFRV9BTkRfTlVMTChzdHIpIGlmICgoc3RyKSAhPSBOVUxMKSB7IHhtbEZyZWUoKHhtbENoYXIgKikgKHN0cikpOyBzdHIgPSBOVUxMOyB9CgovKgoqIFNpbmNlIHdlIHB1dCB0aGUgZGVmYXVsdC9maXhlZCB2YWx1ZXMgaW50byB0aGUgZGljdCwgd2UgY2FuCiogdXNlIHBvaW50ZXIgY29tcGFyaXNvbiBmb3IgdGhvc2UgdmFsdWVzLgoqIFJFTU9WRUQ6ICh4bWxTdHJFcXVhbCgodjEpLCAodjIpKSkKKi8KI2RlZmluZSBXWFNfQVJFX0RFRkFVTFRfU1RSX0VRVUFMKHYxLCB2MikgKCh2MSkgPT0gKHYyKSkKCiNkZWZpbmUgSU5PREVfTklMTEVEKGl0ZW0pIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRCkKCiNkZWZpbmUgQ0FOX1BBUlNFX1NDSEVNQShiKSAoKChiKS0+ZG9jICE9IE5VTEwpICYmICgoYiktPnBhcnNlZCA9PSAwKSkKCiNkZWZpbmUgSEZBSUxVUkUgaWYgKHJlcyA9PSAtMSkgZ290byBleGl0X2ZhaWx1cmU7CgojZGVmaW5lIEhFUlJPUiBpZiAocmVzICE9IDApIGdvdG8gZXhpdF9lcnJvcjsKCiNkZWZpbmUgSFNUT1AoY3R4KSBpZiAoKGN0eCktPnN0b3ApIGdvdG8gZXhpdDsKLyoKKiBTb21lIGZsYWdzIHVzZWQgZm9yIHZhcmlvdXMgc2NoZW1hIGNvbnN0cmFpbnRzLgoqLwojZGVmaW5lIFNVQlNFVF9SRVNUUklDVElPTiAgMTw8MAojZGVmaW5lIFNVQlNFVF9FWFRFTlNJT04gICAgMTw8MQojZGVmaW5lIFNVQlNFVF9TVUJTVElUVVRJT04gMTw8MgojZGVmaW5lIFNVQlNFVF9MSVNUICAgICAgICAgMTw8MwojZGVmaW5lIFNVQlNFVF9VTklPTiAgICAgICAgMTw8NAoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHhtbFNjaGVtYU5vZGVJbmZvOwp0eXBlZGVmIHhtbFNjaGVtYU5vZGVJbmZvICp4bWxTY2hlbWFOb2RlSW5mb1B0cjsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJdGVtTGlzdCB4bWxTY2hlbWFJdGVtTGlzdDsKdHlwZWRlZiB4bWxTY2hlbWFJdGVtTGlzdCAqeG1sU2NoZW1hSXRlbUxpc3RQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSXRlbUxpc3QgewogICAgdm9pZCAqKml0ZW1zOyAgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IG5iSXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBzaXplSXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KfTsKCiNkZWZpbmUgWE1MX1NDSEVNQV9DVFhUX1BBUlNFUiAxCiNkZWZpbmUgWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUiAyCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQWJzdHJhY3RDdHh0IHhtbFNjaGVtYUFic3RyYWN0Q3R4dDsKdHlwZWRlZiB4bWxTY2hlbWFBYnN0cmFjdEN0eHQgKnhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cjsKc3RydWN0IF94bWxTY2hlbWFBYnN0cmFjdEN0eHQgewogICAgaW50IHR5cGU7IC8qIEUuZy4gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUiAqLwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUJ1Y2tldCB4bWxTY2hlbWFCdWNrZXQ7CnR5cGVkZWYgeG1sU2NoZW1hQnVja2V0ICp4bWxTY2hlbWFCdWNrZXRQdHI7CgojZGVmaW5lIFhNTF9TQ0hFTUFfU0NIRU1BX01BSU4gMAojZGVmaW5lIFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCAxCiNkZWZpbmUgWE1MX1NDSEVNQV9TQ0hFTUFfSU5DTFVERSAyCiNkZWZpbmUgWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUgMwoKLyoqCiAqIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uOiAKICoKICogVXNlZCB0byBjcmVhdGUgYSBncmFwaCBvZiBzY2hlbWEgcmVsYXRpb25zaGlwcy4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFTY2hlbWFSZWxhdGlvbiB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbjsKdHlwZWRlZiB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbiAqeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHI7CnN0cnVjdCBfeG1sU2NoZW1hU2NoZW1hUmVsYXRpb24gewogICAgeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25QdHIgbmV4dDsKICAgIGludCB0eXBlOyAvKiBFLmcuIFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCAqLwogICAgY29uc3QgeG1sQ2hhciAqaW1wb3J0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hQnVja2V0UHRyIGJ1Y2tldDsKfTsKCiNkZWZpbmUgWE1MX1NDSEVNQV9CVUNLRVRfTUFSS0VEIDE8PDAKI2RlZmluZSBYTUxfU0NIRU1BX0JVQ0tFVF9DT01QU19BRERFRCAxPDwxCgpzdHJ1Y3QgX3htbFNjaGVtYUJ1Y2tldCB7CiAgICBpbnQgdHlwZTsKICAgIGludCBmbGFnczsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgY29uc3QgeG1sQ2hhciAqb3JpZ1RhcmdldE5hbWVzcGFjZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWxhdGlvbnM7CiAgICBpbnQgbG9jYXRlZDsKICAgIGludCBwYXJzZWQ7CiAgICBpbnQgaW1wb3J0ZWQ7CiAgICBpbnQgcHJlc2VydmVEb2M7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBnbG9iYWxzOyAvKiBHbG9iYWwgY29tcG9uZW50cy4gKi8gCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsb2NhbHM7IC8qIExvY2FsIGNvbXBvbmVudHMuICovCn07CgovKioKICogeG1sU2NoZW1hSW1wb3J0OiAKICogKGV4dGVuZHMgeG1sU2NoZW1hQnVja2V0KQogKgogKiBSZWZsZWN0cyBhIHNjaGVtYS4gSG9sZHMgc29tZSBpbmZvcm1hdGlvbgogKiBhYm91dCB0aGUgc2NoZW1hIGFuZCBpdHMgdG9wbGV2ZWwgY29tcG9uZW50cy4gRHVwbGljYXRlCiAqIHRvcGxldmVsIGNvbXBvbmVudHMgYXJlIG5vdCBjaGVja2VkIGF0IHRoaXMgbGV2ZWwuCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHhtbFNjaGVtYUltcG9ydDsKdHlwZWRlZiB4bWxTY2hlbWFJbXBvcnQgKnhtbFNjaGVtYUltcG9ydFB0cjsKc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgewogICAgaW50IHR5cGU7IC8qIE1haW4gT1IgaW1wb3J0IE9SIGluY2x1ZGUuICovCiAgICBpbnQgZmxhZ3M7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsgLyogVGhlIFVSSSBvZiB0aGUgc2NoZW1hIGRvY3VtZW50LiAqLwogICAgLyogRm9yIGNoYW1lbGVvbiBpbmNsdWRlcywgQG9yaWdUYXJnZXROYW1lc3BhY2Ugd2lsbCBiZSBOVUxMICovCiAgICBjb25zdCB4bWxDaGFyICpvcmlnVGFyZ2V0TmFtZXNwYWNlOwogICAgLyogCiAgICAqIEZvciBjaGFtZWxlb24gaW5jbHVkZXMsIEB0YXJnZXROYW1lc3BhY2Ugd2lsbCBiZSB0aGUKICAgICogdGFyZ2V0TmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRpbmcgc2NoZW1hLiAKICAgICovCiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxEb2NQdHIgZG9jOyAvKiBUaGUgc2NoZW1hIG5vZGUtdHJlZS4gKi8KICAgIC8qIEByZWxhdGlvbnMgd2lsbCBob2xkIGFueSBpbmNsdWRlZC9pbXBvcnRlZC9yZWRlZmluZWQgc2NoZW1hcy4gKi8KICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbGF0aW9uczsKICAgIGludCBsb2NhdGVkOwogICAgaW50IHBhcnNlZDsKICAgIGludCBpbXBvcnRlZDsKICAgIGludCBwcmVzZXJ2ZURvYzsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGdsb2JhbHM7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsb2NhbHM7CiAgICAvKiBUaGUgaW1wb3J0ZWQgc2NoZW1hLiAqLwogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsKfTsKCi8qCiogKGV4dGVuZHMgeG1sU2NoZW1hQnVja2V0KQoqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB4bWxTY2hlbWFJbmNsdWRlOwp0eXBlZGVmIHhtbFNjaGVtYUluY2x1ZGUgKnhtbFNjaGVtYUluY2x1ZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB7CiAgICBpbnQgdHlwZTsKICAgIGludCBmbGFnczsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgY29uc3QgeG1sQ2hhciAqb3JpZ1RhcmdldE5hbWVzcGFjZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWxhdGlvbnM7CiAgICBpbnQgbG9jYXRlZDsKICAgIGludCBwYXJzZWQ7CiAgICBpbnQgaW1wb3J0ZWQ7CiAgICBpbnQgcHJlc2VydmVEb2M7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBnbG9iYWxzOyAvKiBHbG9iYWwgY29tcG9uZW50cy4gKi8gCiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsb2NhbHM7IC8qIExvY2FsIGNvbXBvbmVudHMuICovCgogICAgLyogVGhlIG93bmluZyBtYWluIG9yIGltcG9ydCBzY2hlbWEgYnVja2V0LiAqLwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIG93bmVySW1wb3J0Owp9OwoKLyoqCiAqIHhtbFNjaGVtYUJhc2ljSXRlbToKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3Igc2NoZW1hIGNvbXBvbmVudHMuCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQmFzaWNJdGVtIHhtbFNjaGVtYUJhc2ljSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFCYXNpY0l0ZW0gKnhtbFNjaGVtYUJhc2ljSXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFCYXNpY0l0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKfTsKCi8qKgogKiB4bWxTY2hlbWFBbm5vdEl0ZW06CiAqCiAqIFRoZSBhYnN0cmFjdCBiYXNlIHR5cGUgZm9yIGFubm90YXRlZCBzY2hlbWEgY29tcG9uZW50cy4KICogKEV4dGVuZHMgeG1sU2NoZW1hQmFzaWNJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUFubm90SXRlbSB4bWxTY2hlbWFBbm5vdEl0ZW07CnR5cGVkZWYgeG1sU2NoZW1hQW5ub3RJdGVtICp4bWxTY2hlbWFBbm5vdEl0ZW1QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQW5ub3RJdGVtIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKfTsKCi8qKgogKiB4bWxTY2hlbWFUcmVlSXRlbToKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3IgdHJlZS1saWtlIHN0cnVjdHVyZWQgc2NoZW1hIGNvbXBvbmVudHMuCiAqIChFeHRlbmRzIHhtbFNjaGVtYUFubm90SXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFUcmVlSXRlbSB4bWxTY2hlbWFUcmVlSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFUcmVlSXRlbSAqeG1sU2NoZW1hVHJlZUl0ZW1QdHI7CnN0cnVjdCBfeG1sU2NoZW1hVHJlZUl0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOwp9OwoKCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX1VTRV9GSVhFRCAxPDwwCi8qKgogKiB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHI6CiAqCiAqIFRoZSBhYnN0cmFjdCBiYXNlIHR5cGUgZm9yIHRyZWUtbGlrZSBzdHJ1Y3R1cmVkIHNjaGVtYSBjb21wb25lbnRzLgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyaWJ1dGVVc2UgeG1sU2NoZW1hQXR0cmlidXRlVXNlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZSAqeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJpYnV0ZVVzZSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgbmV4dDsgLyogVGhlIG5leHQgYXR0ci4gdXNlLiAqLwogICAgLyogCiAgICAqIFRoZSBhdHRyLiBkZWNsLiBPUiBhIFFOYW1lLXJlZi4gdG8gYW4gYXR0ci4gZGVjbC4gT1IKICAgICogYSBRTmFtZS1yZWYuIHRvIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLgogICAgKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyRGVjbDsKCiAgICBpbnQgZmxhZ3M7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBpbnQgb2NjdXJzOyAvKiByZXF1aXJlZCwgb3B0aW9uYWwgKi8KICAgIGNvbnN0IHhtbENoYXIgKiBkZWZWYWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciBkZWZWYWw7Cn07CgovKioKICogeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyOgogKgogKiBBIGhlbHBlciBjb21wb25lbnQgdG8gcmVmbGVjdCBhdHRyaWJ1dGUgcHJvaGliaXRpb25zLgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFCYXNpY0l0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYjsKdHlwZWRlZiB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWIgKnhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cjsKc3RydWN0IF94bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWIgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsgLyogPT0gWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUIgKi8KICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICBpbnQgaXNSZWY7Cn07CgovKioKICogeG1sU2NoZW1hUmVkZWY6CiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUmVkZWYgeG1sU2NoZW1hUmVkZWY7CnR5cGVkZWYgeG1sU2NoZW1hUmVkZWYgKnhtbFNjaGVtYVJlZGVmUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVJlZGVmIHsKICAgIHhtbFNjaGVtYVJlZGVmUHRyIG5leHQ7CiAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbTsgLyogVGhlIHJlZGVmaW5pbmcgY29tcG9uZW50LiAqLwogICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIHJlZmVyZW5jZTsgLyogVGhlIHJlZmVyZW5jaW5nIGNvbXBvbmVudC4gKi8KICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciB0YXJnZXQ7IC8qIFRoZSB0by1iZS1yZWRlZmluZWQgY29tcG9uZW50LiAqLwogICAgY29uc3QgeG1sQ2hhciAqcmVmTmFtZTsgLyogVGhlIG5hbWUgb2YgdGhlIHRvLWJlLXJlZGVmaW5lZCBjb21wb25lbnQuICovCiAgICBjb25zdCB4bWxDaGFyICpyZWZUYXJnZXROczsgLyogVGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8tYmUtcmVkZWZpbmVkIGNvbXAuICovCiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgdGFyZ2V0QnVja2V0OyAvKiBUaGUgcmVkZWZpbmVkIHNjaGVtYS4gKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0OgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQgeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dDsKdHlwZWRlZiB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0ICp4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQgewogICAgeG1sU2NoZW1hUHRyIG1haW5TY2hlbWE7IC8qIFRoZSBtYWluIHNjaGVtYS4gKi8KICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBtYWluQnVja2V0OyAvKiBUaGUgbWFpbiBzY2hlbWEgYnVja2V0ICovCiAgICB4bWxEaWN0UHRyIGRpY3Q7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBidWNrZXRzOyAvKiBMaXN0IG9mIHNjaGVtYSBidWNrZXRzLiAqLwogICAgLyogeG1sU2NoZW1hSXRlbUxpc3RQdHIgcmVsYXRpb25zOyAqLyAvKiBMaXN0IG9mIHNjaGVtYSByZWxhdGlvbnMuICovCiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0OyAvKiBUaGUgY3VycmVudCBzY2hlbWEgYnVja2V0ICovICAgIAogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgcGVuZGluZzsgLyogQWxsIENvbXBvbmVudHMgb2YgYWxsIHNjaGVtYXMgdGhhdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZCB0byBiZSBmaXhlZC4gKi8KICAgIHhtbEhhc2hUYWJsZVB0ciBzdWJzdEdyb3VwczsKICAgIHhtbFNjaGVtYVJlZGVmUHRyIHJlZGVmczsKICAgIHhtbFNjaGVtYVJlZGVmUHRyIGxhc3RSZWRlZjsKfTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfUEFSU0VfRVJST1IJCTEKI2RlZmluZSBTQ0hFTUFTX1BBUlNFX09QVElPTlMgWE1MX1BBUlNFX05PRU5UCgpzdHJ1Y3QgX3htbFNjaGVtYVBhcnNlckN0eHQgewogICAgaW50IHR5cGU7CiAgICB2b2lkICplcnJDdHh0OyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGVycm9yIGNvbnRleHQgKi8gICAgCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgICAgICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIgY29uc3RydWN0b3I7CiAgICBpbnQgb3duc0NvbnN0cnVjdG9yOyAvKiBUT0RPOiBNb3ZlIHRoaXMgdG8gcGFyc2VyICpmbGFncyouICovCgogICAgLyogeG1sU2NoZW1hUHRyIHRvcHNjaGVtYTsJKi8KICAgIC8qIHhtbEhhc2hUYWJsZVB0ciBuYW1lc3BhY2VzOyAgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIG1haW4gc2NoZW1hIGluIHVzZSAqLwogICAgaW50IGNvdW50ZXI7CgogICAgY29uc3QgeG1sQ2hhciAqVVJMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCBwcmVzZXJ2ZTsJCS8qIFdoZXRoZXIgdGhlIGRvYyBzaG91bGQgYmUgZnJlZWQgICovCgogICAgY29uc3QgY2hhciAqYnVmZmVyOwogICAgaW50IHNpemU7CgogICAgLyoKICAgICAqIFVzZWQgdG8gYnVpbGQgY29tcGxleCBlbGVtZW50IGNvbnRlbnQgbW9kZWxzCiAgICAgKi8KICAgIHhtbEF1dG9tYXRhUHRyIGFtOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgZW5kOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGF0ZTsKCiAgICB4bWxEaWN0UHRyIGRpY3Q7CQkvKiBkaWN0aW9ubmFyeSBmb3IgaW50ZXJuZWQgc3RyaW5nIG5hbWVzICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIGN0eHRUeXBlOyAvKiBUaGUgY3VycmVudCBjb250ZXh0IHNpbXBsZS9jb21wbGV4IHR5cGUgKi8KICAgIGludCBvcHRpb25zOwogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwogICAgaW50IGlzUzRTOwogICAgaW50IGlzUmVkZWZpbmU7CiAgICBpbnQgeHNpQXNzZW1ibGU7CiAgICBpbnQgc3RvcDsgLyogSWYgdGhlIHBhcnNlciBzaG91bGQgc3RvcDsgaS5lLiBhIGNyaXRpY2FsIGVycm9yLiAqLwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hQnVja2V0UHRyIHJlZGVmaW5lZDsgLyogVGhlIHNjaGVtYSB0byBiZSByZWRlZmluZWQuICovCgogICAgeG1sU2NoZW1hUmVkZWZQdHIgcmVkZWY7IC8qIFVzZWQgZm9yIHJlZGVmaW5pdGlvbnMuICovCiAgICBpbnQgcmVkZWZDb3VudGVyOyAvKiBVc2VkIGZvciByZWRlZmluaXRpb25zLiAqLyAKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGF0dHJQcm9oaWJzOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVFOYW1lUmVmOgogKgogKiBBIGNvbXBvbmVudCByZWZlcmVuY2UgaXRlbSAobm90IGEgc2NoZW1hIGNvbXBvbmVudCkKICogKEV4dGVuZHMgeG1sU2NoZW1hQmFzaWNJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVFOYW1lUmVmIHhtbFNjaGVtYVFOYW1lUmVmOwp0eXBlZGVmIHhtbFNjaGVtYVFOYW1lUmVmICp4bWxTY2hlbWFRTmFtZVJlZlB0cjsKc3RydWN0IF94bWxTY2hlbWFRTmFtZVJlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW07IC8qIFRoZSByZXNvbHZlZCByZWZlcmVuY2VkIGl0ZW0uICovCiAgICB4bWxTY2hlbWFUeXBlVHlwZSBpdGVtVHlwZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxOb2RlUHRyIG5vZGU7Cn07CgovKioKICogeG1sU2NoZW1hUGFydGljbGU6CiAqCiAqIEEgcGFydGljbGUgY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQYXJ0aWNsZSB4bWxTY2hlbWFQYXJ0aWNsZTsKdHlwZWRlZiB4bWxTY2hlbWFQYXJ0aWNsZSAqeG1sU2NoZW1hUGFydGljbGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUGFydGljbGUgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbmV4dCBwYXJ0aWNsZSAqLwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2hpbGRyZW47IC8qIHRoZSAidGVybSIgKGUuZy4gYSBtb2RlbCBncm91cCwKCWEgZ3JvdXAgZGVmaW5pdGlvbiwgYSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGIChpZiBhIHJlZmVyZW5jZSksCiAgICAgICAgZXRjLikgKi8KICAgIGludCBtaW5PY2N1cnM7CiAgICBpbnQgbWF4T2NjdXJzOwogICAgeG1sTm9kZVB0ciBub2RlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYU1vZGVsR3JvdXA6CiAqCiAqIEEgbW9kZWwgZ3JvdXAgY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwIHhtbFNjaGVtYU1vZGVsR3JvdXA7CnR5cGVkZWYgeG1sU2NoZW1hTW9kZWxHcm91cCAqeG1sU2NoZW1hTW9kZWxHcm91cFB0cjsKc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7IC8qIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgWE1MX1NDSEVNQV9UWVBFX0FMTCAqLwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBuZXh0OyAvKiBub3QgdXNlZCAqLwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2hpbGRyZW47IC8qIGZpcnN0IHBhcnRpY2xlIChPUiAiZWxlbWVudCBkZWNsIiBPUiAid2lsZGNhcmQiKSAqLwogICAgeG1sTm9kZVB0ciBub2RlOwp9OwoKI2RlZmluZSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQgMTw8MAojZGVmaW5lIFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX1JFREVGSU5FRCAxPDwxCi8qKgogKiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmOgogKgogKiBBIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwRGVmIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWY7CnR5cGVkZWYgeG1sU2NoZW1hTW9kZWxHcm91cERlZiAqeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cjsKc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwRGVmIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7IC8qIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCAqLwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBuZXh0OyAvKiBub3QgdXNlZCAqLwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2hpbGRyZW47IC8qIHRoZSAibW9kZWwgZ3JvdXAiICovCiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IGZsYWdzOwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQyB4bWxTY2hlbWFJREM7CnR5cGVkZWYgeG1sU2NoZW1hSURDICp4bWxTY2hlbWFJRENQdHI7CgovKioKICogeG1sU2NoZW1hSURDU2VsZWN0OgogKgogKiBUaGUgaWRlbnRpdHktY29uc3RyYWludCAiZmllbGQiIGFuZCAic2VsZWN0b3IiIGl0ZW0sIGhvbGRpbmcgdGhlCiAqIFhQYXRoIGV4cHJlc3Npb24uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDU2VsZWN0IHhtbFNjaGVtYUlEQ1NlbGVjdDsKdHlwZWRlZiB4bWxTY2hlbWFJRENTZWxlY3QgKnhtbFNjaGVtYUlEQ1NlbGVjdFB0cjsKc3RydWN0IF94bWxTY2hlbWFJRENTZWxlY3QgewogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIG5leHQ7CiAgICB4bWxTY2hlbWFJRENQdHIgaWRjOwogICAgaW50IGluZGV4OyAvKiBhbiBpbmRleCBwb3NpdGlvbiBpZiBzaWduaWZpY2FudCBmb3IgSURDIGtleS1zZXF1ZW5jZXMgKi8KICAgIGNvbnN0IHhtbENoYXIgKnhwYXRoOyAvKiB0aGUgWFBhdGggZXhwcmVzc2lvbiAqLwogICAgdm9pZCAqeHBhdGhDb21wOyAvKiB0aGUgY29tcGlsZWQgWFBhdGggZXhwcmVzc2lvbiAqLwp9OwoKLyoqCiAqIHhtbFNjaGVtYUlEQzoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbiBjb21wb25lbnQuCiAqIChFeHRlbmRzIHhtbFNjaGVtYUFubm90SXRlbSkKICovCgpzdHJ1Y3QgX3htbFNjaGVtYUlEQyB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFJRENQdHIgbmV4dDsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsZWN0b3I7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgZmllbGRzOwogICAgaW50IG5iRmllbGRzOwogICAgeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmOwp9OwoKLyoqCiAqIHhtbFNjaGVtYUlEQ0F1ZzoKICoKICogVGhlIGF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb24gdXNlZCBmb3IgdmFsaWRhdGlvbi4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENBdWcgeG1sU2NoZW1hSURDQXVnOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ0F1ZyAqeG1sU2NoZW1hSURDQXVnUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ0F1ZyB7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgbmV4dDsgLyogbmV4dCBpbiBhIGxpc3QgKi8KICAgIHhtbFNjaGVtYUlEQ1B0ciBkZWY7IC8qIHRoZSBJREMgZGVmaW5pdGlvbiAqLwogICAgaW50IGtleXJlZkRlcHRoOyAvKiB0aGUgbG93ZXN0IHRyZWUgbGV2ZWwgdG8gd2hpY2ggSURDCiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlcyBuZWVkIHRvIGJlIGJ1YmJsZWQgdXB3YXJkcyAqLwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENLZXlTZXF1ZW5jZToKICoKICogVGhlIGtleSBzZXF1ZW5jZSBvZiBhIG5vZGUgdGFibGUgaXRlbS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDS2V5IHhtbFNjaGVtYVBTVklJRENLZXk7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ0tleSAqeG1sU2NoZW1hUFNWSUlEQ0tleVB0cjsKc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDS2V5IHsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWw7Cn07CgovKioKICogeG1sU2NoZW1hUFNWSUlEQ05vZGU6CiAqCiAqIFRoZSBub2RlIHRhYmxlIGl0ZW0gb2YgYSBub2RlIHRhYmxlLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENOb2RlIHhtbFNjaGVtYVBTVklJRENOb2RlOwp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENOb2RlICp4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cjsKc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDTm9kZSB7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICprZXlzOwogICAgaW50IG5vZGVMaW5lOwogICAgaW50IG5vZGVRTmFtZUlEOyAgICAKCn07CgovKioKICogeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmc6CiAqCiAqIFRoZSBpZGVudGl0eS1jb25zdHJhaW50IGJpbmRpbmcgaXRlbSBvZiB0aGUgW2lkZW50aXR5LWNvbnN0cmFpbnQgdGFibGVdLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENCaW5kaW5nIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nOwp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nICp4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cjsKc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDQmluZGluZyB7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBuZXh0OyAvKiBuZXh0IGJpbmRpbmcgb2YgYSBzcGVjaWZpYyBub2RlICovCiAgICB4bWxTY2hlbWFJRENQdHIgZGVmaW5pdGlvbjsgLyogdGhlIElEQyBkZWZpbml0aW9uICovCiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqbm9kZVRhYmxlOyAvKiBhcnJheSBvZiBrZXktc2VxdWVuY2VzICovCiAgICBpbnQgbmJOb2RlczsgLyogbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIG5vZGUgdGFibGUgKi8KICAgIGludCBzaXplTm9kZXM7IC8qIHNpemUgb2YgdGhlIG5vZGUgdGFibGUgKi8KICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGR1cGxzOwp9OwoKCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SIDEKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQgMgoKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfTUFUQ0hFUyAtMgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9CTE9DS0VEIC0zCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDTWF0Y2hlciB4bWxTY2hlbWFJRENNYXRjaGVyOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ01hdGNoZXIgKnhtbFNjaGVtYUlEQ01hdGNoZXJQdHI7CgovKioKICogeG1sU2NoZW1hSURDU3RhdGVPYmo6CiAqCiAqIFRoZSBzdGF0ZSBvYmplY3QgdXNlZCB0byBldmFsdWF0ZSBYUGF0aCBleHByZXNzaW9ucy4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENTdGF0ZU9iaiB4bWxTY2hlbWFJRENTdGF0ZU9iajsKdHlwZWRlZiB4bWxTY2hlbWFJRENTdGF0ZU9iaiAqeG1sU2NoZW1hSURDU3RhdGVPYmpQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU3RhdGVPYmogewogICAgaW50IHR5cGU7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBuZXh0OyAvKiBuZXh0IGlmIGluIGEgbGlzdCAqLwogICAgaW50IGRlcHRoOyAvKiBkZXB0aCBvZiBjcmVhdGlvbiAqLwogICAgaW50ICpoaXN0b3J5OyAvKiBsaXN0IG9mIChkZXB0aCwgc3RhdGUtaWQpIHR1cGxlcyAqLwogICAgaW50IG5iSGlzdG9yeTsKICAgIGludCBzaXplSGlzdG9yeTsKICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcjsgLyogdGhlIGNvcnJlc3BvbmRlbnQgZmllbGQvc2VsZWN0b3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlciAqLwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbDsKICAgIHZvaWQgKnhwYXRoQ3R4dDsKfTsKCiNkZWZpbmUgSURDX01BVENIRVIgMAoKLyoqCiAqIHhtbFNjaGVtYUlEQ01hdGNoZXI6CiAqCiAqIFVzZWQgdG8gZXZhbHVhdGUgSURDIHNlbGVjdG9ycyAoYW5kIGZpZWxkcykuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ01hdGNoZXIgewogICAgaW50IHR5cGU7CiAgICBpbnQgZGVwdGg7IC8qIHRoZSB0cmVlIGRlcHRoIGF0IGNyZWF0aW9uIHRpbWUgKi8KICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbmV4dDsgLyogbmV4dCBpbiB0aGUgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7IC8qIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gKi8KICAgIGludCBpZGNUeXBlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKmtleVNlcXM7IC8qIHRoZSBrZXktc2VxdWVuY2VzIG9mIHRoZSB0YXJnZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyAqLwogICAgaW50IHNpemVLZXlTZXFzOwogICAgaW50IHRhcmdldERlcHRoOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgdGFyZ2V0czsgLyogbGlzdCBvZiB0YXJnZXQtbm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSBlbnRyaWVzICovCn07CgovKgoqIEVsZW1lbnQgaW5mbyBmbGFncy4KKi8KI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTICAxPDwwCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMgMTw8MQojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRAkgICAgICAgMTw8MgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0xPQ0FMX1RZUEUJICAgICAgIDE8PDMKCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEICAgICAgMTw8NAojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZICAgICAgICAgICAgIDE8PDUKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfQ09OVEVOVCAgICAgICAxPDw2CgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQgIDE8PDcKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQgIDE8PDgKI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEICAxPDw5CiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFICAxPDwxMAoKLyoqCiAqIHhtbFNjaGVtYU5vZGVJbmZvOgogKgogKiBIb2xkcyBpbmZvcm1hdGlvbiBvZiBhbiBlbGVtZW50IG5vZGUuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHsKICAgIGludCBub2RlVHlwZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBub2RlTGluZTsgICAgCiAgICBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWU7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWw7IC8qIHRoZSBwcmUtY29tcHV0ZWQgdmFsdWUgaWYgYW55ICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWY7IC8qIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24gaWYgYW55ICovCgogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBub2RlIGluZm8gZmxhZ3MgKi8KCiAgICBpbnQgdmFsTmVlZGVkOwogICAgaW50IG5vcm1WYWw7CgogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOyAvKiB0aGUgZWxlbWVudC9hdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGlkY1RhYmxlOyAvKiB0aGUgdGFibGUgb2YgUFNWSSBJREMgYmluZGluZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgdGhlIHNjb3BlIGVsZW1lbnQqLwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBpZGNNYXRjaGVyczsgLyogdGhlIElEQyBtYXRjaGVycyBmb3IgdGhlIHNjb3BlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50ICovCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleEN0eHQ7CgogICAgY29uc3QgeG1sQ2hhciAqKm5zQmluZGluZ3M7IC8qIE5hbWVzcGFjZSBiaW5kaW5ncyBvbiB0aGlzIGVsZW1lbnQgKi8KICAgIGludCBuYk5zQmluZGluZ3M7CiAgICBpbnQgc2l6ZU5zQmluZGluZ3M7ICAgIAoKICAgIGludCBoYXNLZXlyZWZzOwogICAgaW50IGFwcGxpZWRYUGF0aDsgLyogSW5kaWNhdGVzIHRoYXQgYW4gWFBhdGggaGFzIGJlZW4gYXBwbGllZC4gKi8KfTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOIDEKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkcgNAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRSA1CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfTk9fVFlQRSA2CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUUgNwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCA4CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRSA5CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9TVFJJQ1RfTk9fREVDTCAxMAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSEFTX0FUVFJfVVNFIDExCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9IQVNfQVRUUl9ERUNMIDEyCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVAgMTMKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1dJTERfTEFYX05PX0RFQ0wgMTQKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0RVUExJQ0FURV9JRCAxNQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfQU5EX1VTRV9JRCAxNgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSAxNwovKgoqIEBtZXRhVHlwZSB2YWx1ZXMgb2YgeG1sU2NoZW1hQXR0ckluZm8uCiovCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSAxCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMIDIKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DIDMKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DIDQKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TIDUKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRySW5mbyB4bWxTY2hlbWFBdHRySW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFBdHRySW5mbyAqeG1sU2NoZW1hQXR0ckluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXR0ckluZm8gewogICAgaW50IG5vZGVUeXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IG5vZGVMaW5lOyAgICAKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbDsgLyogdGhlIHByZS1jb21wdXRlZCB2YWx1ZSBpZiBhbnkgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZjsgLyogdGhlIGNvbXBsZXgvc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpZiBhbnkgKi8KICAgIGludCBmbGFnczsgLyogY29tYmluYXRpb24gb2Ygbm9kZSBpbmZvIGZsYWdzICovCgogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7IC8qIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2U7ICAvKiB0aGUgYXR0cmlidXRlIHVzZSAqLwogICAgaW50IHN0YXRlOwogICAgaW50IG1ldGFUeXBlOwogICAgY29uc3QgeG1sQ2hhciAqdmNWYWx1ZTsgLyogdGhlIHZhbHVlIGNvbnN0cmFpbnQgdmFsdWUgKi8KICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIHBhcmVudDsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFfVkFMSURfQ1RYVF9GTEFHX1NUUkVBTSAxCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHQ6CiAqCiAqIEEgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQKICovCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIGludCB0eXBlOwogICAgdm9pZCAqZXJyQ3R4dDsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CiAgICB4bWxDaGFyRW5jb2RpbmcgZW5jOwogICAgeG1sU0FYSGFuZGxlclB0ciBzYXg7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CiAgICB2b2lkICp1c2VyX2RhdGE7IC8qIFRPRE86IFdoYXQgaXMgdGhpcyBmb3I/ICovCgogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKCiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIC8qIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsgKi8KCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleHA7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsdWU7CgogICAgaW50IHZhbHVlV1M7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbE5vZGVQdHIgdmFsaWRhdGlvblJvb3Q7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgaW50IHhzaUFzc2VtYmxlOwoKICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyICplbGVtSW5mb3M7IC8qIGFycmF5IG9mIGVsZW1lbnQgaW5mb3JtYXRpb25zICovCiAgICBpbnQgc2l6ZUVsZW1JbmZvczsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlOyAvKiB0aGUgY3VycmVudCBlbGVtZW50IGluZm9ybWF0aW9uICovCgogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGNzOyAvKiBhIGxpc3Qgb2YgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbnMgKi8KCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlczsgLyogZmlyc3QgYWN0aXZlIHN0YXRlIG9iamVjdC4gKi8KICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHhwYXRoU3RhdGVQb29sOyAvKiBmaXJzdCBzdG9yZWQgc3RhdGUgb2JqZWN0LiAqLwoKICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICppZGNOb2RlczsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyovCiAgICBpbnQgbmJJZGNOb2RlczsKICAgIGludCBzaXplSWRjTm9kZXM7CgogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqaWRjS2V5czsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyAqLwogICAgaW50IG5iSWRjS2V5czsKICAgIGludCBzaXplSWRjS2V5czsKCiAgICBpbnQgZmxhZ3M7CgogICAgeG1sRGljdFB0ciBkaWN0OwoKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAogICAgeG1sVGV4dFJlYWRlclB0ciByZWFkZXI7CiNlbmRpZgoKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyICphdHRySW5mb3M7CiAgICBpbnQgbmJBdHRySW5mb3M7CiAgICBpbnQgc2l6ZUF0dHJJbmZvczsKCiAgICBpbnQgc2tpcERlcHRoOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbm9kZVFOYW1lczsKICAgIGludCBoYXNLZXlyZWZzOwogICAgaW50IGNyZWF0ZUlEQ05vZGVUYWJsZXM7CiAgICBpbnQgcHN2aUV4cG9zZUlEQ05vZGVUYWJsZXM7Cn07CgovKioKICogeG1sU2NoZW1hU3Vic3RHcm91cDoKICoKICoKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHhtbFNjaGVtYVN1YnN0R3JvdXA7CnR5cGVkZWYgeG1sU2NoZW1hU3Vic3RHcm91cCAqeG1sU2NoZW1hU3Vic3RHcm91cFB0cjsKc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIG1lbWJlcnM7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU29tZSBwcmVkZWNsYXJhdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hUGFyc2VSZWRlZmluZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBjdHh0KTsKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKTsKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCk7CnN0YXRpYyB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlCnhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCQkgaW50IHdpdGhQYXJ0aWNsZSk7CnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Q29tcG9uZW50VHlwZVN0cih4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlTGlua1B0cgp4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJbnRlcm5hbEVycih4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICAgICBjb25zdCBjaGFyICpmdW5jTmFtZSwKCQkgICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UpOwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCSAgICAgaW50IHN1YnNldCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBvbmVudExpc3RGcmVlKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpOwpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cFJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCXhtbE5vZGVQdHIgbm9kZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlIZWxwZXIgZnVuY3Rpb25zCQkJICAgICAgICAqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUl0ZW1UeXBlVG9TdHI6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hSXRlbVR5cGVUb1N0cih4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJICAgIHJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIHJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybihCQURfQ0FTVCAiZWxlbWVudCBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFX1VTRToKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSB1c2UiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCSAgICByZXR1cm4oQkFEX0NBU1QgIm5vdGF0aW9uIGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChzZXF1ZW5jZSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChjaG9pY2UpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCAoYWxsKSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJwYXJ0aWNsZSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRToKCSAgICByZXR1cm4oQkFEX0NBU1QgInVuaXF1ZSBpZGVudGl0eS1jb25zdHJhaW50Iik7CgkgICAgLyogcmV0dXJuKEJBRF9DQVNUICJJREMgKHVuaXF1ZSkiKTsgKi8KCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJrZXkgaWRlbnRpdHktY29uc3RyYWludCIpOwoJICAgIC8qIHJldHVybihCQURfQ0FTVCAiSURDIChrZXkpIik7ICovCgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJICAgIHJldHVybihCQURfQ0FTVCAia2V5cmVmIGlkZW50aXR5LWNvbnN0cmFpbnQiKTsKCSAgICAvKiByZXR1cm4oQkFEX0NBU1QgIklEQyAoa2V5cmVmKSIpOyAqLwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJICAgIHJldHVybihCQURfQ0FTVCAid2lsZGNhcmQgKGFueSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjoKCSAgICByZXR1cm4oQkFEX0NBU1QgIltoZWxwZXIgY29tcG9uZW50XSBRTmFtZSByZWZlcmVuY2UiKTsKCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUI6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJbaGVscGVyIGNvbXBvbmVudF0gYXR0cmlidXRlIHVzZSBwcm9oaWJpdGlvbiIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENvbXBvbmVudFR5cGVTdHI6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Q29tcG9uZW50VHlwZVN0cih4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSkKewogICAgc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKCSAgICBpZiAoV1hTX0lTX0NPTVBMRVgoV1hTX1RZUEVfQ0FTVCBpdGVtKSkKCQlyZXR1cm4oQkFEX0NBU1QgImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgkgICAgZWxzZQoJCXJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwkKCWRlZmF1bHQ6CgkgICAgcmV0dXJuKHhtbFNjaGVtYUl0ZW1UeXBlVG9TdHIoaXRlbS0+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+aHJlZiwgaXRlbU5vZGUtPm5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCX0gZWxzZQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbU5vZGUtPm5hbWUpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChzdHIpCiAgICAKICAgIHJldHVybiAoKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQ6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEB0eXBlOiB0aGUgdHlwZSBob2xkaW5nIHRoZSBlbnVtZXJhdGlvbiBmYWNldHMKICoKICogQnVpbGRzIGEgc3RyaW5nIGNvbnNpc3Rpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKgogKiBSZXR1cm5zIGEgc3RyaW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgIHhtbENoYXIgKipidWYsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlIHdzOwogICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwogICAgaW50IHJlczsKCiAgICBpZiAoKmJ1ZiAhPSBOVUxMKQoJeG1sRnJlZSgqYnVmKTsgICAgCiAgICAqYnVmID0gTlVMTDsKCiAgICBkbyB7CgkvKgoJKiBVc2UgdGhlIHdoaXRlc3BhY2UgdHlwZSBvZiB0aGUgYmFzZSB0eXBlLgoJKi8JCgl3cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUtPmJhc2VUeXBlKTsKCWZvciAoZmFjZXQgPSB0eXBlLT5mYWNldHM7IGZhY2V0ICE9IE5VTEw7IGZhY2V0ID0gZmFjZXQtPm5leHQpIHsKCSAgICBpZiAoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikKCQljb250aW51ZTsKCSAgICByZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlV2h0c3BFeHQoZmFjZXQtPnZhbCwKCQl3cywgJnZhbHVlKTsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hSW50ZXJuYWxFcnIoYWN0eHQsCgkJICAgICJ4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQiLAoJCSAgICAiY29tcHV0ZSB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24iKTsKCQlpZiAoKmJ1ZiAhPSBOVUxMKQoJCSAgICB4bWxGcmVlKCpidWYpOwoJCSpidWYgPSBOVUxMOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIGlmICgqYnVmID09IE5VTEwpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsICciKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUIHZhbHVlKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCQl4bWxGcmVlKCh4bWxDaGFyICopdmFsdWUpOwoJCXZhbHVlID0gTlVMTDsKCSAgICB9Cgl9Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9IHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKTsKCiAgICByZXR1cm4gKChjb25zdCB4bWxDaGFyICopICpidWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlFcnJvciBmdW5jdGlvbnMJCQkJICAgICAgICAqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyTWVtb3J5KGNvbnN0IGNoYXIgKm1zZykKewogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIG1zZyk7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQU2ltcGxlRXJyKGNvbnN0IGNoYXIgKm1zZykKewogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyck1lbW9yeSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+ZXJyQ3R4dDsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyMjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQG5vZGU6IHRoZSBjdXJyZW50IGNoaWxkCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycjIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIGlmIChjaGlsZCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwogICAgZWxzZQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7Cn0KCgovKioKICogeG1sU2NoZW1hUEVyckV4dDoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQHN0ckRhdGExOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMjogZXh0cmEgZGF0YQogKiBAc3RyRGF0YTM6IGV4dHJhIGRhdGEKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMSwgY29uc3QgeG1sQ2hhciAqIHN0ckRhdGEyLCAKCQljb25zdCB4bWxDaGFyICogc3RyRGF0YTMsIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHIyLCBjb25zdCB4bWxDaGFyICogc3RyMywgY29uc3QgeG1sQ2hhciAqIHN0cjQsCgkJY29uc3QgeG1sQ2hhciAqIHN0cjUpCnsKCiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+ZXJyQ3R4dDsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMSwgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTIsIAoJCSAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMywgMCwgMCwgbXNnLCBzdHIxLCBzdHIyLCAKCQkgICAgc3RyMywgc3RyNCwgc3RyNSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCUFsbHJvdW5kIGVycm9yIGZ1bmN0aW9ucwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hVlR5cGVFcnJNZW1vcnk6CiAqIEBub2RlOiBhIGNvbnRleHQgbm9kZQogKiBAZXh0cmE6ICBleHRyYSBpbmZvcm1hdGlvbnMKICoKICogSGFuZGxlIGFuIG91dCBvZiBtZW1vcnkgY29uZGl0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyTWVtb3J5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGN0eHQtPmVyciA9IFhNTF9TQ0hFTUFWX0lOVEVSTkFMOwogICAgfQogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTViwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUFNpbXBsZUludGVybmFsRXJyKHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqc3RyKQp7CiAgICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIG5vZGUsCgkgbXNnLCAoY29uc3QgY2hhciAqKSBzdHIpOwp9CgojZGVmaW5lIFdYU19FUlJPUl9UWVBFX0VSUk9SIDEKI2RlZmluZSBXWFNfRVJST1JfVFlQRV9XQVJOSU5HIDIKLyoqCiAqIHhtbFNjaGVtYUVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVycjRMaW5lKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBjdHh0LAoJCSAgeG1sRXJyb3JMZXZlbCBlcnJvckxldmVsLAoJCSAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGludCBsaW5lLCBjb25zdCBjaGFyICptc2csCgkJICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7ICAgIAogICAgCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CglpZiAoY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SKSB7CgkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4dDsKCSAgICBjb25zdCBjaGFyICpmaWxlID0gTlVMTDsKCSAgICBpZiAoZXJyb3JMZXZlbCAhPSBYTUxfRVJSX1dBUk5JTkcpIHsKCQl2Y3R4dC0+bmJlcnJvcnMrKzsKCQl2Y3R4dC0+ZXJyID0gZXJyb3I7CgkJY2hhbm5lbCA9IHZjdHh0LT5lcnJvcjsJCQoJICAgIH0gZWxzZSB7CgkJY2hhbm5lbCA9IHZjdHh0LT53YXJuaW5nOwoJICAgIH0KCSAgICBzY2hhbm5lbCA9IHZjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHZjdHh0LT5lcnJDdHh0OwoKCSAgICAvKgoJICAgICogRXJyb3Igbm9kZS4gSWYgd2Ugc3BlY2lmeSBhIGxpbmUgbnVtYmVyLCB0aGVuCgkgICAgKiBkbyBub3QgY2hhbm5lbCBhbnkgbm9kZSB0byB0aGUgZXJyb3IgZnVuY3Rpb24uCgkgICAgKi8KCSAgICBpZiAobGluZSA9PSAwKSB7CgkJaWYgKChub2RlID09IE5VTEwpICYmCgkJICAgICh2Y3R4dC0+ZGVwdGggPj0gMCkgJiYKCQkgICAgKHZjdHh0LT5pbm9kZSAhPSBOVUxMKSkgewoJCSAgICBub2RlID0gdmN0eHQtPmlub2RlLT5ub2RlOwoJCX0KCQkvKgoJCSogR2V0IGZpbGVuYW1lIGFuZCBsaW5lIGlmIG5vIG5vZGUtdHJlZS4KCQkqLwoJCWlmICgobm9kZSA9PSBOVUxMKSAmJgoJCSAgICAodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkgJiYKCQkgICAgKHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dCAhPSBOVUxMKSkgewoJCSAgICBmaWxlID0gdmN0eHQtPnBhcnNlckN0eHQtPmlucHV0LT5maWxlbmFtZTsKCQkgICAgbGluZSA9IHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dC0+bGluZTsKCQl9CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogT3ZlcnJpZGUgdGhlIGdpdmVuIG5vZGUncyAoaWYgYW55KSBwb3NpdGlvbgoJCSogYW5kIGNoYW5uZWwgb25seSB0aGUgZ2l2ZW4gbGluZSBudW1iZXIuCgkJKi8KCQlub2RlID0gTlVMTDsKCQkvKgoJCSogR2V0IGZpbGVuYW1lLgoJCSovCgkJaWYgKHZjdHh0LT5kb2MgIT0gTlVMTCkKCQkgICAgZmlsZSA9IChjb25zdCBjaGFyICopIHZjdHh0LT5kb2MtPlVSTDsKCQllbHNlIGlmICgodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkgJiYKCQkgICAgKHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dCAhPSBOVUxMKSkKCQkgICAgZmlsZSA9IHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dC0+ZmlsZW5hbWU7CgkgICAgfQkgICAgICAgCgkgICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LAoJCW5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAoJCWVycm9yLCBlcnJvckxldmVsLCBmaWxlLCBsaW5lLAoJCShjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsCgkJKGNvbnN0IGNoYXIgKikgc3RyMywgMCwgMCwgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKCgl9IGVsc2UgaWYgKGN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikgewoJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgY3R4dDsKCSAgICBpZiAoZXJyb3JMZXZlbCAhPSBYTUxfRVJSX1dBUk5JTkcpIHsKCQlwY3R4dC0+bmJlcnJvcnMrKzsKCQlwY3R4dC0+ZXJyID0gZXJyb3I7CgkJY2hhbm5lbCA9IHBjdHh0LT5lcnJvcjsJCQoJICAgIH0gZWxzZSB7CgkJY2hhbm5lbCA9IHBjdHh0LT53YXJuaW5nOwoJICAgIH0KCSAgICBzY2hhbm5lbCA9IHBjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHBjdHh0LT5lcnJDdHh0OwoJICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwKCQlub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwgZXJyb3IsCgkJZXJyb3JMZXZlbCwgTlVMTCwgMCwKCQkoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLAoJCShjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgc3RyMywgc3RyNCk7Cgl9IGVsc2UgewoJICAgIFRPRE8KCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVycjMoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LCAgCgkgICAgICBpbnQgZXJyb3IsIHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbXNnLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMiwgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfRVJST1IsIGVycm9yLCBub2RlLCAwLAoJbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBOVUxMKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyNCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsICAKCSAgICAgIGludCBlcnJvciwgeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICptc2csCgkgICAgICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfRVJST1IsIGVycm9yLCBub2RlLCAwLAoJbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCSAgICAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm1zZywKCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sU2NoZW1hRXJyNChhY3R4dCwgZXJyb3IsIG5vZGUsIG1zZywgc3RyMSwgc3RyMiwgTlVMTCwgTlVMTCk7Cn0KCnN0YXRpYyB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKHhtbENoYXIgKiogbXNnLAoJCQkgICAgeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgICptc2cgPSBOVUxMOwogICAgaWYgKChub2RlICE9IE5VTEwpICYmCgkobm9kZS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSAmJgoJKG5vZGUtPnR5cGUgIT0gWE1MX0FUVFJJQlVURV9OT0RFKSkKICAgIHsKCS8qIAoJKiBEb24ndCB0cnkgdG8gZm9ybWF0IG90aGVyIG5vZGVzIHRoYW4gZWxlbWVudCBhbmQKCSogYXR0cmlidXRlIG5vZGVzLgoJKiBQbGF5IHNhdmUgYW5kIHJldHVybiBhbiBlbXB0eSBzdHJpbmcuCgkqLwoJKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiIik7CglyZXR1cm4oKm1zZyk7CiAgICB9CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CgkvKgoJKiBXb3JrIG9uIHRyZWUgbm9kZXMuCgkqLwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CgkgICAgeG1sTm9kZVB0ciBlbGVtID0gbm9kZS0+cGFyZW50OwoJICAgIAoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJICAgIGlmIChlbGVtLT5ucyAhPSBOVUxMKQoJCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgZWxlbS0+bnMtPmhyZWYsIGVsZW0tPm5hbWUpKTsKCSAgICBlbHNlCgkJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBOVUxMLCBlbGVtLT5uYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIicsICIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgImF0dHJpYnV0ZSAnIik7CSAgICAKCX0gZWxzZSB7CgkgICAgKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7Cgl9CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgTlVMTCwgbm9kZS0+bmFtZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJzogIik7CiAgICB9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsKCXhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0OwoJLyoKCSogV29yayBvbiBub2RlIGluZm9zLgoJKi8JCglpZiAodmN0eHQtPmlub2RlLT5ub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbSA9CgkJdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwoKCSAgICAqbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJaWVsZW0tPm5zTmFtZSwgaWVsZW0tPmxvY2FsTmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICInLCAiKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICJhdHRyaWJ1dGUgJyIpOwkgICAgCgl9IGVsc2UgewoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJfQoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJICAgIHZjdHh0LT5pbm9kZS0+bnNOYW1lLCB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJzogIik7CiAgICB9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsKCS8qIAoJKiBIbW0sIG5vIG5vZGUgd2hpbGUgcGFyc2luZz8KCSogUmV0dXJuIGFuIGVtcHR5IHN0cmluZywgaW4gY2FzZSBOVUxMIHdpbGwgYnJlYWsgc29tZXRoaW5nLgoJKi8KCSptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiIpOwogICAgfSBlbHNlIHsKCVRPRE8KCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBWQUwgVE9ETzogVGhlIG91dHB1dCBvZiB0aGUgZ2l2ZW4gc2NoZW1hIGNvbXBvbmVudCBpcyBjdXJyZW50bHkKICAgICogZGlzYWJsZWQuCiAgICAqLwojaWYgMAogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpKSB7CgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICIgWyIpOwoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICJdIik7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuICgqbXNnKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hSW50ZXJuYWxFcnIyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgICBjb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMOwoKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiSW50ZXJuYWwgZXJyb3I6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgZnVuY05hbWUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiwgIik7ICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CgogICAgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpCgl4bWxTY2hlbWFFcnIoYWN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBOVUxMLAoJICAgIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMik7CgogICAgZWxzZSBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikJCgl4bWxTY2hlbWFFcnIoYWN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBOVUxMLAoJICAgIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMik7CgogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUludGVybmFsRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sU2NoZW1hSW50ZXJuYWxFcnIyKGFjdHh0LCBmdW5jTmFtZSwgbWVzc2FnZSwgTlVMTCwgTlVMTCk7Cn0KCiNpZiAwCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbnRlcm5hbEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgY29uc3QgY2hhciAqZnVuY05hbWUsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbFNjaGVtYUludGVybmFsRXJyMihBQ1RYVF9DQVNUIHBjdHh0LCBmdW5jTmFtZSwgbWVzc2FnZSwKCXN0cjEsIHN0cjIpOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ3VzdG9tRXJyNCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMywgY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgJiYgKGl0ZW0gIT0gTlVMTCkgJiYKCShhY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSKSkgewoJbm9kZSA9IFdYU19JVEVNX05PREUoaXRlbSk7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIGl0ZW0sIE5VTEwpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICB9IGVsc2UKCXhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCBhY3R4dCwgbm9kZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsgICAKICAgIHhtbFNjaGVtYUVycjQoYWN0eHQsIGVycm9yLCBub2RlLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0KTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDdXN0b21FcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbFNjaGVtYUN1c3RvbUVycjQoYWN0eHQsIGVycm9yLCBub2RlLCBpdGVtLAoJbWVzc2FnZSwgc3RyMSwgc3RyMiwgTlVMTCwgTlVMTCk7ICAgIAp9CgoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7IAogICAgCiAgICAvKiBVUkdFTlQgVE9ETzogU2V0IHRoZSBlcnJvciBjb2RlIHRvIHNvbWV0aGluZyBzYW5lLiAqLwogICAgeG1sU2NoZW1hRXJyNExpbmUoYWN0eHQsIFhNTF9FUlJfV0FSTklORywgZXJyb3IsIG5vZGUsIDAsCgkoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwoKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUtleXJlZkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGlkY05vZGUsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEwsICpxbmFtZSA9IE5VTEw7CiAgICAKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnJXMnOiAiKTsgICAgICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFFcnI0TGluZShBQ1RYVF9DQVNUIHZjdHh0LCBYTUxfRVJSX0VSUk9SLAoJZXJyb3IsIE5VTEwsIGlkY05vZGUtPm5vZGVMaW5lLCAoY29uc3QgY2hhciAqKSBtc2csCgl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmcW5hbWUsCgkgICAgdmN0eHQtPm5vZGVRTmFtZXMtPml0ZW1zW2lkY05vZGUtPm5vZGVRTmFtZUlEICsxXSwKCSAgICB2Y3R4dC0+bm9kZVFOYW1lcy0+aXRlbXNbaWRjTm9kZS0+bm9kZVFOYW1lSURdKSwgCglzdHIxLCBzdHIyLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwocW5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKQoJcmV0dXJuIChub2RlLT50eXBlKTsKICAgIGlmICgoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgJiYKCSgoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpLT5pbm9kZSAhPSBOVUxMKSkKCXJldHVybiAoICgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPmlub2RlLT5ub2RlVHlwZSk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJc0dsb2JhbEl0ZW0oeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgxKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIGlmICggKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJLyogTm90ZSB0aGF0IGF0dHJpYnV0ZSBncm91cHMgYXJlIGFsd2F5cyBnbG9iYWwuICovCglkZWZhdWx0OgoJICAgIHJldHVybigxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgaW50IGRpc3BsYXlWYWx1ZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwoKICAgIGlmIChkaXNwbGF5VmFsdWUgfHwgKHhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKGFjdHh0LCBub2RlKSA9PQoJICAgIFhNTF9BVFRSSUJVVEVfTk9ERSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyVzJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiAiKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGEgdmFsaWQgIgoJICAgICJ2YWx1ZSBvZiAiKTsKCiAgICBpZiAoISB4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSAiKTsKCiAgICBpZiAoV1hTX0lTX0FUT01JQyh0eXBlKSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJhdG9taWMgdHlwZSIpOwogICAgZWxzZSBpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAibGlzdCB0eXBlIik7CiAgICBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoKICAgIGlmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCWlmICh0eXBlLT5idWlsdEluVHlwZSAhPSAwKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInhzOiIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJfSBlbHNlIAoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLCB0eXBlLT5uYW1lKSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKGRpc3BsYXlWYWx1ZSB8fCAoeG1sU2NoZW1hRXZhbEVycm9yTm9kZVR5cGUoYWN0eHQsIG5vZGUpID09CgkgICAgWE1MX0FUVFJJQlVURV9OT0RFKSkKCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwogICAgZWxzZQoJeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKHhtbENoYXIgKiogc3RyLAoJCQkgICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBuaSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgTlVMTCwgbm9kZS0+bmFtZSkpOwogICAgfSBlbHNlIGlmIChuaSAhPSBOVUxMKQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShzdHIsIG5pLT5uc05hbWUsIG5pLT5sb2NhbE5hbWUpKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFBdHRySW5mb1B0ciBuaSwKCQkJeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCXhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKCZzdHIsICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgbmksIG5vZGUpLAoJTlVMTCk7ICAgICAgICAKICAgIEZSRUVfQU5EX05VTEwoc3RyKQogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWludCBuYnZhbCwKCQkJaW50IG5ibmVnLAoJCQl4bWxDaGFyICoqdmFsdWVzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbENoYXIgKmxvY2FsTmFtZSwgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGludCBpOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLiIpOwogICAgLyoKICAgICogTm90ZSB0aGF0IGlzIGRvZXMgbm90IG1ha2Ugc2Vuc2UgdG8gcmVwb3J0IHRoYXQgd2UgaGF2ZSBhCiAgICAqIHdpbGRjYXJkIGhlcmUsIHNpbmNlIHRoZSB3aWxkY2FyZCBtaWdodCBiZSB1bmZvbGRlZCBpbnRvCiAgICAqIG11bHRpcGxlIHRyYW5zaXRpb25zLgogICAgKi8KICAgIGlmIChuYnZhbCArIG5ibmVnID4gMCkgewoJaWYgKG5idmFsICsgbmJuZWcgPiAxKSB7CgkgICAgc3RyID0geG1sU3RyZHVwKEJBRF9DQVNUICIgRXhwZWN0ZWQgaXMgb25lIG9mICggIik7Cgl9IGVsc2UKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiBFeHBlY3RlZCBpcyAoICIpOwoJbnNOYW1lID0gTlVMTDsKICAgIAkgICAgCglmb3IgKGkgPSAwOyBpIDwgbmJ2YWwgKyBuYm5lZzsgaSsrKSB7CgkgICAgY3VyID0gdmFsdWVzW2ldOwoJICAgIGlmIChjdXIgPT0gTlVMTCkKCSAgICAgICAgY29udGludWU7CgkgICAgaWYgKChjdXJbMF0gPT0gJ24nKSAmJiAoY3VyWzFdID09ICdvJykgJiYgKGN1clsyXSA9PSAndCcpICYmCgkgICAgICAgIChjdXJbM10gPT0gJyAnKSkgewoJCWN1ciArPSA0OwoJCXN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUICIjI290aGVyIik7CgkgICAgfQoJICAgIC8qCgkgICAgKiBHZXQgdGhlIGxvY2FsIG5hbWUuCgkgICAgKi8KCSAgICBsb2NhbE5hbWUgPSBOVUxMOwoJICAgIAoJICAgIGVuZCA9IGN1cjsKCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQlsb2NhbE5hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIioiKTsKCQllbmQrKzsKCSAgICB9IGVsc2UgewoJCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoKmVuZCAhPSAnfCcpKQoJCSAgICBlbmQrKzsKCQlsb2NhbE5hbWUgPSB4bWxTdHJuY2F0KGxvY2FsTmFtZSwgQkFEX0NBU1QgY3VyLCBlbmQgLSBjdXIpOwoJICAgIH0JCQoJICAgIGlmICgqZW5kICE9IDApIHsJCSAgICAKCQllbmQrKzsKCQkvKgoJCSogU2tpcCAiKnwqIiBpZiB0aGV5IGNvbWUgd2l0aCBuZWdhdGVkIGV4cHJlc3Npb25zLCBzaW5jZQoJCSogdGhleSByZXByZXNlbnQgdGhlIHNhbWUgbmVnYXRlZCB3aWxkY2FyZC4KCQkqLwoJCWlmICgobmJuZWcgPT0gMCkgfHwgKCplbmQgIT0gJyonKSB8fCAoKmxvY2FsTmFtZSAhPSAnKicpKSB7CgkJICAgIC8qCgkJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCQkgICAgKi8KCQkgICAgY3VyID0gZW5kOwoJCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQkJbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Kn0iKTsKCQkgICAgfSBlbHNlIHsKCQkJd2hpbGUgKCplbmQgIT0gMCkKCQkJICAgIGVuZCsrOwoJCQkKCQkJaWYgKGkgPj0gbmJ2YWwpCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsjI290aGVyOiIpOwoJCQllbHNlCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsiKTsKCQkJCgkJCW5zTmFtZSA9IHhtbFN0cm5jYXQobnNOYW1lLCBCQURfQ0FTVCBjdXIsIGVuZCAtIGN1cik7CgkJCW5zTmFtZSA9IHhtbFN0cmNhdChuc05hbWUsIEJBRF9DQVNUICJ9Iik7CgkJICAgIH0KCQkgICAgc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgbnNOYW1lKTsKCQkgICAgRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJfSBlbHNlIHsKCQkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCSAgICBjb250aW51ZTsKCQl9CgkgICAgfQkgICAgICAgIAoJICAgIHN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUIGxvY2FsTmFtZSk7CgkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCQoJICAgIGlmIChpIDwgbmJ2YWwgKyBuYm5lZyAtMSkKCQlzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiLCAiKTsKCX0JCglzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiICkuXG4iKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIHN0cik7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0gZWxzZQogICAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZhY2V0RXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwKCQkgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSBmYWNldFR5cGU7CiAgICBpbnQgbm9kZVR5cGUgPSB4bWxTY2hlbWFFdmFsRXJyb3JOb2RlVHlwZShhY3R4dCwgbm9kZSk7CgogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIGlmIChlcnJvciA9PSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQpIHsKCWZhY2V0VHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CgkvKgoJKiBJZiBlbnVtZXJhdGlvbnMgYXJlIHZhbGlkYXRlZCwgb25lIG11c3Qgbm90IGV4cGVjdCB0aGUKCSogZmFjZXQgdG8gYmUgZ2l2ZW4uCgkqLwkKICAgIH0gZWxzZQkKCWZhY2V0VHlwZSA9IGZhY2V0LT50eXBlOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJmYWNldCAnIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldFR5cGUpKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInXSAiKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBhIGRlZmF1bHQgbWVzc2FnZS4KCSovCglpZiAoKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEgpKSB7CgoJICAgIGNoYXIgbGVuWzI1XSwgYWN0TGVuWzI1XTsKCgkgICAgLyogRklYTUUsIFRPRE86IFdoYXQgaXMgdGhlIG1heCBleHBlY3RlZCBzdHJpbmcgbGVuZ3RoIG9mIHRoZQoJICAgICogdGhpcyB2YWx1ZT8KCSAgICAqLwoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGhhcyBhIGxlbmd0aCBvZiAnJXMnOyAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgoJICAgIHNucHJpbnRmKGxlbiwgMjQsICIlbHUiLCB4bWxTY2hlbWFHZXRGYWNldFZhbHVlQXNVTG9uZyhmYWNldCkpOwoJICAgIHNucHJpbnRmKGFjdExlbiwgMjQsICIlbHUiLCBsZW5ndGgpOwoKCSAgICBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGRpZmZlcnMgZnJvbSB0aGUgYWxsb3dlZCBsZW5ndGggb2YgJyVzJy5cbiIpOyAgICAgCgkgICAgZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbWF4aW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyB1bmRlcnJ1bnMgdGhlIGFsbG93ZWQgbWluaW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIAoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJeG1sU2NoZW1hRXJyMyhhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgdmFsdWUsIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCSAgICBlbHNlIAoJCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4pOwoJCgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhbiBlbGVtZW50ICIKCQkib2YgdGhlIHNldCB7JXN9LlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgCgkJeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KGFjdHh0LCAmc3RyLCB0eXBlKSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFjY2VwdGVkICIKCQkiYnkgdGhlIHBhdHRlcm4gJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRSkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBsZXNzIHRoYW4gdGhlICIKCQkibWluaW11bSB2YWx1ZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIGdyZWF0ZXIgdGhhbiB0aGUgIgoJCSJtYXhpbXVtIHZhbHVlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBncmVhdGVyIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBsZXNzIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSAiCgkJImRpZ2l0cyB0aGFuIGFyZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSBmcmFjdGlvbmFsICIKCQkiZGlnaXRzIHRoYW4gYXJlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIqKSBtc2csIHZhbHVlLAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKG5vZGVUeXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewkJCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwkKCX0gZWxzZSB7CSAgICAKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7Cgl4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIpOwogICAgfSAgICAgICAgCiAgICBGUkVFX0FORF9OVUxMKHN0cikKICAgIHhtbEZyZWUobXNnKTsKfQoKI2RlZmluZSBWRVJST1IoZXJyLCB0eXBlLCBtc2cpIFwKICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LCBlcnIsIE5VTEwsIHR5cGUsIG1zZywgTlVMTCwgTlVMTCk7CgojZGVmaW5lIFZFUlJPUl9JTlQoZnVuYywgbXNnKSB4bWxTY2hlbWFJbnRlcm5hbEVycihBQ1RYVF9DQVNUIHZjdHh0LCBmdW5jLCBtc2cpOwoKI2RlZmluZSBQRVJST1JfSU5UKGZ1bmMsIG1zZykgeG1sU2NoZW1hSW50ZXJuYWxFcnIoQUNUWFRfQ0FTVCBwY3R4dCwgZnVuYywgbXNnKTsKI2RlZmluZSBQRVJST1JfSU5UMihmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKEFDVFhUX0NBU1QgY3R4dCwgZnVuYywgbXNnKTsKCiNkZWZpbmUgQUVSUk9SX0lOVChmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKGFjdHh0LCBmdW5jLCBtc2cpOwoKCi8qKgogKiB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lck5hbWU6IHRoZSBuYW1lIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5vZGU6IHRoZSBwYXJlbnQgZWxlbWVudCBub2RlIG9mIHRoZSBtaXNzaW5nIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwoKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsICIlczogJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLAoJICAgICIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nLlxuIiwKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgUU5hbWUKICogQHJlZk5hbWU6IHRoZSByZWZlcmVuY2VkIGxvY2FsIG5hbWUKICogQHJlZlVSSTogdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIFVSSQogKiBAbWVzc2FnZTogb3B0aW9uYWwgbWVzc2FnZQogKgogKiBVc2VkIHRvIHJlcG9ydCBRTmFtZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgZmFpbGVkIHRvIHJlc29sdmUKICogdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkgY29uc3QgY2hhciAqbmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZk5hbWUsCgkJCSBjb25zdCB4bWxDaGFyICpyZWZVUkksCgkJCSB4bWxTY2hlbWFUeXBlVHlwZSByZWZUeXBlLAoJCQkgY29uc3QgY2hhciAqcmVmVHlwZVN0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwogICAgaWYgKHJlZlR5cGVTdHIgPT0gTlVMTCkKCXJlZlR5cGVTdHIgPSAoY29uc3QgY2hhciAqKSB4bWxTY2hlbWFJdGVtVHlwZVRvU3RyKHJlZlR5cGUpOwoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBvd25lckVsZW0sIGVycm9yLAoJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIiVzLCBhdHRyaWJ1dGUgJyVzJzogVGhlIFFOYW1lIHZhbHVlICclcycgZG9lcyBub3QgcmVzb2x2ZSB0byBhKG4pICIKCSAgICAiJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUsCgkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ckEsIHJlZlVSSSwgcmVmTmFtZSksCgkgICAgQkFEX0NBU1QgcmVmVHlwZVN0ciwgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKGRlcykKICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlIGR1cmluZyB0aGUgcGFyc2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJeG1sQ2hhciAqKm93bmVyRGVzLAoJCQl4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQl4bWxBdHRyUHRyIGF0dHIsCgkJCWNvbnN0IGNoYXIgKm1zZykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIGF0dHItPm5hbWUsIChjb25zdCB4bWxDaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgYXR0cmlidXRlJ3Mgb3duZXIKICogQG93bmVySXRlbTogdGhlIGF0dHJpYnV0ZSdzIG93bmVyIGl0ZW0KICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJDb21wIEFUVFJJQlVURV9VTlVTRUQsCgkJCSB4bWxBdHRyUHRyIGF0dHIpCnsKICAgIHhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZzdHJBLCBBQ1RYVF9DQVNUIGN0eHQsIGF0dHItPnBhcmVudCk7CiAgICB4bWxTY2hlbWFFcnI0KEFDVFhUX0NBU1QgY3R4dCwgZXJyb3IsICh4bWxOb2RlUHRyKSBhdHRyLAoJIiVzVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwgQkFEX0NBU1Qgc3RyQSwKCXhtbFNjaGVtYUZvcm1hdFFOYW1lTnMoJnN0ckIsIGF0dHItPm5zLCBhdHRyLT5uYW1lKSwKCU5VTEwsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChzdHJBKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjI6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMzogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMiwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBpdGVtLCBpdGVtRWxlbSk7CiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKChpdGVtRWxlbSA9PSBOVUxMKSAmJiAoaXRlbSAhPSBOVUxMKSkKCWl0ZW1FbGVtID0gV1hTX0lURU1fTk9ERShpdGVtKTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbUVsZW0sIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEpCnsKICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwgZXJyb3IsIGl0ZW0sIGl0ZW1FbGVtLCBtZXNzYWdlLAoJc3RyMSwgTlVMTCwgTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQXR0clVzZUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbTogdGhlIHNjaGVtYSB0eXBlCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSB0eXBlCiAqIEBhdHRyOiB0aGUgaW52YWxpZCBzY2hlbWEgYXR0cmlidXRlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGF0dHJpYnV0ZSB1c2UgZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQXR0clVzZUVycjQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkgICAgY29uc3QgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIGF0dHJ1c2UsCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjMsY29uc3QgeG1sQ2hhciAqc3RyNCkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgb3duZXJJdGVtLCBOVUxMKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsICIpOyAgICAKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCglCQURfQ0FTVCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsCglXWFNfQkFTSUNfQ0FTVCBhdHRydXNlLCBOVUxMKSk7CiAgICBGUkVFX0FORF9OVUxMKHN0cik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgeG1sU2NoZW1hRXJyNChBQ1RYVF9DQVNUIGN0eHQsIGVycm9yLCBub2RlLCAKCShjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMiwgc3RyMywgc3RyNCk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgc2NoZW1hIHR5cGUKICogQGJhc2VUeXBlOiB0aGUgYmFzZSB0eXBlIG9mIHR5cGUKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIGF0b21pYyBzaW1wbGUgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIFdYU19CQVNJQ19DQVNUIHR5cGUsIHR5cGUtPm5vZGUpOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCB0eXBlLT5ub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQgb24gdHlwZXMgZGVyaXZlZCBmcm9tIHRoZSAiCgkidHlwZSAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0clQsIE5VTEwsIFdYU19CQVNJQ19DQVNUIGJhc2VUeXBlLCBOVUxMKSwKCU5VTEwsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJUKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbSBpbnZvbHZlZAogKiBAZmFjZXQ6IHRoZSBpbGxlZ2FsIGZhY2V0CiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBmYWNldCBmb3IgPGxpc3Q+IGFuZCA8dW5pb24+LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0clQgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgV1hTX0JBU0lDX0NBU1QgdHlwZSwKCXR5cGUtPm5vZGUpOwogICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBlcnJvciwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQuXG4iLAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJUKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGVsZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQgbm9kZQogKiBAYXR0cjogdGhlIGJhZCBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvZiB0aGUgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQkgeG1sQXR0clB0ciBhdHRyLAoJCQkgY29uc3QgY2hhciAqbmFtZTEsCgkJCSBjb25zdCBjaGFyICpuYW1lMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIFdYU19CQVNJQ19DQVNUIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJIiVzOiBUaGUgYXR0cmlidXRlcyAnJXMnIGFuZCAnJXMnIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuXG4iLAoJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lMSwgQkFEX0NBU1QgbmFtZTIsIE5VTEwsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwp9CgovKioKICogeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAdHlwZTogdGhlIHR5cGUgc3BlY2lmaWVyCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBpZiBleGlzdGVudCAKICogQG5vZGU6IHRoZSB2YWxpZGF0ZWQgbm9kZQogKiBAdmFsdWU6IHRoZSB2YWxpZGF0ZWQgdmFsdWUKICoKICogUmVwb3J0cyBhIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqIFRPRE86IFNob3VsZCB0aGlzIHJlcG9ydCB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBhcyB3ZWxsPwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtIEFUVFJJQlVURV9VTlVTRUQsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQljb25zdCBjaGFyICpleHBlY3RlZCwKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjEsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCBBQ1RYVF9DQVNUIGN0eHQsIG5vZGUpOwogICAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgewoJLyoKCSogVXNlIGRlZmF1bHQgbWVzc2FnZXMuCgkqLwkKCWlmICh0eXBlICE9IE5VTEwpIHsKCSAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiclcycgaXMgbm90IGEgdmFsaWQgdmFsdWUgb2YgIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGEgIgoJCSJ2YWxpZCB2YWx1ZSBvZiAiKTsJCgkgICAgaWYgKCEgeG1sU2NoZW1hSXNHbG9iYWxJdGVtKHR5cGUpKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJ0aGUgbG9jYWwgIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJ0aGUgIik7CgkgICAgCgkgICAgaWYgKFdYU19JU19BVE9NSUModHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgImF0b21pYyB0eXBlIik7CgkgICAgZWxzZSBpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgImxpc3QgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFdYU19JU19VTklPTih0eXBlKSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoJICAgIAoJICAgIGlmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpIHsKCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgJyIpOwoJCWlmICh0eXBlLT5idWlsdEluVHlwZSAhPSAwKSB7CgkJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJ4czoiKTsKCQkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgdHlwZS0+bmFtZSk7CgkJfSBlbHNlIAoJCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLAoJCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkgICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLCB0eXBlLT5uYW1lKSk7CgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIicuIik7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgdmFsaWQuIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90ICIKCQkidmFsaWQuIik7Cgl9CQoJaWYgKGV4cGVjdGVkKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBFeHBlY3RlZCBpcyAnIik7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgZXhwZWN0ZWQpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInLlxuIik7Cgl9IGVsc2UKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXG4iKTsKCWlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsKCWVsc2UKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgfSBlbHNlIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIG1lc3NhZ2UpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAgKGNvbnN0IGNoYXIqKSBtc2csIHN0cjEsIHN0cjIsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgfQogICAgLyogQ2xlYW51cC4gKi8gICAgCiAgICBGUkVFX0FORF9OVUxMKG1zZykKfQoKLyoqCiAqIHhtbFNjaGVtYVBDb250ZW50RXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvbndlckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGl0ZW0gb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAb3duZXJFbGVtOiB0aGUgbm9kZSBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBjaGlsZDogdGhlIGludmFsaWQgY2hpbGQgbm9kZQogKiBAbWVzc2FnZTogdGhlIG9wdGlvbmFsIGVycm9yIG1lc3NhZ2UKICogQGNvbnRlbnQ6IHRoZSBvcHRpb25hbCBzdHJpbmcgZGVzY3JpYmluZyB0aGUgY29ycmVjdCBjb250ZW50CiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgY29uY2VybmluZyB0aGUgY29udGVudCBvZiBhIHNjaGVtYSBlbGVtZW50LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUENvbnRlbnRFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkgICAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCSAgICAgeG1sTm9kZVB0ciBjaGlsZCwKCQkgICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgICBjb25zdCBjaGFyICpjb250ZW50KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwogICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkKCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLAoJICAgICIlczogJXMuXG4iLAoJICAgIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBlbHNlIHsKCWlmIChjb250ZW50ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC4gRXhwZWN0ZWQgaXMgJXMuXG4iLAoJCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgY29udGVudCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLAoJCSIlczogVGhlIGNvbnRlbnQgaXMgbm90IHZhbGlkLlxuIiwKCQlCQURfQ0FTVCBkZXMsIE5VTEwpOwoJfQogICAgfQogICAgRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTdHJlYW1hYmxlIGVycm9yIGZ1bmN0aW9ucyAgICAgICAgICAgICAgICAgICAgICAqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGhlbHBlciBmdW5jdGlvbnMJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJQWxsb2NhdGlvbiBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3U2NoZW1hRm9yUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUl0ZW1MaXN0UHRyCnhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKHZvaWQpCnsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHJldDsKCiAgICByZXQgPSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUl0ZW1MaXN0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCSAgICAiYWxsb2NhdGluZyBhbiBpdGVtIGxpc3Qgc3RydWN0dXJlIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUl0ZW1MaXN0KSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUl0ZW1MaXN0Q2xlYXIoeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCkKewogICAgaWYgKGxpc3QtPml0ZW1zICE9IE5VTEwpIHsKCXhtbEZyZWUobGlzdC0+aXRlbXMpOwoJbGlzdC0+aXRlbXMgPSBOVUxMOwogICAgfQogICAgbGlzdC0+bmJJdGVtcyA9IDA7CiAgICBsaXN0LT5zaXplSXRlbXMgPSAwOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUl0ZW1MaXN0QWRkKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsIHZvaWQgKml0ZW0pCnsKICAgIGlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CglsaXN0LT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoCgkgICAgMjAgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgbmV3IGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CglsaXN0LT5zaXplSXRlbXMgPSAyMDsKICAgIH0gZWxzZSBpZiAobGlzdC0+c2l6ZUl0ZW1zIDw9IGxpc3QtPm5iSXRlbXMpIHsKCWxpc3QtPnNpemVJdGVtcyAqPSAyOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhsaXN0LT5pdGVtcywKCSAgICBsaXN0LT5zaXplSXRlbXMgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImdyb3dpbmcgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgbGlzdC0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfQogICAgbGlzdC0+aXRlbXNbbGlzdC0+bmJJdGVtcysrXSA9IGl0ZW07CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXRlbUxpc3RBZGRTaXplKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsCgkJCSBpbnQgaW5pdGlhbFNpemUsCgkJCSB2b2lkICppdGVtKQp7CiAgICBpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJaWYgKGluaXRpYWxTaXplIDw9IDApCgkgICAgaW5pdGlhbFNpemUgPSAxOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIGluaXRpYWxTaXplICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIG5ldyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQoJbGlzdC0+c2l6ZUl0ZW1zID0gaW5pdGlhbFNpemU7CiAgICB9IGVsc2UgaWYgKGxpc3QtPnNpemVJdGVtcyA8PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5zaXplSXRlbXMgKj0gMjsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MobGlzdC0+aXRlbXMsCgkgICAgbGlzdC0+c2l6ZUl0ZW1zICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJncm93aW5nIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIGxpc3QtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIGxpc3QtPml0ZW1zW2xpc3QtPm5iSXRlbXMrK10gPSBpdGVtOwogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUl0ZW1MaXN0SW5zZXJ0KHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsIHZvaWQgKml0ZW0sIGludCBpZHgpCnsgICAgCiAgICBpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIDIwICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIG5ldyBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQoJbGlzdC0+c2l6ZUl0ZW1zID0gMjA7CiAgICB9IGVsc2UgaWYgKGxpc3QtPnNpemVJdGVtcyA8PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5zaXplSXRlbXMgKj0gMjsKCWxpc3QtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MobGlzdC0+aXRlbXMsCgkgICAgbGlzdC0+c2l6ZUl0ZW1zICogc2l6ZW9mKHZvaWQgKikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJncm93aW5nIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIGxpc3QtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIEp1c3QgYXBwZW5kIGlmIHRoZSBpbmRleCBpcyBncmVhdGVyL2VxdWFsIHRoYW4gdGhlIGl0ZW0gY291bnQuCiAgICAqLwogICAgaWYgKGlkeCA+PSBsaXN0LT5uYkl0ZW1zKSB7CglsaXN0LT5pdGVtc1tsaXN0LT5uYkl0ZW1zKytdID0gaXRlbTsKICAgIH0gZWxzZSB7CglpbnQgaTsKCWZvciAoaSA9IGxpc3QtPm5iSXRlbXM7IGkgPiBpZHg7IGktLSkKCSAgICBsaXN0LT5pdGVtc1tpXSA9IGxpc3QtPml0ZW1zW2ktMV07CglsaXN0LT5pdGVtc1tpZHhdID0gaXRlbTsKCWxpc3QtPm5iSXRlbXMrKzsKICAgIH0KICAgIHJldHVybigwKTsKfQoKI2lmIDAgLyogZW5hYmxlIGlmIGV2ZXIgbmVlZGVkICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXRlbUxpc3RJbnNlcnRTaXplKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsCgkJCSAgICBpbnQgaW5pdGlhbFNpemUsCgkJCSAgICB2b2lkICppdGVtLAoJCQkgICAgaW50IGlkeCkKeyAgICAKICAgIGlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CglpZiAoaW5pdGlhbFNpemUgPD0gMCkKCSAgICBpbml0aWFsU2l6ZSA9IDE7CglsaXN0LT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoCgkgICAgaW5pdGlhbFNpemUgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgbmV3IGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CglsaXN0LT5zaXplSXRlbXMgPSBpbml0aWFsU2l6ZTsKICAgIH0gZWxzZSBpZiAobGlzdC0+c2l6ZUl0ZW1zIDw9IGxpc3QtPm5iSXRlbXMpIHsKCWxpc3QtPnNpemVJdGVtcyAqPSAyOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhsaXN0LT5pdGVtcywKCSAgICBsaXN0LT5zaXplSXRlbXMgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImdyb3dpbmcgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgbGlzdC0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfQogICAgLyoKICAgICogSnVzdCBhcHBlbmQgaWYgdGhlIGluZGV4IGlzIGdyZWF0ZXIvZXF1YWwgdGhhbiB0aGUgaXRlbSBjb3VudC4KICAgICovCiAgICBpZiAoaWR4ID49IGxpc3QtPm5iSXRlbXMpIHsKCWxpc3QtPml0ZW1zW2xpc3QtPm5iSXRlbXMrK10gPSBpdGVtOwogICAgfSBlbHNlIHsKCWludCBpOwoJZm9yIChpID0gbGlzdC0+bmJJdGVtczsgaSA+IGlkeDsgaS0tKQoJICAgIGxpc3QtPml0ZW1zW2ldID0gbGlzdC0+aXRlbXNbaS0xXTsKCWxpc3QtPml0ZW1zW2lkeF0gPSBpdGVtOwoJbGlzdC0+bmJJdGVtcysrOwogICAgfQogICAgcmV0dXJuKDApOwp9CiNlbmRpZgoKc3RhdGljIGludAp4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZSh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0LCBpbnQgaWR4KQp7CiAgICBpbnQgaTsKICAgIGlmICgobGlzdC0+aXRlbXMgPT0gTlVMTCkgfHwgKGlkeCA+PSBsaXN0LT5uYkl0ZW1zKSkgewoJeG1sU2NoZW1hUFNpbXBsZUVycigiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUl0ZW1MaXN0UmVtb3ZlLCAiCgkgICAgImluZGV4IGVycm9yLlxuIik7CglyZXR1cm4oLTEpOwogICAgfQoKICAgIGlmIChsaXN0LT5uYkl0ZW1zID09IDEpIHsKCS8qIFRPRE86IFJlYWxseSBmcmVlIHRoZSBsaXN0PyAqLwoJeG1sRnJlZShsaXN0LT5pdGVtcyk7CglsaXN0LT5pdGVtcyA9IE5VTEw7CglsaXN0LT5uYkl0ZW1zID0gMDsKCWxpc3QtPnNpemVJdGVtcyA9IDA7CiAgICB9IGVsc2UgaWYgKGxpc3QtPm5iSXRlbXMgLTEgPT0gaWR4KSB7CglsaXN0LT5uYkl0ZW1zLS07CiAgICB9IGVsc2UgewkKCWZvciAoaSA9IGlkeDsgaSA8IGxpc3QtPm5iSXRlbXMgLTE7IGkrKykKCSAgICBsaXN0LT5pdGVtc1tpXSA9IGxpc3QtPml0ZW1zW2krMV07CglsaXN0LT5uYkl0ZW1zLS07CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJdGVtTGlzdEZyZWU6CiAqIEBhbm5vdDogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBhbm5vdGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSXRlbUxpc3RGcmVlKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpCnsKICAgIGlmIChsaXN0ID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAobGlzdC0+aXRlbXMgIT0gTlVMTCkKCXhtbEZyZWUobGlzdC0+aXRlbXMpOwogICAgeG1sRnJlZShsaXN0KTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVja2V0RnJlZSh4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0KQp7CiAgICBpZiAoYnVja2V0ID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAoYnVja2V0LT5nbG9iYWxzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUNvbXBvbmVudExpc3RGcmVlKGJ1Y2tldC0+Z2xvYmFscyk7Cgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoYnVja2V0LT5nbG9iYWxzKTsKICAgIH0KICAgIGlmIChidWNrZXQtPmxvY2FscyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFDb21wb25lbnRMaXN0RnJlZShidWNrZXQtPmxvY2Fscyk7Cgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoYnVja2V0LT5sb2NhbHMpOwkKICAgIH0KICAgIGlmIChidWNrZXQtPnJlbGF0aW9ucyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciBwcmV2LCBjdXIgPSBidWNrZXQtPnJlbGF0aW9uczsKCWRvIHsKCSAgICBwcmV2ID0gY3VyOwkgICAgCgkgICAgY3VyID0gY3VyLT5uZXh0OwoJICAgIHhtbEZyZWUocHJldik7Cgl9IHdoaWxlIChjdXIgIT0gTlVMTCk7CiAgICB9CiAgICBpZiAoKCEgYnVja2V0LT5wcmVzZXJ2ZURvYykgJiYgKGJ1Y2tldC0+ZG9jICE9IE5VTEwpKSB7Cgl4bWxGcmVlRG9jKGJ1Y2tldC0+ZG9jKTsKICAgIH0gCiAgICBpZiAoYnVja2V0LT50eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCkgewoJaWYgKFdYU19JTVBCVUNLRVQoYnVja2V0KS0+c2NoZW1hICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZShXWFNfSU1QQlVDS0VUKGJ1Y2tldCktPnNjaGVtYSk7CiAgICB9CiAgICB4bWxGcmVlKGJ1Y2tldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFCdWNrZXRQdHIKeG1sU2NoZW1hQnVja2V0Q3JlYXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSBpbnQgdHlwZSwgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgcmV0OwogICAgaW50IHNpemU7CiAgICB4bWxTY2hlbWFQdHIgbWFpblNjaGVtYTsKCiAgICBpZiAoV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+bWFpblNjaGVtYSA9PSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWNrZXRDcmVhdGUiLAoJICAgICJubyBtYWluIHNjaGVtYSBvbiBjb25zdHJ1Y3RvciIpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWFpblNjaGVtYSA9IFdYU19DT05TVFJVQ1RPUihwY3R4dCktPm1haW5TY2hlbWE7CiAgICAvKiBDcmVhdGUgdGhlIHNjaGVtYSBidWNrZXQuICovCiAgICBpZiAoV1hTX0lTX0JVQ0tFVF9JTkNSRURFRih0eXBlKSkKCXNpemUgPSBzaXplb2YoeG1sU2NoZW1hSW5jbHVkZSk7CiAgICBlbHNlCglzaXplID0gc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCk7CiAgICByZXQgPSAoeG1sU2NoZW1hQnVja2V0UHRyKSB4bWxNYWxsb2Moc2l6ZSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIGJ1Y2tldCIsIE5VTEwpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZSk7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKICAgIHJldC0+dHlwZSA9IHR5cGU7CiAgICByZXQtPmdsb2JhbHMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+Z2xvYmFscyA9PSBOVUxMKSB7Cgl4bWxGcmVlKHJldCk7CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICByZXQtPmxvY2FscyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CiAgICBpZiAocmV0LT5sb2NhbHMgPT0gTlVMTCkgewoJeG1sRnJlZShyZXQpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgLyogCiAgICAqIFRoZSBmb2xsb3dpbmcgd2lsbCBhc3N1cmUgdGhhdCBvbmx5IHRoZSBmaXJzdCBidWNrZXQgaXMgbWFya2VkIGFzCiAgICAqIFhNTF9TQ0hFTUFfU0NIRU1BX01BSU4gYW5kIGl0IHBvaW50cyB0byB0aGUgKm1haW4qIHNjaGVtYS4KICAgICogRm9yIGVhY2ggZm9sbG93aW5nIGltcG9ydCBidWNrZXRzIGFuIHhtbFNjaGVtYSB3aWxsIGJlIGNyZWF0ZWQuCiAgICAqIEFuIHhtbFNjaGVtYSB3aWxsIGJlIGNyZWF0ZWQgZm9yIGV2ZXJ5IGRpc3RpbmN0IHRhcmdldE5hbWVzcGFjZS4KICAgICogV2UgYXNzaWduIHRoZSB0YXJnZXROYW1lc3BhY2UgdG8gdGhlIHNjaGVtYXRhIGhlcmUuCiAgICAqLwogICAgaWYgKCEgV1hTX0hBU19CVUNLRVRTKHBjdHh0KSkgewoJaWYgKFdYU19JU19CVUNLRVRfSU5DUkVERUYodHlwZSkpIHsKCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWNrZXRDcmVhdGUiLAoJCSJmaXJzdCBidWNrZXQgYnV0IGl0J3MgYW4gaW5jbHVkZSBvciByZWRlZmluZSIpOwoJICAgIHhtbFNjaGVtYUJ1Y2tldEZyZWUocmV0KTsKCSAgICByZXR1cm4oTlVMTCk7Cgl9CgkvKiBGb3JjZSB0aGUgdHlwZSB0byBiZSBYTUxfU0NIRU1BX1NDSEVNQV9NQUlOLiAqLyAKCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfU0NIRU1BX01BSU47CgkvKiBQb2ludCB0byB0aGUgKm1haW4qIHNjaGVtYS4gKi8KCVdYU19DT05TVFJVQ1RPUihwY3R4dCktPm1haW5CdWNrZXQgPSByZXQ7CglXWFNfSU1QQlVDS0VUKHJldCktPnNjaGVtYSA9IG1haW5TY2hlbWE7CgkvKgoJKiBFbnN1cmUgdGhhdCB0aGUgbWFpbiBzY2hlbWEgZ2V0cyBhIHRhcmdldE5hbWVzcGFjZS4KCSovCgltYWluU2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7CiAgICB9IGVsc2UgewoJaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTikgewkgICAgCgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVja2V0Q3JlYXRlIiwKCQkibWFpbiBidWNrZXQgYnV0IGl0J3Mgbm90IHRoZSBmaXJzdCBvbmUiKTsKCSAgICB4bWxTY2hlbWFCdWNrZXRGcmVlKHJldCk7CgkgICAgcmV0dXJuKE5VTEwpOwoJfSBlbHNlIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCkgewkgICAgCgkgICAgLyoKCSAgICAqIENyZWF0ZSBhIHNjaGVtYSBmb3IgaW1wb3J0cyBhbmQgYXNzaWduIHRoZQoJICAgICogdGFyZ2V0TmFtZXNwYWNlLgoJICAgICovCgkgICAgV1hTX0lNUEJVQ0tFVChyZXQpLT5zY2hlbWEgPSB4bWxTY2hlbWFOZXdTY2hlbWEocGN0eHQpOwoJICAgIGlmIChXWFNfSU1QQlVDS0VUKHJldCktPnNjaGVtYSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hQnVja2V0RnJlZShyZXQpOwoJCXJldHVybihOVUxMKTsKCSAgICB9CgkgICAgV1hTX0lNUEJVQ0tFVChyZXQpLT5zY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKCX0KICAgIH0gICAgCiAgICBpZiAoV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHR5cGUpKSB7CglpbnQgcmVzOwoJLyoKCSogSW1wb3J0cyBnbyBpbnRvIHRoZSAic2NoZW1hc0ltcG9ydHMiIHNsb3Qgb2YgdGhlIG1haW4gKnNjaGVtYSouCgkqIE5vdGUgdGhhdCB3ZSBjcmVhdGUgYW4gaW1wb3J0IGVudHJ5IGZvciB0aGUgbWFpbiBzY2hlbWEgYXMgd2VsbDsgaS5lLiwKCSogZXZlbiBpZiB0aGVyZSdzIG9ubHkgb25lIHNjaGVtYSwgd2UnbGwgZ2V0IGFuIGltcG9ydC4KCSovCglpZiAobWFpblNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgPT0gTlVMTCkgewoJICAgIG1haW5TY2hlbWEtPnNjaGVtYXNJbXBvcnRzID0geG1sSGFzaENyZWF0ZURpY3QoNSwKCQlXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5kaWN0KTsKCSAgICBpZiAobWFpblNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUJ1Y2tldEZyZWUocmV0KTsKCQlyZXR1cm4oTlVMTCk7CgkgICAgfQoJfQoJaWYgKHRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKQoJICAgIHJlcyA9IHhtbEhhc2hBZGRFbnRyeShtYWluU2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKCQlYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UsIHJldCk7CgllbHNlCgkgICAgcmVzID0geG1sSGFzaEFkZEVudHJ5KG1haW5TY2hlbWEtPnNjaGVtYXNJbXBvcnRzLAoJCXRhcmdldE5hbWVzcGFjZSwgcmV0KTsKCWlmIChyZXMgIT0gMCkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1Y2tldENyZWF0ZSIsCgkJImZhaWxlZCB0byBhZGQgdGhlIHNjaGVtYSBidWNrZXQgdG8gdGhlIGhhc2giKTsKCSAgICB4bWxTY2hlbWFCdWNrZXRGcmVlKHJldCk7CgkgICAgcmV0dXJuKE5VTEwpOwoJfQogICAgfSBlbHNlIHsKCS8qIFNldCB0aGUgQG93bmVySW1wb3J0IG9mIGFuIGluY2x1ZGUgYnVja2V0LiAqLwoJaWYgKFdYU19JU19CVUNLRVRfSU1QTUFJTihXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXQtPnR5cGUpKQoJICAgIFdYU19JTkNCVUNLRVQocmV0KS0+b3duZXJJbXBvcnQgPQoJCVdYU19JTVBCVUNLRVQoV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+YnVja2V0KTsKCWVsc2UKCSAgICBXWFNfSU5DQlVDS0VUKHJldCktPm93bmVySW1wb3J0ID0KCQlXWFNfSU5DQlVDS0VUKFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCktPm93bmVySW1wb3J0OwoKCS8qIEluY2x1ZGVzIGdvdCBpbnRvIHRoZSAiaW5jbHVkZXMiIHNsb3Qgb2YgdGhlICptYWluKiBzY2hlbWEuICovCglpZiAobWFpblNjaGVtYS0+aW5jbHVkZXMgPT0gTlVMTCkgewoJICAgIG1haW5TY2hlbWEtPmluY2x1ZGVzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCSAgICBpZiAobWFpblNjaGVtYS0+aW5jbHVkZXMgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUJ1Y2tldEZyZWUocmV0KTsKCQlyZXR1cm4oTlVMTCk7CgkgICAgfQkgICAgCgl9Cgl4bWxTY2hlbWFJdGVtTGlzdEFkZChtYWluU2NoZW1hLT5pbmNsdWRlcywgcmV0KTsKICAgIH0KICAgIC8qIAogICAgKiBBZGQgdG8gbGlzdCBvZiBhbGwgYnVja2V0czsgdGhpcyBpcyB1c2VkIGZvciBsb29rdXAKICAgICogZHVyaW5nIHNjaGVtYSBjb25zdHJ1Y3Rpb24gdGltZSBvbmx5LgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFJdGVtTGlzdEFkZChXWFNfQ09OU1RSVUNUT1IocGN0eHQpLT5idWNrZXRzLCByZXQpID09IC0xKQoJcmV0dXJuKE5VTEwpOwogICAgcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkSXRlbVNpemUoeG1sU2NoZW1hSXRlbUxpc3RQdHIgKmxpc3QsIGludCBpbml0aWFsU2l6ZSwgdm9pZCAqaXRlbSkKewogICAgaWYgKCpsaXN0ID09IE5VTEwpIHsKCSpsaXN0ID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCWlmICgqbGlzdCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7CiAgICB9CiAgICB4bWxTY2hlbWFJdGVtTGlzdEFkZFNpemUoKmxpc3QsIGluaXRpYWxTaXplLCBpdGVtKTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhbm5vdC0+bmV4dCA9PSBOVUxMKSB7Cgl4bWxGcmVlKGFubm90KTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFBbm5vdFB0ciBwcmV2OwoKCWRvIHsKCSAgICBwcmV2ID0gYW5ub3Q7CgkgICAgYW5ub3QgPSBhbm5vdC0+bmV4dDsKCSAgICB4bWxGcmVlKHByZXYpOwoJfSB3aGlsZSAoYW5ub3QgIT0gTlVMTCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTm90YXRpb246CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBub3RhdGlvbiBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBOb3RhdGlvbiBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTm90YXRpb24oeG1sU2NoZW1hTm90YXRpb25QdHIgbm90YSkKewogICAgaWYgKG5vdGEgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKG5vdGEpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZToKICogQGF0dHI6ICBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24KICoKICogRGVhbGxvY2F0ZXMgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgaWYgKGF0dHItPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGF0dHItPmRlZlZhbCk7CiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZToKICogQHVzZTogIGFuIGF0dHJpYnV0ZSB1c2UKICoKICogRGVhbGxvY2F0ZXMgYW4gYXR0cmlidXRlIHVzZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0ciB1c2UpCnsKICAgIGlmICh1c2UgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAodXNlLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KHVzZS0+YW5ub3QpOwogICAgaWYgKHVzZS0+ZGVmVmFsICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlVmFsdWUodXNlLT5kZWZWYWwpOwogICAgeG1sRnJlZSh1c2UpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZVByb2hpYjoKICogQHByb2hpYjogIGFuIGF0dHJpYnV0ZSB1c2UgcHJvaGliaXRpb24KICoKICogRGVhbGxvY2F0ZXMgYW4gYXR0cmlidXRlIHVzZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlUHJvaGliKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0ciBwcm9oaWIpCnsKICAgIGlmIChwcm9oaWIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKHByb2hpYik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldDoKICogc2V0OiAgYSBzY2hlbWEgd2lsZGNhcmQgbmFtZXNwYWNlCiAqCiAqIERlYWxsb2NhdGVzIGEgbGlzdCBvZiB3aWxkY2FyZCBjb25zdHJhaW50IHN0cnVjdHVyZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHNldCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuZXh0OwoKICAgIHdoaWxlIChzZXQgIT0gTlVMTCkgewoJbmV4dCA9IHNldC0+bmV4dDsKCXhtbEZyZWUoc2V0KTsKCXNldCA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlV2lsZGNhcmQ6CiAqIEB3aWxkY2FyZDogIGEgd2lsZGNhcmQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGVzIGEgd2lsZGNhcmQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlV2lsZGNhcmQoeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZGNhcmQpCnsKICAgIGlmICh3aWxkY2FyZCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICh3aWxkY2FyZC0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3Qod2lsZGNhcmQtPmFubm90KTsKICAgIGlmICh3aWxkY2FyZC0+bnNTZXQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHdpbGRjYXJkLT5uc1NldCk7CiAgICBpZiAod2lsZGNhcmQtPm5lZ05zU2V0ICE9IE5VTEwpCgl4bWxGcmVlKHdpbGRjYXJkLT5uZWdOc1NldCk7CiAgICB4bWxGcmVlKHdpbGRjYXJkKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBncm91cCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJHcikKewogICAgaWYgKGF0dHJHciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyR3ItPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGF0dHJHci0+YW5ub3QpOwogICAgaWYgKGF0dHJHci0+YXR0clVzZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShXWFNfTElTVF9DQVNUIGF0dHJHci0+YXR0clVzZXMpOwogICAgeG1sRnJlZShhdHRyR3IpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVFOYW1lUmVmOgogKiBAaXRlbTogYSBRTmFtZSByZWZlcmVuY2Ugc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGVhIGEgUU5hbWUgcmVmZXJlbmNlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVRTmFtZVJlZih4bWxTY2hlbWFRTmFtZVJlZlB0ciBpdGVtKQp7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdDoKICogQGFsaW5rOiBhIHR5cGUgbGluawogKgogKiBEZWFsbG9jYXRlIGEgbGlzdCBvZiB0eXBlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3QoeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaykKewogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbmV4dDsKCiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7CgluZXh0ID0gbGluay0+bmV4dDsKCXhtbEZyZWUobGluayk7CglsaW5rID0gbmV4dDsKICAgIH0KfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdCh4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8pCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIG5leHQ7CiAgICB3aGlsZSAoc3RvICE9IE5VTEwpIHsKCW5leHQgPSBzdG8tPm5leHQ7CglpZiAoc3RvLT5oaXN0b3J5ICE9IE5VTEwpCgkgICAgeG1sRnJlZShzdG8tPmhpc3RvcnkpOwoJaWYgKHN0by0+eHBhdGhDdHh0ICE9IE5VTEwpCgkgICAgeG1sRnJlZVN0cmVhbUN0eHQoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCXhtbEZyZWUoc3RvKTsKCXN0byA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSURDOgogKiBAaWRjOiBhIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKgogKiBEZWFsbG9jYXRlcyBhbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSURDKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYpCnsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBjdXIsIHByZXY7CgogICAgaWYgKGlkY0RlZiA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGlkY0RlZi0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoaWRjRGVmLT5hbm5vdCk7CiAgICAvKiBTZWxlY3RvciAqLwogICAgaWYgKGlkY0RlZi0+c2VsZWN0b3IgIT0gTlVMTCkgewoJaWYgKGlkY0RlZi0+c2VsZWN0b3ItPnhwYXRoQ29tcCAhPSBOVUxMKQoJICAgIHhtbEZyZWVQYXR0ZXJuKCh4bWxQYXR0ZXJuUHRyKSBpZGNEZWYtPnNlbGVjdG9yLT54cGF0aENvbXApOwoJeG1sRnJlZShpZGNEZWYtPnNlbGVjdG9yKTsKICAgIH0KICAgIC8qIEZpZWxkcyAqLwogICAgaWYgKGlkY0RlZi0+ZmllbGRzICE9IE5VTEwpIHsKCWN1ciA9IGlkY0RlZi0+ZmllbGRzOwoJZG8gewoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJICAgIGlmIChwcmV2LT54cGF0aENvbXAgIT0gTlVMTCkKCQl4bWxGcmVlUGF0dGVybigoeG1sUGF0dGVyblB0cikgcHJldi0+eHBhdGhDb21wKTsKCSAgICB4bWxGcmVlKHByZXYpOwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgeG1sRnJlZShpZGNEZWYpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUVsZW1lbnQ6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBlbGVtZW50IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEVsZW1lbnQgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUVsZW1lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChlbGVtLT5hbm5vdCk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cChlbGVtLT5jb250TW9kZWwpOwogICAgaWYgKGVsZW0tPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGVsZW0tPmRlZlZhbCk7CiAgICB4bWxGcmVlKGVsZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUZhY2V0OgogKiBAZmFjZXQ6ICBhIHNjaGVtYSBmYWNldCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBGYWNldCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgaWYgKGZhY2V0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGZhY2V0LT52YWwgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoZmFjZXQtPnZhbCk7CiAgICBpZiAoZmFjZXQtPnJlZ2V4cCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZmFjZXQtPnJlZ2V4cCk7CiAgICBpZiAoZmFjZXQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGZhY2V0LT5hbm5vdCk7CiAgICB4bWxGcmVlKGZhY2V0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlOgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QodHlwZS0+YW5ub3QpOwogICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsIG5leHQ7CgogICAgICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwogICAgICAgIHdoaWxlIChmYWNldCAhPSBOVUxMKSB7CiAgICAgICAgICAgIG5leHQgPSBmYWNldC0+bmV4dDsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICAgICAgZmFjZXQgPSBuZXh0OwogICAgICAgIH0KICAgIH0KICAgIGlmICh0eXBlLT5hdHRyVXNlcyAhPSBOVUxMKQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKCh4bWxTY2hlbWFJdGVtTGlzdFB0cikgdHlwZS0+YXR0clVzZXMpOwogICAgaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHR5cGUtPm1lbWJlclR5cGVzKTsKICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldExpbmtQdHIgbmV4dCwgbGluazsKCglsaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CglkbyB7CgkgICAgbmV4dCA9IGxpbmstPm5leHQ7CgkgICAgeG1sRnJlZShsaW5rKTsKCSAgICBsaW5rID0gbmV4dDsKCX0gd2hpbGUgKGxpbmsgIT0gTlVMTCk7CiAgICB9CiAgICBpZiAodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cCh0eXBlLT5jb250TW9kZWwpOwogICAgeG1sRnJlZSh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwRGVmOgogKiBAaXRlbTogIGEgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICoKICogRGVhbGxvY2F0ZXMgYSBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwRGVmKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgaXRlbSkKewogICAgaWYgKGl0ZW0tPmFubm90ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQW5ub3QoaXRlbS0+YW5ub3QpOwogICAgeG1sRnJlZShpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwOgogKiBAaXRlbTogIGEgc2NoZW1hIG1vZGVsIGdyb3VwCiAqCiAqIERlYWxsb2NhdGVzIGEgc2NoZW1hIG1vZGVsIGdyb3VwIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwKHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgaXRlbSkKewogICAgaWYgKGl0ZW0tPmFubm90ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQW5ub3QoaXRlbS0+YW5ub3QpOwogICAgeG1sRnJlZShpdGVtKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ29tcG9uZW50TGlzdEZyZWUoeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCkKewogICAgaWYgKChsaXN0ID09IE5VTEwpIHx8IChsaXN0LT5uYkl0ZW1zID09IDApKQoJcmV0dXJuOwogICAgewoJeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbTsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyICppdGVtcyA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0ciAqKSBsaXN0LT5pdGVtczsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5uYkl0ZW1zOyBpKyspIHsKCSAgICBpdGVtID0gaXRlbXNbaV07CgkgICAgaWYgKGl0ZW0gPT0gTlVMTCkKCQljb250aW51ZTsJICAgIAoJICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCSAgICB4bWxTY2hlbWFGcmVlVHlwZSgoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZSgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFX1VTRToKCQkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZSgoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyKSBpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX0VYVFJBX0FUVFJfVVNFX1BST0hJQjoKCQkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZVByb2hpYigKCQkJKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJICAgIHhtbFNjaGVtYUZyZWVFbGVtZW50KCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkJICAgIGlmIChpdGVtLT5hbm5vdCAhPSBOVUxMKQoJCQl4bWxTY2hlbWFGcmVlQW5ub3QoaXRlbS0+YW5ub3QpOwoJCSAgICB4bWxGcmVlKGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJCSAgICB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cCgoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCSAgICB4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXAoCgkJCSh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCSAgICB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZigKCQkJKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKCh4bWxTY2hlbWFXaWxkY2FyZFB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRToKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJCSAgICB4bWxTY2hlbWFGcmVlSURDKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0pOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCQkgICAgeG1sU2NoZW1hRnJlZU5vdGF0aW9uKCh4bWxTY2hlbWFOb3RhdGlvblB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRjoKCQkgICAgeG1sU2NoZW1hRnJlZVFOYW1lUmVmKCh4bWxTY2hlbWFRTmFtZVJlZlB0cikgaXRlbSk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6IHsKCQkgICAgLyogVE9ETzogVGhpcyBzaG91bGQgbmV2ZXIgYmUgaGl0LiAqLwoJCSAgICB4bWxTY2hlbWFQU2ltcGxlSW50ZXJuYWxFcnIoTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDb21wb25lbnRMaXN0RnJlZSwgIgoJCQkidW5leHBlY3RlZCBjb21wb25lbnQgdHlwZSAnJXMnXG4iLAoJCQkoY29uc3QgeG1sQ2hhciAqKSBXWFNfSVRFTV9UWVBFX05BTUUoaXRlbSkpOwoJCQkgfQoJCSAgICBicmVhazsKCSAgICB9Cgl9CglsaXN0LT5uYkl0ZW1zID0gMDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWUoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIC8qIEB2b2xhdGlsZXMgaXMgbm90IHVzZWQgYW55bW9yZSA6LS8gKi8KICAgIGlmIChzY2hlbWEtPnZvbGF0aWxlcyAhPSBOVUxMKQoJVE9ETwogICAgLyoKICAgICogTm90ZSB0aGF0IHRob3NlIHNsb3RzIGFyZSBub3QgcmVzcG9uc2libGUgZm9yIGZyZWVpbmcKICAgICogc2NoZW1hIGNvbXBvbmVudHMgYW55bW9yZTsgdGhpcyB3aWxsIG5vdyBiZSBkb25lIGJ5CiAgICAqIHRoZSBzY2hlbWEgYnVja2V0cy4KICAgICovCiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+bm90YURlY2wsIE5VTEwpOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJEZWNsLCBOVUxMKTsKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5hdHRyZ3JwRGVjbCwgTlVMTCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+ZWxlbURlY2wsIE5VTEwpOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPnR5cGVEZWNsLCBOVUxMKTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+Z3JvdXBEZWNsLCBOVUxMKTsKICAgIGlmIChzY2hlbWEtPmlkY0RlZiAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+aWRjRGVmLCBOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cyAhPSBOVUxMKQoJeG1sSGFzaEZyZWUoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKCQkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hQnVja2V0RnJlZSk7CiAgICBpZiAoc2NoZW1hLT5pbmNsdWRlcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0ID0gKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSBzY2hlbWEtPmluY2x1ZGVzOwoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgeG1sU2NoZW1hQnVja2V0RnJlZSgoeG1sU2NoZW1hQnVja2V0UHRyKSBsaXN0LT5pdGVtc1tpXSk7CQoJfQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGxpc3QpOwogICAgfQogICAgaWYgKHNjaGVtYS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3Qoc2NoZW1hLT5hbm5vdCk7CiAgICAvKiBOZXZlciBmcmVlIHRoZSBkb2MgaGVyZSwgc2luY2UgdGhpcyB3aWxsIGJlIGRvbmUgYnkgdGhlIGJ1Y2tldHMuICovCgogICAgeG1sRGljdEZyZWUoc2NoZW1hLT5kaWN0KTsKICAgIHhtbEZyZWUoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURlYnVnIGZ1bmN0aW9ucwkJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWZkZWYgTElCWE1MX09VVFBVVF9FTkFCTEVECgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRHVtcCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIEZJTEUgKiBvdXRwdXQpOyAvKiBmb3J3YXJkICovCgovKioKICogeG1sU2NoZW1hRWxlbWVudER1bXA6CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqCiAqIER1bXAgdGhlIGVsZW1lbnQKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVsZW1lbnREdW1wKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSwgRklMRSAqIG91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKCQkgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIGNvbnRleHQgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgoKICAgIGZwcmludGYob3V0cHV0LCAiRWxlbWVudCIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCglmcHJpbnRmKG91dHB1dCwgIiAoZ2xvYmFsKSIpOwogICAgZnByaW50ZihvdXRwdXQsICI6ICclcycgIiwgZWxlbS0+bmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKG91dHB1dCwgIm5zICclcyciLCBuYW1lc3BhY2UpOwogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwojaWYgMAogICAgaWYgKChlbGVtLT5taW5PY2N1cnMgIT0gMSkgfHwgKGVsZW0tPm1heE9jY3VycyAhPSAxKSkgewoJZnByaW50ZihvdXRwdXQsICIgIG1pbiAlZCAiLCBlbGVtLT5taW5PY2N1cnMpOwogICAgICAgIGlmIChlbGVtLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogdW5ib3VuZGVkXG4iKTsKICAgICAgICBlbHNlIGlmIChlbGVtLT5tYXhPY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6ICVkXG4iLCBlbGVtLT5tYXhPY2N1cnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQojZW5kaWYKICAgIC8qCiAgICAqIE1pc2Mgb3RoZXIgcHJvcGVydGllcy4KICAgICovCiAgICBpZiAoKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgfHwKCShlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHx8CgkoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSB8fAoJKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9ERUZBVUxUKSkgewoJZnByaW50ZihvdXRwdXQsICIgIHByb3BzOiAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpCgkgICAgZnByaW50ZihvdXRwdXQsICJbZml4ZWRdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9ERUZBVUxUKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2RlZmF1bHRdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIlthYnN0cmFjdF0gIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKQoJICAgIGZwcmludGYob3V0cHV0LCAiW25pbGxhYmxlXSAiKTsKCWZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIC8qCiAgICAqIERlZmF1bHQvZml4ZWQgdmFsdWUuCiAgICAqLwogICAgaWYgKGVsZW0tPnZhbHVlICE9IE5VTEwpCglmcHJpbnRmKG91dHB1dCwgIiAgdmFsdWU6ICclcydcbiIsIGVsZW0tPnZhbHVlKTsKICAgIC8qCiAgICAqIFR5cGUuCiAgICAqLwogICAgaWYgKGVsZW0tPm5hbWVkVHlwZSAhPSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgdHlwZTogJyVzJyAiLCBlbGVtLT5uYW1lZFR5cGUpOwoJaWYgKGVsZW0tPm5hbWVkVHlwZU5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJucyAnJXMnXG4iLCBlbGVtLT5uYW1lZFR5cGVOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfSBlbHNlIGlmIChlbGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkvKgoJKiBEdW1wIGxvY2FsIHR5cGVzLgoJKi8KCXhtbFNjaGVtYVR5cGVEdW1wKGVsZW0tPnN1YnR5cGVzLCBvdXRwdXQpOwogICAgfQogICAgLyoKICAgICogU3Vic3RpdHV0aW9uIGdyb3VwLgogICAgKi8KICAgIGlmIChlbGVtLT5zdWJzdEdyb3VwICE9IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiICBzdWJzdGl0dXRpb25Hcm91cDogJyVzJyAiLCBlbGVtLT5zdWJzdEdyb3VwKTsKCWlmIChlbGVtLT5zdWJzdEdyb3VwTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIm5zICclcydcbiIsIGVsZW0tPnN1YnN0R3JvdXBOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQW5ub3REdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBhbm5vdDogIGEgYW5ub3RhdGlvbgogKgogKiBEdW1wIHRoZSBhbm5vdGF0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBbm5vdER1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIHhtbENoYXIgKmNvbnRlbnQ7CgogICAgaWYgKGFubm90ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGNvbnRlbnQgPSB4bWxOb2RlR2V0Q29udGVudChhbm5vdC0+Y29udGVudCk7CiAgICBpZiAoY29udGVudCAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIEFubm90OiAlc1xuIiwgY29udGVudCk7CiAgICAgICAgeG1sRnJlZShjb250ZW50KTsKICAgIH0gZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogZW1wdHlcbiIpOwp9CgovKioKICogeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcDoKICogQHBhcnRpY2xlOiB0aGUgc2NoZW1hIHBhcnRpY2xlCiAqIEBvdXRwdXQ6IHRoZSBmaWxlIG91dHB1dAogKiBAZGVwdGg6IHRoZSBkZXB0aCB1c2VkIGZvciBpbnRlbnRhdGlvbgogKgogKiBEdW1wIGEgU2NoZW1hVHlwZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXAoeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUsIEZJTEUgKiBvdXRwdXQsIGludCBkZXB0aCkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIHRlcm07CiAgICBjaGFyIHNoaWZ0WzEwMF07CiAgICBpbnQgaTsKCiAgICBpZiAocGFydGljbGUgPT0gTlVMTCkKCXJldHVybjsKICAgIGZvciAoaSA9IDA7KChpIDwgZGVwdGgpICYmIChpIDwgMjUpKTtpKyspCiAgICAgICAgc2hpZnRbMiAqIGldID0gc2hpZnRbMiAqIGkgKyAxXSA9ICcgJzsKICAgIHNoaWZ0WzIgKiBpXSA9IHNoaWZ0WzIgKiBpICsgMV0gPSAwOwogICAgZnByaW50ZihvdXRwdXQsIHNoaWZ0KTsKICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgewoJZnByaW50ZihvdXRwdXQsICJNSVNTSU5HIHBhcnRpY2xlIHRlcm1cbiIpOwoJcmV0dXJuOwogICAgfQogICAgdGVybSA9IHBhcnRpY2xlLT5jaGlsZHJlbjsKICAgIGlmICh0ZXJtID09IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiKE5VTEwpIik7CiAgICB9IGVsc2UgewoJc3dpdGNoICh0ZXJtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQlmcHJpbnRmKG91dHB1dCwgIkVMRU0gJyVzJyIsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgICgoeG1sU2NoZW1hRWxlbWVudFB0cil0ZXJtKS0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpdGVybSktPm5hbWUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgkJZnByaW50ZihvdXRwdXQsICJTRVFVRU5DRSIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCQlmcHJpbnRmKG91dHB1dCwgIkNIT0lDRSIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCQlmcHJpbnRmKG91dHB1dCwgIkFMTCIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKCQlmcHJpbnRmKG91dHB1dCwgIkFOWSIpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJZnByaW50ZihvdXRwdXQsICJVTktOT1dOXG4iKTsKCQlyZXR1cm47Cgl9CiAgICB9CiAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyAhPSAxKQoJZnByaW50ZihvdXRwdXQsICIgbWluOiAlZCIsIHBhcnRpY2xlLT5taW5PY2N1cnMpOwogICAgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQoJZnByaW50ZihvdXRwdXQsICIgbWF4OiB1bmJvdW5kZWQiKTsKICAgIGVsc2UgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgIT0gMSkKCWZwcmludGYob3V0cHV0LCAiIG1heDogJWQiLCBwYXJ0aWNsZS0+bWF4T2NjdXJzKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICh0ZXJtICYmCgkoKHRlcm0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB8fAoJICh0ZXJtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHx8CgkgKHRlcm0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkpICYmCgkgKHRlcm0tPmNoaWxkcmVuICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgdGVybS0+Y2hpbGRyZW4sCgkgICAgb3V0cHV0LCBkZXB0aCArMSk7CiAgICB9CiAgICBpZiAocGFydGljbGUtPm5leHQgIT0gTlVMTCkKCXhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXAoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+bmV4dCwKCQlvdXRwdXQsIGRlcHRoKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJVc2VzRHVtcDoKICogQHVzZXM6ICBhdHRyaWJ1dGUgdXNlcyBsaXN0CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQgCiAqCiAqIER1bXBzIGEgbGlzdCBvZiBhdHRyaWJ1dGUgdXNlIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyVXNlc0R1bXAoeG1sU2NoZW1hSXRlbUxpc3RQdHIgdXNlcywgRklMRSAqIG91dHB1dCkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIHVzZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0ciBwcm9oaWI7CiAgICB4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWY7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqdG5zOwogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKICAgIGludCBpOwoKICAgIGlmICgodXNlcyA9PSBOVUxMKSB8fCAodXNlcy0+bmJJdGVtcyA9PSAwKSkKICAgICAgICByZXR1cm47CgogICAgZnByaW50ZihvdXRwdXQsICIgIGF0dHJpYnV0ZXM6XG4iKTsgICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgdXNlcy0+bmJJdGVtczsgaSsrKSB7Cgl1c2UgPSB1c2VzLT5pdGVtc1tpXTsKCWlmICh1c2UtPnR5cGUgPT0gWE1MX1NDSEVNQV9FWFRSQV9BVFRSX1VTRV9QUk9ISUIpIHsKCSAgICBmcHJpbnRmKG91dHB1dCwgIiAgW3Byb2hpYml0aW9uXSAiKTsKCSAgICBwcm9oaWIgPSAoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyKSB1c2U7CgkgICAgbmFtZSA9IHByb2hpYi0+bmFtZTsKCSAgICB0bnMgPSBwcm9oaWItPnRhcmdldE5hbWVzcGFjZTsKCX0gZWxzZSBpZiAodXNlLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUYpIHsKCSAgICBmcHJpbnRmKG91dHB1dCwgIiAgW3JlZmVyZW5jZV0gIik7CgkgICAgcmVmID0gKHhtbFNjaGVtYVFOYW1lUmVmUHRyKSB1c2U7CgkgICAgbmFtZSA9IHJlZi0+bmFtZTsKCSAgICB0bnMgPSByZWYtPnRhcmdldE5hbWVzcGFjZTsKCX0gZWxzZSB7CgkgICAgZnByaW50ZihvdXRwdXQsICIgIFt1c2VdICIpOwoJICAgIG5hbWUgPSBXWFNfQVRUUlVTRV9ERUNMX05BTUUodXNlKTsKCSAgICB0bnMgPSBXWFNfQVRUUlVTRV9ERUNMX1ROUyh1c2UpOwoJfQoJZnByaW50ZihvdXRwdXQsICInJXMnXG4iLAoJICAgIChjb25zdCBjaGFyICopIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHRucywgbmFtZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hVHlwZUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHR5cGU6ICBhIHR5cGUgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWFUeXBlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUR1bXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBGSUxFICogb3V0cHV0KQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlR5cGU6ICIpOwogICAgaWYgKHR5cGUtPm5hbWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiclcycgIiwgdHlwZS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIobm8gbmFtZSkgIik7CiAgICBpZiAodHlwZS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKG91dHB1dCwgIm5zICclcycgIiwgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltiYXNpY10gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2ltcGxlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbY29tcGxleF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltzZXF1ZW5jZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbY2hvaWNlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlthbGxdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbdXJdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbcmVzdHJpY3Rpb25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2V4dGVuc2lvbl0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Vua25vd24gdHlwZSAlZF0gIiwgdHlwZS0+dHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJjb250ZW50OiAiKTsKICAgIHN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlt1bmtub3duXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2VtcHR5XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2VsZW1lbnRdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbbWl4ZWRdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKCS8qIG5vdCB1c2VkLiAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYmFzaWNdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3NpbXBsZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0FOWToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYW55XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIGJhc2UgdHlwZTogJyVzJyIsIHR5cGUtPmJhc2UpOwoJaWYgKHR5cGUtPmJhc2VOcyAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAiIG5zICclcydcbiIsIHR5cGUtPmJhc2VOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKHR5cGUtPmF0dHJVc2VzICE9IE5VTEwpCgl4bWxTY2hlbWFBdHRyVXNlc0R1bXAodHlwZS0+YXR0clVzZXMsIG91dHB1dCk7CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFBbm5vdER1bXAob3V0cHV0LCB0eXBlLT5hbm5vdCk7CiNpZmRlZiBEVU1QX0NPTlRFTlRfTU9ERUwKICAgIGlmICgodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCSh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSkgewoJeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzLAoJICAgIG91dHB1dCwgMSk7CiAgICB9CiNlbmRpZgp9CgovKioKICogeG1sU2NoZW1hRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAc2NoZW1hOiAgYSBzY2hlbWEgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWEgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFEdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChvdXRwdXQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoc2NoZW1hID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6IE5VTExcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiU2NoZW1hczogIik7CiAgICBpZiAoc2NoZW1hLT5uYW1lICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcywgIiwgc2NoZW1hLT5uYW1lKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIG5hbWUsICIpOwogICAgaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcyIsIChjb25zdCBjaGFyICopIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIHRhcmdldCBuYW1lc3BhY2UiKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmIChzY2hlbWEtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hQW5ub3REdW1wKG91dHB1dCwgc2NoZW1hLT5hbm5vdCk7CiAgICB4bWxIYXNoU2NhbihzY2hlbWEtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVEdW1wLAogICAgICAgICAgICAgICAgb3V0cHV0KTsKICAgIHhtbEhhc2hTY2FuRnVsbChzY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYUVsZW1lbnREdW1wLCBvdXRwdXQpOwp9CgojaWZkZWYgREVCVUdfSURDX05PREVfVEFCTEUKLyoqCiAqIHhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIERpc3BsYXlzIHRoZSBjdXJyZW50IElEQyB0YWJsZSBmb3IgZGVidWcgcHVycG9zZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFEZWJ1Z0R1bXBJRENUYWJsZShGSUxFICogb3V0cHV0LAoJCQkgICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2VOYW1lLAoJCQkgICBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsCgkJCSAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIHRhYjsKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5OwogICAgaW50IGksIGosIHJlczsKCiAgICBmcHJpbnRmKG91dHB1dCwgIklEQzogVEFCTEVTIG9uICclcydcbiIsCgl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBuYW1lc3BhY2VOYW1lLCBsb2NhbE5hbWUpKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyKQoKICAgIGlmIChiaW5kID09IE5VTEwpCglyZXR1cm47CiAgICBkbyB7CglmcHJpbnRmKG91dHB1dCwgIklEQzogICBCSU5ESU5HICclcycgKCVkKVxuIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCAKCQliaW5kLT5kZWZpbml0aW9uKSwgYmluZC0+bmJOb2Rlcyk7CglGUkVFX0FORF9OVUxMKHN0cikKCWZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCSAgICB0YWIgPSBiaW5kLT5ub2RlVGFibGVbaV07CgkgICAgZnByaW50ZihvdXRwdXQsICIgICAgICAgICAoICIpOwoJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaisrKSB7CgkJa2V5ID0gdGFiLT5rZXlzW2pdOwoJCWlmICgoa2V5ICE9IE5VTEwpICYmIChrZXktPnZhbCAhPSBOVUxMKSkgewoJCSAgICByZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlKGtleS0+dmFsLCAmdmFsdWUpOwoJCSAgICBpZiAocmVzID49IDApCgkJCWZwcmludGYob3V0cHV0LCAiJyVzJyAiLCB2YWx1ZSk7CgkJICAgIGVsc2UKCQkJZnByaW50ZihvdXRwdXQsICJDQU5PTi1WQUxVRS1GQUlMRUQgIik7CgkJICAgIGlmIChyZXMgPT0gMCkKCQkJRlJFRV9BTkRfTlVMTCh2YWx1ZSkKCQl9IGVsc2UgaWYgKGtleSAhPSBOVUxMKQoJCSAgICBmcHJpbnRmKG91dHB1dCwgIihubyB2YWwpLCAiKTsKCQllbHNlCgkJICAgIGZwcmludGYob3V0cHV0LCAiKGtleSBtaXNzaW5nKSwgIik7CgkgICAgfQoJICAgIGZwcmludGYob3V0cHV0LCAiKVxuIik7Cgl9CglpZiAoYmluZC0+ZHVwbHMgJiYgYmluZC0+ZHVwbHMtPm5iSXRlbXMpIHsKCSAgICBmcHJpbnRmKG91dHB1dCwgIklEQzogICAgIGR1cGxzICglZCk6XG4iLCBiaW5kLT5kdXBscy0+bmJJdGVtcyk7CgkgICAgZm9yIChpID0gMDsgaSA8IGJpbmQtPmR1cGxzLT5uYkl0ZW1zOyBpKyspIHsKCQl0YWIgPSBiaW5kLT5kdXBscy0+aXRlbXNbaV07CgkJZnByaW50ZihvdXRwdXQsICIgICAgICAgICAoICIpOwoJCWZvciAoaiA9IDA7IGogPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaisrKSB7CgkJICAgIGtleSA9IHRhYi0+a2V5c1tqXTsKCQkgICAgaWYgKChrZXkgIT0gTlVMTCkgJiYgKGtleS0+dmFsICE9IE5VTEwpKSB7CgkJCXJlcyA9IHhtbFNjaGVtYUdldENhbm9uVmFsdWUoa2V5LT52YWwsICZ2YWx1ZSk7CgkJCWlmIChyZXMgPj0gMCkKCQkJICAgIGZwcmludGYob3V0cHV0LCAiJyVzJyAiLCB2YWx1ZSk7CgkJCWVsc2UKCQkJICAgIGZwcmludGYob3V0cHV0LCAiQ0FOT04tVkFMVUUtRkFJTEVEICIpOwoJCQlpZiAocmVzID09IDApCgkJCSAgICBGUkVFX0FORF9OVUxMKHZhbHVlKQoJCSAgICB9IGVsc2UgaWYgKGtleSAhPSBOVUxMKQoJCSAgICBmcHJpbnRmKG91dHB1dCwgIihubyB2YWwpLCAiKTsKCQkJZWxzZQoJCQkgICAgZnByaW50ZihvdXRwdXQsICIoa2V5IG1pc3NpbmcpLCAiKTsKCQl9CgkJZnByaW50ZihvdXRwdXQsICIpXG4iKTsKCSAgICB9Cgl9CgliaW5kID0gYmluZC0+bmV4dDsKICAgIH0gd2hpbGUgKGJpbmQgIT0gTlVMTCk7Cn0KI2VuZGlmIC8qIERFQlVHX0lEQyAqLwojZW5kaWYgLyogTElCWE1MX09VVFBVVF9FTkFCTEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlVdGlsaXRpZXMJCQkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hR2V0UHJvcE5vZGU6CiAqIEBub2RlOiB0aGUgZWxlbWVudCBub2RlCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFNlZWtzIGFuIGF0dHJpYnV0ZSB3aXRoIGEgbmFtZSBvZiBAbmFtZSBpbgogKiBubyBuYW1lc3BhY2UuCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBvciBOVUxMIGlmIG5vdCBwcmVzZW50LgogKi8Kc3RhdGljIHhtbEF0dHJQdHIKeG1sU2NoZW1hR2V0UHJvcE5vZGUoeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICpuYW1lKQp7CiAgICB4bWxBdHRyUHRyIHByb3A7CgogICAgaWYgKChub2RlID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQoJcmV0dXJuKE5VTEwpOwogICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChwcm9wLT5ucyA9PSBOVUxMKSAmJiB4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBCQURfQ0FTVCBuYW1lKSkKCSAgICByZXR1cm4ocHJvcCk7Cglwcm9wID0gcHJvcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQcm9wTm9kZU5zOgogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZQogKiBAdXJpOiB0aGUgdXJpCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFNlZWtzIGFuIGF0dHJpYnV0ZSB3aXRoIGEgbG9jYWwgbmFtZSBvZiBAbmFtZSBhbmQKICogYSBuYW1lc3BhY2UgVVJJIG9mIEB1cmkuCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBvciBOVUxMIGlmIG5vdCBwcmVzZW50LgogKi8Kc3RhdGljIHhtbEF0dHJQdHIKeG1sU2NoZW1hR2V0UHJvcE5vZGVOcyh4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKnVyaSwgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQXR0clB0ciBwcm9wOwoKICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKCXJldHVybihOVUxMKTsgICAgCiAgICBwcm9wID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChwcm9wICE9IE5VTEwpIHsKCWlmICgocHJvcC0+bnMgIT0gTlVMTCkgJiYKCSAgICB4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBCQURfQ0FTVCBuYW1lKSAmJgoJICAgIHhtbFN0ckVxdWFsKHByb3AtPm5zLT5ocmVmLCBCQURfQ0FTVCB1cmkpKQoJICAgIHJldHVybihwcm9wKTsKCXByb3AgPSBwcm9wLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROb2RlQ29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQoJdmFsID0geG1sU3RyZHVwKCh4bWxDaGFyICopIiIpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldE5vZGVDb250ZW50Tm9EaWN0KHhtbE5vZGVQdHIgbm9kZSkKewogICAgcmV0dXJuKChjb25zdCB4bWxDaGFyKikgeG1sTm9kZUdldENvbnRlbnQobm9kZSkpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UHJvcDoKICogQGN0eHQ6IHRoZSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIG5vZGUKICogQG5hbWU6IHRoZSBwcm9wZXJ0eSBuYW1lCiAqCiAqIFJlYWQgYSBhdHRyaWJ1dGUgdmFsdWUgYW5kIGludGVybmFsaXplIHRoZSBzdHJpbmcKICoKICogUmV0dXJucyB0aGUgc3RyaW5nIG9yIE5VTEwgaWYgbm90IHByZXNlbnQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldFByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbEdldE5vTnNQcm9wKG5vZGUsIEJBRF9DQVNUIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybihOVUxMKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBXWFNfRklORF9HTE9CQUxfSVRFTShzbG90KQkJCVwKICAgIGlmICh4bWxTdHJFcXVhbChuc05hbWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkgeyBcCglyZXQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2xvdCwgbmFtZSk7IFwKCWlmIChyZXQgIT0gTlVMTCkgZ290byBleGl0OyBcCiAgICB9IFwKICAgIGlmICh4bWxIYXNoU2l6ZShzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSA+IDEpIHsgXAoJeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydDsgXAoJaWYgKG5zTmFtZSA9PSBOVUxMKSBcCgkgICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBcCgkJWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsgXAoJZWxzZSBcCgkgICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuc05hbWUpOyBcCglpZiAoaW1wb3J0ID09IE5VTEwpIFwKCSAgICBnb3RvIGV4aXQ7IFwKCXJldCA9IHhtbEhhc2hMb29rdXAoaW1wb3J0LT5zY2hlbWEtPnNsb3QsIG5hbWUpOyBcCiAgICB9CgovKioKICogeG1sU2NoZW1hR2V0RWxlbToKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICogQG5zOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIGluIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFHZXRFbGVtKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuc05hbWUpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0ID0gTlVMTDsKICAgIAogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CglXWFNfRklORF9HTE9CQUxfSVRFTShlbGVtRGVjbCkKICAgIH0gICAKZXhpdDoKI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobnNOYW1lID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBlbGVtZW50IGRlY2wuICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZWxlbWVudCBkZWNsLiAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbnNOYW1lKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRUeXBlOgogKiBAc2NoZW1hOiAgdGhlIG1haW4gc2NoZW1hCiAqIEBuYW1lOiAgdGhlIHR5cGUncyBuYW1lCiAqIG5zTmFtZTogIHRoZSB0eXBlJ3MgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIHR5cGUgaW4gdGhlIHNjaGVtYXMgb3IgdGhlIHByZWRlZmluZWQgdHlwZXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFR5cGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwoKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsgICAgCiAgICAvKiBGaXJzdCB0cnkgdGhlIGJ1aWx0LWluIHR5cGVzLiAqLwogICAgaWYgKChuc05hbWUgIT0gTlVMTCkgJiYgeG1sU3RyRXF1YWwobnNOYW1lLCB4bWxTY2hlbWFOcykpIHsJCglyZXQgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShuYW1lLCBuc05hbWUpOwoJaWYgKHJldCAhPSBOVUxMKQoJICAgIGdvdG8gZXhpdDsKCS8qCgkqIE5vdGUgdGhhdCB3ZSB0cnkgdGhlIHBhcnNlZCBzY2hlbWFzIGFzIHdlbGwgaGVyZQoJKiBzaW5jZSBvbmUgbWlnaHQgaGF2ZSBwYXJzZWQgdGhlIFM0Uywgd2hpY2ggY29udGFpbiBtb3JlCgkqIHRoYW4gdGhlIGJ1aWx0LWluIHR5cGVzLgoJKiBUT0RPOiBDYW4gd2Ugb3B0aW1pemUgdGhpcz8KCSovCiAgICB9CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKCVdYU19GSU5EX0dMT0JBTF9JVEVNKHR5cGVEZWNsKQogICAgfSAKZXhpdDoKCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5zTmFtZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlRGVjbDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2woeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0oYXR0ckRlY2wpCiAgICB9CmV4aXQ6CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuc05hbWUpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGF0dHJpYnV0ZSBncm91cAogKgogKiBMb29rdXAgYSBhbiBhdHRyaWJ1dGUgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuc05hbWUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0oYXR0cmdycERlY2wpCiAgICB9CmV4aXQ6CiAgICAvKiBUT0RPOgogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+cmVkZWYgIT0gTlVMTCkpIHsKCSogUmV0dXJuIHRoZSBsYXN0IHJlZGVmaW5pdGlvbi4gKgoJcmV0ID0gcmV0LT5yZWRlZjsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuc05hbWUpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgZ3JvdXAKICoKICogTG9va3VwIGEgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cgp4bWxTY2hlbWFHZXRHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbnNOYW1lKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0oZ3JvdXBEZWNsKQogICAgfQpleGl0OgogICAgCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbnNOYW1lKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFHZXROb3RhdGlvbih4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hTm90YXRpb25QdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CglXWFNfRklORF9HTE9CQUxfSVRFTShub3RhRGVjbCkKICAgIH0KZXhpdDoKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUlEQ1B0cgp4bWxTY2hlbWFHZXRJREMoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQljb25zdCB4bWxDaGFyICpuYW1lLAoJCWNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hSURDUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewoJV1hTX0ZJTkRfR0xPQkFMX0lURU0oaWRjRGVmKQogICAgfQpleGl0OgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQ6CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGdyb3VwCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBncm91cAogKgogKiBMb29rdXAgYSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIKeG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgeG1sU2NoZW1hVHlwZVR5cGUgaXRlbVR5cGUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5zKQp7CiAgICBzd2l0Y2ggKGl0ZW1UeXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHhtbFNjaGVtYUdldEdyb3VwKHNjaGVtYSwKCQluYW1lLCB0YXJnZXROcykpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHhtbFNjaGVtYUdldEVsZW0oc2NoZW1hLAoJCW5hbWUsIHRhcmdldE5zKSk7CglkZWZhdWx0OgoJICAgIFRPRE8KCSAgICByZXR1cm4gKE5VTEwpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUGFyc2luZyBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIElTX0JMQU5LX05PREUobikJCQkJCQlcCiAgICAoKChuKS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoeG1sU2NoZW1hSXNCbGFuaygobiktPmNvbnRlbnQsIC0xKSkpCgovKioKICogeG1sU2NoZW1hSXNCbGFuazoKICogQHN0cjogIGEgc3RyaW5nCiAqIEBsZW46IHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBvciAtMQogKgogKiBDaGVjayBpZiBhIHN0cmluZyBpcyBpZ25vcmFibGUKICoKICogUmV0dXJucyAxIGlmIHRoZSBzdHJpbmcgaXMgTlVMTCBvciBtYWRlIG9mIGJsYW5rcyBjaGFycywgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNCbGFuayh4bWxDaGFyICogc3RyLCBpbnQgbGVuKQp7CiAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgxKTsKICAgIGlmIChsZW4gPCAwKSB7Cgl3aGlsZSAoKnN0ciAhPSAwKSB7CgkgICAgaWYgKCEoSVNfQkxBTktfQ0goKnN0cikpKQoJCXJldHVybiAoMCk7CgkgICAgc3RyKys7Cgl9CiAgICB9IGVsc2Ugd2hpbGUgKCgqc3RyICE9IDApICYmIChsZW4gIT0gMCkpIHsKCWlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKCSAgICByZXR1cm4gKDApOwoJc3RyKys7CglsZW4tLTsKICAgIH0KICAgIAogICAgcmV0dXJuICgxKTsKfQoKI2RlZmluZSBXWFNfQ09NUF9OQU1FKGMsIHQpICgodCkgKGMpKS0+bmFtZQojZGVmaW5lIFdYU19DT01QX1ROUyhjLCB0KSAoKHQpIChjKSktPnRhcmdldE5hbWVzcGFjZQovKgoqIHhtbFNjaGVtYUZpbmRSZWRlZkNvbXBJbkdyYXBoOgoqIEFUVEVOVElPTiBUT0RPOiBUaGlzIHVzZXMgcG9pbnRlciBjb21wLiBmb3Igc3RyaW5ncy4KKi8Kc3RhdGljIHhtbFNjaGVtYUJhc2ljSXRlbVB0cgp4bWxTY2hlbWFGaW5kUmVkZWZDb21wSW5HcmFwaCh4bWxTY2hlbWFCdWNrZXRQdHIgYnVja2V0LAoJCQkgICAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCQkgICAgICBjb25zdCB4bWxDaGFyICpuYW1lLAoJCQkgICAgICBjb25zdCB4bWxDaGFyICpuc05hbWUpCnsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciByZXQ7CiAgICBpbnQgaTsKCiAgICBpZiAoKGJ1Y2tldCA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKCXJldHVybihOVUxMKTsKICAgIGlmICgoYnVja2V0LT5nbG9iYWxzID09IE5VTEwpIHx8CgkoYnVja2V0LT5nbG9iYWxzLT5uYkl0ZW1zID09IDApKQoJZ290byBzdWJzY2hlbWFzOwogICAgLyoKICAgICogU2VhcmNoIGluIGdsb2JhbCBjb21wb25lbnRzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBidWNrZXQtPmdsb2JhbHMtPm5iSXRlbXM7IGkrKykgewoJcmV0ID0gYnVja2V0LT5nbG9iYWxzLT5pdGVtc1tpXTsKCWlmIChyZXQtPnR5cGUgPT0gdHlwZSkgewoJICAgIHN3aXRjaCAodHlwZSkgewoJCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCSAgICBpZiAoKFdYU19DT01QX05BTUUocmV0LCB4bWxTY2hlbWFUeXBlUHRyKSA9PSBuYW1lKSAmJgoJCQkoV1hTX0NPTVBfVE5TKHJldCwgeG1sU2NoZW1hVHlwZVB0cikgPT0KCQkJbnNOYW1lKSkKCQkgICAgewoJCQlyZXR1cm4ocmV0KTsKCQkgICAgfQoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQkgICAgaWYgKChXWFNfQ09NUF9OQU1FKHJldCwKCQkJICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpID09IG5hbWUpICYmCgkJCShXWFNfQ09NUF9UTlMocmV0LAoJCQkgICAgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgPT0gbnNOYW1lKSkKCQkgICAgewoJCQlyZXR1cm4ocmV0KTsKCQkgICAgfQoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQkgICAgaWYgKChXWFNfQ09NUF9OQU1FKHJldCwKCQkJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSA9PSBuYW1lKSAmJgoJCQkoV1hTX0NPTVBfVE5TKHJldCwKCQkJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSA9PSBuc05hbWUpKQoJCSAgICB7CgkJCXJldHVybihyZXQpOwoJCSAgICB9CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIC8qIFNob3VsZCBub3QgYmUgaGl0LiAqLwoJCSAgICByZXR1cm4oTlVMTCk7CgkgICAgfQkJCgl9CiAgICB9CnN1YnNjaGVtYXM6CiAgICAvKgogICAgKiBQcm9jZXNzIGltcG9ydGVkL2luY2x1ZGVkIHNjaGVtYXMuCiAgICAqLwogICAgaWYgKGJ1Y2tldC0+cmVsYXRpb25zICE9IE5VTEwpIHsKCXhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbCA9IGJ1Y2tldC0+cmVsYXRpb25zOwoKCS8qCgkqIFRPRE86IE1hcmtpbmcgdGhlIGJ1Y2tldCB3aWxsIG5vdCBhdm9pZCBtdWx0aXBsZSBzZWFyY2hlcwoJKiBpbiB0aGUgc2FtZSBzY2hlbWEsIGJ1dCBhdm9pZHMgYXQgbGVhc3QgY2lyY3VsYXJpdHkuCgkqLwoJYnVja2V0LT5mbGFncyB8PSBYTUxfU0NIRU1BX0JVQ0tFVF9NQVJLRUQ7CglkbyB7CgkgICAgaWYgKChyZWwtPmJ1Y2tldCAhPSBOVUxMKSAmJgoJCSgocmVsLT5idWNrZXQtPmZsYWdzICYgWE1MX1NDSEVNQV9CVUNLRVRfTUFSS0VEKSA9PSAwKSkgewoJCXJldCA9IHhtbFNjaGVtYUZpbmRSZWRlZkNvbXBJbkdyYXBoKHJlbC0+YnVja2V0LAoJCSAgICB0eXBlLCBuYW1lLCBuc05hbWUpOwoJCWlmIChyZXQgIT0gTlVMTCkKCQkgICAgcmV0dXJuKHJldCk7CgkgICAgfQoJICAgIHJlbCA9IHJlbC0+bmV4dDsKCX0gd2hpbGUgKHJlbCAhPSBOVUxMKTsKCSBidWNrZXQtPmZsYWdzIF49IFhNTF9TQ0hFTUFfQlVDS0VUX01BUktFRDsKICAgIH0KICAgIHJldHVybihOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBhbm5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYUFkZE5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCSAgICAgeG1sTm9kZVB0ciBub2RlIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hTm90YXRpb25QdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZCBhbm5vdGF0aW9uIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFOb3RhdGlvbikpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOwogICAgcmV0LT5uYW1lID0gbmFtZTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbnNOYW1lOwogICAgLyogVE9ETzogZG8gd2UgbmVlZCB0aGUgbm9kZSB0byBiZSBzZXQ/CiAgICAqIHJldC0+bm9kZSA9IG5vZGU7Ki8KICAgIFdYU19BRERfR0xPQkFMKGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYUFkZEF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSwKCQkgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPm5hbWUgPSBuYW1lOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuc05hbWU7CgogICAgaWYgKHRvcExldmVsKQoJV1hTX0FERF9HTE9CQUwoY3R4dCwgcmV0KTsKICAgIGVsc2UKCVdYU19BRERfTE9DQUwoY3R4dCwgcmV0KTsKICAgIFdYU19BRERfUEVORElORyhjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkQXR0cmlidXRlVXNlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGVVc2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKHBjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVVc2UpKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOwogICAgcmV0LT5ub2RlID0gbm9kZTsKCiAgICBXWFNfQUREX0xPQ0FMKHBjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKgoqIHhtbFNjaGVtYUFkZFJlZGVmOgoqCiogQWRkcyBhIHJlZGVmaW5pdGlvbiBpbmZvcm1hdGlvbi4gVGhpcyBpcyB1c2VkIGF0IGEgbGF0ZXIgc3RhZ2UgdG86CiogcmVzb2x2ZSByZWZlcmVuY2VzIHRvIHRoZSByZWRlZmluZWQgY29tcG9uZW50cyBhbmQgdG8gY2hlY2sgY29uc3RyYWludHMuCiovCnN0YXRpYyB4bWxTY2hlbWFSZWRlZlB0cgp4bWxTY2hlbWFBZGRSZWRlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAkJICAKCQkgIHhtbFNjaGVtYUJ1Y2tldFB0ciB0YXJnZXRCdWNrZXQsCgkJICB2b2lkICppdGVtLAoJCSAgY29uc3QgeG1sQ2hhciAqcmVmTmFtZSwKCQkgIGNvbnN0IHhtbENoYXIgKnJlZlRhcmdldE5zKQp7CiAgICB4bWxTY2hlbWFSZWRlZlB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVJlZGVmUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFSZWRlZikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KHBjdHh0LAoJICAgICJhbGxvY2F0aW5nIHJlZGVmaW5pdGlvbiBpbmZvIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVJlZGVmKSk7CiAgICByZXQtPml0ZW0gPSBpdGVtOwogICAgcmV0LT50YXJnZXRCdWNrZXQgPSB0YXJnZXRCdWNrZXQ7CiAgICByZXQtPnJlZk5hbWUgPSByZWZOYW1lOwogICAgcmV0LT5yZWZUYXJnZXROcyA9IHJlZlRhcmdldE5zOwogICAgaWYgKFdYU19DT05TVFJVQ1RPUihwY3R4dCktPnJlZGVmcyA9PSBOVUxMKQoJV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+cmVkZWZzID0gcmV0OwogICAgZWxzZQoJV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+bGFzdFJlZGVmLT5uZXh0ID0gcmV0OwogICAgV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+bGFzdFJlZGVmID0gcmV0OwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5zTmFtZTogIHRoZSB0YXJnZXQgbmFtZXNwYWNlCiAqIEBub2RlOiB0aGUgY29ycmVzcG9uZGluZyBub2RlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgR3JvdXAgZGVmaW5pdGlvbi4KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hIEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpCiAgICAgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KHBjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUgZ3JvdXAiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5zTmFtZTsKICAgIHJldC0+bm9kZSA9IG5vZGU7ICAgCgogICAgLyogVE9ETzogUmVtb3ZlIHRoZSBmbGFnLiAqLwogICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMOwogICAgaWYgKHBjdHh0LT5pc1JlZGVmaW5lKSB7CglwY3R4dC0+cmVkZWYgPSB4bWxTY2hlbWFBZGRSZWRlZihwY3R4dCwgcGN0eHQtPnJlZGVmaW5lZCwKCSAgICByZXQsIG5hbWUsIG5zTmFtZSk7CglpZiAocGN0eHQtPnJlZGVmID09IE5VTEwpIHsKCSAgICB4bWxGcmVlKHJldCk7CgkgICAgcmV0dXJuKE5VTEwpOwoJfQkgICAgCglwY3R4dC0+cmVkZWZDb3VudGVyID0gMDsKICAgIH0KICAgIFdYU19BRERfR0xPQkFMKHBjdHh0LCByZXQpOwogICAgV1hTX0FERF9QRU5ESU5HKHBjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSB0eXBlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBFbGVtZW50IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hQWRkRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuc05hbWUsCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5zTmFtZTsKICAgIHJldC0+bm9kZSA9IG5vZGU7CgogICAgaWYgKHRvcExldmVsKQoJV1hTX0FERF9HTE9CQUwoY3R4dCwgcmV0KTsKICAgIGVsc2UKCVdYU19BRERfTE9DQUwoY3R4dCwgcmV0KTsKICAgIFdYU19BRERfUEVORElORyhjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgaXRlbQogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUFkZFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbnNOYW1lLAoJCSB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVR5cGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyB0eXBlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5uYW1lID0gbmFtZTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbnNOYW1lOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIGlmICh0b3BMZXZlbCkgewoJaWYgKGN0eHQtPmlzUmVkZWZpbmUpIHsKCSAgICBjdHh0LT5yZWRlZiA9IHhtbFNjaGVtYUFkZFJlZGVmKGN0eHQsIGN0eHQtPnJlZGVmaW5lZCwKCQlyZXQsIG5hbWUsIG5zTmFtZSk7CgkgICAgaWYgKGN0eHQtPnJlZGVmID09IE5VTEwpIHsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuKE5VTEwpOwoJICAgIH0JICAgIAoJICAgIGN0eHQtPnJlZGVmQ291bnRlciA9IDA7Cgl9CglXWFNfQUREX0dMT0JBTChjdHh0LCByZXQpOwogICAgfSBlbHNlCglXWFNfQUREX0xPQ0FMKGN0eHQsIHJldCk7CiAgICBXWFNfQUREX1BFTkRJTkcoY3R4dCwgcmV0KTsgICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFRTmFtZVJlZlB0cgp4bWxTY2hlbWFOZXdRTmFtZVJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgeG1sU2NoZW1hVHlwZVR5cGUgcmVmVHlwZSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnJlZk5hbWUsCgkJICAgICBjb25zdCB4bWxDaGFyICpyZWZOcykKewogICAgeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFRTmFtZVJlZlB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUU5hbWVSZWYpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCSAgICAiYWxsb2NhdGluZyBRTmFtZSByZWZlcmVuY2UgaXRlbSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+bm9kZSA9IE5VTEw7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGOwogICAgcmV0LT5uYW1lID0gcmVmTmFtZTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gcmVmTnM7CiAgICByZXQtPml0ZW0gPSBOVUxMOwogICAgcmV0LT5pdGVtVHlwZSA9IHJlZlR5cGU7CiAgICAvKgogICAgKiBTdG9yZSB0aGUgcmVmZXJlbmNlIGl0ZW0gaW4gdGhlIHNjaGVtYS4KICAgICovCiAgICBXWFNfQUREX0xPQ0FMKHBjdHh0LCByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliUHRyCnhtbFNjaGVtYUFkZEF0dHJpYnV0ZVVzZVByb2hpYih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0KQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KHBjdHh0LAoJICAgICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSB1c2UgcHJvaGliaXRpb24iLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHJvaGliKSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0VYVFJBX0FUVFJfVVNFX1BST0hJQjsKICAgIFdYU19BRERfTE9DQUwocGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hQWRkTW9kZWxHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAdHlwZTogdGhlICJjb21wb3NpdG9yIiB0eXBlIG9mIHRoZSBtb2RlbCBncm91cAogKiBAbm9kZTogdGhlIG5vZGUgaW4gdGhlIHNjaGVtYSBkb2MKICoKICogQWRkcyBhIHNjaGVtYSBtb2RlbCBncm91cAogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyCnhtbFNjaGVtYUFkZE1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCSAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgbW9kZWwgZ3JvdXAgY29tcG9uZW50IiwKCSAgICBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hTW9kZWxHcm91cCkpOwogICAgcmV0LT50eXBlID0gdHlwZTsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICBXWFNfQUREX0xPQ0FMKGN0eHQsIHJldCk7CiAgICBpZiAoKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB8fAoJKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkpCglXWFNfQUREX1BFTkRJTkcoY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFBZGRQYXJ0aWNsZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogdGhlIGNvcnJlc3BvbmRpbmcgbm9kZSBpbiB0aGUgc2NoZW1hIGRvYwogKiBAbWluOiB0aGUgbWluT2NjdXJzCiAqIEBtYXg6IHRoZSBtYXhPY2N1cnMKICoKICogQWRkcyBhbiBYTUwgc2NoZW1hIHBhcnRpY2xlIGNvbXBvbmVudC4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hUGFydGljbGVQdHIKeG1sU2NoZW1hQWRkUGFydGljbGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgbWluLCBpbnQgbWF4KQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByZXQgPSBOVUxMOwogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBwYXJ0aWNsZSBjb21wb25lbnRcbiIpOwojZW5kaWYKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFydGljbGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBwYXJ0aWNsZSBjb21wb25lbnQiLAoJICAgIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRTsKICAgIHJldC0+YW5ub3QgPSBOVUxMOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIHJldC0+bWluT2NjdXJzID0gbWluOwogICAgcmV0LT5tYXhPY2N1cnMgPSBtYXg7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgcmV0LT5jaGlsZHJlbiA9IE5VTEw7CgogICAgV1hTX0FERF9MT0NBTChjdHh0LCByZXQpOwogICAgLyogCiAgICAqIE5vdGUgdGhhdCBhZGRpdGlvbiB0byBwZW5kaW5nIGNvbXBvbmVudHMgd2lsbCBiZSBkb25lIGxvY2FsbHkKICAgICogdG8gdGhlIHNwZWNpZmljIHBhcnNpbmcgZnVuY3Rpb24sIHNpbmNlIHRoZSBtb3N0IHBhcnRpY2xlcwogICAgKiBuZWVkIG5vdCB0byBiZSBmaXhlZCB1cCAoaS5lLiB0aGUgcmVmZXJlbmNlIHRvIGJlIHJlc29sdmVkKS4KICAgICogUkVNT1ZFRDogV1hTX0FERF9QRU5ESU5HKGN0eHQsIHJldCk7CiAgICAqLwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkTW9kZWxHcm91cERlZmluaXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGdyb3VwIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cgp4bWxTY2hlbWFBZGRNb2RlbEdyb3VwRGVmaW5pdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSBjb25zdCB4bWxDaGFyICpuYW1lLAoJCQkJIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgcmV0ID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgZ3JvdXAiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWYpKTsKICAgIHJldC0+bmFtZSA9IG5hbWU7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuc05hbWU7CgogICAgaWYgKGN0eHQtPmlzUmVkZWZpbmUpIHsKCWN0eHQtPnJlZGVmID0geG1sU2NoZW1hQWRkUmVkZWYoY3R4dCwgY3R4dC0+cmVkZWZpbmVkLAoJICAgIHJldCwgbmFtZSwgbnNOYW1lKTsKCWlmIChjdHh0LT5yZWRlZiA9PSBOVUxMKSB7CgkgICAgeG1sRnJlZShyZXQpOwoJICAgIHJldHVybihOVUxMKTsKCX0JICAgIAoJY3R4dC0+cmVkZWZDb3VudGVyID0gMDsKICAgIH0KICAgIFdYU19BRERfR0xPQkFMKGN0eHQsIHJldCk7CiAgICBXWFNfQUREX1BFTkRJTkcoY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1dpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyCnhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkTnMpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJRENQdHIKeG1sU2NoZW1hQWRkSURDKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCSAgaW50IGNhdGVnb3J5LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUlEQ1B0ciByZXQgPSBOVUxMOyAgICAKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFJRENQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsCgkgICAgImFsbG9jYXRpbmcgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFJREMpKTsKICAgIC8qIFRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBwYXJlbnQgZWxlbWVudCBkZWNsYXJhdGlvbi4gKi8KICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbnNOYW1lOwogICAgcmV0LT5uYW1lID0gbmFtZTsKICAgIHJldC0+dHlwZSA9IGNhdGVnb3J5OwogICAgcmV0LT5ub2RlID0gbm9kZTsgICAgICAgIAogICAgCiAgICBXWFNfQUREX0dMT0JBTChjdHh0LCByZXQpOwogICAgLyoKICAgICogT25seSBrZXlyZWZzIG5lZWQgdG8gYmUgZml4dXAgdXAuCiAgICAqLwogICAgaWYgKGNhdGVnb3J5ID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKQoJV1hTX0FERF9QRU5ESU5HKGN0eHQsIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogYSBzY2hlbWEKICoKICogQWRkcyBhIHdpbGRjYXJkLgogKiBJdCBjb3JyZXNwb25kcyB0byBhIHhzZDphbnlBdHRyaWJ1dGUgYW5kIHhzZDphbnkuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFBZGRXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZGluZyB3aWxkY2FyZCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIHJldC0+dHlwZSA9IHR5cGU7CiAgICByZXQtPm5vZGUgPSBub2RlOyAgICAKICAgIFdYU19BRERfTE9DQUwoY3R4dCwgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hU3Vic3RHcm91cEZyZWUoeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBncm91cCkKewogICAgaWYgKGdyb3VwID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAoZ3JvdXAtPm1lbWJlcnMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShncm91cC0+bWVtYmVycyk7CiAgICB4bWxGcmVlKGdyb3VwKTsKfQoKc3RhdGljIHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIKeG1sU2NoZW1hU3Vic3RHcm91cEFkZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQpCnsKICAgIHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIgcmV0OwoKICAgIC8qIEluaXQgc3Vic3QgZ3JvdXAgaGFzaC4gKi8KICAgIGlmIChXWFNfU1VCU1RfR1JPVVBTKHBjdHh0KSA9PSBOVUxMKSB7CglXWFNfU1VCU1RfR1JPVVBTKHBjdHh0KSA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBwY3R4dC0+ZGljdCk7CglpZiAoV1hTX1NVQlNUX0dST1VQUyhwY3R4dCkgPT0gTlVMTCkKCSAgICByZXR1cm4oTlVMTCk7CiAgICB9CiAgICAvKiBDcmVhdGUgYSBuZXcgc3Vic3RpdHV0aW9uIGdyb3VwLiAqLwogICAgcmV0ID0gKHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hU3Vic3RHcm91cCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgYSBzdWJzdGl0dXRpb24gZ3JvdXAgY29udGFpbmVyIiwgTlVMTCk7CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hU3Vic3RHcm91cCkpOwogICAgcmV0LT5oZWFkID0gaGVhZDsKICAgIC8qIENyZWF0ZSBsaXN0IG9mIG1lbWJlcnMuICovCiAgICByZXQtPm1lbWJlcnMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+bWVtYmVycyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFTdWJzdEdyb3VwRnJlZShyZXQpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgLyogQWRkIHN1YnN0IGdyb3VwIHRvIGhhc2guICovCiAgICBpZiAoeG1sSGFzaEFkZEVudHJ5MihXWFNfU1VCU1RfR1JPVVBTKHBjdHh0KSwKCWhlYWQtPm5hbWUsIGhlYWQtPnRhcmdldE5hbWVzcGFjZSwgcmV0KSAhPSAwKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFTdWJzdEdyb3VwQWRkIiwKCSAgICAiZmFpbGVkIHRvIGFkZCBhIG5ldyBzdWJzdGl0dXRpb24gY29udGFpbmVyIik7Cgl4bWxTY2hlbWFTdWJzdEdyb3VwRnJlZShyZXQpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFTdWJzdEdyb3VwUHRyCnhtbFNjaGVtYVN1YnN0R3JvdXBHZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkKQp7ICAgCiAgICBpZiAoV1hTX1NVQlNUX0dST1VQUyhwY3R4dCkgPT0gTlVMTCkKCXJldHVybihOVUxMKTsKICAgIHJldHVybih4bWxIYXNoTG9va3VwMihXWFNfU1VCU1RfR1JPVVBTKHBjdHh0KSwKCWhlYWQtPm5hbWUsIGhlYWQtPnRhcmdldE5hbWVzcGFjZSkpOwoKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEVsZW1lbnRTdWJzdGl0dXRpb25NZW1iZXI6CiAqIEBwY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBoZWFkOiAgdGhlIGhlYWQgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAogKiBAbWVtYmVyOiB0aGUgbmV3IG1lbWJlciBvZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwCiAqCiAqIEFsbG9jYXRlIGEgbmV3IGFubm90YXRpb24gc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uTWVtYmVyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIG1lbWJlcikKewogICAgeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBzdWJzdEdyb3VwID0gTlVMTDsKCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChoZWFkID09IE5VTEwpIHx8IChtZW1iZXIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKCiAgICBzdWJzdEdyb3VwID0geG1sU2NoZW1hU3Vic3RHcm91cEdldChwY3R4dCwgaGVhZCk7CiAgICBpZiAoc3Vic3RHcm91cCA9PSBOVUxMKQoJc3Vic3RHcm91cCA9IHhtbFNjaGVtYVN1YnN0R3JvdXBBZGQocGN0eHQsIGhlYWQpOwogICAgaWYgKHN1YnN0R3JvdXAgPT0gTlVMTCkKCXJldHVybigtMSk7CiAgICBpZiAoeG1sU2NoZW1hSXRlbUxpc3RBZGQoc3Vic3RHcm91cC0+bWVtYmVycywgbWVtYmVyKSA9PSAtMSkKCXJldHVybigtMSk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKgkJVXRpbGl0aWVzIGZvciBwYXJzaW5nCQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIHBhcmVudCBhcyBhIHNjaGVtYSBvYmplY3QKICogQHZhbHVlOiAgdGhlIFFOYW1lIHZhbHVlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIHRoZSBsb2NhbCBuYW1lIGFuZCB0aGUgVVJJIG9mIGEgUU5hbWUgdmFsdWUgYW5kIHZhbGlkYXRlcyBpdC4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQKICogc2hvdWxkIHJlc29sdmUgdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqCiAqIFJldHVybnMgMCwgaW4gY2FzZSB0aGUgUU5hbWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBpZiBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQkJICAgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKipsb2NhbCkKewogICAgY29uc3QgeG1sQ2hhciAqcHJlZjsKICAgIHhtbE5zUHRyIG5zOwogICAgaW50IGxlbiwgcmV0OwoKICAgICp1cmkgPSBOVUxMOwogICAgKmxvY2FsID0gTlVMTDsKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA+IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCSAgICBOVUxMLCB2YWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkqbG9jYWwgPSB2YWx1ZTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSBpZiAocmV0IDwgMCkKCXJldHVybiAoLTEpOwoKICAgIGlmICghc3RyY2hyKChjaGFyICopIHZhbHVlLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCBOVUxMKTsKCWlmIChucykKCSAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSB7CgkgICAgLyogVE9ETzogbW92ZSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUyB0byB0aGUKCSAgICAqIHBhcnNlciBjb250ZXh0LiAqLwoJICAgIC8qCgkgICAgKiBUaGlzIG9uZSB0YWtlcyBjYXJlIG9mIGluY2x1ZGVkIHNjaGVtYXMgd2l0aCBubwoJICAgICogdGFyZ2V0IG5hbWVzcGFjZS4KCSAgICAqLwoJICAgICp1cmkgPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7Cgl9CgkqbG9jYWwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbHVlLCAtMSk7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogQXQgdGhpcyBwb2ludCB4bWxTcGxpdFFOYW1lMyBoYXMgdG8gcmV0dXJuIGEgbG9jYWwgbmFtZS4KICAgICovCiAgICAqbG9jYWwgPSB4bWxTcGxpdFFOYW1lMyh2YWx1ZSwgJmxlbik7CiAgICAqbG9jYWwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsICpsb2NhbCwgLTEpOwogICAgcHJlZiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsdWUsIGxlbik7CiAgICBucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCBwcmVmKTsKICAgIGlmIChucyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIE5VTEwsIHZhbHVlLAoJICAgICJUaGUgdmFsdWUgJyVzJyBvZiBzaW1wbGUgdHlwZSAneHM6UU5hbWUnIGhhcyBubyAiCgkgICAgImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHNjb3BlIiwgdmFsdWUsIE5VTEwpOwoJcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSBlbHNlIHsKICAgICAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBhdHRyOiAgdGhlIGF0dHJpYnV0ZSBub2RlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIFFOYW1lIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQKICogc2hvdWxkIHJlc29sdmUgdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqCiAqIFJldHVybnMgMCwgaW4gY2FzZSB0aGUgUU5hbWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBpZiBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJCSAgICAgICB4bWxBdHRyUHRyIGF0dHIsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKGN0eHQsIHNjaGVtYSwKCW93bmVySXRlbSwgYXR0ciwgdmFsdWUsIHVyaSwgbG9jYWwpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyUU5hbWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06ICB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyB0aGUgUU5hbWUgb2YgYW4gYXR0cmlidXRlIHZhbHVlLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCQkgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJCSAgIGNvbnN0IGNoYXIgKm5hbWUsCgkJCQkgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsKQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG93bmVyRWxlbSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CgkqbG9jYWwgPSBOVUxMOwoJKnVyaSA9IE5VTEw7CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCglvd25lckl0ZW0sIGF0dHIsIHVyaSwgbG9jYWwpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRySUQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06ICB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyB0aGUgSUQgb2YgYW4gYXR0cmlidXRlIHZhbHVlLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIElEIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZUlEKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sQXR0clB0ciBhdHRyKQp7CiAgICBpbnQgcmV0OwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CgogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybigwKTsKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnROb0RpY3QoKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgcmV0ID0geG1sVmFsaWRhdGVOQ05hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA9PSAwKSB7CgkvKgoJKiBOT1RFOiB0aGUgSURuZXNzIG1pZ2h0IGhhdmUgYWxyZWFkeSBiZSBkZWNsYXJlZCBpbiB0aGUgRFRECgkqLwoJaWYgKGF0dHItPmF0eXBlICE9IFhNTF9BVFRSSUJVVEVfSUQpIHsKCSAgICB4bWxJRFB0ciByZXM7CgkgICAgeG1sQ2hhciAqc3RyaXA7CgoJICAgIC8qCgkgICAgKiBUT0RPOiBVc2UgeG1sU2NoZW1hU3RyaXAgaGVyZTsgaXQncyBub3QgZXhwb3J0ZWQgYXQgdGhpcwoJICAgICogbW9tZW50LgoJICAgICovCgkgICAgc3RyaXAgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkgICAgaWYgKHN0cmlwICE9IE5VTEwpIHsKCQl4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlKTsKCQl2YWx1ZSA9IHN0cmlwOwoJICAgIH0KICAgIAkgICAgcmVzID0geG1sQWRkSUQoTlVMTCwgYXR0ci0+ZG9jLCB2YWx1ZSwgYXR0cik7CgkgICAgaWYgKHJlcyA9PSBOVUxMKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfSUQpLAoJCSAgICBOVUxMLCBOVUxMLCAiRHVwbGljYXRlIHZhbHVlICclcycgb2Ygc2ltcGxlICIKCQkgICAgInR5cGUgJ3hzOklEJyIsIHZhbHVlLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlhdHRyLT5hdHlwZSA9IFhNTF9BVFRSSUJVVEVfSUQ7Cgl9CiAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCXJldCA9IFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUU7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfSUQpLAoJICAgIE5VTEwsIE5VTEwsICJUaGUgdmFsdWUgJyVzJyBvZiBzaW1wbGUgdHlwZSAneHM6SUQnIGlzICIKCSAgICAibm90IGEgdmFsaWQgJ3hzOk5DTmFtZSciLAoJICAgIHZhbHVlLCBOVUxMKTsKICAgIH0KICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJeG1sRnJlZSgoeG1sQ2hhciAqKXZhbHVlKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJJRCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCSAgICBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG93bmVyRWxlbSwgKGNvbnN0IGNoYXIgKikgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuKDApOwogICAgcmV0dXJuKHhtbFNjaGVtYVBWYWxBdHRyTm9kZUlEKGN0eHQsIGF0dHIpKTsKCn0KCi8qKgogKiB4bWxHZXRNYXhPY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtYXhPY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNYXhPY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWF4T2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewoJaWYgKG1heCAhPSBVTkJPVU5ERUQpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuIChkZWYpOwoJfSBlbHNlCgkgICAgcmV0dXJuIChVTkJPVU5ERUQpOyAgLyogZW5jb2RpbmcgaXQgd2l0aCAtMSBtaWdodCBiZSBhbm90aGVyIG9wdGlvbiAqLwogICAgfQoKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKGRlZik7CiAgICB9CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICAvKgogICAgKiBUT0RPOiBSZXN0cmljdCB0aGUgbWF4aW1hbCB2YWx1ZSB0byBJbnRlZ2VyLgogICAgKi8KICAgIGlmICgoKmN1ciAhPSAwKSB8fCAocmV0IDwgbWluKSB8fCAoKG1heCAhPSAtMSkgJiYgKHJldCA+IG1heCkpKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0TWluT2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWluT2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWluT2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAoJCWludCBtaW4sIGludCBtYXgsIGludCBkZWYsIGNvbnN0IGNoYXIgKmV4cGVjdGVkKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1pbk9jY3VycyIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoZGVmKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6ICBvd25lciBkZXNpZ25hdGlvbgogKiBAb3duZXJJdGVtOiAgdGhlIG93bmVyIGFzIGEgc2NoZW1hIGl0ZW0KICogQG5vZGU6IHRoZSBub2RlIGhvbGRpbmcgdGhlIHZhbHVlCiAqCiAqIENvbnZlcnRzIGEgYm9vbGVhbiBzdHJpbmcgdmFsdWUgaW50byAxIG9yIDAuCiAqCiAqIFJldHVybnMgMCBvciAxLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBvd25lckl0ZW0sCgkJCSAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwogICAgaW50IHJlcyA9IDA7CgogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKICAgIC8qCiAgICAqIDMuMi4yLjEgTGV4aWNhbCByZXByZXNlbnRhdGlvbgogICAgKiBBbiBpbnN0YW5jZSBvZiBhIGRhdGF0eXBlIHRoYXQgaXMgZGVmaW5lZCBhcyC3Ym9vbGVhbrcKICAgICogY2FuIGhhdmUgdGhlIGZvbGxvd2luZyBsZWdhbCBsaXRlcmFscyB7dHJ1ZSwgZmFsc2UsIDEsIDB9LgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICByZXMgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICJmYWxzZSIpKQogICAgICAgIHJlcyA9IDA7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjEiKSkKCXJlcyA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjAiKSkKICAgICAgICByZXMgPSAwOwogICAgZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0JPT0xFQU4sCgkgICAgb3duZXJJdGVtLCBub2RlLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJICAgIE5VTEwsIEJBRF9DQVNUIHZhbHVlLAoJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgfQogICAgaWYgKHZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKHZhbHVlKTsKICAgIHJldHVybiAocmVzKTsKfQoKLyoqCiAqIHhtbEdldEJvb2xlYW5Qcm9wOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqIEBkZWY6ICB0aGUgZGVmYXVsdCB2YWx1ZQogKgogKiBFdmFsdWF0ZSBpZiBhIGJvb2xlYW4gcHJvcGVydHkgaXMgc2V0CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCAwIGlmIGZvdW5kIHRvIGJlIGZhbHNlLAogKiAxIGlmIGZvdW5kIHRvIGJlIHRydWUKICovCnN0YXRpYyBpbnQKeG1sR2V0Qm9vbGVhblByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBpbnQgZGVmKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CgogICAgdmFsID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKGRlZik7CiAgICAvKgogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63CiAgICAqIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgbGVnYWwgbGl0ZXJhbHMge3RydWUsIGZhbHNlLCAxLCAwfS4KICAgICovCiAgICBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAidHJ1ZSIpKQogICAgICAgIGRlZiA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICJmYWxzZSIpKQogICAgICAgIGRlZiA9IDA7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICIxIikpCglkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMCIpKQogICAgICAgIGRlZiA9IDA7CiAgICBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBOVUxMLAoJICAgICh4bWxOb2RlUHRyKSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCBuYW1lKSwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwKCSAgICBOVUxMLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChkZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVNoZW1hIGV4dHJhY3Rpb24gZnJvbSBhbiBJbmZvc2V0CQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCQkJICBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgIHhtbFNjaGVtYVR5cGVUeXBlIHBhcmVudFR5cGUpOwpzdGF0aWMgeG1sU2NoZW1hQmFzaWNJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciB1c2VzLAoJCQkgICAgIGludCBwYXJlbnRUeXBlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VMaXN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpOwoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlOgogKgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAYXR0cjogIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUgYmVpbmcgdmFsaWRhdGVkCiAqIEB2YWx1ZTogdGhlIHZhbHVlCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdAogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlLgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGludGVybmFsbHkgZm9yIHZhbGlkYXRpb24KICogb2Ygc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZXMgZHVyaW5nIHBhcnNpbmcgb2YgdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCQkgICB4bWxBdHRyUHRyIGF0dHIsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKCiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBOT1RFOiBTaG91bGQgd2UgbW92ZSB0aGlzIHRvIHhtbHNjaGVtYXR5cGVzLmM/IEhtbSwgYnV0IHRoaXMKICAgICogb25lIGlzIHJlYWxseSBtZWFudCB0byBiZSB1c2VkIGludGVybmFsbHksIHNvIGJldHRlciBub3QuCiAgICAqLwogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSB8fCAoYXR0ciA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZSIsCgkgICAgInRoZSBnaXZlbiB0eXBlIGlzIG5vdCBhIGJ1aWx0LWluIHR5cGUiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgc3dpdGNoICh0eXBlLT5idWlsdEluVHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BU19OQ05BTUU6CgljYXNlIFhNTF9TQ0hFTUFTX1FOQU1FOgoJY2FzZSBYTUxfU0NIRU1BU19BTllVUkk6CgljYXNlIFhNTF9TQ0hFTUFTX1RPS0VOOgoJY2FzZSBYTUxfU0NIRU1BU19MQU5HVUFHRToKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZSh0eXBlLCB2YWx1ZSwgTlVMTCwKCQkoeG1sTm9kZVB0cikgYXR0cik7CgkgICAgYnJlYWs7CglkZWZhdWx0OiB7CgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUiLAoJCSJ2YWxpZGF0aW9uIHVzaW5nIHRoZSBnaXZlbiB0eXBlIGlzIG5vdCBzdXBwb3J0ZWQgd2hpbGUgIgoJCSJwYXJzaW5nIGEgc2NoZW1hIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBUT0RPOiBTaG91bGQgd2UgdXNlIHRoZSBTNFMgZXJyb3IgY29kZXMgaW5zdGVhZD8KICAgICovCiAgICBpZiAocmV0IDwgMCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUiLAoJICAgICJmYWlsZWQgdG8gdmFsaWRhdGUgYSBzY2hlbWEgYXR0cmlidXRlIHZhbHVlIik7CglyZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJaWYgKFdYU19JU19MSVNUKHR5cGUpKQoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCWVsc2UKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihwY3R4dCwgCgkgICAgcmV0LCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHR5cGUsIE5VTEwsIHZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZToKICoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3Qgb3duZXIgaWYgZXhpc3RlbnQKICogQGF0dHI6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBub2RlIGJlaW5nIHZhbGlkYXRlZAogKiBAdHlwZTogdGhlIGJ1aWx0LWluIHR5cGUgdG8gYmUgdmFsaWRhdGVkIGFnYWluc3QKICogQHZhbHVlOiB0aGUgcmVzdWx0aW5nIHZhbHVlIGlmIGFueQogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIG93bmVySXRlbSwKCQkJICAgeG1sQXR0clB0ciBhdHRyLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKip2YWx1ZSkKewogICAgY29uc3QgeG1sQ2hhciAqdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSB8fCAoYXR0ciA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwoKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJKnZhbHVlID0gdmFsOwoKICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoY3R4dCwgb3duZXJJdGVtLCBhdHRyLAoJdmFsLCB0eXBlKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0cjoKICoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAb3duZXJFbGVtOiB0aGUgb3duZXIgZWxlbWVudCBub2RlCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGJ1aWx0LWluIHR5cGUgdG8gYmUgdmFsaWRhdGVkIGFnYWluc3QKICogQHZhbHVlOiB0aGUgcmVzdWx0aW5nIHZhbHVlIGlmIGFueQogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAkJICAgICAgIAoJCSAgICAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgb3duZXJJdGVtLAoJCSAgICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkgICAgICAgY29uc3QgY2hhciAqbmFtZSwKCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdmFsdWUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgKnZhbHVlID0gTlVMTDsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUFZhbEF0dHIsIHRoZSBnaXZlbiAiCgkgICAgInR5cGUgJyVzJyBpcyBub3QgYSBidWlsdC1pbiB0eXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG93bmVyRWxlbSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICAqdmFsdWUgPSBOVUxMOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIG93bmVySXRlbSwgYXR0ciwKCXR5cGUsIHZhbHVlKSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgIHhtbFNjaGVtYVB0ciBzY2hlbWEgQVRUUklCVVRFX1VOVVNFRCwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkgIHhtbEF0dHJQdHIgYXR0ciwKCQkgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUpCnsKICAgIC8qIFRPRE86IFBvaW50ZXIgY29tcGFyaXNvbiBpbnN0ZWFkPyAqLwogICAgaWYgKHhtbFN0ckVxdWFsKHBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5hbWVzcGFjZU5hbWUpKQoJcmV0dXJuICgwKTsKICAgIGlmICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFOcywgbmFtZXNwYWNlTmFtZSkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogQ2hlY2sgaWYgdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIHdhcyA8aW1wb3J0PmVkLgogICAgKi8KICAgIGlmIChXWFNfQlVDS0VUKHBjdHh0KS0+cmVsYXRpb25zICE9IE5VTEwpIHsKCXhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbDsKCglyZWwgPSBXWFNfQlVDS0VUKHBjdHh0KS0+cmVsYXRpb25zOwoJZG8gewoJICAgIGlmIChXWFNfSVNfQlVDS0VUX0lNUE1BSU4ocmVsLT50eXBlKSAmJgoJCXhtbFN0ckVxdWFsKG5hbWVzcGFjZU5hbWUsIHJlbC0+aW1wb3J0TmFtZXNwYWNlKSkKCQlyZXR1cm4gKDApOwoJICAgIHJlbCA9IHJlbC0+bmV4dDsKCX0gd2hpbGUgKHJlbCAhPSBOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIE5vIG1hdGNoaW5nIDxpbXBvcnQ+ZWQgbmFtZXNwYWNlIGZvdW5kLgogICAgKi8KICAgIHsKCXhtbE5vZGVQdHIgbiA9IChhdHRyICE9IE5VTEwpID8gKHhtbE5vZGVQdHIpIGF0dHIgOiBub2RlOwoKCWlmIChuYW1lc3BhY2VOYW1lID09IE5VTEwpCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIG4sIE5VTEwsCgkJIlJlZmVyZW5jZXMgZnJvbSB0aGlzIHNjaGVtYSB0byBjb21wb25lbnRzIGluIG5vICIKCQkibmFtZXNwYWNlIGFyZSBub3QgYWxsb3dlZCwgc2luY2Ugbm90IGluZGljYXRlZCBieSBhbiAiCgkJImltcG9ydCBzdGF0ZW1lbnQiLCBOVUxMLCBOVUxMKTsKCWVsc2UKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwgbiwgTlVMTCwKCQkiUmVmZXJlbmNlcyBmcm9tIHRoaXMgc2NoZW1hIHRvIGNvbXBvbmVudHMgaW4gdGhlICIKCQkibmFtZXNwYWNlICclcycgYXJlIG5vdCBhbGxvd2VkLCBzaW5jZSBub3QgaW5kaWNhdGVkIGJ5IGFuICIKCQkiaW1wb3J0IHN0YXRlbWVudCIsIG5hbWVzcGFjZU5hbWUsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxvY2FsQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAdHlwZTogIHRoZSBob3N0aW5nIHR5cGUgd2hlcmUgdGhlIGF0dHJpYnV0ZXMgd2lsbCBiZSBhbmNob3JlZAogKgogKiBQYXJzZXMgYXR0cmlidXRlIHVzZXMgYW5kIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgYW5kCiAqIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzLiAKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VMb2NhbEF0dHJpYnV0ZXMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyICpjaGlsZCwgeG1sU2NoZW1hSXRlbUxpc3RQdHIgKmxpc3QsCgkJCWludCBwYXJlbnRUeXBlLCBpbnQgKmhhc1JlZnMpCnsKICAgIHZvaWQgKml0ZW07CgogICAgd2hpbGUgKChJU19TQ0hFTUEoKCpjaGlsZCksICJhdHRyaWJ1dGUiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKCgqY2hpbGQpLCAiYXR0cmlidXRlR3JvdXAiKSkpIHsKICAgICAgICBpZiAoSVNfU0NIRU1BKCgqY2hpbGQpLCAiYXR0cmlidXRlIikpIHsKCSAgICBpdGVtID0geG1sU2NoZW1hUGFyc2VMb2NhbEF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsICpjaGlsZCwKCQkqbGlzdCwgcGFyZW50VHlwZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaXRlbSA9IHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXBSZWYoY3R4dCwgc2NoZW1hLCAqY2hpbGQpOwoJICAgIGlmICgoaXRlbSAhPSBOVUxMKSAmJiAoaGFzUmVmcyAhPSBOVUxMKSkKCQkqaGFzUmVmcyA9IDE7CiAgICAgICAgfQoJaWYgKGl0ZW0gIT0gTlVMTCkgewoJICAgIGlmICgqbGlzdCA9PSBOVUxMKSB7CgkJLyogVE9ETzogQ3VzdG9taXplIGdyb3cgZmFjdG9yLiAqLwoJCSpsaXN0ID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCQlpZiAoKmxpc3QgPT0gTlVMTCkKCQkgICAgcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgaWYgKHhtbFNjaGVtYUl0ZW1MaXN0QWRkU2l6ZSgqbGlzdCwgMiwgaXRlbSkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0KICAgICAgICAqY2hpbGQgPSAoKmNoaWxkKS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFubm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYUFubm90UHRyCnhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IG5lZWRlZCkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgYmFya2VkID0gMDsKCiAgICAvKgogICAgKiBJTkZPOiBTNFMgY29tcGxldGVkLgogICAgKi8KICAgIC8qCiAgICAqIGlkID0gSUQKICAgICoge2FueSBhdHRyaWJ1dGVzIHdpdGggbm9uLXNjaGVtYSBuYW1lc3BhY2UgLiAuIC59PgogICAgKiBDb250ZW50OiAoYXBwaW5mbyB8IGRvY3VtZW50YXRpb24pKgogICAgKi8KICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgaWYgKG5lZWRlZCkKCXJldCA9IHhtbFNjaGVtYU5ld0Fubm90KGN0eHQsIG5vZGUpOwogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKCgoYXR0ci0+bnMgPT0gTlVMTCkgJiYKCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgfHwKCSAgICAoKGF0dHItPm5zICE9IE5VTEwpICYmCgkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpIHsKCgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXBwaW5mbyIpKSB7CgkgICAgLyogVE9ETzogbWFrZSBhdmFpbGFibGUgdGhlIGNvbnRlbnQgb2YgImFwcGluZm8iLiAqLwoJICAgIC8qCgkgICAgKiBzb3VyY2UgPSBhbnlVUkkKCSAgICAqIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KCSAgICAqIENvbnRlbnQ6ICh7YW55fSkqCgkgICAgKi8KCSAgICBhdHRyID0gY2hpbGQtPnByb3BlcnRpZXM7CgkgICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJCWlmICgoKGF0dHItPm5zID09IE5VTEwpICYmCgkJICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzb3VyY2UiKSkpIHx8CgkJICAgICAoKGF0dHItPm5zICE9IE5VTEwpICYmCgkJICAgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJfQoJCWF0dHIgPSBhdHRyLT5uZXh0OwoJICAgIH0KCSAgICB4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBjaGlsZCwgInNvdXJjZSIsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZG9jdW1lbnRhdGlvbiIpKSB7CgkgICAgLyogVE9ETzogbWFrZSBhdmFpbGFibGUgdGhlIGNvbnRlbnQgb2YgImRvY3VtZW50YXRpb24iLiAqLwoJICAgIC8qCgkgICAgKiBzb3VyY2UgPSBhbnlVUkkKCSAgICAqIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KCSAgICAqIENvbnRlbnQ6ICh7YW55fSkqCgkgICAgKi8KCSAgICBhdHRyID0gY2hpbGQtPnByb3BlcnRpZXM7CgkgICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNvdXJjZSIpKSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykgfHwKCQkJKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJsYW5nIikgJiYKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgWE1MX1hNTF9OQU1FU1BBQ0UpKSkpIHsKCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJCSAgICB9CgkJfQoJCWF0dHIgPSBhdHRyLT5uZXh0OwoJICAgIH0KCSAgICAvKgoJICAgICogQXR0cmlidXRlICJ4bWw6bGFuZyIuCgkgICAgKi8KCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGVOcyhjaGlsZCwgKGNvbnN0IGNoYXIgKikgWE1MX1hNTF9OQU1FU1BBQ0UsICJsYW5nIik7CgkgICAgaWYgKGF0dHIgIT0gTlVMTCkKCQl4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgYXR0ciwKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19MQU5HVUFHRSksIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgewoJICAgIGlmICghYmFya2VkKQoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqIik7CgkgICAgYmFya2VkID0gMTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRmFjZXQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEZhY2V0IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUZhY2V0UHRyCnhtbFNjaGVtYVBhcnNlRmFjZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgZmFjZXQgPSB4bWxTY2hlbWFOZXdGYWNldCgpOwogICAgaWYgKGZhY2V0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGZhY2V0Iiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGZhY2V0LT5ub2RlID0gbm9kZTsKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAidmFsdWUiKTsKICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX0ZBQ0VUX05PX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgbm8gdmFsdWVcbiIsIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5FeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4SW5jbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEV4Y2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ0b3RhbERpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImZyYWN0aW9uRGlnaXRzIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAicGF0dGVybiIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk47CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAiZW51bWVyYXRpb24iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ3aGl0ZVNwYWNlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJsZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4TGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkxlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRkFDRVRfVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAiVW5rbm93biBmYWNldCB0eXBlICVzXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgZmFjZXQtPnZhbHVlID0gdmFsdWU7CiAgICBpZiAoKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgJiYKCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJY29uc3QgeG1sQ2hhciAqZml4ZWQ7CgoJZml4ZWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwoJaWYgKGZpeGVkICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoZml4ZWQsIEJBRF9DQVNUICJ0cnVlIikpCgkJZmFjZXQtPmZpeGVkID0gMTsKCX0KICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIGZhY2V0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRkFDRVRfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkZhY2V0ICVzIGhhcyB1bmV4cGVjdGVkIGNoaWxkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKGZhY2V0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROczoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAd2lsZGM6ICB0aGUgd2lsZGNhcmQsIGFscmVhZHkgY3JlYXRlZAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyB0aGUgYXR0cmlidXRlICJwcm9jZXNzQ29udGVudHMiIGFuZCAibmFtZXNwYWNlIgogKiBvZiBhIHhzZDphbnlBdHRyaWJ1dGUgYW5kIHhzZDphbnkuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAwIGlmIGV2ZXJ5dGhpbmcgZ29lcyBmaW5lLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgc29tZXRoaW5nIGlzIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sU2NoZW1hUHRyIHNjaGVtYSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZGMsCgkJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnBjLCAqbnMsICpkaWN0bnNJdGVtOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxDaGFyICpuc0l0ZW07CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHRtcCwgbGFzdE5zID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBwYyA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInByb2Nlc3NDb250ZW50cyIpOwogICAgaWYgKChwYyA9PSBOVUxMKQogICAgICAgIHx8ICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInN0cmljdCIpKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOwogICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInNraXAiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJsYXgiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfTEFYOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgbm9kZSwKCSAgICBOVUxMLCAiKHN0cmljdCB8IHNraXAgfCBsYXgpIiwgcGMsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgd2lsZGMtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1Q7CglyZXQgPSBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFOwogICAgfQogICAgLyoKICAgICAqIEJ1aWxkIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMuCiAgICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZXNwYWNlIik7CiAgICBucyA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGlmICgoYXR0ciA9PSBOVUxMKSB8fCAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI2FueSIpKSkKCXdpbGRjLT5hbnkgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI290aGVyIikpIHsKCXdpbGRjLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHdpbGRjLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl3aWxkYy0+bmVnTnNTZXQtPnZhbHVlID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKmVuZCwgKmN1cjsKCgljdXIgPSBuczsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIG5zSXRlbSA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIGlmICgoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNvdGhlciIpKSB8fAoJCSAgICAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNhbnkiKSkpIHsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9XSUxEQ0FSRF9JTlZBTElEX05TX01FTUJFUiwKCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsCgkJICAgICIoKCMjYW55IHwgIyNvdGhlcikgfCBMaXN0IG9mICh4czphbnlVUkkgfCAiCgkJICAgICIoIyN0YXJnZXROYW1lc3BhY2UgfCAjI2xvY2FsKSkpIiwKCQkgICAgbnNJdGVtLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQlyZXQgPSBYTUxfU0NIRU1BUF9XSUxEQ0FSRF9JTlZBTElEX05TX01FTUJFUjsKCSAgICB9IGVsc2UgewoJCWlmICh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI3RhcmdldE5hbWVzcGFjZSIpKSB7CgkJICAgIGRpY3Ruc0l0ZW0gPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI2xvY2FsIikpIHsKCQkgICAgZGljdG5zSXRlbSA9IE5VTEw7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBWYWxpZGF0ZSB0aGUgaXRlbSAoYW55VVJJKS4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoY3R4dCwgTlVMTCwgYXR0ciwKCQkJbnNJdGVtLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpKTsKCQkgICAgZGljdG5zSXRlbSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnNJdGVtLCAtMSk7CgkJfQoJCS8qCgkJKiBBdm9pZCBkdWJsaWNhdGUgbmFtZXNwYWNlcy4KCQkqLwoJCXRtcCA9IHdpbGRjLT5uc1NldDsKCQl3aGlsZSAodG1wICE9IE5VTEwpIHsKCQkgICAgaWYgKGRpY3Ruc0l0ZW0gPT0gdG1wLT52YWx1ZSkKCQkJYnJlYWs7CgkJICAgIHRtcCA9IHRtcC0+bmV4dDsKCQl9CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCSAgICBpZiAodG1wID09IE5VTEwpIHsKCQkJeG1sRnJlZShuc0l0ZW0pOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICB0bXAtPnZhbHVlID0gZGljdG5zSXRlbTsKCQkgICAgdG1wLT5uZXh0ID0gTlVMTDsKCQkgICAgaWYgKHdpbGRjLT5uc1NldCA9PSBOVUxMKQoJCQl3aWxkYy0+bnNTZXQgPSB0bXA7CgkJICAgIGVsc2UKCQkJbGFzdE5zLT5uZXh0ID0gdG1wOwoJCSAgICBsYXN0TnMgPSB0bXA7CgkJfQoKCSAgICB9CgkgICAgeG1sRnJlZShuc0l0ZW0pOwoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGl0ZW0gQVRUUklCVVRFX1VOVVNFRCwKCQkJCSB4bWxOb2RlUHRyIG5vZGUsCgkJCQkgaW50IG1pbk9jY3VycywKCQkJCSBpbnQgbWF4T2NjdXJzKSB7CgogICAgaWYgKChtYXhPY2N1cnMgPT0gMCkgJiYgKCBtaW5PY2N1cnMgPT0gMCkpCglyZXR1cm4gKDApOwogICAgaWYgKG1heE9jY3VycyAhPSBVTkJPVU5ERUQpIHsKCS8qCgkqIFRPRE86IE1heWJlIHdlIHNob3VsZCBiZXR0ZXIgbm90IGNyZWF0ZSB0aGUgcGFydGljbGUsCgkqIGlmIG1pbi9tYXggaXMgaW52YWxpZCwgc2luY2UgaXQgY291bGQgY29uZnVzZSB0aGUgYnVpbGQgb2YgdGhlCgkqIGNvbnRlbnQgbW9kZWwuCgkqLwoJLyoKCSogMy45LjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBQYXJ0aWNsZSBDb3JyZWN0CgkqCgkqLwoJaWYgKG1heE9jY3VycyA8IDEpIHsKCSAgICAvKgoJICAgICogMi4yIHttYXggb2NjdXJzfSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAxLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9QX1BST1BTX0NPUlJFQ1RfMl8yLAoJCU5VTEwsIE5VTEwsCgkJeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1heE9jY3VycyIpLAoJCSJUaGUgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMSIpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMik7Cgl9IGVsc2UgaWYgKG1pbk9jY3VycyA+IG1heE9jY3VycykgewoJICAgIC8qCgkgICAgKiAyLjEge21pbiBvY2N1cnN9IG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB7bWF4IG9jY3Vyc30uCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzEsCgkJTlVMTCwgTlVMTCwKCQl4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWluT2NjdXJzIiksCgkJIlRoZSB2YWx1ZSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4gdGhlIHZhbHVlIG9mICdtYXhPY2N1cnMnIik7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9QX1BST1BTX0NPUlJFQ1RfMl8xKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZWEgYSBYTUwgc2NoZW1hIDxhbnk+IGVsZW1lbnQuIEEgcGFydGljbGUgYW5kIHdpbGRjYXJkCiAqIHdpbGwgYmUgY3JlYXRlZCAoZXhjZXB0IGlmIG1pbk9jY3Vycz09bWF4T2NjdXJzPT0wLCBpbiB0aGlzIGNhc2UKICogbm90aGluZyB3aWxsIGJlIGNyZWF0ZWQpLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHBhcnRpY2xlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvciBvciBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MAogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnRpY2xlUHRyCnhtbFNjaGVtYVBhcnNlQW55KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZDsKICAgIGludCBtaW4sIG1heDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90ID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWVzcGFjZSIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInByb2Nlc3NDb250ZW50cyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogbWluT2NjdXJzL21heE9jY3Vycy4KICAgICovCiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLAoJIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsCgkieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCBOVUxMLCBub2RlLCBtaW4sIG1heCk7CiAgICAvKgogICAgKiBDcmVhdGUgJiBwYXJzZSB0aGUgd2lsZGNhcmQuCiAgICAqLwogICAgd2lsZCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQsIHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX0FOWSwgbm9kZSk7CiAgICBpZiAod2lsZCA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyhjdHh0LCBzY2hlbWEsIHdpbGQsIG5vZGUpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICAvKgogICAgKiBObyBjb21wb25lbnQgaWYgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAuCiAgICAqLwogICAgaWYgKChtaW4gPT0gMCkgJiYgKG1heCA9PSAwKSkgewoJLyogRG9uJ3QgZnJlZSB0aGUgd2lsZGNhcmQsIHNpbmNlIGl0J3MgYWxyZWFkeSBvbiB0aGUgbGlzdC4gKi8KCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBDcmVhdGUgdGhlIHBhcnRpY2xlLgogICAgKi8KICAgIHBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUoY3R4dCwgbm9kZSwgbWluLCBtYXgpOwogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHBhcnRpY2xlLT5hbm5vdCA9IGFubm90OwogICAgcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB3aWxkOwoKICAgIHJldHVybiAocGFydGljbGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VOb3RhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgTm90YXRpb24gZGVjbGFyYXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFQYXJzZU5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgbmFtZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChuYW1lID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfTk9UQVRJT05fTk9fTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAiTm90YXRpb24gaGFzIG5vIG5hbWVcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFBZGROb3RhdGlvbihjdHh0LCBzY2hlbWEsIG5hbWUsCgljdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwogICAgaWYgKHJldCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+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+bm9kZSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ1NlbGVjdG9yWFBhdGgsICIKCSAgICAidGhlIHNlbGVjdG9yIGlzIG5vdCBzcGVjaWZpZWQuXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKGF0dHIgPT0gTlVMTCkKCW5vZGUgPSBpZGMtPm5vZGU7CiAgICBlbHNlCglub2RlID0gKHhtbE5vZGVQdHIpIGF0dHI7CiAgICBpZiAoc2VsZWN0b3ItPnhwYXRoID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICAvKiBUT0RPOiBBZGp1c3QgZXJyb3IgY29kZS4gKi8KCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBYUGF0aCBleHByZXNzaW9uIG9mIHRoZSBzZWxlY3RvciBpcyBub3QgdmFsaWQiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSk7CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqKm5zQXJyYXkgPSBOVUxMOwoJeG1sTnNQdHIgKm5zTGlzdCA9IE5VTEw7CgkvKgoJKiBDb21waWxlIHRoZSBYUGF0aCBleHByZXNzaW9uLgoJKi8KCS8qCgkqIFRPRE86IFdlIG5lZWQgdGhlIGFycmF5IG9mIGluLXNjb3BlIG5hbWVzcGFjZXMgZm9yIGNvbXBpbGF0aW9uLgoJKiBUT0RPOiBDYWxsIHhtbFBhdHRlcm5jb21waWxlIHdpdGggZGlmZmVyZW50IG9wdGlvbnMgZm9yIHNlbGVjdG9yLwoJKiBmaWVsZC4KCSovCgluc0xpc3QgPSB4bWxHZXROc0xpc3QoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQpOwoJLyoKCSogQnVpbGQgYW4gYXJyYXkgb2YgcHJlZml4ZXMgYW5kIG5hbWVzcGFjZXMuCgkqLwoJaWYgKG5zTGlzdCAhPSBOVUxMKSB7CgkgICAgaW50IGksIGNvdW50ID0gMDsKCgkgICAgZm9yIChpID0gMDsgbnNMaXN0W2ldICE9IE5VTEw7IGkrKykKCQljb3VudCsrOwoKCSAgICBuc0FycmF5ID0gKGNvbnN0IHhtbENoYXIgKiopIHhtbE1hbGxvYygKCQkoY291bnQgKiAyICsgMSkgKiBzaXplb2YoY29uc3QgeG1sQ2hhciAqKSk7CgkgICAgaWYgKG5zQXJyYXkgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSBuYW1lc3BhY2UgYXJyYXkiLAoJCSAgICBOVUxMKTsKCQl4bWxGcmVlKG5zTGlzdCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJbnNBcnJheVsyICogaV0gPSBuc0xpc3RbaV0tPmhyZWY7CgkJbnNBcnJheVsyICogaSArIDFdID0gbnNMaXN0W2ldLT5wcmVmaXg7CgkgICAgfQoJICAgIG5zQXJyYXlbY291bnQgKiAyXSA9IE5VTEw7CgkgICAgeG1sRnJlZShuc0xpc3QpOwoJfQoJLyoKCSogVE9ETzogRGlmZmVyZW50aWF0ZSBiZXR3ZWVuICJzZWxlY3RvciIgYW5kICJmaWVsZCIuCgkqLwoJaWYgKGlzRmllbGQpCgkgICAgc2VsZWN0b3ItPnhwYXRoQ29tcCA9ICh2b2lkICopIHhtbFBhdHRlcm5jb21waWxlKHNlbGVjdG9yLT54cGF0aCwKCQlOVUxMLCBYTUxfUEFUVEVSTl9YU0ZJRUxELCBuc0FycmF5KTsKCWVsc2UKCSAgICBzZWxlY3Rvci0+eHBhdGhDb21wID0gKHZvaWQgKikgeG1sUGF0dGVybmNvbXBpbGUoc2VsZWN0b3ItPnhwYXRoLAoJCU5VTEwsIFhNTF9QQVRURVJOX1hTU0VMLCBuc0FycmF5KTsKCWlmIChuc0FycmF5ICE9IE5VTEwpCgkgICAgeG1sRnJlZSgoeG1sQ2hhciAqKikgbnNBcnJheSk7CgoJaWYgKHNlbGVjdG9yLT54cGF0aENvbXAgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkvKiBUT0RPOiBBZGp1c3QgZXJyb3IgY29kZT8gKi8KCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCU5VTEwsIG5vZGUsCgkJIlRoZSBYUGF0aCBleHByZXNzaW9uICclcycgY291bGQgbm90IGJlICIKCQkiY29tcGlsZWQiLCBzZWxlY3Rvci0+eHBhdGgpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgojZGVmaW5lIEFERF9BTk5PVEFUSU9OKGFubm90KSAgIFwKICAgIHhtbFNjaGVtYUFubm90UHRyIGN1ciA9IGl0ZW0tPmFubm90OyBcCiAgICBpZiAoaXRlbS0+YW5ub3QgPT0gTlVMTCkgeyAgXAoJaXRlbS0+YW5ub3QgPSBhbm5vdDsgICAgXAoJcmV0dXJuIChhbm5vdCk7ICAgICAgICAgXAogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGN1ciA9IGl0ZW0tPmFubm90OyAgICAgICAgICBcCiAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsgICAgXAoJY3VyID0gY3VyLT5uZXh0OwlcCiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgY3VyLT5uZXh0ID0gYW5ub3Q7CgovKioKICogeG1sU2NoZW1hQXNzaWduQW5ub3RhdGlvbjoKICogQGl0ZW06IHRoZSBzY2hlbWEgY29tcG9uZW50CiAqIEBhbm5vdDogdGhlIGFubm90YXRpb24KICoKICogQWRkcyB0aGUgYW5ub3RhdGlvbiB0byB0aGUgZ2l2ZW4gc2NoZW1hIGNvbXBvbmVudC4KICoKICogUmV0dXJucyB0aGUgZ2l2ZW4gYW5ub3RhaW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUFubm90UHRyCnhtbFNjaGVtYUFkZEFubm90YXRpb24oeG1sU2NoZW1hQW5ub3RJdGVtUHRyIGFubkl0ZW0sCgkJICAgICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICBpZiAoKGFubkl0ZW0gPT0gTlVMTCkgfHwgKGFubm90ID09IE5VTEwpKQoJcmV0dXJuIChOVUxMKTsKICAgIHN3aXRjaCAoYW5uSXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDogewoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgaXRlbSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTogewoJCXhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOiB7CgkJeG1sU2NoZW1hV2lsZGNhcmRQdHIgaXRlbSA9ICh4bWxTY2hlbWFXaWxkY2FyZFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRTogewoJCXhtbFNjaGVtYUFubm90SXRlbVB0ciBpdGVtID0gKHhtbFNjaGVtYUFubm90SXRlbVB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDogewoJCXhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGl0ZW0gPQoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046IHsKCQl4bWxTY2hlbWFOb3RhdGlvblB0ciBpdGVtID0gKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOiB7CgkJeG1sU2NoZW1hRmFjZXRQdHIgaXRlbSA9ICh4bWxTY2hlbWFGYWNldFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOiB7CgkJeG1sU2NoZW1hVHlwZVB0ciBpdGVtID0gKHhtbFNjaGVtYVR5cGVQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6IHsKCQl4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW0gPSAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDogewoJCXhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgaXRlbSA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoTlVMTCwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCBOVUxMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkQW5ub3RhdGlvbiwgIgoJCSJUaGUgaXRlbSBpcyBub3QgYSBhbm5vdGF0ZWQgc2NoZW1hIGNvbXBvbmVudCIsIE5VTEwpOwoJICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoYW5ub3QpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyBhIFhNTCBTY2hlbWEgaWRlbnRpdHktY29udHJhaW50IGRlZmluaXRpb24ncwogKiA8c2VsZWN0b3I+IGFuZCA8ZmllbGQ+IGVsZW1lbnRzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZWQgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUlEQ1NlbGVjdFB0cgp4bWxTY2hlbWFQYXJzZUlEQ1NlbGVjdG9yQW5kRmllbGQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAkJCSAgCgkJCSAgeG1sU2NoZW1hSURDUHRyIGlkYywKCQkJICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgaW50IGlzRmllbGQpCnsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBpdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAieHBhdGgiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogQ3JlYXRlIHRoZSBpdGVtLgogICAgKi8KICAgIGl0ZW0gPSAoeG1sU2NoZW1hSURDU2VsZWN0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ1NlbGVjdCkpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCSAgICAiYWxsb2NhdGluZyBhICdzZWxlY3Rvcicgb2YgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIiwKCSAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KGl0ZW0sIDAsIHNpemVvZih4bWxTY2hlbWFJRENTZWxlY3QpKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAieHBhdGgiIChtYW5kYXRvcnkpLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAieHBhdGgiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKICAgIAl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIm5hbWUiLCBOVUxMKTsKICAgIH0gZWxzZSB7CglpdGVtLT54cGF0aCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCS8qCgkqIFVSR0VOVCBUT0RPOiAiZmllbGQicyBoYXZlIGFuIG90aGVyIHN5bnRheCB0aGFuICJzZWxlY3RvciJzLgoJKi8KCglpZiAoeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aChjdHh0LCBpZGMsIGl0ZW0sIGF0dHIsCgkgICAgaXNGaWVsZCkgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsCgkJKHhtbE5vZGVQdHIpIGF0dHIsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZUlEQ1NlbGVjdG9yQW5kRmllbGQsICIKCQkidmFsaWRhdGluZyB0aGUgWFBhdGggZXhwcmVzc2lvbiBvZiBhIElEQyBzZWxlY3Rvci5cbiIsCgkJTlVMTCwgTlVMTCk7Cgl9CgogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIHBhcmVudCBJREMuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSBpZGMsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKSk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KCiAgICByZXR1cm4gKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJREM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VzIGEgWE1MIFNjaGVtYSBpZGVudGl0eS1jb250cmFpbnQgZGVmaW5pdGlvbi4KICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFJRENQdHIKeG1sU2NoZW1hUGFyc2VJREMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkgIHhtbFNjaGVtYVR5cGVUeXBlIGlkY0NhdGVnb3J5LAoJCSAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFJRENQdHIgaXRlbSA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUgPSBOVUxMOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGZpZWxkID0gTlVMTCwgbGFzdEZpZWxkID0gTlVMTDsKCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJKChpZGNDYXRlZ29yeSAhPSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgfHwKCQkgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmZXIiKSkpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAibmFtZSIgKG1hbmRhdG9yeSkuCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIm5hbWUiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LAoJTlVMTCwgYXR0ciwKCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgLyogQ3JlYXRlIHRoZSBjb21wb25lbnQuICovCiAgICBpdGVtID0geG1sU2NoZW1hQWRkSURDKGN0eHQsIHNjaGVtYSwgbmFtZSwgdGFyZ2V0TmFtZXNwYWNlLAoJaWRjQ2F0ZWdvcnksIG5vZGUpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybihOVUxMKTsKCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaWYgKGlkY0NhdGVnb3J5ID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkvKgoJKiBBdHRyaWJ1dGUgInJlZmVyIiAobWFuZGF0b3J5KS4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZmVyIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLAoJCSJyZWZlciIsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogQ3JlYXRlIGEgcmVmZXJlbmNlIGl0ZW0uCgkgICAgKi8KCSAgICBpdGVtLT5yZWYgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihjdHh0LCBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSwKCQlOVUxMLCBOVUxMKTsKCSAgICBpZiAoaXRlbS0+cmVmID09IE5VTEwpCgkJcmV0dXJuIChOVUxMKTsKCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkJTlVMTCwgYXR0ciwKCQkmKGl0ZW0tPnJlZi0+dGFyZ2V0TmFtZXNwYWNlKSwKCQkmKGl0ZW0tPnJlZi0+bmFtZSkpOwoJICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgYXR0ciwKCQlpdGVtLT5yZWYtPnRhcmdldE5hbWVzcGFjZSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwgY2hpbGQsCgkJIkEgY2hpbGQgZWxlbWVudCBpcyBtaXNzaW5nIiwKCQkiKGFubm90YXRpb24/LCAoc2VsZWN0b3IsIGZpZWxkKykpIik7CiAgICB9CiAgICAvKgogICAgKiBDaGlsZCBlbGVtZW50IDxzZWxlY3Rvcj4uCiAgICAqLwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlbGVjdG9yIikpIHsKCWl0ZW0tPnNlbGVjdG9yID0geG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKGN0eHQsCgkgICAgaXRlbSwgY2hpbGQsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKCS8qCgkqIENoaWxkIGVsZW1lbnRzIDxmaWVsZD4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImZpZWxkIikpIHsKCSAgICBkbyB7CgkJZmllbGQgPSB4bWxTY2hlbWFQYXJzZUlEQ1NlbGVjdG9yQW5kRmllbGQoY3R4dCwKCQkgICAgaXRlbSwgY2hpbGQsIDEpOwoJCWlmIChmaWVsZCAhPSBOVUxMKSB7CgkJICAgIGZpZWxkLT5pbmRleCA9IGl0ZW0tPm5iRmllbGRzOwoJCSAgICBpdGVtLT5uYkZpZWxkcysrOwoJCSAgICBpZiAobGFzdEZpZWxkICE9IE5VTEwpCgkJCWxhc3RGaWVsZC0+bmV4dCA9IGZpZWxkOwoJCSAgICBlbHNlCgkJCWl0ZW0tPmZpZWxkcyA9IGZpZWxkOwoJCSAgICBsYXN0RmllbGQgPSBmaWVsZDsKCQl9CgkJY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB9IHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJmaWVsZCIpKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwKCQlOVUxMLCAiKGFubm90YXRpb24/LCAoc2VsZWN0b3IsIGZpZWxkKykpIik7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAoc2VsZWN0b3IsIGZpZWxkKykpIik7CiAgICB9CgogICAgcmV0dXJuIChpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAdG9wTGV2ZWw6IGluZGljYXRlcyBpZiB0aGlzIGlzIGdsb2JhbCBkZWNsYXJhdGlvbgogKgogKiBQYXJzZXMgYSBYTUwgc2NoZW1hIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBvciBhIHBhcnRpY2xlOyBOVUxMIGluIGNhc2UKICogb2YgYW4gZXJyb3Igb3IgaWYgdGhlIHBhcnRpY2xlIGhhcyBtaW5PY2N1cnM9PW1heE9jY3Vycz09MC4KICovCnN0YXRpYyB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIKeG1sU2NoZW1hUGFyc2VFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50ICppc0VsZW1SZWYsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0gTlVMTDsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyLCBuYW1lQXR0cjsKICAgIGludCBtaW4sIG1heCwgaXNSZWYgPSAwOwogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICAvKiAzLjMuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEVsZW1lbnQgRGVjbGFyYXRpb25zICovCiAgICAvKiBUT0RPOiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiAzLjMuNiAqLwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKGlzRWxlbVJlZiAhPSBOVUxMKQoJKmlzRWxlbVJlZiA9IDA7CiAgICAvKgogICAgKiBJZiB3ZSBnZXQgYSAicmVmIiBhdHRyaWJ1dGUgb24gYSBsb2NhbCA8ZWxlbWVudD4gd2Ugd2lsbCBhc3N1bWUgaXQncwogICAgKiBhIHJlZmVyZW5jZSAtIGV2ZW4gaWYgdGhlcmUncyBhICJuYW1lIiBhdHRyaWJ1dGU7IHRoaXMgc2VlbXMgdG8gYmUgbW9yZQogICAgKiByb2J1c3QuCiAgICAqLwogICAgbmFtZUF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIGlmICgodG9wTGV2ZWwpIHx8IChhdHRyID09IE5VTEwpKSB7CglpZiAobmFtZUF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwgIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfSBlbHNlCglpc1JlZiA9IDE7CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7Cglhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgLyoKICAgICogU2tpcCBwYXJ0aWNsZSBwYXJ0IGlmIGEgZ2xvYmFsIGRlY2xhcmF0aW9uLgogICAgKi8KICAgIGlmICh0b3BMZXZlbCkKCWdvdG8gZGVjbGFyYXRpb25fcGFydDsKICAgIC8qCiAgICAqIFRoZSBwYXJ0aWNsZSBwYXJ0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAqLwogICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIHhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIE5VTEwsIG5vZGUsIG1pbiwgbWF4KTsKICAgIHBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUoY3R4dCwgbm9kZSwgbWluLCBtYXgpOwogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCglnb3RvIHJldHVybl9udWxsOwoKICAgIC8qIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9SRUY7ICovCgogICAgaWYgKGlzUmVmKSB7Cgljb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMOwoJeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmZXIgPSBOVUxMOwoJLyoKCSogVGhlIHJlZmVyZW5jZSBwYXJ0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoJKi8KCWlmIChpc0VsZW1SZWYgIT0gTlVMTCkKCSAgICAqaXNFbGVtUmVmID0gMTsKCgl4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkgICAgTlVMTCwgYXR0ciwgJnJlZk5zLCAmcmVmKTsKCXhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgYXR0ciwgcmVmTnMpOwoJLyoKCSogU1BFQyAoMy4zLjMgOiAyLjEpICJPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGgiCgkqLwoJaWYgKG5hbWVBdHRyICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzEsIE5VTEwsIG5hbWVBdHRyLCAicmVmIiwgIm5hbWUiKTsKCX0KCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkKCQl7CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICAvKiBTUEVDICgzLjMuMyA6IDIuMikgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8yLAoJCQlOVUxMLCBOVUxMLCBhdHRyLAoJCQkiT25seSB0aGUgYXR0cmlidXRlcyAnbWluT2NjdXJzJywgJ21heE9jY3VycycgYW5kICIKCQkJIidpZCcgYXJlIGFsbG93ZWQgaW4gYWRkaXRpb24gdG8gJ3JlZiciKTsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQoJLyoKCSogTm8gY2hpbGRyZW4gZXhjZXB0IDxhbm5vdGF0aW9uPiBleHBlY3RlZC4KCSovCglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/KSIpOwoJfQoJaWYgKChtaW4gPT0gMCkgJiYgKG1heCA9PSAwKSkKCSAgICBnb3RvIHJldHVybl9udWxsOwoJLyoKCSogQ3JlYXRlIHRoZSByZWZlcmVuY2UgaXRlbSBhbmQgYXR0YWNoIGl0IHRvIHRoZSBwYXJ0aWNsZS4KCSovCglyZWZlciA9IHhtbFNjaGVtYU5ld1FOYW1lUmVmKGN0eHQsIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULAoJICAgIHJlZiwgcmVmTnMpOwoJaWYgKHJlZmVyID09IE5VTEwpCgkgICAgZ290byByZXR1cm5fbnVsbDsKCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcmVmZXI7CglwYXJ0aWNsZS0+YW5ub3QgPSBhbm5vdDsKCS8qCgkqIEFkZCB0aGUgcGFydGljbGUgdG8gcGVuZGluZyBjb21wb25lbnRzLCBzaW5jZSB0aGUgcmVmZXJlbmNlCgkqIG5lZWQgdG8gYmUgcmVzb2x2ZWQuCgkqLwoJV1hTX0FERF9QRU5ESU5HKGN0eHQsIHBhcnRpY2xlKTsKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcGFydGljbGUpOwogICAgfQogICAgLyoKICAgICogVGhlIGRlY2xhcmF0aW9uIHBhcnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgICovCmRlY2xhcmF0aW9uX3BhcnQ6CiAgICB7Cgljb25zdCB4bWxDaGFyICpucyA9IE5VTEwsICpmaXhlZCwgKm5hbWUsICphdHRyVmFsdWU7Cgl4bWxTY2hlbWFJRENQdHIgY3VySURDID0gTlVMTCwgbGFzdElEQyA9IE5VTEw7CgoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBuYW1lQXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkKCSAgICBnb3RvIHJldHVybl9udWxsOwoJLyoKCSogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgbnMgPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgewoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZm9ybSIpOwoJICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gY3R4dC0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJCU5VTEwsICIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwKCQkJYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9CgkgICAgfSBlbHNlIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pCgkJbnMgPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7Cgl9CglkZWNsID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBuYW1lLCBucywgbm9kZSwgdG9wTGV2ZWwpOwoJaWYgKGRlY2wgPT0gTlVMTCkgewoJICAgIGdvdG8gcmV0dXJuX251bGw7Cgl9CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJkZWZhdWx0IikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpeGVkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJsb2NrIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5pbGxhYmxlIikpKQoJCXsKCQkgICAgaWYgKHRvcExldmVsID09IDApIHsKCQkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpICYmCgkJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmb3JtIikpKQoJCQl7CgkJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCQkJfQoJCSAgICB9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpICYmCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpICYmCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInN1YnN0aXR1dGlvbkdyb3VwIikpKSB7CgoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCQkgICAgfQoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgkvKgoJKiBFeHRyYWN0L3ZhbGlkYXRlIGF0dHJpYnV0ZXMuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgdG9wIGF0dHJpYnV0ZXMgb2YgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGhlcmUuCgkgICAgKi8KCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTDsKCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1RPUExFVkVMOwoJICAgIHhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLAoJCU5VTEwsIG5vZGUsICJzdWJzdGl0dXRpb25Hcm91cCIsCgkJJihkZWNsLT5zdWJzdEdyb3VwTnMpLCAmKGRlY2wtPnN1YnN0R3JvdXApKTsKCSAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgbm9kZSwgImFic3RyYWN0IiwgMCkpCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVDsKCSAgICAvKgoJICAgICogQXR0cmlidXRlICJmaW5hbCIuCgkgICAgKi8KCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpbmFsIik7CgkgICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCgkJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfRVhURU5TSU9OOwoJCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikKCQkgICAgZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTjsKCSAgICB9IGVsc2UgewoJCWF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCQlpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihkZWNsLT5mbGFncyksCgkJICAgIC0xLAoJCSAgICBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTiwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTiwgLTEsIC0xLCAtMSkgIT0gMCkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkJTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKSIsCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0KCX0KCS8qCgkqIEF0dHJpYnV0ZSAiYmxvY2siLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYmxvY2siKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogQXBwbHkgZGVmYXVsdCAiYmxvY2siIHZhbHVlcy4KCSAgICAqLwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTikKCQlkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OOwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04pCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT047CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1NVQlNUSVRVVElPTikKCQlkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTjsKCX0gZWxzZSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKGRlY2wtPmZsYWdzKSwKCQktMSwKCQlYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTiwKCQlYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OLCAtMSwgLTEpICE9IDApIHsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgIgoJCSAgICAicmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSIsIGF0dHJWYWx1ZSwKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQoJaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIG5vZGUsICJuaWxsYWJsZSIsIDApKQoJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEU7CgoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ0eXBlIik7CglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJCU5VTEwsIGF0dHIsCgkJJihkZWNsLT5uYW1lZFR5cGVOcyksICYoZGVjbC0+bmFtZWRUeXBlKSk7CgkgICAgeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoY3R4dCwgc2NoZW1hLCBub2RlLAoJCWF0dHIsIGRlY2wtPm5hbWVkVHlwZU5zKTsKCX0KCWRlY2wtPnZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZGVmYXVsdCIpOwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaXhlZCIpOwoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIGZpeGVkID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmIChkZWNsLT52YWx1ZSAhPSBOVUxMKSB7CgkJLyoKCQkqIDMuMy4zIDogMQoJCSogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgoJCSovCgkJeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzEsCgkJICAgIE5VTEwsIGF0dHIsICJkZWZhdWx0IiwgImZpeGVkIik7CgkgICAgfSBlbHNlIHsKCQlkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEOwoJCWRlY2wtPnZhbHVlID0gZml4ZWQ7CgkgICAgfQoJfQoJLyoKCSogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikpIHsKCSAgICAvKgoJICAgICogMy4zLjMgOiAzCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkKCSAgICAqIGV4Y2x1c2l2ZQoJICAgICovCgkgICAgaWYgKGRlY2wtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgTlVMTCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxjb21wbGV4VHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZQoJCVdYU19FTEVNX1RZUEVERUYoZGVjbCkgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIC8qCgkgICAgKiAzLjMuMyA6IDMKCSAgICAqICJ0eXBlIiBhbmQgZWl0aGVyIDxzaW1wbGVUeXBlPiBvciA8Y29tcGxleFR5cGU+IGFyZQoJICAgICogbXV0dWFsbHkgZXhjbHVzaXZlCgkgICAgKi8KCSAgICBpZiAoZGVjbC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8zLAoJCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ3R5cGUnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlXWFNfRUxFTV9UWVBFREVGKGRlY2wpID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9Cgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgfHwgKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSkgewoJICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJ1bmlxdWUiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFLCBkZWNsLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHsKCQljdXJJREMgPSB4bWxTY2hlbWFQYXJzZUlEQyhjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSwgZGVjbC0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSB7CgkJY3VySURDID0geG1sU2NoZW1hUGFyc2VJREMoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYsIGRlY2wtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfQoJICAgIGlmIChsYXN0SURDICE9IE5VTEwpCgkJbGFzdElEQy0+bmV4dCA9IGN1cklEQzsKCSAgICBlbHNlCgkJZGVjbC0+aWRjcyA9ICh2b2lkICopIGN1cklEQzsKCSAgICBsYXN0SURDID0gY3VySURDOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUpPywgIgoJCSIodW5pcXVlIHwga2V5IHwga2V5cmVmKSopKSIpOwoJfQoJZGVjbC0+YW5ub3QgPSBhbm5vdDsKICAgIH0KICAgIC8qCiAgICAqIE5PVEU6IEVsZW1lbnQgRGVjbGFyYXRpb24gUmVwcmVzZW50YXRpb24gT0sgNC4gd2lsbCBiZSBjaGVja2VkIGF0IGEKICAgICogZGlmZmVyZW50IGxheWVyLgogICAgKi8KICAgIEZSRUVfQU5EX05VTEwoZGVzKQogICAgaWYgKHRvcExldmVsKQoJcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBkZWNsKTsKICAgIGVsc2UgewoJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBkZWNsOwoJcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBwYXJ0aWNsZSk7CiAgICB9CgpyZXR1cm5fbnVsbDoKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIGlmIChhbm5vdCAhPSBOVUxMKSB7CglpZiAocGFydGljbGUgIT0gTlVMTCkKCSAgICBwYXJ0aWNsZS0+YW5ub3QgPSBOVUxMOwoJaWYgKGRlY2wgIT0gTlVMTCkKCSAgICBkZWNsLT5hbm5vdCA9IE5VTEw7Cgl4bWxTY2hlbWFGcmVlQW5ub3QoYW5ub3QpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlVW5pb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFVuaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgZXJyb3IsIDAgaW4gY2FzZSBvZiBzdWNjZXNzIGFuZCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVVuaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqY3VyID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgLyoKICAgICogTWFyayB0aGUgc2ltcGxlIHR5cGUgYXMgYmVpbmcgb2YgdmFyaWV0eSAidW5pb24iLgogICAgKi8KICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsKICAgIC8qCiAgICAqIFNQRUMgKEJhc2UgdHlwZSkgKDIpICJJZiB0aGUgPGxpc3Q+IG9yIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLAogICAgKiB0aGVuIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuIgogICAgKi8KICAgIHR5cGUtPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtZW1iZXJUeXBlcyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlICJtZW1iZXJUeXBlcyIuIFRoaXMgaXMgYSBsaXN0IG9mIFFOYW1lcy4KICAgICogVE9ETzogQ2hlY2sgdGhlIHZhbHVlIHRvIGNvbnRhaW4gYW55dGhpbmcuCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtZW1iZXJUeXBlcyIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJY29uc3QgeG1sQ2hhciAqZW5kOwoJeG1sQ2hhciAqdG1wOwoJY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lLCAqbnNOYW1lOwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaywgbGFzdExpbmsgPSBOVUxMOwoJeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmOwoKCWN1ciA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCXR5cGUtPmJhc2UgPSBjdXI7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZShjdHh0LCBzY2hlbWEsCgkJTlVMTCwgYXR0ciwgQkFEX0NBU1QgdG1wLCAmbnNOYW1lLCAmbG9jYWxOYW1lKSA9PSAwKSB7CgkJLyoKCQkqIENyZWF0ZSB0aGUgbWVtYmVyIHR5cGUgbGluay4KCQkqLwoJCWxpbmsgPSAoeG1sU2NoZW1hVHlwZUxpbmtQdHIpCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZUxpbmspKTsKCQlpZiAobGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgInhtbFNjaGVtYVBhcnNlVW5pb24sICIKCQkJImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCBOVUxMKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCWxpbmstPnR5cGUgPSBOVUxMOwoJCWxpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0TGluayA9PSBOVUxMKQoJCSAgICB0eXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CgkJZWxzZQoJCSAgICBsYXN0TGluay0+bmV4dCA9IGxpbms7CgkJbGFzdExpbmsgPSBsaW5rOwoJCS8qCgkJKiBDcmVhdGUgYSByZWZlcmVuY2UgaXRlbS4KCQkqLwoJCXJlZiA9IHhtbFNjaGVtYU5ld1FOYW1lUmVmKGN0eHQsIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsCgkJICAgIGxvY2FsTmFtZSwgbnNOYW1lKTsKCQlpZiAocmVmID09IE5VTEwpIHsKCQkgICAgRlJFRV9BTkRfTlVMTCh0bXApCgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQkvKgoJCSogQXNzaWduIHRoZSByZWZlcmVuY2UgdG8gdGhlIGxpbmssIGl0IHdpbGwgYmUgcmVzb2x2ZWQKCQkqIGxhdGVyIGR1cmluZyBmaXh1cCBvZiB0aGUgdW5pb24gc2ltcGxlIHR5cGUuCgkJKi8KCQlsaW5rLT50eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpIHJlZjsKCSAgICB9CgkgICAgRlJFRV9BTkRfTlVMTCh0bXApCgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsKCiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBzaW1wbGUgdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCXhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZSwgbGFzdCA9IE5VTEw7CgoJLyoKCSogQW5jaG9yIHRoZSBtZW1iZXIgdHlwZXMgaW4gdGhlICJzdWJ0eXBlcyIgZmllbGQgb2YgdGhlCgkqIHNpbXBsZSB0eXBlLgoJKi8KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKCQlpZiAobGFzdCA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCQkgICAgbGFzdCA9IHN1YnR5cGU7CgkJfSBlbHNlIHsKCQkgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CgkJICAgIGxhc3QgPSBzdWJ0eXBlOwoJCX0KCQlsYXN0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlKikiKTsKICAgIH0KICAgIGlmICgoYXR0ciA9PSBOVUxMKSAmJiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkpIHsKCSAvKgoJKiBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMKCSogRWl0aGVyIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBvZiB0aGUgPHVuaW9uPiBlbGVtZW50IG11c3QKCSogYmUgbm9uLWVtcHR5IG9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIHNpbXBsZVR5cGUgW2NoaWxkXS4KCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1VOSU9OX01FTUJFUlRZUEVTX09SX1NJTVBMRVRZUEVTLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdtZW1iZXJUeXBlcycgb3IgIgoJICAgICJhdCBsZWFzdCBvbmUgPHNpbXBsZVR5cGU+IGNoaWxkIG11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTGlzdDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgTGlzdCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIC8qCiAgICAqIE1hcmsgdGhlIHR5cGUgYXMgYmVpbmcgb2YgdmFyaWV0eSAibGlzdCIuCiAgICAqLwogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CiAgICAvKgogICAgKiBTUEVDIChCYXNlIHR5cGUpICgyKSAiSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKICAgICogdGhlbiB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LiIKICAgICovCiAgICB0eXBlLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaXRlbVR5cGUiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogQXR0cmlidXRlICJpdGVtVHlwZSIuIE5PVEUgdGhhdCB3ZSB3aWxsIHVzZSB0aGUgInJlZiIgYW5kICJyZWZOcyIKICAgICogZmllbGRzIGZvciBob2xkaW5nIHRoZSByZWZlcmVuY2UgdG8gdGhlIGl0ZW1UeXBlLgogICAgKgogICAgKiBSRVZBTVAgVE9ETzogVXNlIHRoZSAiYmFzZSIgYW5kICJiYXNlTnMiIGZpZWxkcywgc2luY2Ugd2Ugd2lsbCByZW1vdmUKICAgICogdGhlICJyZWYiIGZpZWxkcy4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgTlVMTCwKCW5vZGUsICJpdGVtVHlwZSIsICYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSk7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkvKgoJKiBzcmMtbGlzdC1pdGVtVHlwZS1vci1zaW1wbGVUeXBlCgkqIEVpdGhlciB0aGUgaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb3IgdGhlIDxzaW1wbGVUeXBlPiBbY2hpbGRdIG9mCgkqIHRoZSA8bGlzdD4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4KCSovCglpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJCU5VTEwsIG5vZGUsCgkJIlRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJImFyZSBtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7Cgl9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAodHlwZS0+YmFzZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCSAgICAibXVzdCBiZSBwcmVzZW50IiwgTlVMTCk7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZT8pIik7CiAgICB9CiAgICBpZiAoKHR5cGUtPmJhc2UgPT0gTlVMTCkgJiYKCSh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJgoJKHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJpdGVtVHlwZSIpID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCSAgICAibXVzdCBiZSBwcmVzZW50IiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTaW1wbGUgVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgb2xkQ3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZSA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgaGFzUmVzdHJpY3Rpb24gPSAwOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHRvcExldmVsKSB7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsCgkJIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsCgkJTlVMTCwgYXR0ciwKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmYXR0clZhbHVlKSAhPSAwKQoJCXJldHVybiAoTlVMTCk7CgkgICAgLyoKCSAgICAqIFNraXAgYnVpbHQtaW4gdHlwZXMuCgkgICAgKi8KCSAgICBpZiAoY3R4dC0+aXNTNFMpIHsKCQl4bWxTY2hlbWFUeXBlUHRyIGJpVHlwZTsKCgkJaWYgKGN0eHQtPmlzUmVkZWZpbmUpIHsKCQkgICAgLyoKCQkgICAgKiBSRURFRklORTogRGlzYWxsb3cgcmVkZWZpbml0aW9uIG9mIGJ1aWx0LWluLXR5cGVzLgoJCSAgICAqIFRPRE86IEl0IHNlZW1zIHRoYXQgdGhlIHNwZWMgZG9lcyBub3Qgc2F5IGFueXRoaW5nCgkJICAgICogYWJvdXQgdGhpcyBjYXNlLgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCQkJTlVMTCwgbm9kZSwKCQkJIlJlZGVmaW5pdGlvbiBvZiBidWlsdC1pbiBzaW1wbGUgdHlwZXMgaXMgbm90ICIKCQkJInN1cHBvcnRlZCIsIE5VTEwpOwoJCSAgICByZXR1cm4oTlVMTCk7CgkJfQoJCWJpVHlwZSA9IHhtbFNjaGVtYUdldFByZWRlZmluZWRUeXBlKGF0dHJWYWx1ZSwgeG1sU2NoZW1hTnMpOwoJCWlmIChiaVR5cGUgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChiaVR5cGUpOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIFRhcmdldE5hbWVzcGFjZToKICAgICogU1BFQyAiVGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0KICAgICogb2YgdGhlIDxzY2hlbWE+IGFuY2VzdG9yIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpZiBwcmVzZW50LAogICAgKiBvdGhlcndpc2Ugt2Fic2VudLcuCiAgICAqLwogICAgaWYgKHRvcExldmVsID09IDApIHsKI2lmZGVmIEVOQUJMRV9OQU1FRF9MT0NBTFMKICAgICAgICBjaGFyIGJ1Zls0MF07CiNlbmRpZgoJLyoKCSogUGFyc2UgYXMgbG9jYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSovCiNpZmRlZiBFTkFCTEVfTkFNRURfTE9DQUxTCiAgICAgICAgc25wcmludGYoYnVmLCAzOSwgIiNTVCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7Cgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwKCSAgICB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIChjb25zdCB4bWxDaGFyICopYnVmLCAtMSksCgkgICAgY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlLCAwKTsKI2Vsc2UKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLAoJICAgIE5VTEwsIGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMCk7CiNlbmRpZgoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7Cgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOyAKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIFBhcnNlIGFzIGdsb2JhbCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJKgoJKiBOb3RlIHRoYXQgYXR0clZhbHVlIGlzIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICJuYW1lIiBoZXJlLgoJKi8KCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwKCSAgICBhdHRyVmFsdWUsIGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRTsKCXR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQoJLyoKCSogQXR0cmlidXRlICJmaW5hbCIuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbCIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OOwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNUKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVDsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT04pCgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTjsKCX0gZWxzZSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZmluYWwiKTsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJih0eXBlLT5mbGFncyksCgkJLTEsIC0xLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OLCAtMSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTikgIT0gMCkgewoKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAobGlzdCB8IHVuaW9uIHwgcmVzdHJpY3Rpb24pIiwKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9CiAgICB0eXBlLT50YXJnZXROYW1lc3BhY2UgPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkQ3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIAogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiKTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewkKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSk7CQoJaGFzUmVzdHJpY3Rpb24gPSAxOwkKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJsaXN0IikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZUxpc3QoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAidW5pb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlVW5pb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIpOwogICAgfQogICAgLyoKICAgICogUkVERUZJTkU6IFNQRUMgc3JjLXJlZGVmaW5lICg1KQogICAgKiAiV2l0aGluIHRoZSBbY2hpbGRyZW5dLCBlYWNoIDxzaW1wbGVUeXBlPiBtdXN0IGhhdmUgYQogICAgKiA8cmVzdHJpY3Rpb24+IGFtb25nIGl0cyBbY2hpbGRyZW5dIC4uLiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2Ygd2hvc2UKICAgICogYmFzZSBbYXR0cmlidXRlXSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSC3YWN0dWFsIHZhbHVltyBvZiBpdHMgb3duCiAgICAqIG5hbWUgYXR0cmlidXRlIHBsdXMgdGFyZ2V0IG5hbWVzcGFjZTsiCiAgICAqLwogICAgaWYgKHRvcExldmVsICYmIGN0eHQtPmlzUmVkZWZpbmUgJiYgKCEgaGFzUmVzdHJpY3Rpb24pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCSAgICBOVUxMLCBub2RlLCAiVGhpcyBpcyBhIHJlZGVmaW5pdGlvbiwgdGh1cyB0aGUgIgoJICAgICI8c2ltcGxlVHlwZT4gbXVzdCBoYXZlIGEgPHJlc3RyaWN0aW9uPiBjaGlsZCIsIE5VTEwpOwogICAgfQogICAgCiAgICBjdHh0LT5jdHh0VHlwZSA9IG9sZEN0eHRUeXBlOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZjoKICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIHRoZSBub2RlCiAqCiAqIFBhcnNlcyBhIHJlZmVyZW5jZSB0byBhIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAqCiAqIFdlIHdpbGwgcmV0dXJuIGEgcGFydGljbGUgY29tcG9uZW50IHdpdGggYSBxbmFtZS1jb21wb25lbnQgb3IKICogTlVMTCBpbiBjYXNlIG9mIGFuIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpyZWYgPSBOVUxMLCAqcmVmTnMgPSBOVUxMOwogICAgaW50IG1pbiwgbWF4OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgInJlZiIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLCBOVUxMLAoJYXR0ciwgJnJlZk5zLCAmcmVmKSAhPSAwKSB7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoY3R4dCwgc2NoZW1hLCBub2RlLCBhdHRyLCByZWZOcyk7CiAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJ4czpub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heCA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsCgkiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWYiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaXRlbSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKGN0eHQsIG5vZGUsIG1pbiwgbWF4KTsKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOyAgICAKICAgIC8qCiAgICAqIENyZWF0ZSBhIHFuYW1lLXJlZmVyZW5jZSBhbmQgc2V0IGFzIHRoZSB0ZXJtOyBpdCB3aWxsIGJlIHN1YnN0aXR1dGVkCiAgICAqIGZvciB0aGUgbW9kZWwgZ3JvdXAgYWZ0ZXIgdGhlIHJlZmVyZW5jZSBoYXMgYmVlbiByZXNvbHZlZC4KICAgICovCiAgICBpdGVtLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCXhtbFNjaGVtYU5ld1FOYW1lUmVmKGN0eHQsIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCwgcmVmLCByZWZOcyk7ICAgIAogICAgeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgaXRlbSwgbm9kZSwgbWluLCBtYXgpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIC8qIFRPRE86IElzIGFubm90YXRpb24gZXZlbiBhbGxvd2VkIGZvciBhIG1vZGVsIGdyb3VwIHJlZmVyZW5jZT8gKi8KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIFRPRE86IFdoYXQgdG8gZG8gZXhhY3RseSB3aXRoIHRoZSBhbm5vdGF0aW9uPwoJKi8KCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgLyoKICAgICogQ29ycmVzcG9uZHMgdG8gbm8gY29tcG9uZW50IGF0IGFsbCBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MC4KICAgICovCiAgICBpZiAoKG1pbiA9PSAwKSAmJiAobWF4ID09IDApKQoJcmV0dXJuIChOVUxMKTsKCiAgICByZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyBhIFhNTCBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KICoKICogTm90ZSB0aGF0IHRoZSBjb250cmFpbnQgc3JjLXJlZGVmaW5lICg2LjIpIGNhbid0IGJlIGFwcGxpZWQgdW50aWwKICogcmVmZXJlbmNlcyBoYXZlIGJlZW4gcmVzb2x2ZWQuIFNvIHdlIHdpbGwgZG8gdGhpcyBhdCB0aGUKICogY29tcG9uZW50IGZpeHVwIGxldmVsLgogKiAgICAKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIKeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmaW5pdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAibmFtZSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIGF0dHIsCgl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGl0ZW0gPSB4bWxTY2hlbWFBZGRNb2RlbEdyb3VwRGVmaW5pdGlvbihjdHh0LCBzY2hlbWEsIG5hbWUsCgljdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewoJaXRlbS0+Y2hpbGRyZW4gPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CglpdGVtLT5jaGlsZHJlbiA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJaXRlbS0+Y2hpbGRyZW4gPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KCiAgIAoKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSk/KSIpOwogICAgfQogICAgcmV0dXJuIChpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFudXBEb2M6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50LgogKgogKiByZW1vdmVzIHVud2FudGVkIG5vZGVzIGluIGEgc2NoZW1hcyBkb2N1bWVudCB0cmVlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhbnVwRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciByb290KQp7CiAgICB4bWxOb2RlUHRyIGRlbGV0ZSwgY3VyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAocm9vdCA9PSBOVUxMKSkgcmV0dXJuOwoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIGRlbGV0ZSA9IE5VTEw7CiAgICBjdXIgPSByb290OwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICAgICAgeG1sRnJlZU5vZGUoZGVsZXRlKTsKICAgICAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CiAgICAgICAgICAgIGlmIChJU19CTEFOS19OT0RFKGN1cikpIHsKICAgICAgICAgICAgICAgIGlmICh4bWxOb2RlR2V0U3BhY2VQcmVzZXJ2ZShjdXIpICE9IDEpIHsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgPSBjdXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKChjdXItPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKICAgICAgICAgICAgICAgICAgIChjdXItPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICBnb3RvIHNraXBfY2hpbGRyZW47CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFNraXAgdG8gbmV4dCBub2RlCiAgICAgICAgICovCiAgICAgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgewogICAgICAgICAgICBpZiAoKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9ERUNMKSAmJgogICAgICAgICAgICAgICAgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfTk9ERSkpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgc2tpcF9jaGlsZHJlbjoKICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGRvIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5wYXJlbnQ7CiAgICAgICAgICAgIGlmIChjdXIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBpZiAoY3VyID09IHJvb3QpIHsKICAgICAgICAgICAgICAgIGN1ciA9IE5VTEw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sVW5saW5rTm9kZShkZWxldGUpOwogICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgIH0KfQoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfUVVBTElGX0VMRU07CgogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfUVVBTElGX0FUVFI7CgogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT047CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT047CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVCkKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNUOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1JFU1RSSUNUSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1JFU1RSSUNUSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1NVQlNUSVRVVElPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT047Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTY2hlbWFFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqdmFsOwogICAgaW50IHJlcyA9IDAsIG9sZEVycnMgPSBjdHh0LT5uYmVycm9yczsKCiAgICAvKgogICAgKiBUaG9zZSBmbGFncyBzaG91bGQgYmUgbW92ZWQgdG8gdGhlIHBhcnNlciBjb250ZXh0IGZsYWdzLAogICAgKiBzaW5jZSB0aGV5IGFyZSBub3QgdmlzaWJsZSBhdCB0aGUgY29tcG9uZW50IGxldmVsLiBJLmUuCiAgICAqIHRoZXkgYXJlIHVzZWQgaWYgcHJvY2Vzc2luZyBzY2hlbWEgKmRvY3VtZW50cyogb25seS4KICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgSEZBSUxVUkU7CgogICAgLyoKICAgICogU2luY2UgdGhlIHZlcnNpb24gaXMgb2YgdHlwZSB4czp0b2tlbiwgd2Ugd29uJ3QgYm90aGVyIHRvCiAgICAqIGNoZWNrIGl0LgogICAgKi8KICAgIC8qIFJFTU9WRUQ6CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInZlcnNpb24iKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1RPS0VOKSwgJnZhbCk7ICAgIAoJSEZBSUxVUkU7CiAgICB9CiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIE5VTEwpOwoJSEZBSUxVUkU7CglpZiAocmVzICE9IDApIHsKCSAgICBjdHh0LT5zdG9wID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCSAgICBnb3RvIGV4aXQ7Cgl9CiAgICB9CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImVsZW1lbnRGb3JtRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJcmVzID0geG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdCh2YWwsICZzY2hlbWEtPmZsYWdzLAoJICAgIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKTsKCUhGQUlMVVJFOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9FTEVNRk9STURFRkFVTFRfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQogICAgfQogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJhdHRyaWJ1dGVGb3JtRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJcmVzID0geG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdCh2YWwsICZzY2hlbWEtPmZsYWdzLAoJICAgIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKTsKCUhGQUlMVVJFOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9BVFRSRk9STURFRkFVTFRfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQogICAgfQogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbERlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCXJlcyA9IHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbCh2YWwsICYoc2NoZW1hLT5mbGFncyksIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04sCgkgICAgLTEsCgkgICAgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNULAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT04pOwoJSEZBSUxVUkU7CglpZiAocmVzICE9IDApIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIsCgkJdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYmxvY2tEZWZhdWx0Iik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgl2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CQoJcmVzID0geG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKHZhbCwgJihzY2hlbWEtPmZsYWdzKSwgLTEsCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04sCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTiwKCSAgICBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1NVQlNUSVRVVElPTiwgLTEsIC0xKTsKCUhGQUlMVVJFOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkiLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CgpleGl0OgogICAgaWYgKG9sZEVycnMgIT0gY3R4dC0+bmJlcnJvcnMpCglyZXMgPSBjdHh0LT5lcnI7CiAgICByZXR1cm4ocmVzKTsKZXhpdF9mYWlsdXJlOgogICAgcmV0dXJuKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcwogKiBAbm9kZXM6ICB0aGUgbGlzdCBvZiB0b3AgbGV2ZWwgbm9kZXMKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlcykKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgaW50IHJlcyA9IDAsIG9sZEVycnMsIHRtcE9sZEVycnM7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGVzID09IE5VTEwpKQogICAgICAgIHJldHVybigtMSk7CgogICAgb2xkRXJycyA9IGN0eHQtPm5iZXJyb3JzOwogICAgY2hpbGQgPSBub2RlczsKICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAiaW5jbHVkZSIpKSB8fAoJICAgKElTX1NDSEVNQShjaGlsZCwgImltcG9ydCIpKSB8fAoJICAgKElTX1NDSEVNQShjaGlsZCwgInJlZGVmaW5lIikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJICAgIGFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHsKCSAgICB0bXBPbGRFcnJzID0gY3R4dC0+bmJlcnJvcnM7CgkgICAgcmVzID0geG1sU2NoZW1hUGFyc2VJbXBvcnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgSEZBSUxVUkU7CgkgICAgSFNUT1AoY3R4dCk7CgkgICAgaWYgKHRtcE9sZEVycnMgIT0gY3R4dC0+bmJlcnJvcnMpCgkJZ290byBleGl0OwkgICAgCgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgewoJICAgIHRtcE9sZEVycnMgPSBjdHh0LT5uYmVycm9yczsKCSAgICByZXMgPSB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgSEZBSUxVUkU7CgkgICAgSFNUT1AoY3R4dCk7CgkgICAgaWYgKHRtcE9sZEVycnMgIT0gY3R4dC0+bmJlcnJvcnMpCgkJZ290byBleGl0OwkgICAgCgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlZGVmaW5lIikpIHsKCSAgICB0bXBPbGRFcnJzID0gY3R4dC0+bmJlcnJvcnM7CgkgICAgcmVzID0geG1sU2NoZW1hUGFyc2VSZWRlZmluZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBIRkFJTFVSRTsKCSAgICBIU1RPUChjdHh0KTsKCSAgICBpZiAodG1wT2xkRXJycyAhPSBjdHh0LT5uYmVycm9ycykKCQlnb3RvIGV4aXQ7Cgl9CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgLyoKICAgICogVVJHRU5UIFRPRE86IENoYW5nZSB0aGUgZnVuY3Rpb25zIHRvIHJldHVybiBpbnQgcmVzdWx0cy4KICAgICogV2UgbmVlZCBlc3BlY2lhbGx5IHRvIGNhdGNoIGludGVybmFsIGVycm9ycy4KICAgICovCiAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgTlVMTCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUdsb2JhbEF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cERlZmluaXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZmluaXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibm90YXRpb24iKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBjaGlsZC0+cGFyZW50LCBjaGlsZCwKCQlOVUxMLCAiKChpbmNsdWRlIHwgaW1wb3J0IHwgcmVkZWZpbmUgfCBhbm5vdGF0aW9uKSosICIKCQkiKCgoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlIHwgZ3JvdXAgfCBhdHRyaWJ1dGVHcm91cCkgIgoJCSJ8IGVsZW1lbnQgfCBhdHRyaWJ1dGUgfCBub3RhdGlvbiksIGFubm90YXRpb24qKSopIik7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICAvKgoJICAgICogVE9ETzogV2Ugc2hvdWxkIGFkZCBhbGwgYW5ub3RhdGlvbnMuCgkgICAgKi8KCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KZXhpdDoKICAgIGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKICAgIGlmIChvbGRFcnJzICE9IGN0eHQtPm5iZXJyb3JzKQoJcmVzID0gY3R4dC0+ZXJyOwogICAgcmV0dXJuKHJlcyk7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0cgp4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbkNyZWF0ZSh2b2lkKQp7CiAgICB4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSByZWxhdGlvbiIsIE5VTEwpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uKSk7CiAgICByZXR1cm4ocmV0KTsKfQoKI2lmIDAKc3RhdGljIHZvaWQKeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25GcmVlKHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbCkKewogICAgeG1sRnJlZShyZWwpOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVkZWZMaXN0RnJlZSh4bWxTY2hlbWFSZWRlZlB0ciByZWRlZikKewogICAgeG1sU2NoZW1hUmVkZWZQdHIgcHJldjsKCiAgICB3aGlsZSAocmVkZWYgIT0gTlVMTCkgewoJcHJldiA9IHJlZGVmOwoJcmVkZWYgPSByZWRlZi0+bmV4dDsKCXhtbEZyZWUocHJldik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRGcmVlKHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIgY29uKQp7CiAgICAvKgogICAgKiBBZnRlciB0aGUgY29uc3RydWN0aW9uIGNvbnRleHQgaGFzIGJlZW4gZnJlZWQsIHRoZXJlIHdpbGwgYmUKICAgICogbm8gc2NoZW1hIGdyYXBoIGF2YWlsYWJsZSBhbnkgbW9yZS4gT25seSB0aGUgc2NoZW1hIGJ1Y2tldHMKICAgICogd2lsbCBzdGF5IGFsaXZlLCB3aGljaCBhcmUgcHV0IGludG8gdGhlICJzY2hlbWFzSW1wb3J0cyIgYW5kCiAgICAqICJpbmNsdWRlcyIgc2xvdHMgb2YgdGhlIHhtbFNjaGVtYS4KICAgICovCiAgICBpZiAoY29uLT5idWNrZXRzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoY29uLT5idWNrZXRzKTsKICAgIGlmIChjb24tPnBlbmRpbmcgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjb24tPnBlbmRpbmcpOwogICAgaWYgKGNvbi0+c3Vic3RHcm91cHMgIT0gTlVMTCkKCXhtbEhhc2hGcmVlKGNvbi0+c3Vic3RHcm91cHMsCgkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hU3Vic3RHcm91cEZyZWUpOwogICAgaWYgKGNvbi0+cmVkZWZzICE9IE5VTEwpCgl4bWxTY2hlbWFSZWRlZkxpc3RGcmVlKGNvbi0+cmVkZWZzKTsKICAgIGlmIChjb24tPmRpY3QgIT0gTlVMTCkKCXhtbERpY3RGcmVlKGNvbi0+ZGljdCk7CiAgICB4bWxGcmVlKGNvbik7Cn0KCnN0YXRpYyB4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0UHRyIAp4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0Q3JlYXRlKHhtbERpY3RQdHIgZGljdCkKewogICAgeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dFB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCSAgICAiYWxsb2NhdGluZyBzY2hlbWEgY29uc3RydWN0aW9uIGNvbnRleHQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHQpKTsKCiAgICByZXQtPmJ1Y2tldHMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+YnVja2V0cyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgbGlzdCBvZiBzY2hlbWEgYnVja2V0cyIsIE5VTEwpOwoJeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnBlbmRpbmcgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+cGVuZGluZyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkgICAgImFsbG9jYXRpbmcgbGlzdCBvZiBwZW5kaW5nIGdsb2JhbCBjb21wb25lbnRzIiwgTlVMTCk7Cgl4bWxTY2hlbWFDb25zdHJ1Y3Rpb25DdHh0RnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPmRpY3QgPSBkaWN0OwogICAgeG1sRGljdFJlZmVyZW5jZShkaWN0KTsKICAgIHJldHVybihyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKHZvaWQpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUjsKICAgIHJldC0+YXR0clByb2hpYnMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgaWYgKHJldC0+YXR0clByb2hpYnMgPT0gTlVMTCkgewoJeG1sRnJlZShyZXQpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgcmV0dXJuKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqIEBkaWN0OiB0aGUgZGljdGlvbmFyeSB0byBiZSB1c2VkCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KGNvbnN0IGNoYXIgKlVSTCwgeG1sRGljdFB0ciBkaWN0KQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpICAgICAgICAKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0LT5kaWN0ID0gZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UoZGljdCk7ICAgIAogICAgaWYgKFVSTCAhPSBOVUxMKQoJcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKGRpY3QsIChjb25zdCB4bWxDaGFyICopIFVSTCwgLTEpOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGlmICh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgewogICAgICAgIGlmICh2Y3R4dC0+c2NoZW1hICE9IE5VTEwpCgkgICAgdmN0eHQtPnBjdHh0ID0KCQl4bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdCgiKiIsIHZjdHh0LT5zY2hlbWEtPmRpY3QpOwoJZWxzZQoJICAgIHZjdHh0LT5wY3R4dCA9IHhtbFNjaGVtYU5ld1BhcnNlckN0eHQoIioiKTsKCWlmICh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCIsCgkJImZhaWxlZCB0byBjcmVhdGUgYSB0ZW1wLiBwYXJzZXIgY29udGV4dCIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyogVE9ETzogUGFzcyB1c2VyIGRhdGEuICovCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnModmN0eHQtPnBjdHh0LCB2Y3R4dC0+ZXJyb3IsCgkgICAgdmN0eHQtPndhcm5pbmcsIHZjdHh0LT5lcnJDdHh0KTsKCXhtbFNjaGVtYVNldFBhcnNlclN0cnVjdHVyZWRFcnJvcnModmN0eHQtPnBjdHh0LCB2Y3R4dC0+c2Vycm9yLAoJICAgIHZjdHh0LT5lcnJDdHh0KTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRTY2hlbWFCdWNrZXQ6CiAqIEBwY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hTG9jYXRpb246IHRoZSBVUkkgb2YgdGhlIHNjaGVtYSBkb2N1bWVudAogKgogKiBSZXR1cm5zIGEgc2NoZW1hIGJ1Y2tldCBpZiBpdCB3YXMgYWxyZWFkeSBwYXJzZWQuCiAqCiAqIFJldHVybnMgYSBzY2hlbWEgYnVja2V0IGlmIGl0IHdhcyBhbHJlYWR5IHBhcnNlZCBmcm9tCiAqICAgICAgICAgQHNjaGVtYUxvY2F0aW9uLCBOVUxMIG90aGVyd2lzZS4KICovCnN0YXRpYyB4bWxTY2hlbWFCdWNrZXRQdHIKeG1sU2NoZW1hR2V0U2NoZW1hQnVja2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbikKewogICAgeG1sU2NoZW1hQnVja2V0UHRyIGN1cjsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3Q7CgogICAgbGlzdCA9IHBjdHh0LT5jb25zdHJ1Y3Rvci0+YnVja2V0czsKICAgIGlmIChsaXN0LT5uYkl0ZW1zID09IDApCglyZXR1cm4oTlVMTCk7CiAgICBlbHNlIHsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJICAgIGN1ciA9ICh4bWxTY2hlbWFCdWNrZXRQdHIpIGxpc3QtPml0ZW1zW2ldOwoJICAgIC8qIFBvaW50ZXIgY29tcGFyaXNvbiEgKi8KCSAgICBpZiAoY3VyLT5zY2hlbWFMb2NhdGlvbiA9PSBzY2hlbWFMb2NhdGlvbikKCQlyZXR1cm4oY3VyKTsKCX0KICAgIH0KICAgIHJldHVybihOVUxMKTsKfQoKc3RhdGljIHhtbFNjaGVtYUJ1Y2tldFB0cgp4bWxTY2hlbWFHZXRDaGFtZWxlb25TY2hlbWFCdWNrZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24sCgkJCQkgICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQnVja2V0UHRyIGN1cjsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3Q7CgogICAgbGlzdCA9IHBjdHh0LT5jb25zdHJ1Y3Rvci0+YnVja2V0czsKICAgIGlmIChsaXN0LT5uYkl0ZW1zID09IDApCglyZXR1cm4oTlVMTCk7CiAgICBlbHNlIHsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJICAgIGN1ciA9ICh4bWxTY2hlbWFCdWNrZXRQdHIpIGxpc3QtPml0ZW1zW2ldOwoJICAgIC8qIFBvaW50ZXIgY29tcGFyaXNvbiEgKi8KCSAgICBpZiAoKGN1ci0+b3JpZ1RhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSAmJgoJCShjdXItPnNjaGVtYUxvY2F0aW9uID09IHNjaGVtYUxvY2F0aW9uKSAmJgoJCShjdXItPnRhcmdldE5hbWVzcGFjZSA9PSB0YXJnZXROYW1lc3BhY2UpKQoJCXJldHVybihjdXIpOwoJfQogICAgfQogICAgcmV0dXJuKE5VTEwpOwp9CgoKI2RlZmluZSBJU19CQURfU0NIRU1BX0RPQyhiKSBcCiAgICAoKChiKS0+ZG9jID09IE5VTEwpICYmICgoYiktPnNjaGVtYUxvY2F0aW9uICE9IE5VTEwpKQoKc3RhdGljIHhtbFNjaGVtYUJ1Y2tldFB0cgp4bWxTY2hlbWFHZXRTY2hlbWFCdWNrZXRCeVROUyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSwKCQkJCSBpbnQgaW1wb3J0ZWQpCnsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBjdXI7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0OwoKICAgIGxpc3QgPSBwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldHM7CiAgICBpZiAobGlzdC0+bmJJdGVtcyA9PSAwKQoJcmV0dXJuKE5VTEwpOwogICAgZWxzZSB7CglpbnQgaTsKCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5uYkl0ZW1zOyBpKyspIHsKCSAgICBjdXIgPSAoeG1sU2NoZW1hQnVja2V0UHRyKSBsaXN0LT5pdGVtc1tpXTsKCSAgICBpZiAoKCEgSVNfQkFEX1NDSEVNQV9ET0MoY3VyKSkgJiYKCQkoY3VyLT5vcmlnVGFyZ2V0TmFtZXNwYWNlID09IHRhcmdldE5hbWVzcGFjZSkgJiYKCQkoKGltcG9ydGVkICYmIGN1ci0+aW1wb3J0ZWQpIHx8CgkJICgoIWltcG9ydGVkKSAmJiAoIWN1ci0+aW1wb3J0ZWQpKSkpCgkJcmV0dXJuKGN1cik7Cgl9CiAgICB9CiAgICByZXR1cm4oTlVMTCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VOZXdEb2NXaXRoQ29udGV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQpCnsKICAgIGludCBvbGRGbGFnczsKICAgIHhtbERvY1B0ciBvbGREb2M7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBpbnQgcmV0LCBvbGRFcnJzOwogICAgeG1sU2NoZW1hQnVja2V0UHRyIG9sZGJ1Y2tldCA9IHBjdHh0LT5jb25zdHJ1Y3Rvci0+YnVja2V0OwogICAgCiAgICAvKiAKICAgICogU2F2ZSBvbGQgdmFsdWVzOyByZXNldCB0aGUgKm1haW4qIHNjaGVtYS4KICAgICogVVJHRU5UIFRPRE86IFRoaXMgaXMgbm90IGdvb2Q7IG1vdmUgdGhlIHBlci1kb2N1bWVudCBpbmZvcm1hdGlvbgogICAgKiB0byB0aGUgcGFyc2VyLiBHZXQgcmlkIG9mIHBhc3NpbmcgdGhlIG1haW4gc2NoZW1hIHRvIHRoZQogICAgKiBwYXJzaW5nIGZ1bmN0aW9ucy4KICAgICovCiAgICBvbGRGbGFncyA9IHNjaGVtYS0+ZmxhZ3M7CiAgICBvbGREb2MgPSBzY2hlbWEtPmRvYzsKICAgIGlmIChzY2hlbWEtPmZsYWdzICE9IDApCgl4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHNjaGVtYSk7CiAgICBzY2hlbWEtPmRvYyA9IGJ1Y2tldC0+ZG9jOyAgICAKICAgIHBjdHh0LT5zY2hlbWEgPSBzY2hlbWE7CiAgICAvKiAKICAgICogS2VlcCB0aGUgY3VycmVudCB0YXJnZXQgbmFtZXNwYWNlIG9uIHRoZSBwYXJzZXIgKm5vdCogb24gdGhlCiAgICAqIG1haW4gc2NoZW1hLgogICAgKi8KICAgIHBjdHh0LT50YXJnZXROYW1lc3BhY2UgPSBidWNrZXQtPnRhcmdldE5hbWVzcGFjZTsKICAgIFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCA9IGJ1Y2tldDsKCiAgICBpZiAoKGJ1Y2tldC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpICYmCgl4bWxTdHJFcXVhbChidWNrZXQtPnRhcmdldE5hbWVzcGFjZSwgeG1sU2NoZW1hTnMpKSB7CgkvKgoJKiBXZSBhcmUgcGFyc2luZyB0aGUgc2NoZW1hIGZvciBzY2hlbWFzIQoJKi8KCXBjdHh0LT5pc1M0UyA9IDE7CiAgICB9ICAgIAogICAgLyogTWFyayBpdCBhcyBwYXJzZWQsIGV2ZW4gaWYgcGFyc2luZyBmYWlscy4gKi8KICAgIGJ1Y2tldC0+cGFyc2VkKys7CiAgICAvKiBDb21waWxlIHRoZSBzY2hlbWEgZG9jLiAqLwogICAgbm9kZSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGJ1Y2tldC0+ZG9jKTsKICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlU2NoZW1hRWxlbWVudChwY3R4dCwgc2NoZW1hLCBub2RlKTsKICAgIGlmIChyZXQgIT0gMCkKCWdvdG8gZXhpdDsKICAgIC8qIEFuIGVtcHR5IHNjaGVtYTsganVzdCBnZXQgb3V0LiAqLwogICAgaWYgKG5vZGUtPmNoaWxkcmVuID09IE5VTEwpCglnb3RvIGV4aXQ7CiAgICBvbGRFcnJzID0gcGN0eHQtPm5iZXJyb3JzOwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgc2NoZW1hLCBub2RlLT5jaGlsZHJlbik7CiAgICBpZiAocmV0ICE9IDApCglnb3RvIGV4aXQ7CiAgICAvKgogICAgKiBUT0RPOiBOb3QgbmljZSwgYnV0IEknbSBub3QgMTAwJSBzdXJlIHdlIHdpbGwgZ2V0IGFsd2F5cyBhbiBlcnJvcgogICAgKiBhcyBhIHJlc3VsdCBvZiB0aGUgb2JvdmUgZnVuY3Rpb25zOyBzbyBiZXR0ZXIgcmVseSBvbiBwY3R4dC0+ZXJyCiAgICAqIGFzIHdlbGwuCiAgICAqLwogICAgaWYgKChyZXQgPT0gMCkgJiYgKG9sZEVycnMgIT0gcGN0eHQtPm5iZXJyb3JzKSkgewoJcmV0ID0gcGN0eHQtPmVycjsKCWdvdG8gZXhpdDsKICAgIH0KICAgIApleGl0OgogICAgV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+YnVja2V0ID0gb2xkYnVja2V0OwogICAgLyogUmVzdG9yZSBzY2hlbWEgdmFsdWVzLiAqLwogICAgc2NoZW1hLT5kb2MgPSBvbGREb2M7CiAgICBzY2hlbWEtPmZsYWdzID0gb2xkRmxhZ3M7CiAgICByZXR1cm4ocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZU5ld0RvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgbmV3cGN0eHQ7CiAgICBpbnQgcmVzID0gMDsKCiAgICBpZiAoYnVja2V0ID09IE5VTEwpCglyZXR1cm4oMCk7CiAgICBpZiAoYnVja2V0LT5wYXJzZWQpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlTmV3RG9jIiwKCSAgICAicmVwYXJzaW5nIGEgc2NoZW1hIGRvYyIpOwoJcmV0dXJuKC0xKTsKICAgIH0KICAgIGlmIChidWNrZXQtPmRvYyA9PSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFQYXJzZU5ld0RvYyIsCgkgICAgInBhcnNpbmcgYSBzY2hlbWEgZG9jLCBidXQgdGhlcmUncyBubyBkb2MiKTsKCXJldHVybigtMSk7CiAgICB9CiAgICBpZiAocGN0eHQtPmNvbnN0cnVjdG9yID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlTmV3RG9jIiwKCSAgICAibm8gY29uc3RydWN0b3IiKTsKCXJldHVybigtMSk7CiAgICB9ICAgIAogICAgLyogQ3JlYXRlIGFuZCBpbml0IHRoZSB0ZW1wb3JhcnkgcGFyc2VyIGNvbnRleHQuICovCiAgICBuZXdwY3R4dCA9IHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KAoJKGNvbnN0IGNoYXIgKikgYnVja2V0LT5zY2hlbWFMb2NhdGlvbiwgcGN0eHQtPmRpY3QpOwogICAgaWYgKG5ld3BjdHh0ID09IE5VTEwpCglyZXR1cm4oLTEpOwogICAgbmV3cGN0eHQtPmNvbnN0cnVjdG9yID0gcGN0eHQtPmNvbnN0cnVjdG9yOwogICAgLyoKICAgICogVE9ETzogQ2FuIHdlIGF2b2lkIHRoYXQgdGhlIHBhcnNlciBrbm93cyBhYm91dCB0aGUgbWFpbiBzY2hlbWE/IAogICAgKiBJdCB3b3VsZCBiZSBiZXR0ZXIgaWYgaGUga25vd3MgYWJvdXQgdGhlIGN1cnJlbnQgc2NoZW1hIGJ1Y2tldAogICAgKiBvbmx5LgogICAgKi8KICAgIG5ld3BjdHh0LT5zY2hlbWEgPSBzY2hlbWE7CiAgICB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMobmV3cGN0eHQsIHBjdHh0LT5lcnJvciwgcGN0eHQtPndhcm5pbmcsCglwY3R4dC0+ZXJyQ3R4dCk7CiAgICB4bWxTY2hlbWFTZXRQYXJzZXJTdHJ1Y3R1cmVkRXJyb3JzKG5ld3BjdHh0LCBwY3R4dC0+c2Vycm9yLAoJcGN0eHQtPmVyckN0eHQpOwogICAgbmV3cGN0eHQtPmNvdW50ZXIgPSBwY3R4dC0+Y291bnRlcjsKICAgIAoKICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlTmV3RG9jV2l0aENvbnRleHQobmV3cGN0eHQsIHNjaGVtYSwgYnVja2V0KTsKICAgIAogICAgLyogQ2hhbm5lbCBiYWNrIGVycm9ycyBhbmQgY2xlYW51cCB0aGUgdGVtcG9yYXJ5IHBhcnNlciBjb250ZXh0LiAqLwogICAgaWYgKHJlcyAhPSAwKQoJcGN0eHQtPmVyciA9IHJlczsKICAgIHBjdHh0LT5uYmVycm9ycyArPSBuZXdwY3R4dC0+bmJlcnJvcnM7CiAgICBwY3R4dC0+Y291bnRlciA9IG5ld3BjdHh0LT5jb3VudGVyOwogICAgbmV3cGN0eHQtPmNvbnN0cnVjdG9yID0gTlVMTDsgICAgCiAgICAvKiBGcmVlIHRoZSBwYXJzZXIgY29udGV4dC4gKi8KICAgIHhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld3BjdHh0KTsKICAgIHJldHVybihyZXMpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTY2hlbWFSZWxhdGlvbkFkZENoaWxkKHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQsCgkJCQl4bWxTY2hlbWFTY2hlbWFSZWxhdGlvblB0ciByZWwpCnsKICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIGN1ciA9IGJ1Y2tldC0+cmVsYXRpb25zOwoKICAgIGlmIChjdXIgPT0gTlVMTCkgewoJYnVja2V0LT5yZWxhdGlvbnMgPSByZWw7CglyZXR1cm47CiAgICB9CiAgICB3aGlsZSAoY3VyLT5uZXh0ICE9IE5VTEwpCgljdXIgPSBjdXItPm5leHQ7CiAgICBjdXItPm5leHQgPSByZWw7Cn0KCgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUJ1aWxkQWJzb2x1dGVVUkkoeG1sRGljdFB0ciBkaWN0LCBjb25zdCB4bWxDaGFyKiBsb2NhdGlvbiwKCQkJICB4bWxOb2RlUHRyIGN0eHROb2RlKQp7ICAgIAogICAgLyoKICAgICogQnVpbGQgYW4gYWJzb2x1ZSBsb2NhdGlvbiBVUkkuCiAgICAqLwogICAgaWYgKGxvY2F0aW9uICE9IE5VTEwpIHsJCglpZiAoY3R4dE5vZGUgPT0gTlVMTCkKCSAgICByZXR1cm4obG9jYXRpb24pOwoJZWxzZSB7CgkgICAgeG1sQ2hhciAqYmFzZSwgKlVSSTsKCSAgICBjb25zdCB4bWxDaGFyICpyZXQgPSBOVUxMOwoKCSAgICBiYXNlID0geG1sTm9kZUdldEJhc2UoY3R4dE5vZGUtPmRvYywgY3R4dE5vZGUpOwoJICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQlVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgY3R4dE5vZGUtPmRvYy0+VVJMKTsKCSAgICB9IGVsc2UgewoJCVVSSSA9IHhtbEJ1aWxkVVJJKGxvY2F0aW9uLCBiYXNlKTsKCQl4bWxGcmVlKGJhc2UpOwoJICAgIH0KCSAgICBpZiAoVVJJICE9IE5VTEwpIHsKCQlyZXQgPSB4bWxEaWN0TG9va3VwKGRpY3QsIFVSSSwgLTEpOwoJCXhtbEZyZWUoVVJJKTsKCQlyZXR1cm4ocmV0KTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4oTlVMTCk7Cn0KICAgIAoKCi8qKgogKiB4bWxTY2hlbWFBZGRTY2hlbWFEb2M6CiAqIEBwY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlIGFuIGluY2x1ZGVkIChhbmQgdG8tYmUtcmVkZWZpbmVkKSBYTUwgc2NoZW1hIGRvY3VtZW50LgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGVycm9ycyBhbmQKICogICAgICAgICAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCgpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZFNjaGVtYURvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCWludCB0eXBlLCAvKiBpbXBvcnQgb3IgaW5jbHVkZSBvciByZWRlZmluZSAqLwoJCWNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uLAoJCXhtbERvY1B0ciBzY2hlbWFEb2MsCgkJY29uc3QgY2hhciAqc2NoZW1hQnVmZmVyLAoJCWludCBzY2hlbWFCdWZmZXJMZW4sCgkJeG1sTm9kZVB0ciBpbnZva2luZ05vZGUsCgkJY29uc3QgeG1sQ2hhciAqc291cmNlVGFyZ2V0TmFtZXNwYWNlLAkJCgkJY29uc3QgeG1sQ2hhciAqaW1wb3J0TmFtZXNwYWNlLAkKCQl4bWxTY2hlbWFCdWNrZXRQdHIgKmJ1Y2tldCkKewogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlID0gTlVMTDsKICAgIHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uUHRyIHJlbGF0aW9uID0gTlVMTDsKICAgIHhtbERvY1B0ciBkb2MgPSBOVUxMOwogICAgaW50IHJlcyA9IDAsIGVyciA9IDAsIGxvY2F0ZWQgPSAwLCBwcmVzZXJ2ZURvYyA9IDA7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgYmt0ID0gTlVMTDsKCiAgICBpZiAoYnVja2V0ICE9IE5VTEwpCgkqYnVja2V0ID0gTlVMTDsKICAgIAogICAgc3dpdGNoICh0eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVDoKCWNhc2UgWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTjoKCSAgICBlcnIgPSBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1NDSEVNQV9JTkNMVURFOgoJICAgIGVyciA9IFhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1NDSEVNQV9SRURFRklORToKCSAgICBlcnIgPSBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkU7CgkgICAgYnJlYWs7CiAgICB9ICAgIAogICAgICAgCgogICAgLyogU3BlY2lhbCBoYW5kbGluZyBmb3IgdGhlIG1haW4gc2NoZW1hOgogICAgKiBza2lwIHRoZSBsb2NhdGlvbiBhbmQgcmVsYXRpb24gbG9naWMgYW5kIGp1c3QgcGFyc2UgdGhlIGRvYy4KICAgICogV2UgbmVlZCBqdXN0IGEgYnVja2V0IHRvIGJlIHJldHVybmVkIGluIHRoaXMgY2FzZS4KICAgICovICAgIAogICAgaWYgKCh0eXBlID09IFhNTF9TQ0hFTUFfU0NIRU1BX01BSU4pIHx8ICghIFdYU19IQVNfQlVDS0VUUyhwY3R4dCkpKQoJZ290byBkb2NfbG9hZDsJCgogICAgLyogTm90ZSB0aGF0IHdlIGV4cGVjdCB0aGUgbG9jYXRpb24gdG8gYmUgYW4gYWJzdWx1dGUgVVJJLiAqLyAKICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7Cglia3QgPSB4bWxTY2hlbWFHZXRTY2hlbWFCdWNrZXQocGN0eHQsIHNjaGVtYUxvY2F0aW9uKTsKCWlmICgoYmt0ICE9IE5VTEwpICYmCgkgICAgKHBjdHh0LT5jb25zdHJ1Y3Rvci0+YnVja2V0ID09IGJrdCkpIHsKCSAgICAvKiBSZXBvcnQgc2VsZi1pbXBvcnRzL2luY2x1c2lvbnMvcmVkZWZpbml0aW9ucy4gKi8KCSAgICAKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgZXJyLAoJCWludm9raW5nTm9kZSwgTlVMTCwKCQkiVGhlIHNjaGVtYSBtdXN0IG5vdCBpbXBvcnQvaW5jbHVkZS9yZWRlZmluZSBpdHNlbGYiLAoJCU5VTEwsIE5VTEwpOwoJICAgIGdvdG8gZXhpdDsKCX0KICAgIH0KICAgIC8qCiAgICAqIENyZWF0ZSBhIHJlbGF0aW9uIGZvciB0aGUgZ3JhcGggb2Ygc2NoZW1hcy4KICAgICovCiAgICByZWxhdGlvbiA9IHhtbFNjaGVtYVNjaGVtYVJlbGF0aW9uQ3JlYXRlKCk7CiAgICBpZiAocmVsYXRpb24gPT0gTlVMTCkKCXJldHVybigtMSk7ICAgIAogICAgeG1sU2NoZW1hU2NoZW1hUmVsYXRpb25BZGRDaGlsZChwY3R4dC0+Y29uc3RydWN0b3ItPmJ1Y2tldCwKCXJlbGF0aW9uKTsKICAgIHJlbGF0aW9uLT50eXBlID0gdHlwZTsKCiAgICAvKgogICAgKiBTYXZlIHRoZSBuYW1lc3BhY2UgaW1wb3J0IGluZm9ybWF0aW9uLgogICAgKi8KICAgIGlmIChXWFNfSVNfQlVDS0VUX0lNUE1BSU4odHlwZSkpIHsKCXJlbGF0aW9uLT5pbXBvcnROYW1lc3BhY2UgPSBpbXBvcnROYW1lc3BhY2U7CQoJaWYgKHNjaGVtYUxvY2F0aW9uID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogTm8gbG9jYXRpb247IHRoaXMgaXMganVzdCBhbiBpbXBvcnQgb2YgdGhlIG5hbWVzcGFjZS4KCSAgICAqIE5vdGUgdGhhdCB3ZSBkb24ndCBhc3NpZ24gYSBidWNrZXQgdG8gdGhlIHJlbGF0aW9uCgkgICAgKiBpbiB0aGlzIGNhc2UuCgkgICAgKi8KCSAgICBnb3RvIGV4aXQ7Cgl9Cgl0YXJnZXROYW1lc3BhY2UgPSBpbXBvcnROYW1lc3BhY2U7CiAgICB9CgogICAgLyogRGlkIHdlIGFscmVhZHkgZmV0Y2ggdGhlIGRvYz8gKi8KICAgIGlmIChia3QgIT0gTlVMTCkgewkJCgkvKiBUT0RPOiBUaGUgZm9sbG93aW5nIG5hc3R5IGNhc2VzIHdpbGwgcHJvZHVjZSBhbiBlcnJvci4gKi8KCWlmICgoV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHR5cGUpKSAmJiAoISBia3QtPmltcG9ydGVkKSkgewoJICAgIC8qIFdlIGluY2x1ZGVkL3JlZGVmaW5lZCBhbmQgdGhlbiB0cnkgdG8gaW1wb3J0IGEgc2NoZW1hLiAqLwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LCBlcnIsCgkJaW52b2tpbmdOb2RlLCBOVUxMLAoJCSJUaGUgc2NoZW1hIGRvY3VtZW50ICclcycgY2Fubm90IGJlIGltcG9ydGVkLCBzaW5jZSAiCgkJIml0IHdhcyBhbHJlYWR5IGluY2x1ZGVkIG9yIHJlZGVmaW5lZCIsCgkJc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoJICAgIGdvdG8gZXhpdDsKCX0gZWxzZSBpZiAoKCEgV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHR5cGUpKSAmJiAoYmt0LT5pbXBvcnRlZCkpIHsKCSAgICAvKiBXZSBpbXBvcnRlZCBhbmQgdGhlbiB0cnkgdG8gaW5jbHVkZS9yZWRlZmluZSBhIHNjaGVtYS4gKi8KCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgZXJyLAoJCWludm9raW5nTm9kZSwgTlVMTCwKCQkiVGhlIHNjaGVtYSBkb2N1bWVudCAnJXMnIGNhbm5vdCBiZSBpbmNsdWRlZCBvciAiCgkJInJlZGVmaW5lZCwgc2luY2UgaXQgd2FzIGFscmVhZHkgaW1wb3J0ZWQiLAoJCXNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCSAgICBnb3RvIGV4aXQ7Cgl9CQogICAgfQogICAgCQogICAgaWYgKFdYU19JU19CVUNLRVRfSU1QTUFJTih0eXBlKSkgewoJLyoKCSogR2l2ZW4gdGhhdCB0aGUgc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gaXMgb25seSBhIGhpbnQsIGl0IGlzIG9wZW4KCSogdG8gYXBwbGljYXRpb25zIHRvIGlnbm9yZSBhbGwgYnV0IHRoZSBmaXJzdCA8aW1wb3J0PiBmb3IgYSBnaXZlbgoJKiBuYW1lc3BhY2UsIHJlZ2FyZGxlc3Mgb2YgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHNjaGVtYUxvY2F0aW9uLCBidXQKCSogc3VjaCBhIHN0cmF0ZWd5IHJpc2tzIG1pc3NpbmcgdXNlZnVsIGluZm9ybWF0aW9uIHdoZW4gbmV3CgkqIHNjaGVtYUxvY2F0aW9ucyBhcmUgb2ZmZXJlZC4KCSoKCSogV2Ugd2lsbCB1c2UgdGhlIGZpcnN0IDxpbXBvcnQ+IHRoYXQgY29tZXMgd2l0aCBhIGxvY2F0aW9uLgoJKiBGdXJ0aGVyIDxpbXBvcnQ+cyAqd2l0aCogYSBsb2NhdGlvbiwgd2lsbCByZXN1bHQgaW4gYW4gZXJyb3IuCgkqIFRPRE86IEJldHRlciB3b3VsZCBiZSB0byBqdXN0IHJlcG9ydCBhIHdhcm5pbmcgaGVyZSwgYnV0CgkqIHdlJ2xsIHRyeSBpdCB0aGlzIHdheSB1bnRpbCBzb21lb25lIGNvbXBsYWlucy4KCSoKCSogU2NoZW1hIERvY3VtZW50IExvY2F0aW9uIFN0cmF0ZWd5OgoJKiAzIEJhc2VkIG9uIHRoZSBuYW1lc3BhY2UgbmFtZSwgaWRlbnRpZnkgYW4gZXhpc3Rpbmcgc2NoZW1hIGRvY3VtZW50LAoJKiBlaXRoZXIgYXMgYSByZXNvdXJjZSB3aGljaCBpcyBhbiBYTUwgZG9jdW1lbnQgb3IgYSA8c2NoZW1hPiBlbGVtZW50CgkqIGluZm9ybWF0aW9uIGl0ZW0sIGluIHNvbWUgbG9jYWwgc2NoZW1hIHJlcG9zaXRvcnk7CgkqIDUgQXR0ZW1wdCB0byByZXNvbHZlIHRoZSBuYW1lc3BhY2UgbmFtZSB0byBsb2NhdGUgc3VjaCBhIHJlc291cmNlLgoJKgoJKiBOT1RFOiAoMykgYW5kICg1KSBhcmUgbm90IHN1cHBvcnRlZC4KCSovCQoJaWYgKGJrdCAhPSBOVUxMKSB7CgkgICAgcmVsYXRpb24tPmJ1Y2tldCA9IGJrdDsKCSAgICBnb3RvIGV4aXQ7Cgl9Cglia3QgPSB4bWxTY2hlbWFHZXRTY2hlbWFCdWNrZXRCeVROUyhwY3R4dCwKCSAgICBpbXBvcnROYW1lc3BhY2UsIDEpOwoKCWlmIChia3QgIT0gTlVMTCkgewkgICAgCgkgICAgcmVsYXRpb24tPmJ1Y2tldCA9IGJrdDsKCSAgICBpZiAoYmt0LT5zY2hlbWFMb2NhdGlvbiA9PSBOVUxMKSB7CgkJLyogRmlyc3QgZ2l2ZW4gbG9jYXRpb24gb2YgdGhlIHNjaGVtYTsgbG9hZCB0aGUgZG9jLiAqLwoJCWJrdC0+c2NoZW1hTG9jYXRpb24gPSBzY2hlbWFMb2NhdGlvbjsKCSAgICB9IGVsc2UgewoJCWlmICgheG1sU3RyRXF1YWwoc2NoZW1hTG9jYXRpb24sCgkJICAgIGJrdC0+c2NoZW1hTG9jYXRpb24pKSB7CgkJICAgIC8qCgkJICAgICogQWRkaXRpb25hbCBsb2NhdGlvbiBnaXZlbjsganVzdCBza2lwIGl0LgoJCSAgICAqIFVSR0VOVCBUT0RPOiBXZSBzaG91bGQgcmVwb3J0IGEgd2FybmluZyBoZXJlLgoJCSAgICAqIHJlcyA9IFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlQ7CgkJICAgICovCgkJICAgIHhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJWE1MX1NDSEVNQVBfV0FSTl9TS0lQX1NDSEVNQSwKCQkJaW52b2tpbmdOb2RlLCBOVUxMLAoJCQkiU2tpcHBpbmcgaW1wb3J0IG9mIHNjaGVtYSBsb2NhdGVkIGF0ICclcycgZm9yIHRoZSAiCgkJCSJuYW1lc3BhY2UgJyVzJywgc2luY2UgdGhpcyBuYW1lc3BhY2Ugd2FzIGFscmVhZHkgIgoJCQkiaW1wb3J0ZWQgd2l0aCB0aGUgc2NoZW1hIGxvY2F0ZWQgYXQgJyVzJyIsCgkJCXNjaGVtYUxvY2F0aW9uLCBpbXBvcnROYW1lc3BhY2UsIGJrdC0+c2NoZW1hTG9jYXRpb24pOwoJCX0KCQlnb3RvIGV4aXQ7CgkgICAgfQoJfQkKCS8qIAoJKiBObyBidWNrZXQgKyBmaXJzdCBsb2NhdGlvbjogbG9hZCB0aGUgZG9jIGFuZCBjcmVhdGUgYQoJKiBidWNrZXQuCgkqLwogICAgfSBlbHNlIHsKCS8qIDxpbmNsdWRlPiBhbmQgPHJlZGVmaW5lPiAqLwoJaWYgKGJrdCAhPSBOVUxMKSB7CgkgICAgCSAgICAKCSAgICBpZiAoKGJrdC0+b3JpZ1RhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSAmJgoJCShia3QtPnRhcmdldE5hbWVzcGFjZSAhPSBzb3VyY2VUYXJnZXROYW1lc3BhY2UpKSB7CgkJeG1sU2NoZW1hQnVja2V0UHRyIGNoYW1lbDsKCQkKCQkvKgoJCSogQ2hhbWVsZW9uIGluY2x1ZGUvcmVkZWZpbmU6IHNraXAgbG9hZGluZyBvbmx5IGlmIGl0IHdhcwoJCSogYWxlYWR5IGJ1aWxkIGZvciB0aGUgdGFyZ2V0TmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRpbmcKCQkqIHNjaGVtYS4KCQkqLwoJCS8qCgkJKiBVUkdFTlQgVE9ETzogSWYgdGhlIHNjaGVtYSBpcyBhIGNoYW1lbGVvbi1pbmNsdWRlIHRoZW4gY29weQoJCSogdGhlIGNvbXBvbmVudHMgaW50byB0aGUgaW5jbHVkaW5nIHNjaGVtYSBhbmQgbW9kaWZ5IHRoZQoJCSogdGFyZ2V0TmFtZXNwYWNlIG9mIHRob3NlIGNvbXBvbmVudHMsIGRvIG5vdGhpbmcgb3RoZXJ3aXNlLgoJCSogTk9URTogVGhpcyBpcyBjdXJyZW50bHkgd29ya2VkLWFyb3VuZCBieSBjb21waWxpbmcgdGhlCgkJKiBjaGFtZWxlb24gZm9yIGV2ZXJ5IGRlc3RpbmN0IGluY2x1ZGluZyB0YXJnZXROYW1lc3BhY2U7IHRodXMKCQkqIG5vdCBwZXJmb3JtYW50IGF0IHRoZSBtb21lbnQuCgkJKiBUT0RPOiBDaGVjayB3aGVuIHRoZSBuYW1lc3BhY2UgaW4gd2lsZGNhcmRzIGZvciBjaGFtZWxlb25zCgkJKiBuZWVkcyB0byBiZSBjb252ZXJ0ZWQ6IGJlZm9yZSB3ZSBidWlsdCB3aWxkY2FyZCBpbnRlcnNlY3Rpb25zCgkJKiBvciBhZnRlci4KCQkqICAgQW5zd2VyOiBhZnRlciEKCQkqLwoJCWNoYW1lbCA9IHhtbFNjaGVtYUdldENoYW1lbGVvblNjaGVtYUJ1Y2tldChwY3R4dCwKCQkgICAgc2NoZW1hTG9jYXRpb24sIHNvdXJjZVRhcmdldE5hbWVzcGFjZSk7CgkJaWYgKGNoYW1lbCAhPSBOVUxMKSB7CgkJICAgIC8qIEEgZml0dGluZyBjaGFtZWxlb24gd2FzIGFscmVhZHkgcGFyc2VkOyBOT1AuICovCgkJICAgIHJlbGF0aW9uLT5idWNrZXQgPSBjaGFtZWw7CgkJICAgIGdvdG8gZXhpdDsKCQl9CgkJLyogCgkJKiBXZSBuZWVkIHRvIHBhcnNlIHRoZSBjaGFtZWxlb24gYWdhaW4gZm9yIGEgZGlmZmVyZW50CgkJKiB0YXJnZXROYW1lc3BhY2UuCgkJKiBDSEFNRUxFT04gVE9ETzogT3B0aW1pemUgdGhpcyBieSBvbmx5IHBhcnNpbmcgdGhlCgkJKiBjaGFtZWxlb24gb25jZSwgYW5kIHRoZW4gY29weWluZyB0aGUgY29tcG9uZW50cyB0bwoJCSogdGhlIG5ldyB0YXJnZXROYW1lc3BhY2UuCgkJKi8KCQlia3QgPSBOVUxMOwoJICAgIH0gZWxzZSB7CgkJcmVsYXRpb24tPmJ1Y2tldCA9IGJrdDsKCQlnb3RvIGV4aXQ7CgkgICAgfQkgICAgCgl9CiAgICB9CiAgICBpZiAoKGJrdCAhPSBOVUxMKSAmJiAoYmt0LT5kb2MgIT0gTlVMTCkpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUFkZFNjaGVtYURvYyIsCgkgICAgInRyeWluZyB0byBsb2FkIGEgc2NoZW1hIGRvYywgYnV0IGEgZG9jIGlzIGFscmVhZHkgIgoJICAgICJhc3NpZ25lZCB0byB0aGUgc2NoZW1hIGJ1Y2tldCIpOwoJZ290byBleGl0X2ZhaWx1cmU7CiAgICB9Cgpkb2NfbG9hZDoKICAgIC8qCiAgICAqIExvYWQgdGhlIGRvY3VtZW50LgogICAgKi8KICAgIGlmIChzY2hlbWFEb2MgIT0gTlVMTCkgewoJZG9jID0gc2NoZW1hRG9jOwoJLyogRG9uJyBmcmVlIHRoaXMgb25lLCBzaW5jZSBpdCB3YXMgcHJvdmlkZWQgYnkgdGhlIGNhbGxlci4gKi8KCXByZXNlcnZlRG9jID0gMTsKCS8qIFRPRE86IERvZXMgdGhlIGNvbnRleHQgb3IgdGhlIGRvYyBob2xkIHRoZSBsb2NhdGlvbj8gKi8KCWlmIChzY2hlbWFEb2MtPlVSTCAhPSBOVUxMKQoJICAgIHNjaGVtYUxvY2F0aW9uID0geG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwKCQlzY2hlbWFEb2MtPlVSTCwgLTEpOwoKICAgIH0gZWxzZSBpZiAoKHNjaGVtYUxvY2F0aW9uICE9IE5VTEwpIHx8IChzY2hlbWFCdWZmZXIgIT0gTlVMTCkpIHsKCXhtbFBhcnNlckN0eHRQdHIgcGFyc2VyQ3R4dDsKCglwYXJzZXJDdHh0ID0geG1sTmV3UGFyc2VyQ3R4dCgpOwoJaWYgKHBhcnNlckN0eHQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgInhtbFNjaGVtYUdldERvYywgIgoJCSJhbGxvY2F0aW5nIGEgcGFyc2VyIGNvbnRleHQiLCBOVUxMKTsKCSAgICBnb3RvIGV4aXRfZmFpbHVyZTsKCX0KCWlmICgocGN0eHQtPmRpY3QgIT0gTlVMTCkgJiYgKHBhcnNlckN0eHQtPmRpY3QgIT0gTlVMTCkpIHsKCSAgICAvKgoJICAgICogVE9ETzogRG8gd2UgaGF2ZSB0byBidXJkZW4gdGhlIHNjaGVtYSBwYXJzZXIgZGljdCB3aXRoIGFsbAoJICAgICogdGhlIGNvbnRlbnQgb2YgdGhlIHNjaGVtYSBkb2M/CgkgICAgKi8KCSAgICB4bWxEaWN0RnJlZShwYXJzZXJDdHh0LT5kaWN0KTsKCSAgICBwYXJzZXJDdHh0LT5kaWN0ID0gcGN0eHQtPmRpY3Q7CgkgICAgeG1sRGljdFJlZmVyZW5jZShwYXJzZXJDdHh0LT5kaWN0KTsKCX0KCWlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CgkgICAgLyogUGFyc2UgZnJvbSBmaWxlLiAqLwoJICAgIGRvYyA9IHhtbEN0eHRSZWFkRmlsZShwYXJzZXJDdHh0LCAoY29uc3QgY2hhciAqKSBzY2hlbWFMb2NhdGlvbiwKCQlOVUxMLCBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwoJfSBlbHNlIGlmIChzY2hlbWFCdWZmZXIgIT0gTlVMTCkgewoJICAgIC8qIFBhcnNlIGZyb20gbWVtb3J5IGJ1ZmZlci4gKi8KCSAgICBkb2MgPSB4bWxDdHh0UmVhZE1lbW9yeShwYXJzZXJDdHh0LCBzY2hlbWFCdWZmZXIsIHNjaGVtYUJ1ZmZlckxlbiwKCQlOVUxMLCBOVUxMLCBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwoJICAgIHNjaGVtYUxvY2F0aW9uID0geG1sU3RyZHVwKEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIik7CgkgICAgaWYgKGRvYyAhPSBOVUxMKQoJCWRvYy0+VVJMID0gc2NoZW1hTG9jYXRpb247CSAgICAKCX0KCS8qCgkqIEZvciA8aW1wb3J0PjoKCSogMi4xIFRoZSByZWZlcmVudCBpcyAoYSBmcmFnbWVudCBvZikgYSByZXNvdXJjZSB3aGljaCBpcyBhbgoJKiBYTUwgZG9jdW1lbnQgKHNlZSBjbGF1c2UgMS4xKSwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyB0bwoJKiBhIDxzY2hlbWE+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpbiBhIHdlbGwtZm9ybWVkIGluZm9ybWF0aW9uCgkqIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyB0byBhIHZhbGlkIHNjaGVtYS4KCSogVE9ETzogKDIuMSkgZnJhZ21lbnRzIG9mIFhNTCBkb2N1bWVudHMgYXJlIG5vdCBzdXBwb3J0ZWQuCgkqCgkqIDIuMiBUaGUgcmVmZXJlbnQgaXMgYSA8c2NoZW1hPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaW4KCSogYSB3ZWxsLWZvcm1lZCBpbmZvcm1hdGlvbiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMKCSogdG8gYSB2YWxpZCBzY2hlbWEuCgkqIFRPRE86ICgyLjIpIGlzIG5vdCBzdXBwb3J0ZWQuCgkqLwoJaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sRXJyb3JQdHIgbGVycjsKCSAgICBsZXJyID0geG1sR2V0TGFzdEVycm9yKCk7CgkgICAgLyoKCSAgICAqIENoZWNrIGlmIHRoaXMgYSBwYXJzZXIgZXJyb3IsIG9yIGlmIHRoZSBkb2N1bWVudCBjb3VsZAoJICAgICoganVzdCBub3QgYmUgbG9jYXRlZC4KCSAgICAqIFRPRE86IFRyeSB0byBmaW5kIHNwZWNpZmljIGVycm9yIGNvZGVzIHRvIHJlYWN0IG9ubHkgb24KCSAgICAqIGxvY2FsaXNhdGlvbiBmYWlsdXJlcy4KCSAgICAqLwoJICAgIGlmICgobGVyciA9PSBOVUxMKSB8fCAobGVyci0+ZG9tYWluICE9IFhNTF9GUk9NX0lPKSkgewoJCS8qCgkJKiBXZSBhc3N1bWUgYSBwYXJzZXIgZXJyb3IgaGVyZS4KCQkqLwoJCWxvY2F0ZWQgPSAxOwoJCS8qIFRPRE86IEVycm9yIGNvZGUgPz8gKi8KCQlyZXMgPSBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMTsKCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgcmVzLAoJCSAgICBpbnZva2luZ05vZGUsIE5VTEwsCgkJICAgICJGYWlsZWQgdG8gcGFyc2UgdGhlIFhNTCByZXNvdXJjZSAnJXMnIiwKCQkgICAgc2NoZW1hTG9jYXRpb24sIE5VTEwpOwkJCgkgICAgfQoJfQoJeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CglpZiAoKGRvYyA9PSBOVUxMKSAmJiBsb2NhdGVkKQoJICAgIGdvdG8gZXhpdF9lcnJvcjsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFQX05PVEhJTkdfVE9fUEFSU0UsCgkgICAgIk5vIGluZm9ybWF0aW9uIGZvciBwYXJzaW5nIHdhcyBwcm92aWRlZCB3aXRoIHRoZSAiCgkgICAgImdpdmVuIHNjaGVtYSBwYXJzZXIgY29udGV4dC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7Cglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIH0KICAgIC8qCiAgICAqIFByZXByb2Nlc3MgdGhlIGRvY3VtZW50LgogICAgKi8KICAgIGlmIChkb2MgIT0gTlVMTCkgewoJeG1sTm9kZVB0ciBkb2NFbGVtID0gTlVMTDsKCglsb2NhdGVkID0gMTsJCglkb2NFbGVtID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKCWlmIChkb2NFbGVtID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgWE1MX1NDSEVNQVBfTk9ST09ULAoJCWludm9raW5nTm9kZSwgTlVMTCwgCgkJIlRoZSBkb2N1bWVudCAnJXMnIGhhcyBubyBkb2N1bWVudCBlbGVtZW50IiwKCQlzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJICAgIGRvYyA9IE5VTEw7CgkgICAgZ290byBleGl0X2Vycm9yOwoJfQoJLyoKCSogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2Rlcy4KCSovCgl4bWxTY2hlbWFDbGVhbnVwRG9jKHBjdHh0LCBkb2NFbGVtKTsKCS8qCgkqIENoZWNrIHRoZSBzY2hlbWEncyB0b3AgbGV2ZWwgZWxlbWVudC4KCSovCglpZiAoIUlTX1NDSEVNQShkb2NFbGVtLCAic2NoZW1hIikpIHsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQlpbnZva2luZ05vZGUsIE5VTEwsCgkJIlRoZSBYTUwgZG9jdW1lbnQgJyVzJyBpcyBub3QgYSBzY2hlbWEgZG9jdW1lbnQiLAoJCXNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCSAgICB4bWxGcmVlRG9jKGRvYyk7CgkgICAgZG9jID0gTlVMTDsKCSAgICBnb3RvIGV4aXRfZXJyb3I7Cgl9CgkvKiAKCSogTm90ZSB0aGF0IHdlIGRvbid0IGFwcGx5IGEgdHlwZSBjaGVjayBmb3IgdGhlCgkqIHRhcmdldE5hbWVzcGFjZSB2YWx1ZSBoZXJlLgoJKi8KCXRhcmdldE5hbWVzcGFjZSA9IHhtbFNjaGVtYUdldFByb3AocGN0eHQsIGRvY0VsZW0sCgkgICAgInRhcmdldE5hbWVzcGFjZSIpOwogICAgfQogICAgCi8qIGFmdGVyX2RvY19sb2FkaW5nOiAqLwogICAgaWYgKChia3QgPT0gTlVMTCkgJiYgbG9jYXRlZCkgewoJLyogT25seSBjcmVhdGUgYSBidWNrZXQgaWYgdGhlIHNjaGVtYSB3YXMgbG9jYXRlZC4gKi8KICAgICAgICBia3QgPSB4bWxTY2hlbWFCdWNrZXRDcmVhdGUocGN0eHQsIHR5cGUsCgkgICAgdGFyZ2V0TmFtZXNwYWNlKTsKCWlmIChia3QgPT0gTlVMTCkKCSAgICBnb3RvIGV4aXRfZmFpbHVyZTsKICAgIH0KICAgIGlmIChia3QgIT0gTlVMTCkgewoJYmt0LT5zY2hlbWFMb2NhdGlvbiA9IHNjaGVtYUxvY2F0aW9uOwoJYmt0LT5sb2NhdGVkID0gbG9jYXRlZDsKCWlmIChkb2MgIT0gTlVMTCkgewoJICAgIGJrdC0+ZG9jID0gZG9jOwoJICAgIGJrdC0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwoJICAgIGJrdC0+b3JpZ1RhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKCSAgICBpZiAocHJlc2VydmVEb2MpCgkJYmt0LT5wcmVzZXJ2ZURvYyA9IDE7Cgl9CglpZiAoV1hTX0lTX0JVQ0tFVF9JTVBNQUlOKHR5cGUpKQoJICAgIGJrdC0+aW1wb3J0ZWQrKzsKCSAgICAvKgoJICAgICogQWRkIGl0IHRvIHRoZSBncmFwaCBvZiBzY2hlbWFzLgoJICAgICovCglpZiAocmVsYXRpb24gIT0gTlVMTCkKCSAgICByZWxhdGlvbi0+YnVja2V0ID0gYmt0OwogICAgfQogIApleGl0OgogICAgLyoKICAgICogUmV0dXJuIHRoZSBidWNrZXQgZXhwbGljaXRlbHk7IHRoaXMgaXMgbmVlZGVkIGZvciB0aGUKICAgICogbWFpbiBzY2hlbWEuCiAgICAqLwogICAgaWYgKGJ1Y2tldCAhPSBOVUxMKQoJKmJ1Y2tldCA9IGJrdDsgICAgCiAgICByZXR1cm4gKDApOwoKZXhpdF9lcnJvcjoKICAgIGlmICgoZG9jICE9IE5VTEwpICYmICghIHByZXNlcnZlRG9jKSkgewoJeG1sRnJlZURvYyhkb2MpOwoJaWYgKGJrdCAhPSBOVUxMKQoJICAgIGJrdC0+ZG9jID0gTlVMTDsKICAgIH0KICAgIHJldHVybihwY3R4dC0+ZXJyKTsKCmV4aXRfZmFpbHVyZToKICAgIGlmICgoZG9jICE9IE5VTEwpICYmICghIHByZXNlcnZlRG9jKSkgewoJeG1sRnJlZURvYyhkb2MpOwoJaWYgKGJrdCAhPSBOVUxMKQoJICAgIGJrdC0+ZG9jID0gTlVMTDsKICAgIH0gICAgCiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSW1wb3J0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBJbXBvcnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBpZgogKiBub3QgdmFsaWQgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUgPSBOVUxMLCAqc2NoZW1hTG9jYXRpb24gPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdGhpc1RhcmdldE5hbWVzcGFjZTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hQnVja2V0UHRyIGJ1Y2tldCA9IE5VTEw7CgogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWVzcGFjZSIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHIocGN0eHQsIE5VTEwsIG5vZGUsCgkibmFtZXNwYWNlIiwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSZuYW1lc3BhY2VOYW1lKSAhPSAwKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICBOVUxMLCBuYW1lc3BhY2VOYW1lLCBOVUxMLCBOVUxMLCBOVUxMKTsKCXJldHVybiAocGN0eHQtPmVycik7CiAgICB9CgogICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyKHBjdHh0LCBOVUxMLCBub2RlLAoJInNjaGVtYUxvY2F0aW9uIiwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSZzY2hlbWFMb2NhdGlvbikgIT0gMCkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBOVUxMLCBub2RlLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkgICAgTlVMTCwgbmFtZXNwYWNlTmFtZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKHBjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZSBhbm5vdGF0aW9uIGhlcmUgaXMgc2ltcGx5IGRpc2NhcmRlZCAuLi4KCSAqIFRPRE86IHJlYWxseT8KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICAvKgogICAgKiBBcHBseSBhZGRpdGlvbmFsIGNvbnN0cmFpbnRzLgogICAgKgogICAgKiBOb3RlIHRoYXQgaXQgaXMgaW1wb3J0YW50IHRvIHVzZSB0aGUgb3JpZ2luYWwgQHRhcmdldE5hbWVzcGFjZQogICAgKiAob3Igbm9uZSBhdCBhbGwpLCB0byBydWxlIG91dCBpbXBvcnRzIG9mIHNjaGVtYXMgX3dpdGhfIGEKICAgICogQHRhcmdldE5hbWVzcGFjZSBpZiB0aGUgaW1wb3J0aW5nIHNjaGVtYSBpcyBhIGNoYW1lbGVvbiBzY2hlbWEKICAgICogKHdpdGggbm8gQHRhcmdldE5hbWVzcGFjZSkuCiAgICAqLwogICAgdGhpc1RhcmdldE5hbWVzcGFjZSA9IFdYU19CVUNLRVQocGN0eHQpLT5vcmlnVGFyZ2V0TmFtZXNwYWNlOwogICAgaWYgKG5hbWVzcGFjZU5hbWUgIT0gTlVMTCkgewoJLyoKCSogMS4xIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgcHJlc2VudCwgdGhlbiBpdHMgt2FjdHVhbCB2YWx1ZbcKCSogbXVzdCBub3QgbWF0Y2ggdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBlbmNsb3NpbmcgPHNjaGVtYT4ncwoJKiB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHhtbFN0ckVxdWFsKHRoaXNUYXJnZXROYW1lc3BhY2UsIG5hbWVzcGFjZU5hbWUpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzFfMSwKCQlOVUxMLCBub2RlLAoJCSJUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IG5vdCBtYXRjaCAiCgkJInRoZSB0YXJnZXQgbmFtZXNwYWNlICclcycgb2YgdGhlIGltcG9ydGluZyBzY2hlbWEiLAoJCXRoaXNUYXJnZXROYW1lc3BhY2UpOwoJICAgIHJldHVybiAocGN0eHQtPmVycik7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogMS4yIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgbm90IHByZXNlbnQsIHRoZW4gdGhlIGVuY2xvc2luZwoJKiA8c2NoZW1hPiBtdXN0IGhhdmUgYSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHRoaXNUYXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIsCgkJTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IGJlIGV4aXN0ZW50IGlmICIKCQkidGhlIGltcG9ydGluZyBzY2hlbWEgaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCU5VTEwpOwoJICAgIHJldHVybiAocGN0eHQtPmVycik7Cgl9CiAgICB9CiAgICAvKgogICAgKiBMb2NhdGUgYW5kIGFjcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICBpZiAoc2NoZW1hTG9jYXRpb24gIT0gTlVMTCkKCXNjaGVtYUxvY2F0aW9uID0geG1sU2NoZW1hQnVpbGRBYnNvbHV0ZVVSSShwY3R4dC0+ZGljdCwKCSAgICBzY2hlbWFMb2NhdGlvbiwgbm9kZSk7CiAgICByZXQgPSB4bWxTY2hlbWFBZGRTY2hlbWFEb2MocGN0eHQsIFhNTF9TQ0hFTUFfU0NIRU1BX0lNUE9SVCwKCXNjaGVtYUxvY2F0aW9uLCBOVUxMLCBOVUxMLCAwLCBub2RlLCB0aGlzVGFyZ2V0TmFtZXNwYWNlLAoJbmFtZXNwYWNlTmFtZSwgJmJ1Y2tldCk7CgogICAgaWYgKHJldCAhPSAwKQoJcmV0dXJuKHJldCk7CgogICAgLyoKICAgICogRm9yIDxpbXBvcnQ+OiAiSXQgaXMgKm5vdCogYW4gZXJyb3IgZm9yIHRoZSBhcHBsaWNhdGlvbgogICAgKiBzY2hlbWEgcmVmZXJlbmNlIHN0cmF0ZWd5IHRvIGZhaWwuIgogICAgKiBTbyBqdXN0IGRvbid0IHBhcnNlIGlmIG5vIHNjaGVtYSBkb2N1bWVudCB3YXMgZm91bmQuCiAgICAqIE5vdGUgdGhhdCB3ZSB3aWxsIGdldCBubyBidWNrZXQgaWYgdGhlIHNjaGVtYSBjb3VsZCBub3QgYmUKICAgICogbG9jYXRlZCBvciBpZiB0aGVyZSB3YXMgbm8gc2NoZW1hTG9jYXRpb24uCiAgICAqLwogICAgaWYgKChidWNrZXQgPT0gTlVMTCkgJiYgKHNjaGVtYUxvY2F0aW9uICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFDdXN0b21XYXJuaW5nKEFDVFhUX0NBU1QgcGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfV0FSTl9VTkxPQ0FURURfU0NIRU1BLAoJICAgIG5vZGUsIE5VTEwsCgkgICAgIkZhaWxlZCB0byBsb2NhdGUgYSBzY2hlbWEgYXQgbG9jYXRpb24gJyVzJy4gIgoJICAgICJTa2lwcGluZyB0aGUgaW1wb3J0Iiwgc2NoZW1hTG9jYXRpb24sIE5VTEwsIE5VTEwpOwogICAgfQogICAgCiAgICBpZiAoKGJ1Y2tldCAhPSBOVUxMKSAmJiBDQU5fUEFSU0VfU0NIRU1BKGJ1Y2tldCkpIHsJCglyZXQgPSB4bWxTY2hlbWFQYXJzZU5ld0RvYyhwY3R4dCwgc2NoZW1hLCBidWNrZXQpOwogICAgfQogICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZUF0dHJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCSAgICAgeG1sQ2hhciAqKnNjaGVtYUxvY2F0aW9uLAoJCQkJICAgICBpbnQgdHlwZSkKewogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fAoJKHNjaGVtYUxvY2F0aW9uID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgICpzY2hlbWFMb2NhdGlvbiA9IE5VTEw7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKiBBcHBsaWVzIGZvciBib3RoIDxpbmNsdWRlPiBhbmQgPHJlZGVmaW5lPi4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKHBjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIFByZWxpbWluYXJ5IHN0ZXAsIGV4dHJhY3QgdGhlIFVSSS1SZWZlcmVuY2UgYW5kIG1ha2UgYW4gVVJJCiAgICAqIGZyb20gdGhlIGJhc2UuCiAgICAqLwogICAgLyoKICAgICogQXR0cmlidXRlICJzY2hlbWFMb2NhdGlvbiIgaXMgbWFuZGF0b3J5LgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKICAgICAgICB4bWxDaGFyICp1cmkgPSBOVUxMOwoKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUocGN0eHQsIE5VTEwsIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICAoY29uc3QgeG1sQ2hhciAqKikgc2NoZW1hTG9jYXRpb24pICE9IDApCgkgICAgZ290byBleGl0X2Vycm9yOwoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgdXJpID0geG1sQnVpbGRVUkkoKnNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKCpzY2hlbWFMb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmICh1cmkgPT0gTlVMTCkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUiLAoJCSJjb3VsZCBub3QgYnVpbGQgYW4gVVJJIGZyb20gdGhlIHNjaGVtYUxvY2F0aW9uIikKCSAgICBnb3RvIGV4aXRfZmFpbHVyZTsKCX0KCSgqc2NoZW1hTG9jYXRpb24pID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwgdXJpLCAtMSk7Cgl4bWxGcmVlKHVyaSk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgInNjaGVtYUxvY2F0aW9uIiwgTlVMTCk7Cglnb3RvIGV4aXRfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBSZXBvcnQgc2VsZi1pbmNsdXNpb24gYW5kIHNlbGYtcmVkZWZpbml0aW9uLgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbCgqc2NoZW1hTG9jYXRpb24sIHBjdHh0LT5VUkwpKSB7CglpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9SRURFRklORSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FLAoJCU5VTEwsIG5vZGUsCgkJIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgcmVkZWZpbmUgaXRzZWxmLiIsCgkJKnNjaGVtYUxvY2F0aW9uKTsJICAgIAoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIG5vZGUsCgkJIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgaW5jbHVkZSBpdHNlbGYuIiwKCQkqc2NoZW1hTG9jYXRpb24pOwoJfQoJZ290byBleGl0X2Vycm9yOwogICAgfQogICAgCiAgICByZXR1cm4oMCk7CmV4aXRfZXJyb3I6CiAgICByZXR1cm4ocGN0eHQtPmVycik7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJCWludCB0eXBlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uID0gTlVMTDsKICAgIGludCByZXMgPSAwOyAvKiBoYXNSZWRlZmluaXRpb25zID0gMCAqLwogICAgaW50IGlzQ2hhbWVsZW9uID0gMCwgd2FzQ2hhbWVsZW9uID0gMDsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQgPSBOVUxMOwoKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgKiBQYXJzZSBhdHRyaWJ1dGVzLiBOb3RlIHRoYXQgdGhlIHJldHVybmVkIHNjaGVtYUxvY2F0aW9uIHdpbGwKICAgICogYmUgYWxyZWFkeSBjb252ZXJ0ZWQgdG8gYW4gYWJzb2x1dGUgVVJJLgogICAgKi8KICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmVBdHRycyhwY3R4dCwgc2NoZW1hLAoJbm9kZSwgKHhtbENoYXIgKiopICgmc2NoZW1hTG9jYXRpb24pLCB0eXBlKTsKICAgIGlmIChyZXMgIT0gMCkKCXJldHVybihyZXMpOyAgICAJICAgCiAgICAvKgogICAgKiBMb2FkIGFuZCBhZGQgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFBZGRTY2hlbWFEb2MocGN0eHQsIHR5cGUsIHNjaGVtYUxvY2F0aW9uLCBOVUxMLAoJTlVMTCwgMCwgbm9kZSwgcGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgTlVMTCwgJmJ1Y2tldCk7CiAgICBpZiAocmVzICE9IDApCglyZXR1cm4ocmVzKTsgICAgCiAgICAvKgogICAgKiBJZiB3ZSBnZXQgbm8gc2NoZW1hIGJ1Y2tldCBiYWNrLCB0aGVuIHRoaXMgbWVhbnMgdGhhdCB0aGUgc2NoZW1hCiAgICAqIGRvY3VtZW50IGNvdWxkIG5vdCBiZSBsb2NhdGVkIG9yIHdhcyBicm9rZW4gWE1MIG9yIHdhcyBub3QKICAgICogYSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLyAgICAKICAgIGlmICgoYnVja2V0ID09IE5VTEwpIHx8IChidWNrZXQtPmRvYyA9PSBOVUxMKSkgewoJaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfSU5DTFVERSkgewoJICAgIC8qCgkgICAgKiBXQVJOSU5HIGZvciA8aW5jbHVkZT46CgkgICAgKiBXZSB3aWxsIHJhaXNlIGFuIGVycm9yIGlmIHRoZSBzY2hlbWEgY2Fubm90IGJlIGxvY2F0ZWQKCSAgICAqIGZvciBpbmNsdXNpb25zLCBzaW5jZSB0aGUgdGhhdCB3YXMgdGhlIGZlZWRiYWNrIGZyb20gdGhlCgkgICAgKiBzY2hlbWEgcGVvcGxlLiBJLmUuIHRoZSBmb2xsb3dpbmcgc3BlYyBwaWVjZSB3aWxsICpub3QqIGJlCgkgICAgKiBzYXRpc2ZpZWQ6CgkgICAgKiBTUEVDIHNyYy1pbmNsdWRlOiAiSXQgaXMgbm90IGFuIGVycm9yIGZvciB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlCgkgICAgKiBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSB0byBmYWlsIHRvIHJlc29sdmUgaXQgYWxsLCBpbiB3aGljaAoJICAgICogY2FzZSBubyBjb3JyZXNwb25kaW5nIGluY2x1c2lvbiBpcyBwZXJmb3JtZWQuCgkgICAgKiBTbyBkbyB3ZSBuZWVkIGEgd2FybmluZyByZXBvcnQgaGVyZT8iCgkgICAgKi8KCSAgICByZXMgPSBYTUxfU0NIRU1BUF9TUkNfSU5DTFVERTsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwgcmVzLAoJCW5vZGUsIE5VTEwsCgkJIkZhaWxlZCB0byBsb2FkIHRoZSBkb2N1bWVudCAnJXMnIGZvciBpbmNsdXNpb24iLAoJCXNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIE5PVEU6IFRoaXMgd2FzIGNoYW5nZWQgdG8gcmFpc2UgYW4gZXJyb3IgZXZlbiBpZiBubyByZWRlZmluaXRpb25zCgkgICAgKiBhcmUgc3BlY2lmaWVkLgoJICAgICoKCSAgICAqIFNQRUMgc3JjLXJlZGVmaW5lICgxKQoJICAgICogIklmIHRoZXJlIGFyZSBhbnkgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtcyBhbW9uZyB0aGUgW2NoaWxkcmVuXQoJICAgICogb3RoZXIgdGhhbiA8YW5ub3RhdGlvbj4gdGhlbiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlCgkgICAgKiBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSBtdXN0IHN1Y2Nlc3NmdWxseSByZXNvbHZlLiIKCSAgICAqIFRPRE86IEFzayB0aGUgV0cgaWYgYSB0aGUgbG9jYXRpb24gaGFzIGFsd2F5cyB0byByZXNvbHZlCgkgICAgKiBoZXJlIGFzIHdlbGwhCgkgICAgKi8KCSAgICByZXMgPSBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkU7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsIHJlcywKCQlub2RlLCBOVUxMLAoJCSJGYWlsZWQgdG8gbG9hZCB0aGUgZG9jdW1lbnQgJyVzJyBmb3IgcmVkZWZpbml0aW9uIiwKCQlzY2hlbWFMb2NhdGlvbiwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogQ2hlY2sgdGFyZ2V0TmFtZXNwYWNlIHNhbml0eSBiZWZvcmUgcGFyc2luZyB0aGUgbmV3IHNjaGVtYS4KCSogVE9ETzogTm90ZSB0aGF0IHdlIHdvbid0IGNoZWNrIGZ1cnRoZXIgY29udGVudCBpZiB0aGUKCSogdGFyZ2V0TmFtZXNwYWNlIHdhcyBiYWQuCgkqLyAgICAKCWlmIChidWNrZXQtPm9yaWdUYXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewkgICAgCgkgICAgLyoKCSAgICAqIFNQRUMgc3JjLWluY2x1ZGUgKDIuMSkKCSAgICAqICJTSUkgaGFzIGEgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLCBhbmQgaXRzILdhY3R1YWwKCSAgICAqIHZhbHVltyBpcyBpZGVudGljYWwgdG8gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0YXJnZXROYW1lc3BhY2UKCSAgICAqIFthdHRyaWJ1dGVdIG9mIFNJSZIgKHdoaWNoIG11c3QgaGF2ZSBzdWNoIGFuIFthdHRyaWJ1dGVdKS4iCgkgICAgKi8KCSAgICBpZiAocGN0eHQtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCSAgICBub2RlLCBOVUxMLAoJCSAgICAiVGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGluY2x1ZGVkL3JlZGVmaW5lZCBzY2hlbWEgIgoJCSAgICAiJyVzJyBoYXMgdG8gYmUgYWJzZW50LCBzaW5jZSB0aGUgaW5jbHVkaW5nL3JlZGVmaW5pbmcgIgoJCSAgICAic2NoZW1hIGhhcyBubyB0YXJnZXQgbmFtZXNwYWNlIiwKCQkgICAgc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoJCWdvdG8gZXhpdF9lcnJvcjsKCSAgICB9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChidWNrZXQtPm9yaWdUYXJnZXROYW1lc3BhY2UsCgkJcGN0eHQtPnRhcmdldE5hbWVzcGFjZSkpIHsKCQkvKiBUT0RPOiBDaGFuZ2UgZXJyb3IgZnVuY3Rpb24uICovCgkJeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREUsCgkJICAgIE5VTEwsIG5vZGUsCgkJICAgICJUaGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbmNsdWRlZC9yZWRlZmluZWQgIgoJCSAgICAic2NoZW1hICclcycgZGlmZmVycyBmcm9tICclcycgb2YgdGhlICIKCQkgICAgImluY2x1ZGluZy9yZWRlZmluaW5nIHNjaGVtYSIsCgkJICAgIGJ1Y2tldC0+b3JpZ1RhcmdldE5hbWVzcGFjZSwgc2NoZW1hTG9jYXRpb24sCgkJICAgIHBjdHh0LT50YXJnZXROYW1lc3BhY2UpOwoJCWdvdG8gZXhpdF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UgaWYgKHBjdHh0LT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewkgICAgCgkgICAgLyoKCSAgICAqIENoYW1lbGVvbnM6IHRoZSBvcmlnaW5hbCB0YXJnZXQgbmFtZXNwYWNlIHdpbGwKCSAgICAqIGRpZmZlciBmcm9tIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlLgoJICAgICovCgkgICAgaXNDaGFtZWxlb24gPSAxOwoJICAgIGlmIChidWNrZXQtPnBhcnNlZCAmJgoJCShidWNrZXQtPnRhcmdldE5hbWVzcGFjZSAhPSBwY3R4dC0+dGFyZ2V0TmFtZXNwYWNlKSkgewoJCS8qCgkJKiBUaGlzIGlzIGEgc2FuaXR5IGNoZWNrLCBJIGR1bm5vIHlldCBpZiB0aGlzIGNhbiBoYXBwZW4uCgkJKi8KCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFQYXJzZUluY2x1ZGVPclJlZGVmaW5lIiwKCQkgICAgInRyeWluZyB0byB1c2UgYW4gYWxyZWFkeSBwYXJzZWQgc2NoZW1hIGZvciBhICIKCQkgICAgImRpZmZlcmVudCB0YXJnZXROYW1lc3BhY2UiKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICBidWNrZXQtPnRhcmdldE5hbWVzcGFjZSA9IHBjdHh0LT50YXJnZXROYW1lc3BhY2U7Cgl9CiAgICB9ICAgIAogICAgLyoKICAgICogUGFyc2UgdGhlIHNjaGVtYS4KICAgICovICAgCiAgICBpZiAoYnVja2V0ICYmICghYnVja2V0LT5wYXJzZWQpICYmIChidWNrZXQtPmRvYyAhPSBOVUxMKSkgewoJaWYgKGlzQ2hhbWVsZW9uKSB7CgkgICAgLyogVE9ETzogR2V0IHJpZCBvZiB0aGlzIGZsYWcgb24gdGhlIHNjaGVtYSBpdHNlbGYuICovCgkgICAgaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpID09IDApIHsKCQlzY2hlbWEtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TOwoJICAgIH0gZWxzZQoJCXdhc0NoYW1lbGVvbiA9IDE7Cgl9Cgl4bWxTY2hlbWFQYXJzZU5ld0RvYyhwY3R4dCwgc2NoZW1hLCBidWNrZXQpOwoJLyogUmVzdG9yZSBjaGFtZWxlb24gZmxhZy4gKi8KCWlmIChpc0NoYW1lbGVvbiAmJiAoIXdhc0NoYW1lbGVvbikpCgkgICAgc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47ICAgIAogICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpIHsJCgkvKgoJKiBQYXJzZSAoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlIHwgZ3JvdXAgfCBhdHRyaWJ1dGVHcm91cCkpKgoJKi8KCXBjdHh0LT5yZWRlZmluZWQgPSBidWNrZXQ7CgkvKgoJKiBIb3cgdG8gcHJvY2VlZCBpZiB0aGUgcmVkZWZpbmVkIHNjaGVtYSB3YXMgbm90IGxvY2F0ZWQ/CgkqLwoJcGN0eHQtPmlzUmVkZWZpbmUgPSAxOwoJd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSB8fAoJICAgIElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSB8fAoJICAgIElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikgfHwKCSAgICBJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpIHx8CgkgICAgSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCQkvKgoJCSogVE9ETzogZGlzY2FyZCBvciBub3Q/CgkJKi8KCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShwY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkJeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShwY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkJLyogaGFzUmVkZWZpbml0aW9ucyA9IDE7ICovCgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CQkKCQkvKiBoYXNSZWRlZmluaXRpb25zID0gMTsgKi8KCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uKHBjdHh0LAoJCSAgICBzY2hlbWEsIGNoaWxkKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpIHsKCQkvKiBoYXNSZWRlZmluaXRpb25zID0gMTsgKi8KCQl4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwRGVmaW5pdGlvbihwY3R4dCwgc2NoZW1hLAoJCSAgICBjaGlsZCk7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CglwY3R4dC0+cmVkZWZpbmVkID0gTlVMTDsKCXBjdHh0LT5pc1JlZGVmaW5lID0gMDsKICAgIH0gZWxzZSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IGRpc2NhcmQgb3Igbm90PwoJICAgICovCgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0gICAgCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJcmVzID0gWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQ7CglpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1NDSEVNQV9SRURFRklORSkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKHBjdHh0LCByZXMsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uIHwgKHNpbXBsZVR5cGUgfCBjb21wbGV4VHlwZSB8IGdyb3VwIHwgYXR0cmlidXRlR3JvdXApKSoiKTsKCX0gZWxzZSB7CgkgICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKHBjdHh0LCByZXMsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPykiKTsKCX0JCiAgICB9ICAgICAgIAogICAgcmV0dXJuKHJlcyk7CgpleGl0X2Vycm9yOgogICAgcmV0dXJuKHBjdHh0LT5lcnIpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlUmVkZWZpbmUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCByZXM7CiNpZm5kZWYgRU5BQkxFX1JFREVGSU5FCiAgICBUT0RPCiAgICByZXR1cm4oMCk7CiNlbmRpZgogICAgcmVzID0geG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZShwY3R4dCwgc2NoZW1hLCBub2RlLAoJWE1MX1NDSEVNQV9TQ0hFTUFfUkVERUZJTkUpOwogICAgaWYgKHJlcyAhPSAwKQoJcmV0dXJuKHJlcyk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmVzOwoKICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUocGN0eHQsIHNjaGVtYSwgbm9kZSwKCVhNTF9TQ0hFTUFfU0NIRU1BX0lOQ0xVREUpOwogICAgaWYgKHJlcyAhPSAwKQoJcmV0dXJuKHJlcyk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHR5cGU6IHRoZSAiY29tcG9zaXRvciIgdHlwZQogKiBAcGFydGljbGVOZWVkZWQ6IGlmIGEgYSBtb2RlbCBncm91cCB3aXRoIGEgcGFydGljbGUKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNlcXVlbmNlIGRlZmluaXRpb24uCiAqIEFwcGxpZXMgcGFydHMgb2Y6CiAqICAgU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6CiAqICAgICBSZWRlZmluaXRpb24gQ29uc3RyYWludHMgYW5kIFNlbWFudGljcyAoc3JjLXJlZGVmaW5lKQogKiAgICAgKDYuMSksICg2LjEuMSksICg2LjEuMikKICoKICogICBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IAogKiAgICAgQWxsIEdyb3VwIExpbWl0ZWQgKGNvcy1hbGwtbGltaXRlZCkgKDIpCiAqICAgICBUT0RPOiBBY3R1YWxseSB0aGlzIHNob3VsZCBnbyB0byBjb21wb25lbnQtbGV2ZWwgY2hlY2tzLAogKiAgICAgYnV0IGlzIGRvbmUgaGVyZSBkdWUgdG8gcGVyZm9ybWFuY2UuIE1vdmUgaXQgdG8gYW4gb3RoZXIgbGF5ZXIKICogICAgIGlzIHNjaGVtYSBjb25zdHJ1Y3Rpb24gdmlhIGFuIEFQSSBpcyBpbXBsZW1lbnRlZC4KICoKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUsCgkJCSBpbnQgd2l0aFBhcnRpY2xlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW07CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBtaW4gPSAxLCBtYXggPSAxLCBpc0VsZW1SZWYsIGhhc1JlZnMgPSAwOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBDcmVhdGUgYSBtb2RlbCBncm91cCB3aXRoIHRoZSBnaXZlbiBjb21wb3NpdG9yLgogICAgKi8KICAgIGl0ZW0gPSB4bWxTY2hlbWFBZGRNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgdHlwZSwgbm9kZSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKCiAgICBpZiAod2l0aFBhcnRpY2xlKSB7CglpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB7CgkgICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIDEsIDEsICIoMCB8IDEpIik7CgkgICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDEsIDEsIDEsICIxIik7Cgl9IGVsc2UgewoJICAgIC8qIGNob2ljZSArIHNlcXVlbmNlICovCgkgICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CgkgICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwKCQkiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKCX0KCXhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIE5VTEwsIG5vZGUsIG1pbiwgbWF4KTsKCS8qCgkqIENyZWF0ZSBhIHBhcnRpY2xlCgkqLwoJcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShjdHh0LCBub2RlLCBtaW4sIG1heCk7CglpZiAocGFydGljbGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBpdGVtOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQogICAgfQoKICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0LCBsYXN0ID0gTlVMTDsKCgl3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkgICAgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsCgkJc2NoZW1hLCBjaGlsZCwgJmlzRWxlbVJlZiwgMCk7CgkgICAgLyoKCSAgICAqIFNQRUMgY29zLWFsbC1saW1pdGVkICgyKQoJICAgICogIlRoZSB7bWF4IG9jY3Vyc30gb2YgYWxsIHRoZSBwYXJ0aWNsZXMgaW4gdGhlIHtwYXJ0aWNsZXN9CgkgICAgKiBvZiB0aGUgKCdhbGwnKSBncm91cCBtdXN0IGJlIDAgb3IgMS4KCSAgICAqLwoJICAgIGlmIChwYXJ0ICE9IE5VTEwpIHsKCQlpZiAoaXNFbGVtUmVmKQoJCSAgICBoYXNSZWZzKys7CgkJaWYgKHBhcnQtPm1pbk9jY3VycyA+IDEpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfQUxMX0xJTUlURUQsCgkJCU5VTEwsIGNoaWxkLAoJCQkiSW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzIChtdXN0IGJlIDAgb3IgMSkiLAoJCQlOVUxMKTsKCQkgICAgLyogUmVzZXQgdG8gMS4gKi8KCQkgICAgcGFydC0+bWluT2NjdXJzID0gMTsKCQl9CgkJaWYgKHBhcnQtPm1heE9jY3VycyA+IDEpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfQUxMX0xJTUlURUQsCgkJCU5VTEwsIGNoaWxkLAoJCQkiSW52YWxpZCB2YWx1ZSBmb3IgbWF4T2NjdXJzIChtdXN0IGJlIDAgb3IgMSkiLAoJCQlOVUxMKTsKCQkgICAgLyogUmVzZXQgdG8gMS4gKi8KCQkgICAgcGFydC0+bWF4T2NjdXJzID0gMTsKCQl9CgkJaWYgKGxhc3QgPT0gTlVMTCkKCQkgICAgaXRlbS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHBhcnQ7CgkJZWxzZQoJCSAgICBsYXN0LT5uZXh0ID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0OwoJCWxhc3QgPSBwYXJ0OwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChhbm5vdGF0aW9uPywgZWxlbWVudCopIik7Cgl9CiAgICB9IGVsc2UgewoJLyogY2hvaWNlICsgc2VxdWVuY2UgKi8KCXhtbFNjaGVtYVRyZWVJdGVtUHRyIHBhcnQgPSBOVUxMLCBsYXN0ID0gTlVMTDsKCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSkgewoKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkJcGFydCA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCQkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsICZpc0VsZW1SZWYsIDApOwoJCWlmIChwYXJ0ICYmIGlzRWxlbVJlZikKCQkgICAgaGFzUmVmcysrOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJCXBhcnQgPQoJCSAgICB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkJaWYgKHBhcnQgIT0gTlVMTCkKCQkgICAgaGFzUmVmcysrOwoJCS8qCgkJKiBIYW5kbGUgcmVkZWZpbml0aW9ucy4KCQkqLwoJCWlmIChjdHh0LT5pc1JlZGVmaW5lICYmIGN0eHQtPnJlZGVmICYmCgkJICAgIChjdHh0LT5yZWRlZi0+aXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApICYmCgkJICAgIHBhcnQgJiYgcGFydC0+Y2hpbGRyZW4pCgkJewoJCSAgICBpZiAoKHhtbFNjaGVtYUdldFFOYW1lUmVmTmFtZShwYXJ0LT5jaGlsZHJlbikgPT0KCQkJICAgIGN0eHQtPnJlZGVmLT5yZWZOYW1lKSAmJgoJCQkoeG1sU2NoZW1hR2V0UU5hbWVSZWZUYXJnZXROcyhwYXJ0LT5jaGlsZHJlbikgPT0KCQkJICAgIGN0eHQtPnJlZGVmLT5yZWZUYXJnZXROcykpCgkJICAgIHsKCQkJLyoKCQkJKiBTUEVDIHNyYy1yZWRlZmluZToKCQkJKiAoNi4xKSAiSWYgaXQgaGFzIGEgPGdyb3VwPiBhbW9uZyBpdHMgY29udGVudHMgYXQKCQkJKiBzb21lIGxldmVsIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB3aG9zZSByZWYKCQkJKiBbYXR0cmlidXRlXSBpcyB0aGUgc2FtZSBhcyB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YKCQkJKiBpdHMgb3duIG5hbWUgYXR0cmlidXRlIHBsdXMgdGFyZ2V0IG5hbWVzcGFjZSwgdGhlbgoJCQkqIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkJCSogKDYuMS4xKSAiSXQgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHN1Y2ggZ3JvdXAuIgoJCQkqLwoJCQlpZiAoY3R4dC0+cmVkZWZDb3VudGVyICE9IDApIHsKCQkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgoJCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwgY2hpbGQsIE5VTEwsCgkJCQkiVGhlIHJlZGVmaW5pbmcgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAiCgkJCQkiJyVzJyBtdXN0IG5vdCBjb250YWluIG1vcmUgdGhhbiBvbmUgIgoJCQkJInJlZmVyZW5jZSB0byB0aGUgcmVkZWZpbmVkIGRlZmluaXRpb24iLAoJCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJCSAgICBjdHh0LT5yZWRlZi0+cmVmVGFyZ2V0TnMsCgkJCQkgICAgY3R4dC0+cmVkZWYtPnJlZk5hbWUpLAoJCQkJTlVMTCk7CgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJICAgIHBhcnQgPSBOVUxMOwoJCQl9IGVsc2UgaWYgKCgoV1hTX1BBUlRJQ0xFKHBhcnQpKS0+bWluT2NjdXJzICE9IDEpIHx8CgkJCSAgICAoKFdYU19QQVJUSUNMRShwYXJ0KSktPm1heE9jY3VycyAhPSAxKSkKCQkJewoJCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkJICAgIC8qCgkJCSAgICAqIFNQRUMgc3JjLXJlZGVmaW5lOgoJCQkgICAgKiAoNi4xLjIpICJUaGUgt2FjdHVhbCB2YWx1Zbcgb2YgYm90aCB0aGF0CgkJCSAgICAqIGdyb3VwJ3MgbWluT2NjdXJzIGFuZCBtYXhPY2N1cnMgW2F0dHJpYnV0ZV0KCQkJICAgICogbXVzdCBiZSAxIChvciC3YWJzZW50tykuCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwgY2hpbGQsIE5VTEwsCgkJCQkiVGhlIHJlZGVmaW5pbmcgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAiCgkJCQkiJyVzJyBtdXN0IG5vdCBjb250YWluIGEgcmVmZXJlbmNlIHRvIHRoZSAiCgkJCQkicmVkZWZpbmVkIGRlZmluaXRpb24gd2l0aCBhICIKCQkJCSJtYXhPY2N1cnMvbWluT2NjdXJzIG90aGVyIHRoYW4gMSIsCgkJCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkJICAgIGN0eHQtPnJlZGVmLT5yZWZUYXJnZXROcywKCQkJCSAgICBjdHh0LT5yZWRlZi0+cmVmTmFtZSksCgkJCQlOVUxMKTsKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQkgICAgcGFydCA9IE5VTEw7CgkJCX0KCQkJY3R4dC0+cmVkZWYtPnJlZmVyZW5jZSA9IFdYU19CQVNJQ19DQVNUIHBhcnQ7CgkJCWN0eHQtPnJlZGVmQ291bnRlcisrOwoJCSAgICB9CQkgICAgICAgIAkJICAgCgkJfQoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHsKCQlwYXJ0ID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKQoJCSAgICB4bWxTY2hlbWFQYXJzZUFueShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkJcGFydCA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCQlwYXJ0ID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgMSk7CgkgICAgfQoJICAgIGlmIChwYXJ0ICE9IE5VTEwpIHsKCQlpZiAobGFzdCA9PSBOVUxMKQoJCSAgICBpdGVtLT5jaGlsZHJlbiA9IHBhcnQ7CgkJZWxzZQoJCSAgICBsYXN0LT5uZXh0ID0gcGFydDsKCQlsYXN0ID0gcGFydDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoZWxlbWVudCB8IGdyb3VwIHwgY2hvaWNlIHwgc2VxdWVuY2UgfCBhbnkpKikiKTsKCX0KICAgIH0KICAgIGlmICgobWF4ID09IDApICYmIChtaW4gPT0gMCkpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKGhhc1JlZnMpIHsKCS8qCgkqIFdlIG5lZWQgdG8gcmVzb2x2ZSByZWZlcmVuY2VzLgoJKi8KCVdYU19BRERfUEVORElORyhjdHh0LCBpdGVtKTsKICAgIH0KICAgIGlmICh3aXRoUGFydGljbGUpCglyZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcGFydGljbGUpOwkKICAgIGVsc2UKCXJldHVybiAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFJlc3RyaWN0aW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHBhcmVudFR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmFzZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgCiAgICAqLwogICAgLyoKICAgICogRXh0cmFjdCB0aGUgYmFzZSB0eXBlLiBUaGUgImJhc2UiIGF0dHJpYnV0ZSBpcyBtYW5kYXRvcnkgaWYgaW5zaWRlCiAgICAqIGEgY29tcGxleCB0eXBlIG9yIGlmIHJlZGVmaW5pbmcuCiAgICAqCiAgICAqIFNQRUMgKDEuMikgIi4uLm90aGVyd2lzZSAoPHJlc3RyaWN0aW9uPiBoYXMgbm8gPHNpbXBsZVR5cGU+ICIKICAgICogYW1vbmcgaXRzIFtjaGlsZHJlbl0pLCB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiB3aGljaCBpcwogICAgKiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5CiAgICAqIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXSIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIG5vZGUsICJiYXNlIiwKCSYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSkgPT0gMCkKICAgIHsKCWlmICgodHlwZS0+YmFzZSA9PSBOVUxMKSAmJiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsICJiYXNlIiwgTlVMTCk7Cgl9IGVsc2UgaWYgKChjdHh0LT5pc1JlZGVmaW5lKSAmJgoJICAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCXsKCSAgICBpZiAodHlwZS0+YmFzZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJICAgIE5VTEwsIG5vZGUsICJiYXNlIiwgTlVMTCk7CgkgICAgfSBlbHNlIGlmICgoISB4bWxTdHJFcXVhbCh0eXBlLT5iYXNlLCB0eXBlLT5uYW1lKSkgfHwKCQkoISB4bWxTdHJFcXVhbCh0eXBlLT5iYXNlTnMsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSkpKQoJICAgIHsKCQl4bWxDaGFyICpzdHIxID0gTlVMTCwgKnN0cjIgPSBOVUxMOwoJCS8qCgkJKiBSRURFRklORTogU1BFQyBzcmMtcmVkZWZpbmUgKDUpCgkJKiAiV2l0aGluIHRoZSBbY2hpbGRyZW5dLCBlYWNoIDxzaW1wbGVUeXBlPiBtdXN0IGhhdmUgYQoJCSogPHJlc3RyaWN0aW9uPiBhbW9uZyBpdHMgW2NoaWxkcmVuXSAuLi4gdGhlILdhY3R1YWwgdmFsdWW3IG9mCgkJKiB3aG9zZSBiYXNlIFthdHRyaWJ1dGVdIG11c3QgYmUgdGhlIHNhbWUgYXMgdGhlILdhY3R1YWwgdmFsdWW3CgkJKiBvZiBpdHMgb3duIG5hbWUgYXR0cmlidXRlIHBsdXMgdGFyZ2V0IG5hbWVzcGFjZTsiCgkJKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCQkgICAgTlVMTCwgbm9kZSwgIlRoaXMgaXMgYSByZWRlZmluaXRpb24sIGJ1dCB0aGUgUU5hbWUgIgoJCSAgICAidmFsdWUgJyVzJyBvZiB0aGUgJ2Jhc2UnIGF0dHJpYnV0ZSBkb2VzIG5vdCBtYXRjaCB0aGUgIgoJCSAgICAidHlwZSdzIGRlc2lnbmF0aW9uICclcyciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyMSwgdHlwZS0+YmFzZU5zLCB0eXBlLT5iYXNlKSwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0cjEsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSwKCQkJdHlwZS0+bmFtZSksIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyMSk7CgkJRlJFRV9BTkRfTlVMTChzdHIyKTsKCQkvKiBBdm9pZCBjb25mdXNpb24gYW5kIGVyYXNlIHRoZSB2YWx1ZXMuICovCgkJdHlwZS0+YmFzZSA9IE5VTEw7CgkJdHlwZS0+YmFzZU5zID0gTlVMTDsKCSAgICB9Cgl9CQkKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIHNpbXBsZSB0eXBlIGFuY2VzdG9yLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uPjxzaW1wbGVUeXBlPi4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewoJCS8qCgkJKiBzcmMtcmVzdHJpY3Rpb24tYmFzZS1vci1zaW1wbGVUeXBlCgkJKiBFaXRoZXIgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gb3IgdGhlIHNpbXBsZVR5cGUgW2NoaWxkXSBvZiB0aGUKCQkqIDxyZXN0cmljdGlvbj4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4KCQkqLwoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19SRVNUUklDVElPTl9CQVNFX09SX1NJTVBMRVRZUEUsCgkJICAgIE5VTEwsIG5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAnYmFzZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJdHlwZS0+YmFzZVR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQkgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmICh0eXBlLT5iYXNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNUUklDVElPTl9CQVNFX09SX1NJTVBMRVRZUEUsCgkJTlVMTCwgbm9kZSwgY2hpbGQsCgkJIkVpdGhlciB0aGUgYXR0cmlidXRlICdiYXNlJyBvciBhIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJIm11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwoJfQogICAgfSBlbHNlIGlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCS8qCgkqIENvcnJlc3BvbmRzIHRvIDxjb21wbGV4VHlwZT48Y29tcGxleENvbnRlbnQ+PHJlc3RyaWN0aW9uPi4uLgoJKiBmb2xsb3dlZCBieToKCSoKCSogTW9kZWwgZ3JvdXBzIDxhbGw+LCA8Y2hvaWNlPiBhbmQgPHNlcXVlbmNlPi4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsCgkJICAgIHNjaGVtYSwgY2hpbGQsIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkvKgoJKiBNb2RlbCBncm91cCByZWZlcmVuY2UgPGdyb3VwPi4KCSovCgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsJICAgIAoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmUmVmKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIC8qCgkgICAgKiBOb3RlIHRoYXQgdGhlIHJlZmVyZW5jZSB3aWxsIGJlIHJlc29sdmVkIGluCgkgICAgKiB4bWxTY2hlbWFSZXNvbHZlVHlwZVJlZmVyZW5jZXMoKTsKCSAgICAqLwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8Y29tcGxleFR5cGU+PHNpbXBsZUNvbnRlbnQ+PHJlc3RyaWN0aW9uPi4uLgoJKgoJKiAiMS4xIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPgoJKiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8cmVzdHJpY3Rpb24+IGlmIHRoZXJlIGlzIG9uZTsiCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIC8qCgkgICAgKiBXZSB3aWxsIHN0b3JlIHRoZSB0by1iZS1yZXN0cmljdGVkIHNpbXBsZSB0eXBlIGluCgkgICAgKiB0eXBlLT5jb250ZW50VHlwZURlZiAqdGVtcG9yYXJpbHkqLgoJICAgICovCgkgICAgdHlwZS0+Y29udGVudFR5cGVEZWYgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgaWYgKCB0eXBlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKQoJCXJldHVybiAoTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KCiAgICBpZiAoKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwKCShwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBsYXN0ZmFjZXQgPSBOVUxMOwoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50PjxyZXN0cmljdGlvbj4uLi4KCSogPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uPi4uLgoJKi8KCgkvKgoJKiBBZGQgdGhlIGZhY2V0cyB0byB0aGUgc2ltcGxlIHR5cGUgYW5jZXN0b3IuCgkqLwoJLyoKCSogVE9ETzogRGF0YXR5cGVzOiA0LjEuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb24gb2YKCSogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKCSogKlNpbmdsZSBGYWNldCBWYWx1ZSoKCSovCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgIm1pbkluY2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5FeGNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4SW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heEV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJ0b3RhbERpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJmcmFjdGlvbkRpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJwYXR0ZXJuIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImVudW1lcmF0aW9uIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIndoaXRlU3BhY2UiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heExlbmd0aCIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5MZW5ndGgiKSkpIHsKCSAgICBmYWNldCA9IHhtbFNjaGVtYVBhcnNlRmFjZXQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKGZhY2V0ICE9IE5VTEwpIHsKCQlpZiAobGFzdGZhY2V0ID09IE5VTEwpCgkJICAgIHR5cGUtPmZhY2V0cyA9IGZhY2V0OwoJCWVsc2UKCQkgICAgbGFzdGZhY2V0LT5uZXh0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCS8qCgkqIENyZWF0ZSBsaW5rcyBmb3IgZGVyaXZhdGlvbiBhbmQgdmFsaWRhdGlvbi4KCSovCglpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rLCBsYXN0RmFjZXRMaW5rID0gTlVMTDsKCgkgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkgICAgZG8gewoJCWZhY2V0TGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkJaWYgKGZhY2V0TGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJICAgIHhtbEZyZWUoZmFjZXRMaW5rKTsKCQkgICAgcmV0dXJuIChOVUxMKTsKCQl9CgkJZmFjZXRMaW5rLT5mYWNldCA9IGZhY2V0OwoJCWZhY2V0TGluay0+bmV4dCA9IE5VTEw7CgkJaWYgKGxhc3RGYWNldExpbmsgPT0gTlVMTCkKCQkgICAgdHlwZS0+ZmFjZXRTZXQgPSBmYWNldExpbms7CgkJZWxzZQoJCSAgICBsYXN0RmFjZXRMaW5rLT5uZXh0ID0gZmFjZXRMaW5rOwoJCWxhc3RGYWNldExpbmsgPSBmYWNldExpbms7CgkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCX0KICAgIH0KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7CgkvKgoJKiBBdHRyaWJ1dGUgdXNlcy9kZWNsYXJhdGlvbnMuCgkqLwoJaWYgKHhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGVzKGN0eHQsIHNjaGVtYSwgJmNoaWxkLAoJICAgICh4bWxTY2hlbWFJdGVtTGlzdFB0ciAqKSAmKHR5cGUtPmF0dHJVc2VzKSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04sIE5VTEwpID09IC0xKQoJICAgIHJldHVybihOVUxMKTsKCS8qCgkqIEF0dHJpYnV0ZSB3aWxkY2FyZC4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9CgkJeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CglpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiYW5ub3RhdGlvbj8sIChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKCX0gZWxzZSBpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpIHsKCSAgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8sIChtaW5FeGNsdXNpdmUgfCBtaW5JbmNsdXNpdmUgfCAiCgkJIm1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCAiCgkJImxlbmd0aCB8IG1pbkxlbmd0aCB8IG1heExlbmd0aCB8IGVudW1lcmF0aW9uIHwgd2hpdGVTcGFjZSB8ICIKCQkicGF0dGVybikqKT8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpIik7Cgl9IGVsc2UgewoJICAgIC8qIFNpbXBsZSB0eXBlICovCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8sIChtaW5FeGNsdXNpdmUgfCBtaW5JbmNsdXNpdmUgfCAiCgkJIm1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCAiCgkJImxlbmd0aCB8IG1pbkxlbmd0aCB8IG1heExlbmd0aCB8IGVudW1lcmF0aW9uIHwgd2hpdGVTcGFjZSB8ICIKCQkicGF0dGVybikqKSkiKTsKCX0KICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYW4gPGV4dGVuc2lvbj4sIHdoaWNoIGlzIGZvdW5kIGluc2lkZSBhCiAqIDxzaW1wbGVDb250ZW50PiBvciA8Y29tcGxleENvbnRlbnQ+LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlLgogKgogKiBUT0RPOiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgeG1sU2NoZW1hVHlwZVR5cGUgcGFyZW50VHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT047CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmFzZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImJhc2UiIC0gbWFuZGF0b3J5LgogICAgKi8KICAgIGlmICgoeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIG5vZGUsCgkiYmFzZSIsICYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSkgPT0gMCkgJiYKCSh0eXBlLT5iYXNlID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsICJiYXNlIiwgTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSB0eXBlIGFuY2VzdG9yLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxjb21wbGV4Q29udGVudD48ZXh0ZW5zaW9uPi4uLiBhbmQ6CgkqCgkqIE1vZGVsIGdyb3VwcyA8YWxsPiwgPGNob2ljZT4sIDxzZXF1ZW5jZT4gYW5kIDxncm91cD4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLAoJCSAgICBjaGlsZCwgWE1MX1NDSEVNQV9UWVBFX0FMTCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsCgkJICAgIGNoaWxkLCBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLAoJCWNoaWxkLCBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICAvKgoJICAgICogTm90ZSB0aGF0IHRoZSByZWZlcmVuY2Ugd2lsbCBiZSByZXNvbHZlZCBpbgoJICAgICogeG1sU2NoZW1hUmVzb2x2ZVR5cGVSZWZlcmVuY2VzKCk7CgkgICAgKi8KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCS8qCgkqIEF0dHJpYnV0ZSB1c2VzL2RlY2xhcmF0aW9ucy4KCSovCglpZiAoeG1sU2NoZW1hUGFyc2VMb2NhbEF0dHJpYnV0ZXMoY3R4dCwgc2NoZW1hLCAmY2hpbGQsCgkgICAgKHhtbFNjaGVtYUl0ZW1MaXN0UHRyICopICYodHlwZS0+YXR0clVzZXMpLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT04sIE5VTEwpID09IC0xKQoJICAgIHJldHVybihOVUxMKTsKCS8qCgkqIEF0dHJpYnV0ZSB3aWxkY2FyZC4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICBjdHh0LT5jdHh0VHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPQoJCXhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJICAgIC8qIENvbXBsZXggY29udGVudCBleHRlbnNpb24uICovCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoKGdyb3VwIHwgYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpPywgIgoJCSIoKGF0dHJpYnV0ZSB8IGF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSkiKTsKCX0gZWxzZSB7CgkgICAgLyogU2ltcGxlIGNvbnRlbnQgZXh0ZW5zaW9uLiAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCAiCgkJImFueUF0dHJpYnV0ZT8pKSIpOwoJfQogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlQ29udGVudCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgaW50ICpoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fAoJKGhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbiA9IDA7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBjaGlsZCwgMSkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsIE5VTEwsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsJCiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsIE5VTEwsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsJCiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpOwoJKCpoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKSA9IDE7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZXh0ZW5zaW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbihjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCk7CgkoKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pID0gMTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4Q29udGVudCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgaW50ICpoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSB8fAoJKGhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbiA9IDA7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1peGVkIikpKQoJICAgIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogU2V0IHRoZSAnbWl4ZWQnIG9uIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCiAgICAqLwogICAgaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIG5vZGUsICJtaXhlZCIsIDApKSAgewoJaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpID09IDApCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIGNvbXBsZXggdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIGNoaWxkLCAxKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgTlVMTCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCSAgICBOVUxMLCBub2RlLCBOVUxMLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImV4dGVuc2lvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENvbXBsZXggVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlOwojaWZkZWYgRU5BQkxFX05BTUVEX0xPQ0FMUwogICAgY2hhciBidWZbNDBdOwojZW5kaWYKICAgIGludCBmaW5hbCA9IDAsIGJsb2NrID0gMCwgaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbiA9IDA7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKCiAgICBpZiAodG9wTGV2ZWwpIHsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIE5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQkKICAgIH0KCiAgICBpZiAodG9wTGV2ZWwgPT0gMCkgewoJLyoKCSogUGFyc2UgYXMgbG9jYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwojaWZkZWYgRU5BQkxFX05BTUVEX0xPQ0FMUwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjQ1QlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYLAoJICAgIHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKilidWYsIC0xKSwKCSAgICBjdHh0LT50YXJnZXROYW1lc3BhY2UsIG5vZGUsIDApOwojZWxzZQoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYLAoJICAgIE5VTEwsIGN0eHQtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMCk7CiNlbmRpZgoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJbmFtZSA9IHR5cGUtPm5hbWU7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKCS8qCgkqIFRPRE86IFdlIG5lZWQgdGhlIHRhcmdldCBuYW1lc3BhY2UuCgkqLwogICAgfSBlbHNlIHsKCS8qCgkqIFBhcnNlIGFzIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbi4KCSovCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgsCgkgICAgbmFtZSwgY3R4dC0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlLCAxKTsKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOwoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUw7CiAgICB9CiAgICB0eXBlLT50YXJnZXROYW1lc3BhY2UgPSBjdHh0LT50YXJnZXROYW1lc3BhY2U7CiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZSAiaWQiLgoJCSovCgkJeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaXhlZCIpKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZSAibWl4ZWQiLgoJCSovCgkJaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsCgkJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyKSkKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKCSAgICB9IGVsc2UgaWYgKHRvcExldmVsKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZXMgb2YgZ2xvYmFsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9ucy4KCQkqLwoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSB7CgkJICAgIC8qIFBhc3MuICovCgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYWJzdHJhY3QiKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiYWJzdHJhY3QiLgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoY3R4dCwKCQkJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyKSkKCQkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9BQlNUUkFDVDsKCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJmaW5hbCIuCgkJICAgICovCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsCgkJCSh4bWxOb2RlUHRyKSBhdHRyKTsKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsCgkJCSYodHlwZS0+ZmxhZ3MpLAoJCQktMSwKCQkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04sCgkJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04sCgkJCS0xLCAtMSwgLTEpICE9IDApCgkJICAgIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkJICAgICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLAoJCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkgICAgfSBlbHNlIAoJCQlmaW5hbCA9IDE7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmxvY2siKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiYmxvY2siLgoJCSAgICAqLwoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CgkJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwKCQkJLTEsCgkJCVhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OLAoJCQktMSwgLTEsIC0xKSAhPSAwKSB7CgkJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpICIsCgkJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCSAgICB9IGVsc2UgCgkJCWJsb2NrID0gMTsKCQl9IGVsc2UgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCBOVUxMLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIGlmICghIGJsb2NrKSB7CgkvKgoJKiBBcHBseSBkZWZhdWx0ICJibG9jayIgdmFsdWVzLgoJKi8KCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTikKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OOwoJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTikKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTjsKICAgIH0KICAgIGlmICghIGZpbmFsKSB7CgkvKgoJKiBBcHBseSBkZWZhdWx0ICJibG9jayIgdmFsdWVzLgoJKi8KCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OOwoJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTikKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTjsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgY2hpbGQsIDEpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBjdHh0LT5jdHh0VHlwZSA9IHR5cGU7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlQ29udGVudCIpKSB7CgkvKgoJKiA8Y29tcGxleFR5cGU+PHNpbXBsZUNvbnRlbnQ+Li4uCgkqIDMuNC4zIDogMi4yCgkqIFNwZWNpZnlpbmcgbWl4ZWQ9J3RydWUnIHdoZW4gdGhlIDxzaW1wbGVDb250ZW50PgoJKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4gaGFzIG5vIGVmZmVjdAoJKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgICAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICAmaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbik7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleENvbnRlbnQiKSkgewoJLyoKCSogPGNvbXBsZXhUeXBlPjxjb21wbGV4Q29udGVudD4uLi4KCSovCgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKICAgICAgICB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgJmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgewoJLyoKCSogRS5nIDxjb21wbGV4VHlwZT48c2VxdWVuY2U+Li4uIG9yIDxjb21wbGV4VHlwZT48YXR0cmlidXRlPi4uLiBldGMuCgkqCgkqIFNQRUMKCSogIi4uLnRoZSB0aGlyZCBhbHRlcm5hdGl2ZSAobmVpdGhlciA8c2ltcGxlQ29udGVudD4gbm9yCgkqIDxjb21wbGV4Q29udGVudD4pIGlzIGNob3Nlbi4gVGhpcyBjYXNlIGlzIHVuZGVyc3Rvb2QgYXMgc2hvcnRoYW5kCgkqIGZvciBjb21wbGV4IGNvbnRlbnQgcmVzdHJpY3RpbmcgdGhlILd1ci10eXBlIGRlZmluaXRpb263LCBhbmQgdGhlCgkqIGRldGFpbHMgb2YgdGhlIG1hcHBpbmdzIHNob3VsZCBiZSBtb2RpZmllZCBhcyBuZWNlc3NhcnkuCgkqLwoJdHlwZS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgkvKgoJKiBQYXJzZSBtb2RlbCBncm91cHMuCgkqLwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDEpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDEpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICAvKgoJICAgICogTm90ZSB0aGF0IHRoZSByZWZlcmVuY2Ugd2lsbCBiZSByZXNvbHZlZCBpbgoJICAgICogeG1sU2NoZW1hUmVzb2x2ZVR5cGVSZWZlcmVuY2VzKCk7CgkgICAgKi8KICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgZGVjbHMvcmVmcy4KCSovCiAgICAgICAgaWYgKHhtbFNjaGVtYVBhcnNlTG9jYWxBdHRyaWJ1dGVzKGN0eHQsIHNjaGVtYSwgJmNoaWxkLAoJICAgICh4bWxTY2hlbWFJdGVtTGlzdFB0ciAqKSAmKHR5cGUtPmF0dHJVc2VzKSwKCSAgICBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04sIE5VTEwpID09IC0xKQoJICAgIHJldHVybihOVUxMKTsKCS8qCgkqIFBhcnNlIGF0dHJpYnV0ZSB3aWxkY2FyZC4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAoc2ltcGxlQ29udGVudCB8IGNvbXBsZXhDb250ZW50IHwgIgoJICAgICIoKGdyb3VwIHwgYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpPywgKChhdHRyaWJ1dGUgfCAiCgkgICAgImF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSkpIik7CiAgICB9CiAgICAvKgogICAgKiBSRURFRklORTogU1BFQyBzcmMtcmVkZWZpbmUgKDUpCiAgICAqLwogICAgaWYgKHRvcExldmVsICYmIGN0eHQtPmlzUmVkZWZpbmUgJiYgKCEgaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FLAoJICAgIE5VTEwsIG5vZGUsICJUaGlzIGlzIGEgcmVkZWZpbml0aW9uLCB0aHVzIHRoZSAiCgkgICAgIjxjb21wbGV4VHlwZT4gbXVzdCBoYXZlIGEgPHJlc3RyaWN0aW9uPiBvciA8ZXh0ZW5zaW9uPiAiCgkgICAgImdyYW5kLWNoaWxkIiwgTlVMTCk7CiAgICB9CiAgICBjdHh0LT5jdHh0VHlwZSA9IGN0eHRUeXBlOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpbmcgdXNpbmcgU2NoZW1hcwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVJlYWRpbmcvV3JpdGluZyBTY2hlbWFzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAgLyogV2lsbCBiZSBlbmFibGVkIGlmIGl0IGlzIGNsZWFyIHdoYXQgb3B0aW9ucyBhcmUgbmVlZGVkLiAqLwovKioKICogeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFQYXJzZXJPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgcGFyc2UuCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgIGludCBvcHRpb25zKQoKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVBhcnNlT3B0aW9uLgogICAgKi8KICAgIGZvciAoaSA9IDE7IGkgPCAoaW50KSBzaXplb2YoaW50KSAqIDg7IGkrKykgewogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkgewoJICAgIHJldHVybiAoLTEpOwogICAgICAgIH0KICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OiBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb2YgdGhlIHBhcnNlciBjb250ZXh0LgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZXJDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCgp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHQ6CiAqIEBVUkw6ICB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBmaWxlL3Jlc291cmNlIGV4cGVjdGVkCiAqIHRvIGNvbnRhaW4gYW4gWE1MIFNjaGVtYXMgZmlsZS4KICoKICogUmV0dXJucyB0aGUgcGFyc2VyIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld1BhcnNlckN0eHQoY29uc3QgY2hhciAqVVJMKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoVVJMID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICByZXQtPlVSTCA9IHhtbERpY3RMb29rdXAocmV0LT5kaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dDoKICogQGRvYzogIGEgcHJlcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZG9jdW1lbnQuCiAqIE5CLiBUaGUgZG9jdW1lbnQgbWF5IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgcGFyc2luZyBwcm9jZXNzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dCh4bWxEb2NQdHIgZG9jKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoZG9jID09IE5VTEwpCiAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIC8qIFRoZSBhcHBsaWNhdGlvbiBoYXMgcmVzcG9uc2liaWxpdHkgZm9yIHRoZSBkb2N1bWVudCAqLwogICAgcmV0LT5wcmVzZXJ2ZSA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+ZG9jICE9IE5VTEwgJiYgIWN0eHQtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2MoY3R4dC0+ZG9jKTsgICAgCiAgICBpZiAoY3R4dC0+dmN0eHQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dChjdHh0LT52Y3R4dCk7CiAgICB9CiAgICBpZiAoY3R4dC0+b3duc0NvbnN0cnVjdG9yICYmIChjdHh0LT5jb25zdHJ1Y3RvciAhPSBOVUxMKSkgewoJeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dEZyZWUoY3R4dC0+Y29uc3RydWN0b3IpOwoJY3R4dC0+Y29uc3RydWN0b3IgPSBOVUxMOwoJY3R4dC0+b3duc0NvbnN0cnVjdG9yID0gMDsKICAgIH0KICAgIGlmIChjdHh0LT5hdHRyUHJvaGlicyAhPSBOVUxMKQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGN0eHQtPmF0dHJQcm9oaWJzKTsKICAgIHhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICoJCQlCdWlsZGluZyB0aGUgY29udGVudCBtb2RlbHMJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWxGb3JTdWJzdEdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSwgaW50IGNvdW50ZXIsIHhtbEF1dG9tYXRhU3RhdGVQdHIgZW5kKQp7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCB0bXA7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLCBtZW1iZXI7CiAgICB4bWxTY2hlbWFTdWJzdEdyb3VwUHRyIHN1YnN0R3JvdXA7CiAgICBpbnQgaTsKCiAgICBlbGVtRGVjbCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW47CiAgICAvKgogICAgKiBXcmFwIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgd2l0aCBhIENIT0lDRS4KICAgICovCiAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKICAgIGlmIChlbmQgPT0gTlVMTCkKCWVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUocGN0eHQtPmFtKTsKICAgIHN1YnN0R3JvdXAgPSB4bWxTY2hlbWFTdWJzdEdyb3VwR2V0KHBjdHh0LCBlbGVtRGVjbCk7CiAgICBpZiAoc3Vic3RHcm91cCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBXWFNfSVRFTV9OT0RFKHBhcnRpY2xlKSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cCwgIgoJICAgICJkZWNsYXJhdGlvbiBpcyBtYXJrZWQgaGF2aW5nIGEgc3Vic3QuIGdyb3VwIGJ1dCBub25lICIKCSAgICAiYXZhaWxhYmxlLlxuIiwgZWxlbURlY2wtPm5hbWUsIE5VTEwpOwoJcmV0dXJuOwogICAgfQogICAgaWYgKGNvdW50ZXIgPj0gMCkgewoJLyoKCSogTk9URSB0aGF0IHdlIHB1dCB0aGUgZGVjbGFyYXRpb24gaW4sIGV2ZW4gaWYgaXQncyBhYnN0cmFjdC4KCSogSG93ZXZlciwgYW4gZXJyb3Igd2lsbCBiZSByYWlzZWQgZHVyaW5nICp2YWxpZGF0aW9uKiBpZiBhbiBlbGVtZW50CgkqIGluZm9ybWF0aW9uIGl0ZW0gc2hhbGwgYmUgdmFsaWRhdGVkIGFnYWluc3QgYW4gYWJzdHJhY3QgZWxlbWVudAoJKiBkZWNsYXJhdGlvbi4KCSovCgl0bXAgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLCBjb3VudGVyKTsKICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwgdG1wLCBlbmQsCgkgICAgICAgICAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwoJLyoKCSogQWRkIHN1YnN0LiBncm91cCBtZW1iZXJzLgoJKi8KCWZvciAoaSA9IDA7IGkgPCBzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zOyBpKyspIHsKCSAgICBtZW1iZXIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXNbaV07CiAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLCB0bXAsIGVuZCwKCQkgICAgICAgICAgICAgICBtZW1iZXItPm5hbWUsIG1lbWJlci0+dGFyZ2V0TmFtZXNwYWNlLCBtZW1iZXIpOwoJfQogICAgfSBlbHNlIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCS8qCgkqIE5PVEUgdGhhdCB3ZSBwdXQgdGhlIGRlY2xhcmF0aW9uIGluLCBldmVuIGlmIGl0J3MgYWJzdHJhY3QsCgkqLwoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCSAgICBzdGFydCwgTlVMTCwKCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpLCBlbmQpOwoJLyoKCSogQWRkIHN1YnN0LiBncm91cCBtZW1iZXJzLgoJKi8KCWZvciAoaSA9IDA7IGkgPCBzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zOyBpKyspIHsKCSAgICBtZW1iZXIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXNbaV07CgkgICAgdG1wID0geG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKHBjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJICAgICAgICAgICAgICAgbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgICAgIDEsIDEsIG1lbWJlcik7CgkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgdG1wLCBlbmQpOwoJfQogICAgfSBlbHNlIHsKCXhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwoJaW50IG1heE9jY3VycyA9IHBhcnRpY2xlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KCSAgICBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKCWludCBtaW5PY2N1cnMgPSBwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMSA/IDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCgljb3VudGVyID0KCSAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXIocGN0eHQtPmFtLCBtaW5PY2N1cnMsCgkgICAgbWF4T2NjdXJzKTsKCWhvcCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUocGN0eHQtPmFtKTsKCgl4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJICAgIHN0YXJ0LCBOVUxMLAoJICAgIGVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCksCgkgICAgaG9wKTsKCS8qCgkgKiBBZGQgc3Vic3QuIGdyb3VwIG1lbWJlcnMuCgkgKi8KCWZvciAoaSA9IDA7IGkgPCBzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zOyBpKyspIHsKCSAgICBtZW1iZXIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXNbaV07CgkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQlzdGFydCwgTlVMTCwKCQltZW1iZXItPm5hbWUsIG1lbWJlci0+dGFyZ2V0TmFtZXNwYWNlLCBtZW1iZXIpLAoJCWhvcCk7Cgl9Cgl4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIGhvcCwgc3RhcnQsIGNvdW50ZXIpOwoJeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMocGN0eHQtPmFtLCBob3AsIGVuZCwgY291bnRlcik7CiAgICB9CiAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKQoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CiAgICBwY3R4dC0+c3RhdGUgPSBlbmQ7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlKQp7CiAgICBpZiAoKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4pLT5mbGFncyAmCglYTUxfU0NIRU1BU19FTEVNX1NVQlNUX0dST1VQX0hFQUQpIHsKCS8qCgkqIFN1YnN0aXR1dGlvbiBncm91cHMuCgkqLwoJeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWxGb3JTdWJzdEdyb3VwKGN0eHQsIHBhcnRpY2xlLCAtMSwgTlVMTCk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsKCXhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgoJZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwoKCWlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKQoJICAgIHJldHVybjsKCWlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCSAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJICAgIGVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCk7Cgl9IGVsc2UgaWYgKChwYXJ0aWNsZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkgJiYKCSAgICAgICAgICAgKHBhcnRpY2xlLT5taW5PY2N1cnMgPCAyKSkgewoJICAgIC8qIFNwZWNpYWwgY2FzZS4gKi8KCSAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwkgICAgCgkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLCBzdGFydCwgTlVMTCwKCQllbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwkgICAgCgkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgY3R4dC0+c3RhdGUsCgkJZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsJICAgIAoJfSBlbHNlIHsKCSAgICBpbnQgY291bnRlcjsKCSAgICBpbnQgbWF4T2NjdXJzID0gcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwoJCQkgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CgkgICAgaW50IG1pbk9jY3VycyA9IHBhcnRpY2xlLT5taW5PY2N1cnMgPCAxID8KCQkJICAgIDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCgkgICAgc3RhcnQgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMKTsKCSAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CgkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLCBzdGFydCwgTlVMTCwKCQllbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwoJICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgc3RhcnQsIGNvdW50ZXIpOwoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAoJCU5VTEwsIGNvdW50ZXIpOwoJfQoJaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkKCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBjdHh0LT5zdGF0ZSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWw6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcGFydGljbGU6ICB0aGUgcGFydGljbGUgY29tcG9uZW50CiAqIEBuYW1lOiAgdGhlIGNvbXBsZXggdHlwZSdzIG5hbWUgd2hvc2UgY29udGVudCBpcyBiZWluZyBidWlsdAogKgogKiBDcmVhdGUgdGhlIGF1dG9tYXRvbiBmb3IgdGhlIHtjb250ZW50IHR5cGV9IG9mIGEgY29tcGxleCB0eXBlLgogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCIsICJwYXJ0aWNsZSBpcyBOVUxMIik7CSAgICAKCXJldHVybjsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgewoJLyoKCSogSnVzdCByZXR1cm4gaW4gdGhpcyBjYXNlLiBBIG1pc3NpbmcgInRlcm0iIG9mIHRoZSBwYXJ0aWNsZQoJKiBtaWdodCBhcmlzZSBkdWUgdG8gYW4gaW52YWxpZCAidGVybSIgY29tcG9uZW50LgoJKi8KCXJldHVybjsKICAgIH0KCiAgICBzd2l0Y2ggKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOiB7CgkgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQ7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsKCgkgICAgd2lsZCA9ICh4bWxTY2hlbWFXaWxkY2FyZFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwoKCSAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKCSAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCQlpZiAod2lsZC0+YW55ID09IDEpIHsKCQkgICAgLyoKCQkgICAgKiBXZSBuZWVkIHRvIGFkZCBib3RoIHRyYW5zaXRpb25zOgoJCSAgICAqCgkJICAgICogMS4gdGhlIHsiKiIsICIqIn0gZm9yIGVsZW1lbnRzIGluIGEgbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBlbmQpOwoJCSAgICAvKgoJCSAgICAqIDIuIHRoZSB7IioifSBmb3IgZWxlbWVudHMgaW4gbm8gbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgTlVMTCwgd2lsZCk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIG5zID0gd2lsZC0+bnNTZXQ7CgkJICAgIGRvIHsKCQkJcGN0eHQtPnN0YXRlID0gc3RhcnQ7CgkJCXBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQkgICAgcGN0eHQtPnN0YXRlLCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgd2lsZCk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld05lZ1RyYW5zKHBjdHh0LT5hbSwKCQkJc3RhcnQsIGVuZCwgQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsCgkJCXdpbGQpOwoJCX0KCSAgICB9IGVsc2UgewoJCWludCBjb3VudGVyOwoJCXhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwoJCWludCBtYXhPY2N1cnMgPQoJCSAgICBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/IFVOQk9VTkRFRCA6IHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxOwoJCWludCBtaW5PY2N1cnMgPQoJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMSA/IDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCgkJY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCQlob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgkJaWYgKHdpbGQtPmFueSA9PSAxKSB7CgkJICAgIHBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHdpbGQpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGhvcCk7CgkJICAgIHBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBob3ApOwoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCXBjdHh0LT5zdGF0ZSA9CgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgd2lsZCk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgaG9wKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld05lZ1RyYW5zKHBjdHh0LT5hbSwKCQkJc3RhcnQsIGhvcCwgQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsCgkJCXdpbGQpOwoJCX0KCQl4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIGhvcCwgc3RhcnQsIGNvdW50ZXIpOwoJCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKHBjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwoJICAgIH0KCSAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CgkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CgkgICAgfQoJICAgIHBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgYnJlYWs7Cgl9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvckVsZW1lbnQocGN0eHQsIHBhcnRpY2xlKTsKCSAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBzdWI7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIG1heCBhbmQgbWluIG9jY3VyYW5jZXMgYXJlIGRlZmF1bHQgKDEpIHRoZW4KICAgICAgICAgICAgICAgICAqIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlIHBhcnRpY2xlcyBvZiB0aGUgPHNlcXVlbmNlPi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDEpICYmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlID0gcGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJCQlvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IHBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwKCQkJCXBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLCBVTkJPVU5ERUQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBjb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBwY3R4dC0+c3RhdGU7CgoJCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKCQkJICAgIC8qCgkJCSAgICAgKiBlcHNpbG9uIG5lZWRlZCB0byBibG9jayBwcmV2aW91cyB0cmFucyBmcm9tCgkJCSAgICAgKiBiZWluZyBhbGxvd2VkIHRvIGVudGVyIGJhY2sgZnJvbSBhbm90aGVyCgkJCSAgICAgKiBjb25zdHJ1Y3QKCQkJICAgICAqLwoJCQkgICAgcGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQkJCQkJcGN0eHQtPnN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJICAgIG9sZHN0YXRlLCBwY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocGFydGljbGUtPm1heE9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAocGFydGljbGUtPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJCSAgICBvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gcGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sCgkJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwKCQkJICAgIHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLAoJCQkgICAgdG1wLCBvbGRzdGF0ZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIHRtcCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIHBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJCSh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgc3ViOwogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gcGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzIGFuZCByZW1lcmdlIHRoZSBlbmQgd2l0aCBhbgogICAgICAgICAgICAgICAgICogZXBzaWxvbiB0cmFuc2l0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBlbmQpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcCwgYmFzZTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4T2NjdXJzID0gcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwogICAgICAgICAgICAgICAgICAgICAgICBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWluT2NjdXJzID0KICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogdXNlIGEgY291bnRlciB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgdHJhbnN0aW9ucwogICAgICAgICAgICAgICAgICAgICAqIHdoaWNoIHdlbnQgdGhyb3VnaCB0aGUgY2hvaWNlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPQogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXIocGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CiAgICAgICAgICAgICAgICAgICAgaG9wID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwogICAgICAgICAgICAgICAgICAgIGJhc2UgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJCSAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSBiYXNlOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yik7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgaG9wKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBzdGFydCwgYmFzZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwgaG9wLCBiYXNlLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIGhvcCwgZW5kLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBzdGFydCwgZW5kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOnsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgkJeG1sU2NoZW1hUGFydGljbGVQdHIgc3ViOwoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CiAgICAgICAgICAgICAgICBpbnQgbGF4OwoKCQlzdWIgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICBpZiAoc3ViID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoKCQkgICAgZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3ViLT5jaGlsZHJlbjsKCQkgICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsIiwKCQkJICAgICI8ZWxlbWVudD4gcGFydGljbGUgaGFzIG5vIHRlcm0iKTsKCQkJcmV0dXJuOwoJCSAgICB9OwoJCSAgICAvKgoJCSAgICAqIE5PVEU6IFRoZSB7bWF4IG9jY3Vyc30gb2YgYWxsIHRoZSBwYXJ0aWNsZXMgaW4gdGhlCgkJICAgICoge3BhcnRpY2xlc30gb2YgdGhlIGdyb3VwIG11c3QgYmUgMCBvciAxOyB0aGlzIGlzCgkJICAgICogYWxyZWFkeSBlbnN1cmVkIGR1cmluZyB0aGUgcGFyc2Ugb2YgdGhlIGNvbnRlbnQgb2YKCQkgICAgKiA8YWxsPi4KCQkgICAgKi8KCQkgICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fU1VCU1RfR1JPVVBfSEVBRCkgewoJCQlpbnQgY291bnRlcjsKCgkJICAgICAgICAvKgoJCQkgKiBUaGlzIGlzIGFuIGFic3RyYWN0IGdyb3VwLCB3ZSBuZWVkIHRvIHNoYXJlCgkJCSAqIHRoZSBzYW1lIGNvdW50ZXIgZm9yIGFsbCB0aGUgZWxlbWVudCB0cmFuc2l0aW9ucwoJCQkgKiBkZXJpdmVkIGZyb20gdGhlIGdyb3VwCgkJCSAqLwoJCQljb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwKCQkJICAgICAgICAgICAgICAgICAgIHN1Yi0+bWluT2NjdXJzLCBzdWItPm1heE9jY3Vycyk7CgkJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cChwY3R4dCwKCQkJCQkgICBzdWIsIGNvdW50ZXIsIHBjdHh0LT5zdGF0ZSk7CgkJICAgIH0gZWxzZSB7CgkJCWlmICgoc3ViLT5taW5PY2N1cnMgPT0gMSkgJiYKCQkJICAgIChzdWItPm1heE9jY3VycyA9PSAxKSkgewoJCQkgICAgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLAoJCQkJCQkgICAgcGN0eHQtPnN0YXRlLAoJCQkJCQkgICAgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSAgICBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkJCQkgICAgMSwgMSwgZWxlbURlY2wpOwoJCQl9IGVsc2UgaWYgKChzdWItPm1pbk9jY3VycyA9PSAwKSAmJgoJCQkgICAgKHN1Yi0+bWF4T2NjdXJzID09IDEpKSB7CgoJCQkgICAgeG1sQXV0b21hdGFOZXdDb3VudFRyYW5zMihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwKCQkJCQkJICAgICBwY3R4dC0+c3RhdGUsCgkJCQkJCSAgICAgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSAgICAgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJCQkJICAgICAwLAoJCQkJCQkgICAgIDEsCgkJCQkJCSAgICAgZWxlbURlY2wpOwoJCQl9CgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBzdWIgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxheCA9IHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMDsKICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdBbGxUcmFucyhwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgTlVMTCwgbGF4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICAvKgoJICAgICogSWYgd2UgaGl0IGEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiwgdGhlbiB0aGlzIG1lYW5zIHRoYXQKCSAgICAqIGl0IHdhcyBlbXB0eSwgdGh1cyB3YXMgbm90IHN1YnN0aXR1dGVkIGZvciB0aGUgY29udGFpbmluZwoJICAgICogbW9kZWwgZ3JvdXAuIEp1c3QgZG8gbm90aGluZyBpbiB0aGlzIGNhc2UuCgkgICAgKiBUT0RPOiBCdXQgdGhlIGdyb3VwIHNob3VsZCBiZSBzdWJzdGl0dXRlZCBhbmQgbm90IG9jY3VyIGF0CgkgICAgKiBhbGwgaW4gdGhlIGNvbnRlbnQgbW9kZWwgYXQgdGhpcyBwb2ludC4gRml4IHRoaXMuCgkgICAgKi8KCSAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgoJICAgIHhtbFNjaGVtYUludGVybmFsRXJyMihBQ1RYVF9DQVNUIHBjdHh0LAoJCSJ4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwiLAoJCSJmb3VuZCB1bmV4cGVjdGVkIHRlcm0gb2YgdHlwZSAnJXMnIGluIGNvbnRlbnQgbW9kZWwiLAoJCVdYU19JVEVNX1RZUEVfTkFNRShwYXJ0aWNsZS0+Y2hpbGRyZW4pLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWw6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICoKICogQnVpbGRzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSBjb21wbGV4IHR5cGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fAoJKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB8fAoJKCh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpICYmCgkodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSkpCglyZXR1cm47CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgIkJ1aWxkaW5nIGNvbnRlbnQgbW9kZWwgZm9yICVzXG4iLCBuYW1lKTsKI2VuZGlmCiAgICBjdHh0LT5hbSA9IE5VTEw7CiAgICBjdHh0LT5hbSA9IHhtbE5ld0F1dG9tYXRhKCk7CiAgICBpZiAoY3R4dC0+YW0gPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICJDYW5ub3QgY3JlYXRlIGF1dG9tYXRhIGZvciBjb21wbGV4IHR5cGUgJXNcbiIsIHR5cGUtPm5hbWUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFHZXRJbml0U3RhdGUoY3R4dC0+YW0pOwogICAgLyoKICAgICogQnVpbGQgdGhlIGF1dG9tYXRvbi4KICAgICovCiAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoY3R4dCwgV1hTX1RZUEVfUEFSVElDTEUodHlwZSkpOwogICAgeG1sQXV0b21hdGFTZXRGaW5hbFN0YXRlKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSk7CiAgICB0eXBlLT5jb250TW9kZWwgPSB4bWxBdXRvbWF0YUNvbXBpbGUoY3R4dC0+YW0pOwogICAgaWYgKHR5cGUtPmNvbnRNb2RlbCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIHR5cGUtPm5vZGUsCgkgICAgIkZhaWxlZCB0byBjb21waWxlIHRoZSBjb250ZW50IG1vZGVsIiwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFJlZ2V4cElzRGV0ZXJtaW5pc3QodHlwZS0+Y29udE1vZGVsKSAhPSAxKSB7CiAgICAgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PVF9ERVRFUk1JTklTVElDLAoJICAgIC8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RERVRFUk1JTklTVCwgKi8KCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCB0eXBlLT5ub2RlLAoJICAgICJUaGUgY29udGVudCBtb2RlbCBpcyBub3QgZGV0ZXJtaW5pc3QiLCBOVUxMKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBERUJVR19DT05URU5UX1JFR0VYUAogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudCBtb2RlbCBvZiAlczpcbiIsIHR5cGUtPm5hbWUpOwogICAgICAgIHhtbFJlZ2V4cFByaW50KHN0ZGVyciwgdHlwZS0+Y29udE1vZGVsKTsKI2VuZGlmCiAgICB9CiAgICBjdHh0LT5zdGF0ZSA9IE5VTEw7CiAgICB4bWxGcmVlQXV0b21hdGEoY3R4dC0+YW0pOwogICAgY3R4dC0+YW0gPSBOVUxMOwp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZUVsZW1lbnRSZWZlcmVuY2VzOgogKiBAZWxlbTogIHRoZSBzY2hlbWEgZWxlbWVudCBjb250ZXh0CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBSZXNvbHZlcyB0aGUgcmVmZXJlbmNlcyBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCiAqIG9yIHBhcnRpY2xlLCB3aGljaCBoYXMgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBhcyBpdCdzCiAqIHRlcm0uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFSZXNvbHZlRWxlbWVudFJlZmVyZW5jZXMoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW1EZWNsID09IE5VTEwpIHx8CgkoKGVsZW1EZWNsICE9IE5VTEwpICYmCgkoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9SRVNPTFZFRCkpKQogICAgICAgIHJldHVybjsKICAgIGVsZW1EZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX1JFU09MVkVEOwoKICAgIGlmICgoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpICYmIChlbGVtRGVjbC0+bmFtZWRUeXBlICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJLyogKHR5cGUgZGVmaW5pdGlvbikgLi4uIG90aGVyd2lzZSB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcKCSogdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlIFthdHRyaWJ1dGVdIC4uLgoJKi8KCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgZWxlbURlY2wtPm5hbWVkVHlwZSwKCSAgICBlbGVtRGVjbC0+bmFtZWRUeXBlTnMpOwoJaWYgKHR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCVdYU19CQVNJQ19DQVNUIGVsZW1EZWNsLCBlbGVtRGVjbC0+bm9kZSwKCQkidHlwZSIsIGVsZW1EZWNsLT5uYW1lZFR5cGUsIGVsZW1EZWNsLT5uYW1lZFR5cGVOcywKCQlYTUxfU0NIRU1BX1RZUEVfQkFTSUMsICJ0eXBlIGRlZmluaXRpb24iKTsKCX0gZWxzZQoJICAgIGVsZW1EZWNsLT5zdWJ0eXBlcyA9IHR5cGU7CiAgICB9CiAgICBpZiAoZWxlbURlY2wtPnN1YnN0R3JvdXAgIT0gTlVMTCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBzdWJzdEhlYWQ7CgoJLyoKCSogRklYTUUgVE9ETzogRG8gd2UgbmVlZCBhIG5ldyBmaWVsZCBpbiBfeG1sU2NoZW1hRWxlbWVudCBmb3IKCSogc3Vic3RpdHV0aW9uR3JvdXA/CgkqLwoJc3Vic3RIZWFkID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGVsZW1EZWNsLT5zdWJzdEdyb3VwLAoJICAgIGVsZW1EZWNsLT5zdWJzdEdyb3VwTnMpOwoJaWYgKHN1YnN0SGVhZCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJV1hTX0JBU0lDX0NBU1QgZWxlbURlY2wsIE5VTEwsCgkJInN1YnN0aXR1dGlvbkdyb3VwIiwgZWxlbURlY2wtPnN1YnN0R3JvdXAsCgkJZWxlbURlY2wtPnN1YnN0R3JvdXBOcywgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFSZXNvbHZlRWxlbWVudFJlZmVyZW5jZXMoc3Vic3RIZWFkLCBjdHh0KTsKCSAgICAvKgoJICAgICogU2V0IHRoZSAic3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9uIi4KCSAgICAqIE5PVEUgdGhhdCBub3cgd2UgdXNlIHRoZSAicmVmRGVjbCIgZmllbGQgZm9yIHRoaXMuCgkgICAgKi8KCSAgICBXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCkgPSBzdWJzdEhlYWQ7CgkgICAgLyoKCSAgICAqIFRoZSB0eXBlIGRlZmluaXRpb25zIGlzIHNldCB0bzoKCSAgICAqIFNQRUMgIi4uLnRoZSB7dHlwZSBkZWZpbml0aW9ufSBvZiB0aGUgZWxlbWVudAoJICAgICogZGVjbGFyYXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1ZbcKCSAgICAqIG9mIHRoZSBzdWJzdGl0dXRpb25Hcm91cCBbYXR0cmlidXRlXSwgaWYgcHJlc2VudCIKCSAgICAqLwoJICAgIGlmIChlbGVtRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkKCQllbGVtRGVjbC0+c3VidHlwZXMgPSBzdWJzdEhlYWQtPnN1YnR5cGVzOwoJfQogICAgfQogICAgLyoKICAgICogU1BFQyAiVGhlIGRlZmluaXRpb24gb2YgYW55VHlwZSBzZXJ2ZXMgYXMgdGhlIGRlZmF1bHQgdHlwZSBkZWZpbml0aW9uCiAgICAqIGZvciBlbGVtZW50IGRlY2xhcmF0aW9ucyB3aG9zZSBYTUwgcmVwcmVzZW50YXRpb24gZG9lcyBub3Qgc3BlY2lmeSBvbmUuIgogICAgKi8KICAgIGlmICgoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpICYmCgkoZWxlbURlY2wtPm5hbWVkVHlwZSA9PSBOVUxMKSAmJgoJKGVsZW1EZWNsLT5zdWJzdEdyb3VwID09IE5VTEwpKQoJZWxlbURlY2wtPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlVW5pb25NZW1iZXJUeXBlczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNjaGVtYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBhbmQgYnVpbGRzIHRoZSAibWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMiIHByb3BlcnR5IG9mIHRoZSB1bmlvbgogKiBzaW1wbGUgdHlwZS4gVGhpcyBoYW5kbGVzIHBhcnQgKDEpLCBwYXJ0ICgyKSBpcyBkb25lIGluCiAqIHhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KCkKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVzb2x2ZVVuaW9uTWVtYmVyVHlwZXMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewoKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rLCBuZXdMaW5rOwogICAgeG1sU2NoZW1hVHlwZVB0ciBtZW1iZXJUeXBlOwoKICAgIC8qCiAgICAqIFNQRUMgKDEpICJJZiB0aGUgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gW0RlZmluaXRpb246XQogICAgKiBkZWZpbmUgdGhlIGV4cGxpY2l0IG1lbWJlcnMgYXMgdGhlIHR5cGUgZGVmaW5pdGlvbnMgt3Jlc29sdmVktwogICAgKiB0byBieSB0aGUgaXRlbXMgaW4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSwKICAgICogaWYgYW55LCBmb2xsb3dlZCBieSB0aGUgdHlwZSBkZWZpbml0aW9ucyBjb3JyZXNwb25kaW5nIHRvIHRoZQogICAgKiA8c2ltcGxlVHlwZT5zIGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDx1bmlvbj4sIGlmIGFueS4iCiAgICAqLwogICAgLyoKICAgICogUmVzb2x2ZSByZWZlcmVuY2VzLgogICAgKi8KICAgIGxpbmsgPSB0eXBlLT5tZW1iZXJUeXBlczsKICAgIGxhc3RMaW5rID0gTlVMTDsKICAgIHdoaWxlIChsaW5rICE9IE5VTEwpIHsKCWNvbnN0IHhtbENoYXIgKm5hbWUsICpuc05hbWU7CgoJbmFtZSA9ICgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGxpbmstPnR5cGUpLT5uYW1lOwoJbnNOYW1lID0gKCh4bWxTY2hlbWFRTmFtZVJlZlB0cikgbGluay0+dHlwZSktPnRhcmdldE5hbWVzcGFjZTsKCgltZW1iZXJUeXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIG5hbWUsIG5zTmFtZSk7CglpZiAoKG1lbWJlclR5cGUgPT0gTlVMTCkgfHwgKCEgV1hTX0lTX1NJTVBMRShtZW1iZXJUeXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgdHlwZS0+bm9kZSwgIm1lbWJlclR5cGVzIiwKCQluYW1lLCBuc05hbWUsIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJICAgIC8qCgkgICAgKiBSZW1vdmUgdGhlIG1lbWJlciB0eXBlIGxpbmsuCgkgICAgKi8KCSAgICBpZiAobGFzdExpbmsgPT0gTlVMTCkKCQl0eXBlLT5tZW1iZXJUeXBlcyA9IGxpbmstPm5leHQ7CgkgICAgZWxzZQoJCWxhc3RMaW5rLT5uZXh0ID0gbGluay0+bmV4dDsKCSAgICBuZXdMaW5rID0gbGluazsKCSAgICBsaW5rID0gbGluay0+bmV4dDsKCSAgICB4bWxGcmVlKG5ld0xpbmspOwoJfSBlbHNlIHsKCSAgICBsaW5rLT50eXBlID0gbWVtYmVyVHlwZTsKCSAgICBsYXN0TGluayA9IGxpbms7CgkgICAgbGluayA9IGxpbmstPm5leHQ7Cgl9CiAgICB9CiAgICAvKgogICAgKiBBZGQgbG9jYWwgc2ltcGxlIHR5cGVzLAogICAgKi8KICAgIG1lbWJlclR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKICAgIHdoaWxlIChtZW1iZXJUeXBlICE9IE5VTEwpIHsKCWxpbmsgPSAoeG1sU2NoZW1hVHlwZUxpbmtQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZUxpbmspKTsKCWlmIChsaW5rID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgdHlwZSBsaW5rIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglsaW5rLT50eXBlID0gbWVtYmVyVHlwZTsKCWxpbmstPm5leHQgPSBOVUxMOwoJaWYgKGxhc3RMaW5rID09IE5VTEwpCgkgICAgdHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rOwoJZWxzZQoJICAgIGxhc3RMaW5rLT5uZXh0ID0gbGluazsKCWxhc3RMaW5rID0gbGluazsKCW1lbWJlclR5cGUgPSBtZW1iZXJUeXBlLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVmaW5pdGlvbgogKiBAdmFsVHlwZTogdGhlIHZhbHVlIHR5cGUKICoKICoKICogUmV0dXJucyAxIGlmIHRoZSB0eXBlIGhhcyB0aGUgZ2l2ZW4gdmFsdWUgdHlwZSwgb3IKICogaXMgZGVyaXZlZCBmcm9tIHN1Y2ggYSB0eXBlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgdmFsVHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAoV1hTX0lTX0NPTVBMRVgodHlwZSkpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gdmFsVHlwZSkKCSAgICByZXR1cm4oMSk7CglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHx8CgkgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoJICAgIHJldHVybiAoMCk7CglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzLCB2YWxUeXBlKSk7CiAgICB9CiAgICByZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzLCB2YWxUeXBlKSk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBoYXMgdGhlIGdpdmVuIHZhbHVlIHR5cGUsIG9yCiAqIGlzIGRlcml2ZWQgZnJvbSBzdWNoIGEgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNVc2VyRGVyaXZlZEZyb21CdWlsdEluVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCB2YWxUeXBlKQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGlmIChXWFNfSVNfQ09NUExFWCh0eXBlKSkKCXJldHVybiAoMCk7CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5idWlsdEluVHlwZSA9PSB2YWxUeXBlKQoJICAgIHJldHVybigxKTsKCXJldHVybiAoMCk7CiAgICB9IGVsc2UKCXJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUodHlwZS0+c3VidHlwZXMsIHZhbFR5cGUpKTsKCiAgICByZXR1cm4gKDApOwp9CiNlbmRpZgoKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUXVlcnlCdWlsdEluVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKFdYU19JU19DT01QTEVYKHR5cGUpKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCXJldHVybih0eXBlKTsKICAgIHJldHVybih4bWxTY2hlbWFRdWVyeUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKCiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CgkvKgoJKiBOb3RlIHRoYXQgYW55U2ltcGxlVHlwZSBpcyBhY3R1YWxseSBub3QgYSBwcmltaXRpdmUgdHlwZQoJKiBidXQgd2UgbmVlZCB0aGF0IGhlcmUuCgkqLwoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSB8fAoJICAgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkpCgkgICAgcmV0dXJuICh0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CgojaWYgMAovKioKICogeG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3RvcjoKICogQHR5cGU6ICB0aGUgc2ltcGxlVHlwZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIHByaW1pdGl2ZSB0eXBlIG9mIHRoZSBnaXZlbiB0eXBlIG9yCiAqIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlQW5jZXN0b3IoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAoV1hTX0lTX0xJU1QodHlwZSkgfHwgV1hTX0lTX1VOSU9OKHR5cGUpKQoJcmV0dXJuICgwKTsKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVzdDogIHRoZSBkZXN0aW5hdGlvbiB3aWxkY2FyZAogKiBAc291cmNlOiB0aGUgc291cmNlIHdpbGRjYXJkCiAqCiAqIENsb25lcyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHNvdXJjZQogKiBhbmQgYXNzaWduZXMgdGhlbSB0byBkZXN0LgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGRlc3QsCgkJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgc291cmNlKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgdG1wLCBsYXN0OwoKICAgIGlmICgoc291cmNlID09IE5VTEwpIHx8IChkZXN0ID09IE5VTEwpKQoJcmV0dXJuKC0xKTsKICAgIGRlc3QtPmFueSA9IHNvdXJjZS0+YW55OwogICAgY3VyID0gc291cmNlLT5uc1NldDsKICAgIGxhc3QgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7Cgl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICh0bXAgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgIGRlc3QtPm5zU2V0ID0gdG1wOwoJZWxzZQoJICAgIGxhc3QtPm5leHQgPSB0bXA7CglsYXN0ID0gdG1wOwoJY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgaWYgKGRlc3QtPm5lZ05zU2V0ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChkZXN0LT5uZWdOc1NldCk7CiAgICBpZiAoc291cmNlLT5uZWdOc1NldCAhPSBOVUxMKSB7CglkZXN0LT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKGRlc3QtPm5lZ05zU2V0ID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCWRlc3QtPm5lZ05zU2V0LT52YWx1ZSA9IHNvdXJjZS0+bmVnTnNTZXQtPnZhbHVlOwogICAgfSBlbHNlCglkZXN0LT5uZWdOc1NldCA9IE5VTEw7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFVbmlvbldpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQKICoKICogVW5pb25zIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyB1bmlvbi4KICogUmV0dXJucyBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZSwgLTEgaW4gY2FzZSBvZiBhbgogKiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCgkJLyoKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZQogICAgKi8KICAgIGlmIChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpIHsKCWlmIChjb21wbGV0ZVdpbGQtPmFueSA9PSAwKSB7CgkgICAgY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCXhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDMgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksCiAgICAqIHRoZW4gdGhlIHVuaW9uIG9mIHRob3NlIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgewoJaW50IGZvdW5kOwoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzdGFydDsKCgljdXIgPSBjdXJXaWxkLT5uc1NldDsKCXN0YXJ0ID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGZvdW5kID0gMDsKCSAgICBjdXJCID0gc3RhcnQ7CgkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJICAgIGZvdW5kID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCWN1ckIgPSBjdXJCLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoIWZvdW5kKSB7CgkJdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKHRtcCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCQl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCQl0bXAtPm5leHQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSB0bXA7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgKiA0IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgdmFsdWVzIChuYW1lc3BhY2UgbmFtZXMKICAgICogb3Igt2Fic2VudLcpLCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoKCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAgKiA1LgogICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWludCBuc0ZvdW5kLCBhYnNlbnRGb3VuZCA9IDA7CgoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5lZ05zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICBjdXJCID0gY29tcGxldGVXaWxkLT5uZWdOc1NldDsKCX0KCW5zRm91bmQgPSAwOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkKCQlhYnNlbnRGb3VuZCA9IDE7CgkgICAgZWxzZSBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkKCQluc0ZvdW5kID0gMTsKCSAgICBpZiAobnNGb3VuZCAmJiBhYnNlbnRGb3VuZCkKCQlicmVhazsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CgoJaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyBib3RoIHRoZSBuZWdhdGVkIG5hbWVzcGFjZQoJICAgICogbmFtZSBhbmQgt2Fic2VudLcsIHRoZW4gYW55IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCXhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkgICAgfQoJfSBlbHNlIGlmIChuc0ZvdW5kICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyoKCSAgICAqIDUuMiBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIG5hbWUKCSAgICAqIGJ1dCBub3Qgt2Fic2VudLcsIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdAoJICAgICogYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4zIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tyBidXQgbm90IHRoZSBuZWdhdGVkCgkgICAgKiBuYW1lc3BhY2UgbmFtZSwgdGhlbiB0aGUgdW5pb24gaXMgbm90IGV4cHJlc3NpYmxlLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsCgkJWE1MX1NDSEVNQVBfVU5JT05fTk9UX0VYUFJFU1NJQkxFLAoJCSJUaGUgdW5pb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oWE1MX1NDSEVNQVBfVU5JT05fTk9UX0VYUFJFU1NJQkxFKTsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiAoIWFic2VudEZvdW5kKSkgewoJICAgIC8qCgkgICAgKiA1LjQgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuZWdhdGVkIG5hbWVzcGFjZQoJICAgICogbmFtZSBvciC3YWJzZW50tywgdGhlbiB3aGljaGV2ZXIgb2YgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdAoJICAgICogYW5kIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkJfQoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICB9Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICAqIDYuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7CgoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl9IGVsc2UgewoJICAgIGN1ciA9IGN1cldpbGQtPm5zU2V0OwoJfQoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCS8qCgkJKiA2LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZQoJCSogdmFsdWUuCgkJKi8KCQljb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkJfQoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkJfQoJCXJldHVybiAoMCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogNi4yIElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QKCSAgICAqIGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJcmV0dXJuICgtMSk7CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cgp9CgovKioKICogeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGNvbXBsZXRlV2lsZDogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAY3VyV2lsZDogdGhlIHNlY29uZCB3aWxkY2FyZAogKgogKiBJbnRlcnNlY3RzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyBpbnRlcnNlY3Rpb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY29tcGxldGVXaWxkLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY3VyV2lsZCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckIsIHByZXYsICB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCgkJLyoKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIHRoZSBvdGhlciBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ICE9IGN1cldpbGQtPmFueSkgJiYgKGNvbXBsZXRlV2lsZC0+YW55KSkgewoJaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsIGNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAqIDMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgdmFsdWUgKGEgbmFtZXNwYWNlCiAgICAqIG5hbWUgb3Igt2Fic2VudLcpIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YgKG5hbWVzcGFjZSBuYW1lcyBvcgogICAgKiC3YWJzZW50tyksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkIHZhbHVlIGlmIGl0IHdhcyBpbgogICAgKiB0aGUgc2V0LCBtaW51cyC3YWJzZW50tyBpZiBpdCB3YXMgaW4gdGhlIHNldCwgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoJY29uc3QgeG1sQ2hhciAqbmVnOwoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpIHsKCSAgICBuZWcgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJfSBlbHNlCgkgICAgbmVnID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJLyoKCSogUmVtb3ZlIGFic2VudCBhbmQgbmVnYXRlZC4KCSovCglwcmV2ID0gTlVMTDsKCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQllbHNlCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCWlmIChuZWcgIT0gTlVMTCkgewoJICAgIHByZXYgPSBOVUxMOwoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gbmVnKSB7CgkJICAgIGlmIChwcmV2ID09IE5VTEwpCgkJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJICAgIGVsc2UKCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkgICAgeG1sRnJlZShjdXIpOwoJCSAgICBicmVhazsKCQl9CgkJcHJldiA9IGN1cjsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJfQoKCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAqIDQgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsKCWludCBmb3VuZDsKCgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJcHJldiA9IE5VTEw7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXRtcCA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKGN1cik7CgkJY3VyID0gdG1wOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKiA1IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzLAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gaXMgbm90IGV4cHJlc3NpYmxlCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkpIHsKCgl4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSwKCSAgICAiVGhlIGludGVyc2VjdGlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGUuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuKFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUpOwogICAgfQogICAgLyoKICAgICogNiBJZiB0aGUgb25lIGlzIGEgbmVnYXRpb24gb2YgYSBuYW1lc3BhY2UgbmFtZSBhbmQgdGhlIG90aGVyCiAgICAqIGlzIGEgbmVnYXRpb24gb2Ygt2Fic2VudLcsIHRoZW4gdGhlIG9uZSB3aGljaCBpcyB0aGUgbmVnYXRpb24KICAgICogb2YgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpKSB7Cgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9ICBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHN1YjogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAc3VwZXI6IHRoZSBzZWNvbmQgd2lsZGNhcmQKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBXaWxkY2FyZCBTdWJzZXQgKGNvcy1ucy1zdWJzZXQpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnQgb2YgQHN1YiBpcyBhbiBpbnRlbnNpb25hbAogKiBzdWJzZXQgb2YgQHN1cGVyLCAxIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NOU1N1YnNldCh4bWxTY2hlbWFXaWxkY2FyZFB0ciBzdWIsCgkJCSAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgc3VwZXIpCnsKICAgIC8qCiAgICAqIDEgc3VwZXIgbXVzdCBiZSBhbnkuCiAgICAqLwogICAgaWYgKHN1cGVyLT5hbnkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogMi4xIHN1YiBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3Igt2Fic2VudLcuCiAgICAqIDIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIHRoZSBzYW1lIHZhbHVlLgogICAgKi8KICAgIGlmICgoc3ViLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHN1cGVyLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHN1Yi0+bmVnTnNTZXQtPnZhbHVlID09IHN1Yi0+bmVnTnNTZXQtPnZhbHVlKSkKCXJldHVybiAoMCk7CiAgICAvKgogICAgKiAzLjEgc3ViIG11c3QgYmUgYSBzZXQgd2hvc2UgbWVtYmVycyBhcmUgZWl0aGVyIG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50ty4KICAgICovCiAgICBpZiAoc3ViLT5uc1NldCAhPSBOVUxMKSB7CgkvKgoJKiAzLjIuMSBzdXBlciBtdXN0IGJlIHRoZSBzYW1lIHNldCBvciBhIHN1cGVyc2V0IHRoZXJlb2YuCgkqLwoJaWYgKHN1cGVyLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckI7CgkgICAgaW50IGZvdW5kID0gMDsKCgkgICAgY3VyID0gc3ViLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJY3VyQiA9IHN1cGVyLT5uc1NldDsKCQl3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJICAgIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCWZvdW5kID0gMTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgY3VyQiA9IGN1ckItPm5leHQ7CgkJfQoJCWlmICghZm91bmQpCgkJICAgIHJldHVybiAoMSk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoZm91bmQpCgkJcmV0dXJuICgwKTsKCX0gZWxzZSBpZiAoc3VwZXItPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCSAgICAvKgoJICAgICogMy4yLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yCgkgICAgKiC3YWJzZW50tyBhbmQgdGhhdCB2YWx1ZSBtdXN0IG5vdCBiZSBpbiBzdWIncyBzZXQuCgkgICAgKi8KCSAgICBjdXIgPSBzdWItPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IHN1cGVyLT5uZWdOc1NldC0+dmFsdWUpCgkJICAgIHJldHVybiAoMSk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCSAgICByZXR1cm4gKDApOwoJfQogICAgfQogICAgcmV0dXJuICgxKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIGF0dHJ1c2UsCgkJCQkgICAgIGludCAqZml4ZWQsCgkJCQkgICAgIGNvbnN0IHhtbENoYXIgKip2YWx1ZSwKCQkJCSAgICAgeG1sU2NoZW1hVmFsUHRyICp2YWwpCnsKICAgICpmaXhlZCA9IDA7CiAgICAqdmFsdWUgPSBOVUxMOwogICAgaWYgKHZhbCAhPSAwKQoJKnZhbCA9IE5VTEw7CgogICAgaWYgKGF0dHJ1c2UtPmRlZlZhbHVlICE9IE5VTEwpIHsJICAgIAoJKnZhbHVlID0gYXR0cnVzZS0+ZGVmVmFsdWU7CglpZiAodmFsICE9IE5VTEwpCgkgICAgKnZhbCA9IGF0dHJ1c2UtPmRlZlZhbDsKCWlmIChhdHRydXNlLT5mbGFncyAmIFhNTF9TQ0hFTUFfQVRUUl9VU0VfRklYRUQpCgkgICAgKmZpeGVkID0gMTsKCXJldHVybigxKTsKICAgIH0gZWxzZSBpZiAoKGF0dHJ1c2UtPmF0dHJEZWNsICE9IE5VTEwpICYmCgkoYXR0cnVzZS0+YXR0ckRlY2wtPmRlZlZhbHVlICE9IE5VTEwpKSB7CgkqdmFsdWUgPSBhdHRydXNlLT5hdHRyRGVjbC0+ZGVmVmFsdWU7CglpZiAodmFsICE9IE5VTEwpCgkgICAgKnZhbCA9IGF0dHJ1c2UtPmF0dHJEZWNsLT5kZWZWYWw7CglpZiAoYXR0cnVzZS0+YXR0ckRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkKCSAgICAqZml4ZWQgPSAxOwoJcmV0dXJuKDEpOwogICAgfQogICAgcmV0dXJuKDApOwp9Ci8qKgogKiB4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlOgogKiBAd2lsZDogIHRoZSB3aWxkY2FyZAogKiBAbnM6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIFZhbGlkYXRpb24gUnVsZTogV2lsZGNhcmQgYWxsb3dzIE5hbWVzcGFjZSBOYW1lCiAqIChjdmMtd2lsZGNhcmQtbmFtZXNwYWNlKQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGdpdmVuIG5hbWVzcGFjZSBtYXRjaGVzIHRoZSB3aWxkY2FyZCwKICogMSBvdGhlcndpc2UgYW5kIC0xIG9uIEFQSSBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDV2lsZGNhcmROYW1lc3BhY2UoeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwKCQkJCSAgIGNvbnN0IHhtbENoYXIqIG5zKQp7CiAgICBpZiAod2lsZCA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDApOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigwKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYKCSgheG1sU3RyRXF1YWwod2lsZC0+bmVnTnNTZXQtPnZhbHVlLCBucykpKQoJcmV0dXJuKDApOwoKICAgIHJldHVybigxKTsKfQoKI2RlZmluZSBYTUxfU0NIRU1BX0FDVElPTl9ERVJJVkUgMAojZGVmaW5lIFhNTF9TQ0hFTUFfQUNUSU9OX1JFREVGSU5FIDEKCiNkZWZpbmUgV1hTX0FDVElPTl9TVFIoYSkgXAooKGEpID09IFhNTF9TQ0hFTUFfQUNUSU9OX0RFUklWRSkgPyAoY29uc3QgeG1sQ2hhciAqKSAiYmFzZSIgOiAoY29uc3QgeG1sQ2hhciAqKSAicmVkZWZpbmVkIgoKLyoKKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiogICBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkKKiAgIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gKDIpIC0gKDQpCioKKiBBVFRFTlRJT046CiogSW4gWE1MIFNjaGVtYSAxLjEgdGhpcyB3aWxsIGJlOgoqIFZhbGlkYXRpb24gUnVsZToKKiAgICAgQ2hlY2tpbmcgY29tcGxleCB0eXBlIHN1YnN1bXB0aW9uIChwcmFjdGljYWxTdWJzdW1wdGlvbikgKDEsIDIgYW5kIDMpCioKKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25PS1Jlc3RyaWN0aW9uMnRvNCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICAgIGludCBhY3Rpb24sCgkJCQkgICAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0sCgkJCQkgICAgICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGJhc2VJdGVtLAoJCQkJICAgICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHVzZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgYmFzZVVzZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwKCQkJCSAgICAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBiYXNlV2lsZCkKeyAgICAgICAgCiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgY3VyID0gTlVMTCwgYmN1cjsKICAgIGludCBpLCBqLCBmb3VuZDsgLyogZXJyID0gMDsgKi8KICAgIGNvbnN0IHhtbENoYXIgKmJFZmZWYWx1ZTsKICAgIGludCBlZmZGaXhlZDsKICAgIAogICAgaWYgKHVzZXMgIT0gTlVMTCkgewoJZm9yIChpID0gMDsgaSA8IHVzZXMtPm5iSXRlbXM7IGkrKykgewoJICAgIGN1ciA9IHVzZXMtPml0ZW1zW2ldOwoJICAgIGZvdW5kID0gMDsKCSAgICBpZiAoYmFzZVVzZXMgPT0gTlVMTCkKCQlnb3RvIG5vdF9mb3VuZDsKCSAgICBmb3IgKGogPSAwOyBqIDwgYmFzZVVzZXMtPm5iSXRlbXM7IGorKykgewoJCWJjdXIgPSBiYXNlVXNlcy0+aXRlbXNbal07CQoJCWlmICgoV1hTX0FUVFJVU0VfREVDTF9OQU1FKGN1cikgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9OQU1FKGJjdXIpKSAmJgoJCSAgICAoV1hTX0FUVFJVU0VfREVDTF9UTlMoY3VyKSA9PQoJCQlXWFNfQVRUUlVTRV9ERUNMX1ROUyhiY3VyKSkpCgkJewoJCSAgICAvKgoJCSAgICAqICgyLjEpICJJZiB0aGVyZSBpcyBhbiBhdHRyaWJ1dGUgdXNlIGluIHRoZSB7YXR0cmlidXRlCgkJICAgICogdXNlc30gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gKGNhbGwgdGhpcyBCKSB3aG9zZQoJCSAgICAqIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyB0aGUgc2FtZSB7bmFtZX0gYW5kIHt0YXJnZXQKCQkgICAgKiBuYW1lc3BhY2V9LCB0aGVuICBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJCSAgICAqLwoJCSAgICBmb3VuZCA9IDE7CgkJICAgIAoJCSAgICBpZiAoKGN1ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJCQkoYmN1ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkKCQkgICAgewoJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoJCQkvKgoJCQkqICgyLjEuMSkgIm9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkJCSogKDIuMS4xLjEpICJCJ3Mge3JlcXVpcmVkfSBpcyBmYWxzZS4iCgkJCSogKDIuMS4xLjIpICJSJ3Mge3JlcXVpcmVkfSBpcyB0cnVlLiIKCQkJKi8KCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnI0KHBjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMSwKCQkJICAgIFdYU19JVEVNX05PREUoaXRlbSksIGl0ZW0sIGN1ciwKCQkJICAgICJUaGUgJ29wdGlvbmFsJyBhdHRyaWJ1dGUgdXNlIGlzIGluY29uc2lzdGVudCAiCgkJCSAgICAid2l0aCB0aGUgY29ycmVzcG9uZGluZyAncmVxdWlyZWQnIGF0dHJpYnV0ZSB1c2Ugb2YgIgoJCQkgICAgInRoZSAlcyAlcyIsCgkJCSAgICBXWFNfQUNUSU9OX1NUUihhY3Rpb24pLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgYmFzZUl0ZW0pLAoJCQkgICAgTlVMTCwgTlVMTCk7CgkJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQkJLyogZXJyID0gcGN0eHQtPmVycjsgKi8KCQkgICAgfSBlbHNlIGlmICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKEFDVFhUX0NBU1QgcGN0eHQsCgkJCVdYU19BVFRSVVNFX1RZUEVERUYoY3VyKSwKCQkJV1hTX0FUVFJVU0VfVFlQRURFRihiY3VyKSwgMCkgIT0gMCkKCQkgICAgewoJCQl4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMLCAqc3RyQyA9IE5VTEw7CgkJCQoJCQkvKgoJCQkqIFNQRUMgKDIuMS4yKSAiUidzIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3MKCQkJKiB7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tCgkJCSogQidzIHt0eXBlIGRlZmluaXRpb259IGdpdmVuIHRoZSBlbXB0eSBzZXQgYXMKCQkJKiBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuIgoJCQkqLwoJCQl4bWxTY2hlbWFQQXR0clVzZUVycjQocGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8yLAoJCQkgICAgV1hTX0lURU1fTk9ERShpdGVtKSwgaXRlbSwgY3VyLAoJCQkgICAgIlRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24ncyAlcyAiCgkJCSAgICAiaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tICIKCQkJICAgICJ0aGUgY29ycmVzcG9uZGluZyAlcyBvZiB0aGUgIgoJCQkgICAgImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBpbiB0aGUgJXMgJXMiLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckEsCgkJCQlXWFNfQVRUUlVTRV9UWVBFREVGKGN1cikpLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckIsCgkJCQlXWFNfQVRUUlVTRV9UWVBFREVGKGJjdXIpKSwKCQkJICAgIFdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyQywgYmFzZUl0ZW0pKTsKCQkJICAgIC8qIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHIsIGJhc2VJdGVtKSwgKi8KCQkJRlJFRV9BTkRfTlVMTChzdHJBKTsKCQkJRlJFRV9BTkRfTlVMTChzdHJCKTsKCQkJRlJFRV9BTkRfTlVMTChzdHJDKTsKCQkJLyogZXJyID0gcGN0eHQtPmVycjsgKi8KCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiAyLjEuMyBbRGVmaW5pdGlvbjpdICBMZXQgdGhlIGVmZmVjdGl2ZSB2YWx1ZQoJCQkqIGNvbnN0cmFpbnQgb2YgYW4gYXR0cmlidXRlIHVzZSBiZSBpdHMge3ZhbHVlCgkJCSogY29uc3RyYWludH0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSBpdHMge2F0dHJpYnV0ZQoJCQkqIGRlY2xhcmF0aW9ufSdzIHt2YWx1ZSBjb25zdHJhaW50fSAuCgkJCSovCgkJCXhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiY3VyLAoJCQkgICAgJmVmZkZpeGVkLCAmYkVmZlZhbHVlLCBOVUxMKTsKCQkJLyoKCQkJKiAyLjEuMyAuLi4gb25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlCgkJCSoKCQkJKiAyLjEuMy4xIEIncyC3ZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnS3IGlzCgkJCSogt2Fic2VudLcgb3IgZGVmYXVsdC4KCQkJKi8KCQkJaWYgKChiRWZmVmFsdWUgIT0gTlVMTCkgJiYKCQkJICAgIChlZmZGaXhlZCA9PSAxKSkgewoJCQkgICAgY29uc3QgeG1sQ2hhciAqckVmZlZhbHVlID0gTlVMTDsKCQkJICAgIAoJCQkgICAgeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGJjdXIsCgkJCQkmZWZmRml4ZWQsICZyRWZmVmFsdWUsIE5VTEwpOwoJCQkgICAgLyoKCQkJICAgICogMi4xLjMuMiBSJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcwoJCQkgICAgKiBmaXhlZCB3aXRoIHRoZSBzYW1lIHN0cmluZyBhcyBCJ3MuCgkJCSAgICAqIE1BWUJFIFRPRE86IENvbXBhcmUgdGhlIGNvbXB1dGVkIHZhbHVlcy4KCQkJICAgICogICAgICAgSG1tLCBpdCBzYXlzICJzYW1lIHN0cmluZyIgc28KCQkJICAgICogICAgICAgc3RyaW5nLWVxdWFsaXR5IG1pZ2h0IHJlYWxseSBiZSBzdWZmaWNpZW50LgoJCQkgICAgKi8KCQkJICAgIGlmICgoZWZmRml4ZWQgPT0gMCkgfHwKCQkJCSghIFdYU19BUkVfREVGQVVMVF9TVFJfRVFVQUwockVmZlZhbHVlLCBiRWZmVmFsdWUpKSkKCQkJICAgIHsKCQkJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJCQkKCQkJCXhtbFNjaGVtYVBBdHRyVXNlRXJyNChwY3R4dCwKCQkJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8zLAoJCQkJICAgIFdYU19JVEVNX05PREUoaXRlbSksIGl0ZW0sIGN1ciwKCQkJCSAgICAiVGhlIGVmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJCQkgICAgImF0dHJpYnV0ZSB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggIgoJCQkJICAgICJpdHMgY29ycmVzcG9uZGVudCBpbiB0aGUgJXMgJXMiLAoJCQkJICAgIFdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwKCQkJCQliYXNlSXRlbSksCgkJCQkgICAgTlVMTCwgTlVMTCk7CgkJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCQkvKiBlcnIgPSBwY3R4dC0+ZXJyOyAqLwoJCQkgICAgfQoJCQl9CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJfQoJICAgIH0Kbm90X2ZvdW5kOgkKCSAgICBpZiAoIWZvdW5kKSB7CgkJLyoKCQkqICgyLjIpICJvdGhlcndpc2UgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGFuCgkJKiB7YXR0cmlidXRlIHdpbGRjYXJkfSBhbmQgdGhlIHt0YXJnZXQgbmFtZXNwYWNlfSBvZiB0aGUKCQkqIFIncyB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0CgkJKiB0byB0aGF0IHdpbGRjYXJkLCBhcyBkZWZpbmVkIGluIFdpbGRjYXJkIGFsbG93cyBOYW1lc3BhY2UKCQkqIE5hbWUgKKczLjEwLjQpLiIKCQkqLwoJCWlmICgoYmFzZVdpbGQgPT0gTlVMTCkgfHwKCQkgICAgKHhtbFNjaGVtYUNoZWNrQ1ZDV2lsZGNhcmROYW1lc3BhY2UoYmFzZVdpbGQsCgkJICAgIChXWFNfQVRUUlVTRV9ERUNMKGN1cikpLT50YXJnZXROYW1lc3BhY2UpICE9IDApKQoJCXsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkgICAgCgkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyNChwY3R4dCwKCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzIsCgkJCVdYU19JVEVNX05PREUoaXRlbSksIGl0ZW0sIGN1ciwKCQkJIk5laXRoZXIgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlLCAiCgkJCSJub3IgYSBtYXRjaGluZyB3aWxkY2FyZCBleGlzdHMgaW4gdGhlICVzICVzIiwKCQkJV1hTX0FDVElPTl9TVFIoYWN0aW9uKSwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgYmFzZUl0ZW0pLAoJCQlOVUxMLCBOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICAvKiBlcnIgPSBwY3R4dC0+ZXJyOyAqLwoJCX0KCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBTUEVDIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gKDMpOiAgICAKICAgICogKDMpICJGb3IgZWFjaCBhdHRyaWJ1dGUgdXNlIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSB7YmFzZSB0eXBlCiAgICAqIGRlZmluaXRpb259IHdob3NlIHtyZXF1aXJlZH0gaXMgdHJ1ZSwgdGhlcmUgbXVzdCBiZSBhbiBhdHRyaWJ1dGUKICAgICogdXNlIHdpdGggYW4ge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gd2l0aCB0aGUgc2FtZSB7bmFtZX0gYW5kCiAgICAqIHt0YXJnZXQgbmFtZXNwYWNlfSBhcyBpdHMge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaW4gdGhlIHthdHRyaWJ1dGUKICAgICogdXNlc30gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZiB3aG9zZSB7cmVxdWlyZWR9IGlzIHRydWUuCiAgICAqLwogICAgaWYgKGJhc2VVc2VzICE9IE5VTEwpIHsKCWZvciAoaiA9IDA7IGogPCBiYXNlVXNlcy0+bmJJdGVtczsgaisrKSB7CgkgICAgYmN1ciA9IGJhc2VVc2VzLT5pdGVtc1tqXTsKCSAgICBpZiAoYmN1ci0+b2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKQoJCWNvbnRpbnVlOwoJICAgIGZvdW5kID0gMDsKCSAgICBpZiAodXNlcyAhPSBOVUxMKSB7CgkJZm9yIChpID0gMDsgaSA8IHVzZXMtPm5iSXRlbXM7IGkrKykgewoJCSAgICBjdXIgPSB1c2VzLT5pdGVtc1tpXTsJCgkJICAgIGlmICgoV1hTX0FUVFJVU0VfREVDTF9OQU1FKGN1cikgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9OQU1FKGJjdXIpKSAmJgoJCQkoV1hTX0FUVFJVU0VfREVDTF9UTlMoY3VyKSA9PQoJCQlXWFNfQVRUUlVTRV9ERUNMX1ROUyhiY3VyKSkpIHsKCQkJZm91bmQgPSAxOwoJCQlicmVhazsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCXhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgkJCgkJeG1sU2NoZW1hQ3VzdG9tRXJyNChBQ1RYVF9DQVNUIHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzMsCgkJICAgIE5VTEwsIGl0ZW0sCgkJICAgICJBIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgZm9yIHRoZSAiCgkJICAgICIncmVxdWlyZWQnICVzIG9mIHRoZSAlcyAlcyBpcyBtaXNzaW5nIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ckEsIGJjdXIpLAoJCSAgICBXWFNfQUNUSU9OX1NUUihhY3Rpb24pLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnREZXNpZ25hdGlvbigmc3RyQiwgYmFzZUl0ZW0pLAoJCSAgICBOVUxMKTsKCQlGUkVFX0FORF9OVUxMKHN0ckEpOwoJCUZSRUVfQU5EX05VTEwoc3RyQik7CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAoNCkKICAgICovCiAgICBpZiAod2lsZCAhPSBOVUxMKSB7CgkvKgoJKiAoNCkgIklmIHRoZXJlIGlzIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LCBhbGwgb2YgdGhlCgkqIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJKi8gICAKCWlmIChiYXNlV2lsZCA9PSBOVUxMKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkgICAgLyoKCSAgICAqICg0LjEpICJUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGFsc28gaGF2ZSBvbmUuIgoJICAgICovCSAgICAKCSAgICB4bWxTY2hlbWFDdXN0b21FcnI0KEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzEsCgkJTlVMTCwgaXRlbSwKCQkiVGhlICVzIGhhcyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQsICIKCQkiYnV0IHRoZSAlcyAlcyAnJXMnIGRvZXMgbm90IGhhdmUgb25lIiwKCQlXWFNfSVRFTV9UWVBFX05BTUUoaXRlbSksCQkgICAgCgkJV1hTX0FDVElPTl9TVFIoYWN0aW9uKSwKCQlXWFNfSVRFTV9UWVBFX05BTUUoYmFzZUl0ZW0pLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGJhc2VJdGVtKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgIHJldHVybihwY3R4dC0+ZXJyKTsKCX0gZWxzZSBpZiAoKGJhc2VXaWxkLT5hbnkgPT0gMCkgJiYKCQl4bWxTY2hlbWFDaGVja0NPU05TU3Vic2V0KHdpbGQsIGJhc2VXaWxkKSkKCXsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIC8qCgkgICAgKiAoNC4yKSAiVGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncwoJICAgICoge25hbWVzcGFjZSBjb25zdHJhaW50fSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSB7YmFzZSB0eXBlCgkgICAgKiBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUgd2lsZGNhcmR9J3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSwKCSAgICAqIGFzIGRlZmluZWQgYnkgV2lsZGNhcmQgU3Vic2V0ICinMy4xMC42KS4iCgkgICAgKi8KCSAgICB4bWxTY2hlbWFDdXN0b21FcnI0KEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzIsCgkJTlVMTCwgaXRlbSwKCQkiVGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyBub3QgYSB2YWxpZCAiCgkJInN1YnNldCBvZiB0aGUgd2lsZGNhcmQgaW4gdGhlICVzICVzICclcyciLAoJCVdYU19BQ1RJT05fU1RSKGFjdGlvbiksCgkJV1hTX0lURU1fVFlQRV9OQU1FKGJhc2VJdGVtKSwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlSXRlbSksCgkJTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgIHJldHVybihwY3R4dC0+ZXJyKTsKCX0KCS8qIDQuMyBVbmxlc3MgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILd1ci10eXBlCgkqIGRlZmluaXRpb263LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlCgkqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSBtdXN0IGJlIGlkZW50aWNhbCB0byBvcgoJKiBzdHJvbmdlciB0aGFuIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2F0dHJpYnV0ZQoJKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlcgoJKiB0aGFuIGxheCBpcyBzdHJvbmdlciB0aGFuIHNraXAuCgkqLwoJaWYgKCghIFdYU19JU19BTllUWVBFKGJhc2VJdGVtKSkgJiYKCSAgICAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzIDwgYmFzZVdpbGQtPnByb2Nlc3NDb250ZW50cykpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycjQoQUNUWFRfQ0FTVCBwY3R4dCwKCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMywKCQlOVUxMLCBiYXNlSXRlbSwKCQkiVGhlIHtwcm9jZXNzIGNvbnRlbnRzfSBvZiB0aGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzICIKCQkid2Vha2VyIHRoYW4gdGhlIG9uZSBpbiB0aGUgJXMgJXMgJyVzJyIsCgkJV1hTX0FDVElPTl9TVFIoYWN0aW9uKSwKCQlXWFNfSVRFTV9UWVBFX05BTUUoYmFzZUl0ZW0pLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGJhc2VJdGVtKSwKCQlOVUxMKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4ocGN0eHQtPmVycik7Cgl9CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCgpzdGF0aWMgaW50CnhtbFNjaGVtYUV4cGFuZEF0dHJpYnV0ZUdyb3VwUmVmcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkJCSAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmNvbXBsZXRlV2lsZCwKCQkJCSAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCwKCQkJCSAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgcHJvaGlicyk7Ci8qKgogKiB4bWxTY2hlbWFGaXh1cFR5cGVBdHRyaWJ1dGVVc2VzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICoKICogQnVpbGRzIHRoZSB3aWxkY2FyZCBhbmQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFJldHVybnMgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLCAwIG90aGVyd2lzZS4KICoKICogQVRURU5USU9OIFRPRE86IEV4cGVyaW1hbnRhbGx5IHRoaXMgdXNlcyBwb2ludGVyIGNvbXBhcmlzb25zIGZvcgogKiBzdHJpbmdzLCBzbyByZWNoZWNrIHRoaXMgaWYgd2Ugc3RhcnQgdG8gaGFyZGNvZGUgc29tZSBzY2hlbWF0YSwgc2luY2UKICogdGhleSBtaWdodCBub3QgYmUgaW4gdGhlIHNhbWUgZGljdC4KICogTk9URTogSXQgaXMgYWxsb3dlZCB0byAiZXh0ZW5kIiB0aGUgeHM6YW55VHlwZSB0eXBlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFGaXh1cFR5cGVBdHRyaWJ1dGVVc2VzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlOyAgICAKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHVzZXMsIGJhc2VVc2VzLCBwcm9oaWJzID0gTlVMTDsKCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlcyIsCgkgICAgIm5vIGJhc2UgdHlwZSIpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsgICAgICAgIAogICAgaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChiYXNlVHlwZSkpCglpZiAoeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBBQ1RYVF9DQVNUIHBjdHh0KSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwoKICAgIHVzZXMgPSB0eXBlLT5hdHRyVXNlczsKICAgIGJhc2VVc2VzID0gYmFzZVR5cGUtPmF0dHJVc2VzOwogICAgLyoKICAgICogRXhwYW5kIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzLiBBbmQgYnVpbGQgdGhlICdjb21wbGV0ZScKICAgICogd2lsZGNhcmQsIGkuZS4gaW50ZXJzZWN0IG11bHRpcGxlIHdpbGRjYXJkcy4KICAgICogTW92ZSBhdHRyaWJ1dGUgcHJvaGliaXRpb25zIGludG8gYSBzZXBhcmF0ZSBsaXN0LgogICAgKi8KICAgIGlmICh1c2VzICE9IE5VTEwpIHsJCglpZiAoV1hTX0lTX1JFU1RSSUNUSU9OKHR5cGUpKSB7CgkgICAgLyoKCSAgICAqIFRoaXMgb25lIHdpbGwgdHJhbnNmZXIgYWxsIGF0dHIuIHByb2hpYml0aW9ucwoJICAgICogaW50byBwY3R4dC0+YXR0clByb2hpYnMuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzKHBjdHh0LAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsICYodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpLCB1c2VzLAoJCXBjdHh0LT5hdHRyUHJvaGlicykgPT0gLTEpCgkgICAgewoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUZpeHVwVHlwZUF0dHJpYnV0ZVVzZXMiLAoJCSJmYWlsZWQgdG8gZXhwYW5kIGF0dHJpYnV0ZXMiKTsKCSAgICB9CgkgICAgaWYgKHBjdHh0LT5hdHRyUHJvaGlicy0+bmJJdGVtcyAhPSAwKQoJCXByb2hpYnMgPSBwY3R4dC0+YXR0clByb2hpYnM7Cgl9IGVsc2UgewoJICAgIGlmICh4bWxTY2hlbWFFeHBhbmRBdHRyaWJ1dGVHcm91cFJlZnMocGN0eHQsCgkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgJih0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCksIHVzZXMsCgkJTlVMTCkgPT0gLTEpCgkgICAgewoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUZpeHVwVHlwZUF0dHJpYnV0ZVVzZXMiLAoJCSJmYWlsZWQgdG8gZXhwYW5kIGF0dHJpYnV0ZXMiKTsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBJbmhlcml0IHRoZSBhdHRyaWJ1dGUgdXNlcyBvZiB0aGUgYmFzZSB0eXBlLgogICAgKi8KICAgIGlmIChiYXNlVXNlcyAhPSBOVUxMKSB7CglpbnQgaSwgajsKCXhtbFNjaGVtYUF0dHJpYnV0ZVVzZVByb2hpYlB0ciBwcm87CgoJaWYgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSkgewoJICAgIGludCB1c2VzQ291bnQ7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlVXNlUHRyIHRtcDsgCgoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJdXNlc0NvdW50ID0gdXNlcy0+bmJJdGVtczsKCSAgICBlbHNlCgkJdXNlc0NvdW50ID0gMDsKCgkgICAgLyogUmVzdHJpY3Rpb24uICovCgkgICAgZm9yIChpID0gMDsgaSA8IGJhc2VVc2VzLT5uYkl0ZW1zOyBpKyspIHsKCQl1c2UgPSBiYXNlVXNlcy0+aXRlbXNbaV07CgkJaWYgKHByb2hpYnMpIHsKCQkgICAgLyoKCQkgICAgKiBGaWx0ZXIgb3V0IHByb2hpYml0ZWQgdXNlcy4KCQkgICAgKi8KCQkgICAgZm9yIChqID0gMDsgaiA8IHByb2hpYnMtPm5iSXRlbXM7IGorKykgewoJCQlwcm8gPSBwcm9oaWJzLT5pdGVtc1tqXTsKCQkJaWYgKChXWFNfQVRUUlVTRV9ERUNMX05BTUUodXNlKSA9PSBwcm8tPm5hbWUpICYmCgkJCSAgICAoV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKSA9PQoJCQkJcHJvLT50YXJnZXROYW1lc3BhY2UpKQoJCQl7CgkJCSAgICBnb3RvIGluaGVyaXRfbmV4dDsKCQkJfQoJCSAgICB9CgkJfQoJCWlmICh1c2VzQ291bnQpIHsKCQkgICAgLyoKCQkgICAgKiBGaWx0ZXIgb3V0IGV4aXN0aW5nIHVzZXMuCgkJICAgICovCgkJICAgIGZvciAoaiA9IDA7IGogPCB1c2VzQ291bnQ7IGorKykgewoJCQl0bXAgPSB1c2VzLT5pdGVtc1tqXTsKCQkJaWYgKChXWFNfQVRUUlVTRV9ERUNMX05BTUUodXNlKSA9PQoJCQkJV1hTX0FUVFJVU0VfREVDTF9OQU1FKHRtcCkpICYmCgkJCSAgICAoV1hTX0FUVFJVU0VfREVDTF9UTlModXNlKSA9PQoJCQkJV1hTX0FUVFJVU0VfREVDTF9UTlModG1wKSkpCgkJCXsKCQkJICAgIGdvdG8gaW5oZXJpdF9uZXh0OwoJCQl9CgkJICAgIH0KCQl9CgkJaWYgKHVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyVXNlcyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkJICAgIGlmICh0eXBlLT5hdHRyVXNlcyA9PSBOVUxMKQoJCQlnb3RvIGV4aXRfZmFpbHVyZTsKCQkgICAgdXNlcyA9IHR5cGUtPmF0dHJVc2VzOwoJCX0KCQl4bWxTY2hlbWFJdGVtTGlzdEFkZFNpemUodXNlcywgMiwgdXNlKTsKaW5oZXJpdF9uZXh0OiB7fQoJICAgIH0KCX0gZWxzZSB7CgkgICAgLyogRXh0ZW5zaW9uLiAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBiYXNlVXNlcy0+bmJJdGVtczsgaSsrKSB7CSAgICAKCQl1c2UgPSBiYXNlVXNlcy0+aXRlbXNbaV07CQkKCQlpZiAodXNlcyA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPmF0dHJVc2VzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCQkgICAgaWYgKHR5cGUtPmF0dHJVc2VzID09IE5VTEwpCgkJCWdvdG8gZXhpdF9mYWlsdXJlOwoJCSAgICB1c2VzID0gdHlwZS0+YXR0clVzZXM7CgkJfQoJCXhtbFNjaGVtYUl0ZW1MaXN0QWRkU2l6ZSh1c2VzLCBiYXNlVXNlcy0+bmJJdGVtcywgdXNlKTsgCgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogU2hyaW5rIGF0dHIuIHVzZXMuCiAgICAqLwogICAgaWYgKHVzZXMpIHsKCWlmICh1c2VzLT5uYkl0ZW1zID09IDApIHsKCSAgICB4bWxTY2hlbWFJdGVtTGlzdEZyZWUodXNlcyk7CgkgICAgdHlwZS0+YXR0clVzZXMgPSBOVUxMOwoJfQoJLyoKCSogVE9ETzogV2UgY291bGQgc2hyaW5rIHRoZSBzaXplIG9mIHRoZSBhcnJheQoJKiB0byBmaXQgdGhlIGFjdHVhbCBudW1iZXIgb2YgaXRlbXMuCgkqLwogICAgfQogICAgLyoKICAgICogQ29tcHV0ZSB0aGUgY29tcGxldGUgd2lsZGNhcmQuCiAgICAqLwogICAgaWYgKFdYU19JU19FWFRFTlNJT04odHlwZSkpIHsJCglpZiAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogKDMuMi4yLjEpICJJZiB0aGUgt2Jhc2Ugd2lsZGNhcmS3IGlzIG5vbi23YWJzZW50tywgdGhlbgoJICAgICogdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZzoiCgkgICAgKi8KCSAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJCS8qCgkJKiBVbmlvbiB0aGUgY29tcGxldGUgd2lsZGNhcmQgd2l0aCB0aGUgYmFzZSB3aWxkY2FyZC4KCQkqIFNQRUMge2F0dHJpYnV0ZSB3aWxkY2FyZH0KCQkqICgzLjIuMi4xLjIpICJvdGhlcndpc2UgYSB3aWxkY2FyZCB3aG9zZSB7cHJvY2VzcyBjb250ZW50c30KCQkqIGFuZCB7YW5ub3RhdGlvbn0gYXJlIHRob3NlIG9mIHRoZSC3Y29tcGxldGUgd2lsZGNhcmS3LAoJCSogYW5kIHdob3NlIHtuYW1lc3BhY2UgY29uc3RyYWludH0gaXMgdGhlIGludGVuc2lvbmFsIHVuaW9uCgkJKiBvZiB0aGUge25hbWVzcGFjZSBjb25zdHJhaW50fSBvZiB0aGUgt2NvbXBsZXRlIHdpbGRjYXJktwoJCSogYW5kIG9mIHRoZSC3YmFzZSB3aWxkY2FyZLcsIGFzIGRlZmluZWQgaW4gQXR0cmlidXRlCgkJKiBXaWxkY2FyZCBVbmlvbiAopzMuMTAuNikuIgoJCSovCgkJaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKHBjdHh0LCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCQkgICAgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkgICAgZ290byBleGl0X2ZhaWx1cmU7CQkKCSAgICB9IGVsc2UgewoJCS8qCgkJKiAoMy4yLjIuMS4xKSAiSWYgdGhlILdjb21wbGV0ZSB3aWxkY2FyZLcgaXMgt2Fic2VudLcsCgkJKiB0aGVuIHRoZSC3YmFzZSB3aWxkY2FyZLcuIgoJCSovCgkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSBiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQ7CgkgICAgfQkgCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAoMy4yLjIuMikgIm90aGVyd2lzZSAodGhlILdiYXNlIHdpbGRjYXJktyBpcyC3YWJzZW50tykgdGhlCgkgICAgKiC3Y29tcGxldGUgd2lsZGNhcmQiCgkgICAgKiBOT09QCgkgICAgKi8KCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDIHthdHRyaWJ1dGUgd2lsZGNhcmR9CgkqICgzLjEpICJJZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlCgkqILdjb21wbGV0ZSB3aWxkY2FyZLc7IgoJKiBOT09QCgkqLwogICAgfQogICAgCiAgICByZXR1cm4gKDApOwoKZXhpdF9mYWlsdXJlOgogICAgcmV0dXJuKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYQogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQGZpbmFsOiB0aGUgZmluYWwKICoKICogRXZhbHVhdGVzIGlmIGEgdHlwZSBkZWZpbml0aW9uIGNvbnRhaW5zIHRoZSBnaXZlbiAiZmluYWwiLgogKiBUaGlzIGRvZXMgdGFrZSAiZmluYWxEZWZhdWx0IiBpbnRvIGFjY291bnQgYXMgd2VsbC4KICoKICogUmV0dXJucyAxIGlmIHRoZSB0eXBlIGRvZXMgY29udGFpbnQgdGhlIGdpdmVuICJmaW5hbCIsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCBmaW5hbCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBmaW5hbCkKCXJldHVybiAoMSk7CiAgICBlbHNlCglyZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXM6CiAqIEB0eXBlOiAgdGhlIFVuaW9uIFNpbXBsZSBUeXBlCiAqCiAqIFJldHVybnMgYSBsaXN0IG9mIG1lbWJlciB0eXBlcyBvZiBAdHlwZSBpZiBleGlzdGluZywKICogcmV0dXJucyBOVUxMIG90aGVyd2lzZS4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlTGlua1B0cgp4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkgewoJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgkgICAgcmV0dXJuICh0eXBlLT5tZW1iZXJUeXBlcyk7CgllbHNlCgkgICAgdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbjoKICogQHBhcnRpY2xlOiB0aGUgcGFydGljbGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFZmZlY3RpdmUgVG90YWwgUmFuZ2UKICogKGFsbCBhbmQgc2VxdWVuY2UpICsgKGNob2ljZSkKICoKICogUmV0dXJucyB0aGUgbWluaW11biBFZmZlY3RpdmUgVG90YWwgUmFuZ2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbih4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApKQoJcmV0dXJuICgwKTsKICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgewoJaW50IG1pbiA9IC0xLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJaWYgKHBhcnQgPT0gTlVMTCkKCSAgICByZXR1cm4gKDApOwoJd2hpbGUgKHBhcnQgIT0gTlVMTCkgewoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1pbk9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHBhcnQpOwoJICAgIGlmIChjdXIgPT0gMCkKCQlyZXR1cm4gKDApOwoJICAgIGlmICgobWluID4gY3VyKSB8fCAobWluID09IC0xKSkKCQltaW4gPSBjdXI7CgkgICAgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dDsKCX0KCXJldHVybiAocGFydGljbGUtPm1pbk9jY3VycyAqIG1pbik7CiAgICB9IGVsc2UgewoJLyogPGFsbD4gYW5kIDxzZXF1ZW5jZT4gKi8KCWludCBzdW0gPSAwOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWlmIChwYXJ0ID09IE5VTEwpCgkgICAgcmV0dXJuICgwKTsKCWRvIHsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQlzdW0gKz0gcGFydC0+bWluT2NjdXJzOwoJICAgIGVsc2UKCQlzdW0gKz0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHBhcnQpOwoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQ7Cgl9IHdoaWxlIChwYXJ0ICE9IE5VTEwpOwoJcmV0dXJuIChwYXJ0aWNsZS0+bWluT2NjdXJzICogc3VtKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heDoKICogQHBhcnRpY2xlOiB0aGUgcGFydGljbGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFZmZlY3RpdmUgVG90YWwgUmFuZ2UKICogKGFsbCBhbmQgc2VxdWVuY2UpICsgKGNob2ljZSkKICoKICogUmV0dXJucyB0aGUgbWF4aW11bSBFZmZlY3RpdmUgVG90YWwgUmFuZ2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heCh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuICgwKTsKICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgewoJaW50IG1heCA9IC0xLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJZm9yICg7IHBhcnQgIT0gTlVMTDsgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dCkgewoJICAgIGlmIChwYXJ0LT5jaGlsZHJlbiA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1heE9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWF4KHBhcnQpOwoJICAgIGlmIChjdXIgPT0gVU5CT1VOREVEKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBpZiAoKG1heCA8IGN1cikgfHwgKG1heCA9PSAtMSkpCgkJbWF4ID0gY3VyOwoJfQoJLyogVE9ETzogSGFuZGxlIG92ZXJmbG93cz8gKi8KCXJldHVybiAocGFydGljbGUtPm1heE9jY3VycyAqIG1heCk7CiAgICB9IGVsc2UgewoJLyogPGFsbD4gYW5kIDxzZXF1ZW5jZT4gKi8KCWludCBzdW0gPSAwLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJZm9yICg7IHBhcnQgIT0gTlVMTDsgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dCkgewoJICAgIGlmIChwYXJ0LT5jaGlsZHJlbiA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1heE9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWF4KHBhcnQpOwoJICAgIGlmIChjdXIgPT0gVU5CT1VOREVEKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBpZiAoKGN1ciA+IDApICYmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCkpCgkJcmV0dXJuIChVTkJPVU5ERUQpOwoJICAgIHN1bSArPSBjdXI7Cgl9CgkvKiBUT0RPOiBIYW5kbGUgb3ZlcmZsb3dzPyAqLwoJcmV0dXJuIChwYXJ0aWNsZS0+bWF4T2NjdXJzICogc3VtKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGU6CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogUGFydGljbGUgRW1wdGlhYmxlCiAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBwYXJ0aWNsZSBpcyBlbXB0aWFibGUuCiAqCiAqIFJldHVybnMgMSBpZiBlbXB0aWFibGUsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlKHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlKQp7CiAgICAvKgogICAgKiBTUEVDICgxKSAiSXRzIHttaW4gb2NjdXJzfSBpcyAwLiIKICAgICovCiAgICBpZiAoKHBhcnRpY2xlID09IE5VTEwpIHx8IChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHx8CgkocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDIpICJJdHMge3Rlcm19IGlzIGEgZ3JvdXAgYW5kIHRoZSBtaW5pbXVtIHBhcnQgb2YgdGhlCiAgICAqIGVmZmVjdGl2ZSB0b3RhbCByYW5nZSBvZiB0aGF0IGdyb3VwLCBbLi4uXSBpcyAwLiIKICAgICovCiAgICBpZiAoV1hTX0lTX01PREVMX0dST1VQKHBhcnRpY2xlLT5jaGlsZHJlbikpIHsKCWlmICh4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW4ocGFydGljbGUpID09IDApCgkgICAgcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LOgogKiBAYWN0eHQ6IGEgY29udGV4dAogKiBAdHlwZTogIHRoZSBkZXJpdmVkIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGJhc2VUeXBlOiAgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uCiAqIEBzdWJzZXQ6IHRoZSBzdWJzZXQgb2YgKCdyZXN0cmljdGlvbicsIGVjdC4pCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpIChjb3Mtc3QtZGVyaXZlZC1PSykKICoKICogQ2hlY2tzIHdoZXRlciBAdHlwZSBjYW4gYmUgdmFsaWRseQogKiBkZXJpdmVkIGZyb20gQGJhc2VUeXBlLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYW4gcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICAgIGludCBzdWJzZXQpCnsKICAgIC8qCiAgICAqIDEgVGhleSBhcmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLgogICAgKiBUT0RPOiBUaGUgaWRlbnR5IGNoZWNrIG1pZ2h0IGhhdmUgdG8gYmUgbW9yZSBjb21wbGV4IHRoYW4gdGhpcy4KICAgICovCiAgICBpZiAodHlwZSA9PSBiYXNlVHlwZSkKCXJldHVybiAoMCk7CiAgICAvKgogICAgKiAyLjEgcmVzdHJpY3Rpb24gaXMgbm90IGluIHRoZSBzdWJzZXQsIG9yIGluIHRoZSB7ZmluYWx9CiAgICAqIG9mIGl0cyBvd24ge2Jhc2UgdHlwZSBkZWZpbml0aW9ufTsKICAgICoKICAgICogTk9URSB0aGF0IHRoaXMgd2lsbCBiZSB1c2VkIGFsc28gdmlhICJ4c2k6dHlwZSIuCiAgICAqCiAgICAqIFRPRE86IFJldmlzZSB0aGlzLCBpdCBsb29rcyBzdHJhbmdlLiBIb3cgY2FuIHRoZSAidHlwZSIKICAgICogbm90IGJlIGZpeGVkIG9yICppbiogZml4aW5nPwogICAgKi8KICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQodHlwZSkpCglpZiAoeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGUsIGFjdHh0KSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwogICAgaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChiYXNlVHlwZSkpCglpZiAoeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBhY3R4dCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKICAgIGlmICgoc3Vic2V0ICYgU1VCU0VUX1JFU1RSSUNUSU9OKSB8fAoJKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHR5cGUtPmJhc2VUeXBlLAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSkgewoJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzEpOwogICAgfQogICAgLyogMi4yICovCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gYmFzZVR5cGUpIHsKCS8qCgkqIDIuMi4xIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIEIuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDIuMi4yIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIG5vdCB0aGUgt3VyLXR5cGUgZGVmaW5pdGlvbrcKICAgICogYW5kIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEIgZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzCiAgICAqIGNvbnN0cmFpbnQuCiAgICAqLwogICAgaWYgKCghIFdYU19JU19BTllUWVBFKHR5cGUtPmJhc2VUeXBlKSkgJiYKCSh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKGFjdHh0LCB0eXBlLT5iYXNlVHlwZSwKCSAgICBiYXNlVHlwZSwgc3Vic2V0KSA9PSAwKSkgewoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDIuMi4zIEQncyB7dmFyaWV0eX0gaXMgbGlzdCBvciB1bmlvbiBhbmQgQiBpcyB0aGUgt3NpbXBsZSB1ci10eXBlCiAgICAqIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmIChXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKGJhc2VUeXBlKSAmJgoJKFdYU19JU19MSVNUKHR5cGUpIHx8IFdYU19JU19VTklPTih0eXBlKSkpIHsKCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAyLjIuNCBCJ3Mge3ZhcmlldHl9IGlzIHVuaW9uIGFuZCBEIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIGEgdHlwZQogICAgKiBkZWZpbml0aW9uIGluIEIncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBzdWJzZXQsIGFzCiAgICAqIGRlZmluZWQgYnkgdGhpcyBjb25zdHJhaW50LgogICAgKgogICAgKiBOT1RFOiBUaGlzIHNlZW1zIG5vdCB0byBpbnZvbHZlIGJ1aWx0LWluIHR5cGVzLCBzaW5jZSB0aGVyZSBpcyBubwogICAgKiBidWlsdC1pbiBVbmlvbiBTaW1wbGUgVHlwZS4KICAgICovCiAgICBpZiAoV1hTX0lTX1VOSU9OKGJhc2VUeXBlKSkgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgY3VyOwoKCWN1ciA9IGJhc2VUeXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChXWFNfSVNfVFlQRV9OT1RfRklYRUQoY3VyLT50eXBlKSkKCQlpZiAoeG1sU2NoZW1hVHlwZUZpeHVwKGN1ci0+dHlwZSwgYWN0eHQpID09IC0xKQoJCSAgICByZXR1cm4oLTEpOwoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKGFjdHh0LAoJCSAgICB0eXBlLCBjdXItPnR5cGUsIHN1YnNldCkgPT0gMCkKCSAgICB7CgkJLyoKCQkqIEl0IGp1c3QgaGFzIHRvIGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIGF0IGxlYXN0IG9uZQoJCSogbWVtYmVyLXR5cGUuCgkJKi8KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9CiAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9ERVJJVkVEX09LXzJfMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsOgogKiBAcGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjdHh0VHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQGFuY2VzdG9yOiBhbiBhbmNlc3RvciBvZiBAY3R4dFR5cGUKICoKICogQ2hlY2tzIHN0LXByb3BzLWNvcnJlY3QgKDIpICsgY3QtcHJvcHMtY29ycmVjdCAoMykuCiAqIENpcmN1bGFyIHR5cGUgZGVmaW5pdGlvbnMgYXJlIG5vdCBhbGxvd2VkLgogKgogKiBSZXR1cm5zIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiBpZiB0aGUgZ2l2ZW4gdHlwZSBpcwogKiBjaXJjdWxhciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZSwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBhbmNlc3RvcikKewogICAgaW50IHJldDsKCiAgICBpZiAoKGFuY2VzdG9yID09IE5VTEwpIHx8IChhbmNlc3Rvci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJcmV0dXJuICgwKTsKCiAgICBpZiAoY3R4dFR5cGUgPT0gYW5jZXN0b3IpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yLAoJICAgIFdYU19CQVNJQ19DQVNUIGN0eHRUeXBlLCBXWFNfSVRFTV9OT0RFKGN0eHRUeXBlKSwKCSAgICAiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yKTsKICAgIH0KICAgIGlmIChhbmNlc3Rvci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01BUktFRCkgewoJLyoKCSogQXZvaWQgaW5pZmluaXRlIHJlY3Vyc2lvbiBvbiBjaXJjdWxhciB0eXBlcyBub3QgeWV0IGNoZWNrZWQuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGFuY2VzdG9yLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWwocGN0eHQsIGN0eHRUeXBlLAoJYW5jZXN0b3ItPmJhc2VUeXBlKTsKICAgIGFuY2VzdG9yLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyOgogKiBAaXRlbTogIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHR5cGUgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhcih4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJCSAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKChpdGVtID09IE5VTEwpIHx8CgkoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHx8CgkoaXRlbS0+YmFzZVR5cGUgPT0gTlVMTCkpCglyZXR1cm47CiAgICB4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsKGN0eHQsIGl0ZW0sCglpdGVtLT5iYXNlVHlwZSk7Cn0KCi8qCiogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSyAoc3JjLXNpbXBsZS10eXBlKSA0CioKKiAiNCBDaXJjdWxhciB1bmlvbiB0eXBlIGRlZmluaXRpb24gaXMgZGlzYWxsb3dlZC4gVGhhdCBpcywgaWYgdGhlCiogPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZXJlIG11c3Qgbm90IGJlIGFueSBlbnRyaWVzIGluIHRoZQoqIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIGF0IGFueSBkZXB0aCB3aGljaCByZXNvbHZlIHRvIHRoZSBjb21wb25lbnQKKiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4uIgoqCiogTm90ZSB0aGF0IHRoaXMgc2hvdWxkIHdvcmsgb24gdGhlICpyZXByZXNlbnRhdGlvbiogb2YgYSBjb21wb25lbnQsCiogdGh1cyBhc3N1bWVzIGFueSB1bmlvbiB0eXBlcyBpbiB0aGUgbWVtYmVyIHR5cGVzIG5vdCBiZWluZyB5ZXQKKiBzdWJzdGl0dXRlZC4gQXQgdGhpcyBzdGFnZSB3ZSBuZWVkIHRoZSB2YXJpZXR5IG9mIHRoZSB0eXBlcwoqIHRvIGJlIGFscmVhZHkgY29tcHV0ZWQuCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tVbmlvblR5cGVEZWZDaXJjdWxhclJlY3VyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkJeG1sU2NoZW1hVHlwZVB0ciBjdHhUeXBlLAoJCQkJCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcnMpCnsgICAgCiAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG1lbWJlclR5cGU7CiAgICAKICAgIG1lbWJlciA9IG1lbWJlcnM7CiAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCW1lbWJlclR5cGUgPSBtZW1iZXItPnR5cGU7Cgl3aGlsZSAoKG1lbWJlclR5cGUgIT0gTlVMTCkgJiYKCSAgICAobWVtYmVyVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CgkgICAgaWYgKG1lbWJlclR5cGUgPT0gY3R4VHlwZSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80LAoJCSAgICBXWFNfQkFTSUNfQ0FTVCBjdHhUeXBlLCBOVUxMLAoJCSAgICAiVGhlIHVuaW9uIHR5cGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzQpOwoJICAgIH0KCSAgICBpZiAoKFdYU19JU19VTklPTihtZW1iZXJUeXBlKSkgJiYKCQkoKG1lbWJlclR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQpID09IDApKQoJICAgIHsKCQlpbnQgcmVzOwoJCW1lbWJlclR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwoJCXJlcyA9IHhtbFNjaGVtYUNoZWNrVW5pb25UeXBlRGVmQ2lyY3VsYXJSZWN1cihwY3R4dCwKCQkgICAgY3R4VHlwZSwKCQkgICAgeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMobWVtYmVyVHlwZSkpOwoJCW1lbWJlclR5cGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwoJCWlmIChyZXMgIT0gMCkKCQkgICAgcmV0dXJuKHJlcyk7CgkgICAgfQoJICAgIG1lbWJlclR5cGUgPSBtZW1iZXJUeXBlLT5iYXNlVHlwZTsKCX0KCW1lbWJlciA9IG1lbWJlci0+bmV4dDsKICAgIH0KICAgIHJldHVybigwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1VuaW9uVHlwZURlZkNpcmN1bGFyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICghIFdYU19JU19VTklPTih0eXBlKSkKCXJldHVybigwKTsKICAgIHJldHVybih4bWxTY2hlbWFDaGVja1VuaW9uVHlwZURlZkNpcmN1bGFyUmVjdXIocGN0eHQsIHR5cGUsCgl0eXBlLT5tZW1iZXJUeXBlcykpOwp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZVR5cGVSZWZlcmVuY2VzOgogKiBAaXRlbTogIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBSZXNvbHZlc2UgdHlwZSBkZWZpbml0aW9uIHJlZmVyZW5jZXMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVJlc29sdmVUeXBlUmVmZXJlbmNlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWYsCgkJCSB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGlmICh0eXBlRGVmID09IE5VTEwpCglyZXR1cm47CgogICAgLyoKICAgICogUmVzb2x2ZSB0aGUgYmFzZSB0eXBlLgogICAgKi8KICAgIGlmICh0eXBlRGVmLT5iYXNlVHlwZSA9PSBOVUxMKSB7Cgl0eXBlRGVmLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLAoJICAgIHR5cGVEZWYtPmJhc2UsIHR5cGVEZWYtPmJhc2VOcyk7CglpZiAodHlwZURlZi0+YmFzZVR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCVdYU19CQVNJQ19DQVNUIHR5cGVEZWYsIHR5cGVEZWYtPm5vZGUsCgkJImJhc2UiLCB0eXBlRGVmLT5iYXNlLCB0eXBlRGVmLT5iYXNlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgaWYgKFdYU19JU19TSU1QTEUodHlwZURlZikpIHsKCWlmIChXWFNfSVNfVU5JT04odHlwZURlZikpIHsKCSAgICAvKgoJICAgICogUmVzb2x2ZSB0aGUgbWVtYmVyVHlwZXMuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFSZXNvbHZlVW5pb25NZW1iZXJUeXBlcyhjdHh0LCB0eXBlRGVmKTsKCSAgICByZXR1cm47Cgl9IGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGVEZWYpKSB7CgkgICAgLyoKCSAgICAqIFJlc29sdmUgdGhlIGl0ZW1UeXBlLgoJICAgICovCgkgICAgaWYgKCh0eXBlRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAodHlwZURlZi0+YmFzZSAhPSBOVUxMKSkgewoKCQl0eXBlRGVmLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLAoJCSAgICB0eXBlRGVmLT5iYXNlLCB0eXBlRGVmLT5iYXNlTnMpOwoKCQlpZiAoKHR5cGVEZWYtPnN1YnR5cGVzID09IE5VTEwpIHx8CgkJICAgICghIFdYU19JU19TSU1QTEUodHlwZURlZi0+c3VidHlwZXMpKSkKCQl7CgkJICAgIHR5cGVEZWYtPnN1YnR5cGVzID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCQlXWFNfQkFTSUNfQ0FTVCB0eXBlRGVmLCB0eXBlRGVmLT5ub2RlLAoJCQkiaXRlbVR5cGUiLCB0eXBlRGVmLT5iYXNlLCB0eXBlRGVmLT5iYXNlTnMsCgkJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJCX0KCSAgICB9CgkgICAgcmV0dXJuOwoJfQogICAgfSAKICAgIC8qCiAgICAqIFRoZSBiYWxsIG9mIGxldHRlcnMgYmVsb3cgbWVhbnMsIHRoYXQgaWYgd2UgaGF2ZSBhIHBhcnRpY2xlCiAgICAqIHdoaWNoIGhhcyBhIFFOYW1lLWhlbHBlciBjb21wb25lbnQgYXMgaXRzIHt0ZXJtfSwgd2Ugd2FudAogICAgKiB0byByZXNvbHZlIGl0Li4uCiAgICAqLwogICAgZWxzZSBpZiAoKFdYU19UWVBFX0NPTlRFTlRUWVBFKHR5cGVEZWYpICE9IE5VTEwpICYmCgkoKFdYU19UWVBFX0NPTlRFTlRUWVBFKHR5cGVEZWYpKS0+dHlwZSA9PQoJICAgIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkgJiYKCShXWFNfVFlQRV9QQVJUSUNMRV9URVJNKHR5cGVEZWYpICE9IE5VTEwpICYmCgkoKFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZURlZikpLT50eXBlID09CgkgICAgWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRikpCiAgICB7Cgl4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWYgPQoJICAgIFdYU19RTkFNRV9DQVNUIFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZURlZik7Cgl4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGdyb3VwRGVmOwoKCS8qCgkqIFVSR0VOVCBUT0RPOiBUZXN0IHRoaXMuCgkqLwoJV1hTX1RZUEVfUEFSVElDTEVfVEVSTSh0eXBlRGVmKSA9IE5VTEw7CgkvKgoJKiBSZXNvbHZlIHRoZSBNRyBkZWZpbml0aW9uIHJlZmVyZW5jZS4KCSovCglncm91cERlZiA9CgkgICAgV1hTX01PREVMX0dST1VQREVGX0NBU1QgeG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoY3R4dC0+c2NoZW1hLAoJCXJlZi0+aXRlbVR5cGUsIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UpOwoJaWYgKGdyb3VwRGVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJTlVMTCwgV1hTX0lURU1fTk9ERShXWFNfVFlQRV9QQVJUSUNMRSh0eXBlRGVmKSksCgkJInJlZiIsIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UsIHJlZi0+aXRlbVR5cGUsCgkJTlVMTCk7CgkgICAgLyogUmVtb3ZlIHRoZSBwYXJ0aWNsZS4gKi8KCSAgICBXWFNfVFlQRV9DT05URU5UVFlQRSh0eXBlRGVmKSA9IE5VTEw7Cgl9IGVsc2UgaWYgKFdYU19NT0RFTEdST1VQREVGX01PREVMKGdyb3VwRGVmKSA9PSBOVUxMKQoJICAgIC8qIFJlbW92ZSB0aGUgcGFydGljbGUuICovCgkgICAgV1hTX1RZUEVfQ09OVEVOVFRZUEUodHlwZURlZikgPSBOVUxMOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEFzc2lnbiB0aGUgTUcgZGVmaW5pdGlvbidzIHttb2RlbCBncm91cH0gdG8gdGhlCgkgICAgKiBwYXJ0aWNsZSdzIHt0ZXJtfS4KCSAgICAqLwoJICAgIFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZURlZikgPSBXWFNfTU9ERUxHUk9VUERFRl9NT0RFTChncm91cERlZik7CgkgICAgCgkgICAgaWYgKFdYU19NT0RFTEdST1VQREVGX01PREVMKGdyb3VwRGVmKS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB7CgkJLyoKCQkqIFNQRUMgY29zLWFsbC1saW1pdGVkICgxLjIpCgkJKiAiMS4yIHRoZSB7dGVybX0gcHJvcGVydHkgb2YgYSBwYXJ0aWNsZSB3aXRoCgkJKiB7bWF4IG9jY3Vyc309MSB3aGljaCBpcyBwYXJ0IG9mIGEgcGFpciB3aGljaCBjb25zdGl0dXRlcwoJCSogdGhlIHtjb250ZW50IHR5cGV9IG9mIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24uIgoJCSovCgkJaWYgKChXWFNfVFlQRV9QQVJUSUNMRSh0eXBlRGVmKSktPm1heE9jY3VycyAhPSAxKSB7CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIGN0eHQsCgkJCS8qIFRPRE86IGVycm9yIGNvZGUgKi8KCQkJWE1MX1NDSEVNQVBfQ09TX0FMTF9MSU1JVEVELAoJCQlXWFNfSVRFTV9OT0RFKFdYU19UWVBFX1BBUlRJQ0xFKHR5cGVEZWYpKSwgTlVMTCwKCQkJIlRoZSBwYXJ0aWNsZSdzIHttYXggb2NjdXJzfSBtdXN0IGJlIDEsIHNpbmNlIHRoZSAiCgkJCSJyZWZlcmVuY2UgcmVzb2x2ZXMgdG8gYW4gJ2FsbCcgbW9kZWwgZ3JvdXAiLAoJCQlOVUxMLCBOVUxMKTsKCQl9CgkgICAgfQoJfQogICAgfQp9CgoKCi8qKgogKiB4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3Mgc3QtcHJvcHMtY29ycmVjdC4KICoKICogUmV0dXJucyAwIGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSBjb3JyZWN0LAogKiBpZiBub3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBhbmQgLTEgb24gaW50ZXJuYWwKICogZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgLyogU1RBVEU6IGVycm9yIGZ1bmNzIGNvbnZlcnRlZC4gKi8KICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICoKICAgICogTk9URTogVGhpcyBpcyBzb21laG93IHJlZHVuZGFudCwgc2luY2Ugd2UgYWN0dWFsbHkgYnVpbHQgYSBzaW1wbGUgdHlwZQogICAgKiB0byBoYXZlIGFsbCB0aGUgbmVlZGVkIGluZm9ybWF0aW9uOyB0aGlzIGFjdHMgYXMgYW4gc2VsZiB0ZXN0LgogICAgKi8KICAgIC8qIEJhc2UgdHlwZTogSWYgdGhlIGRhdGF0eXBlIGhhcyBiZWVuILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263CiAgICAqIHRoZW4gdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gY29tcG9uZW50IGZyb20gd2hpY2ggaXQgaXMgt2Rlcml2ZWS3LAogICAgKiBvdGhlcndpc2UgdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gZm9yIGFueVNpbXBsZVR5cGUgKKc0LjEuNikuCiAgICAqLwogICAgaWYgKGJhc2VUeXBlID09IE5VTEwpIHsKCS8qCgkqIFRPRE86IFRoaW5rIGFib3V0OiAibW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZwoJKiBTdWItY29tcG9uZW50cyAopzUuMykuIgoJKi8KCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCSAgICAiTm8gYmFzZSB0eXBlIGV4aXN0ZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CgogICAgfQogICAgaWYgKCEgV1hTX0lTX1NJTVBMRShiYXNlVHlwZSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCSAgICAiVGhlIGJhc2UgdHlwZSAnJXMnIGlzIG5vdCBhIHNpbXBsZSB0eXBlIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlVHlwZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoIChXWFNfSVNfTElTVCh0eXBlKSB8fCBXWFNfSVNfVU5JT04odHlwZSkpICYmCgkgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSA9PSAwKSAmJgoJICghIFdYU19JU19BTllfU0lNUExFX1RZUEUoYmFzZVR5cGUpKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJICAgICJBIHR5cGUsIGRlcml2ZWQgYnkgbGlzdCBvciB1bmlvbiwgbXVzdCBoYXZlIgoJICAgICJ0aGUgc2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbiBhcyBiYXNlIHR5cGUsIG5vdCAnJXMnIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlVHlwZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKgogICAgKiBWYXJpZXR5OiBPbmUgb2Yge2F0b21pYywgbGlzdCwgdW5pb259LgogICAgKi8KICAgIGlmICgoISBXWFNfSVNfQVRPTUlDKHR5cGUpKSAmJiAoISBXWFNfSVNfVU5JT04odHlwZSkpICYmCgkoISBXWFNfSVNfTElTVCh0eXBlKSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCSAgICAiVGhlIHZhcmlldHkgaXMgYWJzZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKiBUT0RPOiBGaW5pc2ggdGhpcy4gSG1tLCBpcyB0aGlzIGZpbmlzaGVkPyAqLwoKICAgIC8qCiAgICAqIDMgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoYmFzZVR5cGUsCglYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMywKCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJICAgICJUaGUgJ2ZpbmFsJyBvZiBpdHMgYmFzZSB0eXBlICclcycgbXVzdCBub3QgY29udGFpbiAiCgkgICAgIidyZXN0cmljdGlvbiciLAoJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGJhc2VUeXBlKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8zKTsKICAgIH0KCiAgICAvKgogICAgKiAyIEFsbCBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucyBtdXN0IGJlIGRlcml2ZWQgdWx0aW1hdGVseSBmcm9tIHRoZSC3c2ltcGxlCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbiAoc2+3IGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS4gVGhhdCBpcywgaXQKICAgICogbXVzdCBiZSBwb3NzaWJsZSB0byByZWFjaCBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZSBvciB0aGUgt3NpbXBsZQogICAgKiB1ci10eXBlIGRlZmluaXRpb263IGJ5IHJlcGVhdGVkbHkgZm9sbG93aW5nIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgogICAgKgogICAgKiBOT1RFOiB0aGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXIoKS4KICAgICovCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0czoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgU2ltcGxlKSAoY29zLXN0LXJlc3RyaWN0cykKCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gQHR5cGUgKHNpbXBsZVR5cGUpIGlzIGRlcml2ZWQgdmFsaWRseSBieSByZXN0cmljdGlvbi4KICogU1RBVFVTOgogKgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9ycywgMCBpZiB0aGUgdHlwZSBpcyB2YWxpZGx5IGRlcml2ZWQsCiAqIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkgICAgImdpdmVuIHR5cGUgaXMgbm90IGEgdXNlci1kZXJpdmVkIHNpbXBsZVR5cGUiKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChXWFNfSVNfQVRPTUlDKHR5cGUpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHByaW1pdGl2ZTsKCS8qCgkqIDEuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIGFuIGF0b21pYyBzaW1wbGUKCSogdHlwZSBkZWZpbml0aW9uIG9yIGEgYnVpbHQtaW4gcHJpbWl0aXZlIGRhdGF0eXBlLgoJKi8KCWlmICghIFdYU19JU19BVE9NSUModHlwZS0+YmFzZVR5cGUpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMSwKCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSJUaGUgYmFzZSB0eXBlICclcycgaXMgbm90IGFuIGF0b21pYyBzaW1wbGUgdHlwZSIsCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgdHlwZS0+YmFzZVR5cGUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xKTsKCX0KCS8qIDEuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluCgkqIHJlc3RyaWN0aW9uLgoJKi8KCS8qIE9QVElNSVpFIFRPRE8gOiBUaGlzIGlzIGFscmVhZHkgZG9uZSBpbiB4bWxTY2hlbWFDaGVja1N0UHJvcHNDb3JyZWN0ICovCglpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnModHlwZS0+YmFzZVR5cGUsCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yLAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJIlRoZSBmaW5hbCBvZiBpdHMgYmFzZSB0eXBlICclcycgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzIpOwoJfQoKCS8qCgkqIDEuMy4xIERGIG11c3QgYmUgYW4gYWxsb3dlZCBjb25zdHJhaW5pbmcgZmFjZXQgZm9yIHRoZSB7cHJpbWl0aXZlCgkqIHR5cGUgZGVmaW5pdGlvbn0sIGFzIHNwZWNpZmllZCBpbiB0aGUgYXBwcm9wcmlhdGUgc3Vic2VjdGlvbiBvZiAzLjIKCSogUHJpbWl0aXZlIGRhdGF0eXBlcy4KCSovCglpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICBpbnQgb2sgPSAxOwoKCSAgICBwcmltaXRpdmUgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5cGUpOwoJICAgIGlmIChwcmltaXRpdmUgPT0gTlVMTCkgewoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCSAgICAiZmFpbGVkIHRvIGdldCBwcmltaXRpdmUgdHlwZSIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKCSAgICBkbyB7CgkJaWYgKHhtbFNjaGVtYUlzQnVpbHRJblR5cGVGYWNldChwcmltaXRpdmUsIGZhY2V0LT50eXBlKSA9PSAwKSB7CgkJICAgIG9rID0gMDsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0VycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSwKCQkJdHlwZSwgcHJpbWl0aXZlLCBmYWNldCk7CgkJfQoJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkgICAgaWYgKG9rID09IDApCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfM18xKTsKCX0KCS8qCgkqIFNQRUMgKDEuMy4yKSAiSWYgdGhlcmUgaXMgYSBmYWNldCBvZiB0aGUgc2FtZSBraW5kIGluIHRoZSB7ZmFjZXRzfQoJKiBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSAoY2FsbCB0aGlzIEJGKSx0aGVuIHRoZSBERidzIHt2YWx1ZX0KCSogbXVzdCBiZSBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEJGJ3Mge3ZhbHVlfSBhcyBkZWZpbmVkIGluCgkqIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4iCgkqCgkqIE5PVEUgKDEuMy4yKSBGYWNldCBkZXJpdmF0aW9uIGNvbnN0cmFpbnRzIGFyZSBjdXJyZW50bHkgaGFuZGxlZCBpbgoJKiB4bWxTY2hlbWFEZXJpdmVBbmRWYWxpZGF0ZUZhY2V0cygpCgkqLwogICAgfSBlbHNlIGlmIChXWFNfSVNfTElTVCh0eXBlKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBpdGVtVHlwZSA9IE5VTEw7CgoJaXRlbVR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKCWlmICgoaXRlbVR5cGUgPT0gTlVMTCkgfHwgKCEgV1hTX0lTX1NJTVBMRShpdGVtVHlwZSkpKSB7CgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkJImZhaWxlZCB0byBldmFsdWF0ZSB0aGUgaXRlbSB0eXBlIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAoV1hTX0lTX1RZUEVfTk9UX0ZJWEVEKGl0ZW1UeXBlKSkKCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbVR5cGUsIEFDVFhUX0NBU1QgcGN0eHQpOwoJLyoKCSogMi4xIFRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiBhdG9taWMgb3IKCSogdW5pb24gKGluIHdoaWNoIGNhc2UgYWxsIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9CgkqIG11c3QgYmUgYXRvbWljKS4KCSovCglpZiAoKCEgV1hTX0lTX0FUT01JQyhpdGVtVHlwZSkpICYmCgkgICAgKCEgV1hTX0lTX1VOSU9OKGl0ZW1UeXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJIlRoZSBpdGVtIHR5cGUgJyVzJyBkb2VzIG5vdCBoYXZlIGEgdmFyaWV0eSBvZiBhdG9taWMgb3IgdW5pb24iLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW1UeXBlKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSk7Cgl9IGVsc2UgaWYgKFdYU19JU19VTklPTihpdGVtVHlwZSkpIHsKCSAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7CgoJICAgIG1lbWJlciA9IGl0ZW1UeXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoISBXWFNfSVNfQVRPTUlDKG1lbWJlci0+dHlwZSkpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEsCgkJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJCSJUaGUgaXRlbSB0eXBlIGlzIGEgdW5pb24gdHlwZSwgYnV0IHRoZSAiCgkJCSJtZW1iZXIgdHlwZSAnJXMnIG9mIHRoaXMgaXRlbSB0eXBlIGlzIG5vdCBhdG9taWMiLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBtZW1iZXItPnR5cGUpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJfQoKCWlmIChXWFNfSVNfQU5ZX1NJTVBMRV9UWVBFKHR5cGUtPmJhc2VUeXBlKSkgewoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxsaXN0IC4uCgkgICAgKi8KCSAgICAvKgoJICAgICogMi4zLjEKCSAgICAqIDIuMy4xLjEgVGhlIHtmaW5hbH0gb2YgdGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QKCSAgICAqIGNvbnRhaW4gbGlzdC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhpdGVtVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBpdGVtIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdsaXN0JyIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW1UeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBvbmx5IGNvbnRhaW4gdGhlIHdoaXRlU3BhY2UKCSAgICAqIGZhY2V0IGNvbXBvbmVudC4KCSAgICAqIE9QVElNSVpFIFRPRE86IHRoZSBTNFMgYWxyZWFkeSBkaXNhbGxvd3MgYW55IGZhY2V0CgkgICAgKiB0byBiZSBzcGVjaWZpZWQuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihwY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMiwKCQkJICAgIHR5cGUsIGZhY2V0KTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIpOwoJCSAgICB9CgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBNQVlCRSBUT0RPOiAoSG1tLCBub3QgcmVhbGx5KSBEYXRhdHlwZXMgc3RhdGVzOgoJICAgICogQSC3bGlzdLcgZGF0YXR5cGUgY2FuIGJlILdkZXJpdmVktyBmcm9tIGFuILdhdG9taWO3IGRhdGF0eXBlCgkgICAgKiB3aG9zZSC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlIChzdWNoIGFzIHN0cmluZyBvciBhbnlVUkkpb3IKCSAgICAqIGEgt3VuaW9utyBkYXRhdHlwZSBhbnkgb2Ygd2hvc2Uge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSdzCgkgICAgKiC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlLgoJICAgICovCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbiAuLi4KCSAgICAqIEkuZS4gdGhlIHZhcmlldHkgb2YgImxpc3QiIGlzIGluaGVyaXRlZC4KCSAgICAqLwoJICAgIC8qCgkgICAgKiAyLjMuMgoJICAgICogMi4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgbGlzdC4KCSAgICAqLwoJICAgIGlmICghIFdYU19JU19MSVNUKHR5cGUtPmJhc2VUeXBlKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBiYXNlIHR5cGUgJyVzJyBtdXN0IGJlIGEgbGlzdCB0eXBlIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgdHlwZS0+YmFzZVR5cGUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkgICAgKiBjb250YWluIHJlc3RyaWN0aW9uLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHR5cGUtPmJhc2VUeXBlLAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlICdmaW5hbCcgb2YgdGhlIGJhc2UgdHlwZSAnJXMnIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzIpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMyBUaGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZAoJICAgICogZnJvbSB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gZ2l2ZW4KCSAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2VJdGVtVHlwZTsKCgkJYmFzZUl0ZW1UeXBlID0gdHlwZS0+YmFzZVR5cGUtPnN1YnR5cGVzOwoJCWlmICgoYmFzZUl0ZW1UeXBlID09IE5VTEwpIHx8ICghIFdYU19JU19TSU1QTEUoYmFzZUl0ZW1UeXBlKSkpIHsKCQkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkJCSJmYWlsZWQgdG8gZXZhbCB0aGUgaXRlbSB0eXBlIG9mIGEgYmFzZSB0eXBlIik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlpZiAoKGl0ZW1UeXBlICE9IGJhc2VJdGVtVHlwZSkgJiYKCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soQUNUWFRfQ0FTVCBwY3R4dCwgaXRlbVR5cGUsCgkJCWJhc2VJdGVtVHlwZSwgMCkgIT0gMCkpIHsKCQkgICAgeG1sQ2hhciAqc3RyQklUID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8zLAoJCQlXWFNfQkFTSUNfQ0FTVCB0eXBlLCBOVUxMLAoJCQkiVGhlIGl0ZW0gdHlwZSAnJXMnIGlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSAiCgkJCSJ0aGUgaXRlbSB0eXBlICclcycgb2YgdGhlIGJhc2UgdHlwZSAnJXMnIiwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgaXRlbVR5cGUpLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQklULCBiYXNlSXRlbVR5cGUpLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQlQsIHR5cGUtPmJhc2VUeXBlKSk7CgoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCSVQpCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQlQpCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8zKTsKCQl9CgkgICAgfQoKCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCQlpbnQgb2sgPSAxOwoJCS8qCgkJKiAyLjMuMi40IE9ubHkgbGVuZ3RoLCBtaW5MZW5ndGgsIG1heExlbmd0aCwgd2hpdGVTcGFjZSwgcGF0dGVybgoJCSogYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIGFsbG93ZWQgYW1vbmcgdGhlIHtmYWNldHN9LgoJCSovCgkJZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkJZG8gewoJCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJCQkgICAgLyoKCQkJICAgICogVE9ETzogMi41LjEuMiBMaXN0IGRhdGF0eXBlcwoJCQkgICAgKiBUaGUgdmFsdWUgb2Ygt3doaXRlU3BhY2W3IGlzIGZpeGVkIHRvIHRoZSB2YWx1ZSBjb2xsYXBzZS4KCQkJICAgICovCgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJCSAgICBicmVhazsKCQkJZGVmYXVsdDogewoJCQkgICAgeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihwY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfNCwKCQkJCXR5cGUsIGZhY2V0KTsKCQkJICAgIC8qCgkJCSAgICAqIFdlIGNvdWxkIHJldHVybiwgYnV0IGl0J3MgbmljZXIgdG8gcmVwb3J0IGFsbAoJCQkgICAgKiBpbnZhbGlkIGZhY2V0cy4KCQkJICAgICovCgkJCSAgICBvayA9IDA7CgkJCX0KCQkgICAgfQoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJCWlmIChvayA9PSAwKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfNCk7CgkJLyoKCQkqIFNQRUMgKDIuMy4yLjUpIChzYW1lIGFzIDEuMy4yKQoJCSoKCQkqIE5PVEUgKDIuMy4yLjUpIFRoaXMgaXMgY3VycmVudGx5IGRvbmUgaW4KCQkqIHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKCkKCQkqLwoJICAgIH0KCX0KICAgIH0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUpKSB7CgkvKgoJKiAzLjEgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBhbGwgaGF2ZSB7dmFyaWV0eX0gb2YKCSogYXRvbWljIG9yIGxpc3QuCgkqLwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChtZW1iZXItPnR5cGUpKQoJCXhtbFNjaGVtYVR5cGVGaXh1cChtZW1iZXItPnR5cGUsIEFDVFhUX0NBU1QgcGN0eHQpOwoKCSAgICBpZiAoKCEgV1hTX0lTX0FUT01JQyhtZW1iZXItPnR5cGUpKSAmJgoJCSghIFdYU19JU19MSVNUKG1lbWJlci0+dHlwZSkpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgbWVtYmVyIHR5cGUgJyVzJyBpcyBuZWl0aGVyIGFuIGF0b21pYywgbm9yIGEgbGlzdCB0eXBlIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgbWVtYmVyLT50eXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfMSk7CgkgICAgfQoJICAgIG1lbWJlciA9IG1lbWJlci0+bmV4dDsKCX0KCS8qCgkqIDMuMy4xIElmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3c2ltcGxlIHVyLXR5cGUKCSogZGVmaW5pdGlvbrcKCSovCglpZiAodHlwZS0+YmFzZVR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHsKCSAgICAvKgoJICAgICogMy4zLjEuMSBBbGwgb2YgdGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBoYXZlIGEKCSAgICAqIHtmaW5hbH0gd2hpY2ggZG9lcyBub3QgY29udGFpbiB1bmlvbi4KCSAgICAqLwoJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCWlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhtZW1iZXItPnR5cGUsCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT04pKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzEsCgkJCVdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJCSJUaGUgJ2ZpbmFsJyBvZiBtZW1iZXIgdHlwZSAnJXMnIGNvbnRhaW5zICd1bmlvbiciLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBtZW1iZXItPnR5cGUpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMSk7CgkJfQoJCW1lbWJlciA9IG1lbWJlci0+bmV4dDsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4xLjIgVGhlIHtmYWNldHN9IG11c3QgYmUgZW1wdHkuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzFfMiwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIk5vIGZhY2V0cyBhbGxvd2VkIiwgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIpOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIDMuMy4yLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIHVuaW9uLgoJICAgICogSS5lLiB0aGUgdmFyaWV0eSBvZiAibGlzdCIgaXMgaW5oZXJpdGVkLgoJICAgICovCgkgICAgaWYgKCEgV1hTX0lTX1VOSU9OKHR5cGUtPmJhc2VUeXBlKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMSwKCQkgICAgV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBiYXNlIHR5cGUgJyVzJyBpcyBub3QgYSB1bmlvbiB0eXBlIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgdHlwZS0+YmFzZVR5cGUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnModHlwZS0+YmFzZVR5cGUsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzIsCgkJICAgIFdYU19CQVNJQ19DQVNUIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgJ2ZpbmFsJyBvZiBpdHMgYmFzZSB0eXBlICclcycgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgdHlwZS0+YmFzZVR5cGUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMik7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMi4zIFRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9LCBpbiBvcmRlciwgbXVzdCBiZSB2YWxpZGx5CgkgICAgKiBkZXJpdmVkIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBkZWZpbml0aW9ucyBpbiB0aGUge2Jhc2UKCSAgICAqIHR5cGUgZGVmaW5pdGlvbn0ncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBlbXB0eSBzZXQsCgkgICAgKiBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuCgkgICAgKi8KCSAgICB7CgkJeG1sU2NoZW1hVHlwZUxpbmtQdHIgYmFzZU1lbWJlcjsKCgkJLyoKCQkqIE9QVElNSVpFOiBpZiB0aGUgdHlwZSBpcyByZXN0cmljdGluZywgaXQgaGFzIG5vIGxvY2FsIGRlZmluZWQKCQkqIG1lbWJlciB0eXBlcyBhbmQgaW5oZXJpdHMgdGhlIG1lbWJlciB0eXBlcyBvZiB0aGUgYmFzZSB0eXBlOwoJCSogdGh1cyBhIGNoZWNrIGZvciBlcXVhbGl0eSBjYW4gYmUgc2tpcHBlZC4KCQkqLwoJCS8qCgkJKiBFdmVuIHdvcnNlOiBJIGNhbm5vdCBzZWUgYSBzY2VuYXJpbyB3aGVyZSBhIHJlc3RyaWN0aW5nCgkJKiB1bmlvbiBzaW1wbGUgdHlwZSBjYW4gaGF2ZSBvdGhlciBtZW1iZXIgdHlwZXMgYXMgdGhlIG1lbWJlcgoJCSogdHlwZXMgb2YgaXQncyBiYXNlIHR5cGUuIFRoaXMgY2hlY2sgc2VlbXMgbm90IG5lY2Vzc2FyeSB3aXRoCgkJKiByZXNwZWN0IHRvIHRoZSBkZXJpdmF0aW9uIHByb2Nlc3MgaW4gbGlieG1sMi4KCQkqIEJ1dCBuZWNlc3NhcnkgaWYgY29uc3RydWN0aW5nIHR5cGVzIHdpdGggYW4gQVBJLgoJCSovCgkJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpIHsKCQkgICAgbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7CgkJICAgIGJhc2VNZW1iZXIgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlLT5iYXNlVHlwZSk7CgkJICAgIGlmICgobWVtYmVyID09IE5VTEwpICYmIChiYXNlTWVtYmVyICE9IE5VTEwpKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCQkgICAgImRpZmZlcmVudCBudW1iZXIgb2YgbWVtYmVyIHR5cGVzIGluIGJhc2UiKTsKCQkgICAgfQoJCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQkJaWYgKGJhc2VNZW1iZXIgPT0gTlVMTCkgewoJCQkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkJCSAgICAiZGlmZmVyZW50IG51bWJlciBvZiBtZW1iZXIgdHlwZXMgaW4gYmFzZSIpOwoJCQl9CgkJCWlmICgobWVtYmVyLT50eXBlICE9IGJhc2VNZW1iZXItPnR5cGUpICYmCgkJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhBQ1RYVF9DQVNUIHBjdHh0LAoJCQkJbWVtYmVyLT50eXBlLCBiYXNlTWVtYmVyLT50eXBlLCAwKSAhPSAwKSkgewoJCQkgICAgeG1sQ2hhciAqc3RyQk1UID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zLAoJCQkJV1hTX0JBU0lDX0NBU1QgdHlwZSwgTlVMTCwKCQkJCSJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgIgoJCQkJImRlcml2ZWQgZnJvbSBpdHMgY29ycmVzcG9uZGluZyBtZW1iZXIgIgoJCQkJInR5cGUgJXMgb2YgdGhlIGJhc2UgdHlwZSAlcyIsCgkJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBtZW1iZXItPnR5cGUpLAoJCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckJNVCwgYmFzZU1lbWJlci0+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+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBTUEVDICgzLjIpICJJZiA8ZXh0ZW5zaW9uPi4uLiIKCSAgICAqLwoJICAgIGlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkvKgoJCSogU1BFQyAoMy4yLjEpCgkJKi8KCQl0eXBlLT5jb250ZW50VHlwZSA9IGJhc2VUeXBlLT5jb250ZW50VHlwZTsKCQl0eXBlLT5zdWJ0eXBlcyA9IGJhc2VUeXBlLT5zdWJ0eXBlczsKCQkvKgoJCSogTk9URSB0aGF0IHRoZSBlZmZlY3RpdmUgbWl4ZWQgaXMgaWdub3JlZCBoZXJlLgoJCSovCgkgICAgfSBlbHNlIGlmIChiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJLyoKCQkqIFNQRUMgKDMuMi4yKQoJCSovCgkJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCQkgICAgdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU1BFQyAoMy4yLjMpCgkJKi8KCQlpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCQkgICAgLyoKCQkgICAgKiAiQSBtb2RlbCBncm91cCB3aG9zZSB7Y29tcG9zaXRvcn0gaXMgc2VxdWVuY2UgYW5kIHdob3NlCgkJICAgICoge3BhcnRpY2xlc30gYXJlLi4uIgoJCSAgICAqLwoJCWlmICgoV1hTX1RZUEVfUEFSVElDTEUodHlwZSkgIT0gTlVMTCkgJiYKCQkgICAgKFdYU19UWVBFX1BBUlRJQ0xFX1RFUk0odHlwZSkgIT0gTlVMTCkgJiYKCQkgICAgKChXWFNfVFlQRV9QQVJUSUNMRV9URVJNKHR5cGUpKS0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfQUxMKSkKCQl7CgkJICAgIC8qCgkJICAgICogU1BFQyBjb3MtYWxsLWxpbWl0ZWQgKDEpCgkJICAgICovCgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQkvKiBUT0RPOiBlcnJvciBjb2RlICovCgkJCVhNTF9TQ0hFTUFQX0NPU19BTExfTElNSVRFRCwKCQkJV1hTX0lURU1fTk9ERSh0eXBlKSwgTlVMTCwKCQkJIlRoZSB0eXBlIGhhcyBhbiAnYWxsJyBtb2RlbCBncm91cCBpbiBpdHMgIgoJCQkie2NvbnRlbnQgdHlwZX0gYW5kIHRodXMgY2Fubm90IGJlIGRlcml2ZWQgZnJvbSAiCgkJCSJhIG5vbi1lbXB0eSB0eXBlLCBzaW5jZSB0aGlzIHdvdWxkIHByb2R1Y2UgYSAiCgkJCSInc2VxdWVuY2UnIG1vZGVsIGdyb3VwIGNvbnRhaW5pbmcgdGhlICdhbGwnICIKCQkJIm1vZGVsIGdyb3VwOyAnYWxsJyBtb2RlbCBncm91cHMgYXJlIG5vdCAiCgkJCSJhbGxvd2VkIHRvIGFwcGVhciBpbnNpZGUgb3RoZXIgbW9kZWwgZ3JvdXBzIiwKCQkJTlVMTCwgTlVMTCk7CgoJCX0gZWxzZSBpZiAoKFdYU19UWVBFX1BBUlRJQ0xFKGJhc2VUeXBlKSAhPSBOVUxMKSAmJgoJCSAgICAoV1hTX1RZUEVfUEFSVElDTEVfVEVSTShiYXNlVHlwZSkgIT0gTlVMTCkgJiYKCQkgICAgKChXWFNfVFlQRV9QQVJUSUNMRV9URVJNKGJhc2VUeXBlKSktPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0FMTCkpCgkJewoJCSAgICAvKgoJCSAgICAqIFNQRUMgY29zLWFsbC1saW1pdGVkICgxKQoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJLyogVE9ETzogZXJyb3IgY29kZSAqLwoJCQlYTUxfU0NIRU1BUF9DT1NfQUxMX0xJTUlURUQsCgkJCVdYU19JVEVNX05PREUodHlwZSksIE5VTEwsCgkJCSJBIHR5cGUgY2Fubm90IGJlIGRlcml2ZWQgYnkgZXh0ZW5zaW9uIGZyb20gYSB0eXBlICIKCQkJIndoaWNoIGhhcyBhbiAnYWxsJyBtb2RlbCBncm91cCBpbiBpdHMgIgoJCQkie2NvbnRlbnQgdHlwZX0sIHNpbmNlIHRoaXMgd291bGQgcHJvZHVjZSBhICIKCQkJIidzZXF1ZW5jZScgbW9kZWwgZ3JvdXAgY29udGFpbmluZyB0aGUgJ2FsbCcgIgoJCQkibW9kZWwgZ3JvdXA7ICdhbGwnIG1vZGVsIGdyb3VwcyBhcmUgbm90ICIKCQkJImFsbG93ZWQgdG8gYXBwZWFyIGluc2lkZSBvdGhlciBtb2RlbCBncm91cHMiLAoJCQlOVUxMLCBOVUxMKTsKCgkJfSBlbHNlIGlmICghIGR1bW15U2VxdWVuY2UpIHsKCQkgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgZWZmZWN0aXZlQ29udGVudCA9CgkJCSh4bWxTY2hlbWFUcmVlSXRlbVB0cikgdHlwZS0+c3VidHlwZXM7CgkJICAgIC8qCgkJICAgICogQ3JlYXRlIHRoZSBwYXJ0aWNsZS4KCQkgICAgKi8KCQkgICAgcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShwY3R4dCwKCQkJdHlwZS0+bm9kZSwgMSwgMSk7CgkJICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJCQlnb3RvIGV4aXRfZmFpbHVyZTsKCQkgICAgLyoKCQkgICAgKiBDcmVhdGUgdGhlICJzZXF1ZW5jZSIgbW9kZWwgZ3JvdXAuCgkJICAgICovCgkJICAgIHBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCQkJeG1sU2NoZW1hQWRkTW9kZWxHcm91cChwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCB0eXBlLT5ub2RlKTsKCQkgICAgaWYgKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKQoJCQlnb3RvIGV4aXRfZmFpbHVyZTsKCQkgICAgV1hTX1RZUEVfQ09OVEVOVFRZUEUodHlwZSkgPSAoeG1sU2NoZW1hVHlwZVB0cikgcGFydGljbGU7CgkJICAgIC8qCgkJICAgICogU1BFQyAidGhlIHBhcnRpY2xlIG9mIHRoZSB7Y29udGVudCB0eXBlfSBvZgoJCSAgICAqIHRoZSAuLi4gYmFzZSAuLi4iCgkJICAgICogQ3JlYXRlIGEgZHVwbGljYXRlIG9mIHRoZSBiYXNlIHR5cGUncyBwYXJ0aWNsZQoJCSAgICAqIGFuZCBhc3NpZ24gaXRzICJ0ZXJtIiB0byBpdC4KCQkgICAgKi8KCQkgICAgcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbiA9CgkJCSh4bWxTY2hlbWFUcmVlSXRlbVB0cikgeG1sU2NoZW1hQWRkUGFydGljbGUocGN0eHQsCgkJCXR5cGUtPm5vZGUsCgkJCSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzKS0+bWluT2NjdXJzLAoJCQkoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0eXBlLT5zdWJ0eXBlcyktPm1heE9jY3Vycyk7CgkJICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID09IE5VTEwpCgkJCWdvdG8gZXhpdF9mYWlsdXJlOwoJCSAgICBwYXJ0aWNsZSA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCQkJcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKCQkgICAgcGFydGljbGUtPmNoaWxkcmVuID0KCQkJKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgYmFzZVR5cGUtPnN1YnR5cGVzKS0+Y2hpbGRyZW47CgkJICAgIC8qCgkJICAgICogU1BFQyAiZm9sbG93ZWQgYnkgdGhlILdlZmZlY3RpdmUgY29udGVudLcuIgoJCSAgICAqLwoJCSAgICBwYXJ0aWNsZS0+bmV4dCA9IGVmZmVjdGl2ZUNvbnRlbnQ7CgkJICAgIC8qCgkJICAgICogVGhpcyBhbGwgd2lsbCByZXN1bHQgaW46CgkJICAgICogbmV3LXBhcnRpY2xlCgkJICAgICogICAtLT4gbmV3LXNlcXVlbmNlKAoJCSAgICAqICAgICAgICAgbmV3LXBhcnRpY2xlCgkJICAgICogICAgICAgICAgIC0tPiBiYXNlLW1vZGVsLAoJCSAgICAqICAgICAgICAgdGhpcy1wYXJ0aWNsZQoJCSAgICAqCSAgICAgICAgLS0+IHRoaXMtbW9kZWwKCQkgICAgKgkgICAgKQoJCSAgICAqLwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogVGhpcyBpcyB0aGUgY2FzZSB3aGVuIHRoZXJlIGlzIGFscmVhZHkgYW4gZW1wdHkKCQkgICAgKiA8c2VxdWVuY2U+IHdpdGggbWluT2NjdXJzPT1tYXhPY2N1cnM9PTEuCgkJICAgICogSnVzdCBhZGQgdGhlIGJhc2UgdHlwZXMncyBjb250ZW50IHR5cGUuCgkJICAgICogTk9URSB0aGF0LCBhbHRob3VnaCB3ZSBtaXNzIHRvIGFkZCBhbiBpbnRlcm1lZGlhdGUKCQkgICAgKiA8c2VxdWVuY2U+LCB0aGlzIHNob3VsZCBwcm9kdWNlIG5vIGRpZmZlcmVuY2UgdG8KCQkgICAgKiBuZWl0aGVyIHRoZSByZWdleCBjb21waWxhdGlvbiBvZiB0aGUgY29udGVudCBtb2RlbCwKCQkgICAgKiBub3IgdG8gdGhlIGNvbXBsZXggdHlwZSBjb250cmFpbnRzLgoJCSAgICAqLwoJCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID0KCQkJKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBiYXNlVHlwZS0+c3VidHlwZXM7CgkJfQoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIE5vdyBmaXh1cCBhdHRyaWJ1dGUgdXNlczoKICAgICogICAtIGV4cGFuZCBhdHRyLiBncm91cCByZWZlcmVuY2VzCiAgICAqICAgICAtIGludGVyc2VjdCBhdHRyaWJ1dGUgd2lsZGNhcmRzCiAgICAqICAgLSBpbmhlcml0IGF0dHJpYnV0ZSB1c2VzIG9mIHRoZSBiYXNlIHR5cGUKICAgICogICAtIGluaGVyaXQgb3IgdW5pb24gYXR0ci4gd2lsZGNhcmRzIGlmIGV4dGVuZGluZwogICAgKiAgIC0gYXBwbHkgYXR0ci4gdXNlIHByb2hpYml0aW9ucyBpZiByZXN0cmljdGluZwogICAgKi8KICAgIHJlcyA9IHhtbFNjaGVtYUZpeHVwVHlwZUF0dHJpYnV0ZVVzZXMocGN0eHQsIHR5cGUpOwogICAgSEZBSUxVUkUgSEVSUk9SCiAgICAvKgogICAgKiBBcHBseSB0aGUgY29tcGxleCB0eXBlIGNvbXBvbmVudCBjb25zdHJhaW50czsgdGhpcyB3aWxsIG5vdAogICAgKiBjaGVjayBhdHRyaWJ1dGVzLCBzaW5jZSB0aGlzIGlzIGRvbmUgaW4KICAgICogeG1sU2NoZW1hRml4dXBUeXBlQXR0cmlidXRlVXNlcygpLgogICAgKi8KICAgIHJlcyA9IHhtbFNjaGVtYUNoZWNrQ1RDb21wb25lbnQocGN0eHQsIHR5cGUpOwogICAgSEZBSUxVUkUgSEVSUk9SCgojaWZkZWYgREVCVUdfVFlQRQogICAgeG1sU2NoZW1hRGVidWdGaXhlZFR5cGUocGN0eHQsIHR5cGUpOwojZW5kaWYKICAgIGlmIChvbGRlcnJzICE9IHBjdHh0LT5uYmVycm9ycykKCXJldHVybihwY3R4dC0+ZXJyKTsKICAgIGVsc2UKCXJldHVybigwKTsKCmV4aXRfZXJyb3I6CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0lOVEVSTkFMX0lOVkFMSUQ7CiNpZmRlZiBERUJVR19UWVBFCiAgICB4bWxTY2hlbWFEZWJ1Z0ZpeGVkVHlwZShwY3R4dCwgdHlwZSk7CiNlbmRpZgogICAgcmV0dXJuKHBjdHh0LT5lcnIpOwoKZXhpdF9mYWlsdXJlOgogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9JTlZBTElEOwojaWZkZWYgREVCVUdfVFlQRQogICAgeG1sU2NoZW1hRGVidWdGaXhlZFR5cGUocGN0eHQsIHR5cGUpOwojZW5kaWYKICAgIHJldHVybigtMSk7Cn0KCgovKioKICogeG1sU2NoZW1hVHlwZUZpeHVwOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4ZXMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIHR5cGUuCiAqIFVSR0VOVCBUT0RPOiBXZSBuZWVkIGFuIGludCByZXN1bHQhCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuKDApOwogICAgaWYgKGFjdHh0LT50eXBlICE9IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsKCUFFUlJPUl9JTlQoInhtbFNjaGVtYVR5cGVGaXh1cCIsCgkgICAgInRoaXMgZnVuY3Rpb24gbmVlZHMgYSBwYXJzZXIgY29udGV4dCIpOwoJcmV0dXJuKC0xKTsKICAgIH0KICAgIGlmICghIFdYU19JU19UWVBFX05PVF9GSVhFRCh0eXBlKSkKCXJldHVybigwKTsKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKQoJcmV0dXJuKHhtbFNjaGVtYUZpeHVwQ29tcGxleFR5cGUoUENUWFRfQ0FTVCBhY3R4dCwgdHlwZSkpOwogICAgZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKQoJcmV0dXJuKHhtbFNjaGVtYUZpeHVwU2ltcGxlVHlwZVN0YWdlVHdvKFBDVFhUX0NBU1QgYWN0eHQsIHR5cGUpKTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRmFjZXQ6CiAqIEBmYWNldDogIHRoZSBmYWNldAogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAcGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IHRoZSBvcHRpb25hbCBuYW1lIG9mIHRoZSB0eXBlCiAqCiAqIENoZWNrcyBhbmQgY29tcHV0ZXMgdGhlIHZhbHVlcyBvZiBmYWNldHMuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGlmIG5vdCB2YWxpZCBhbmQKICogICAgICAgICAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaW50IHJldCA9IDAsIGN0eHRHaXZlbjsKCiAgICBpZiAoKGZhY2V0ID09IE5VTEwpIHx8ICh0eXBlRGVjbCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4oLTEpOwogICAgLyoKICAgICogVE9ETzogd2lsbCB0aGUgcGFyc2VyIGNvbnRleHQgYmUgZ2l2ZW4gaWYgdXNlZCBmcm9tCiAgICAqIHRoZSByZWxheE5HIG1vZHVsZT8KICAgICovCiAgICBpZiAocGN0eHQgPT0gTlVMTCkKCWN0eHRHaXZlbiA9IDA7CiAgICBlbHNlCgljdHh0R2l2ZW4gPSAxOwoKICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOiB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogT2theSB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogYXQgdGhhdCBwb2ludC4KICAgICAgICAgICAgICAgICAqLwoJCXhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCgkJLyogNC4zLjUuNSBDb25zdHJhaW50cyBvbiBlbnVtZXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50cwoJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBlbnVtZXJhdGlvbiB2YWxpZCByZXN0cmljdGlvbgoJCSogSXQgaXMgYW4gt2Vycm9ytyBpZiBhbnkgbWVtYmVyIG9mIHt2YWx1ZX0gaXMgbm90IGluIHRoZQoJCSogt3ZhbHVlIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259LgoJCSoKCQkqIG1pbkluY2x1c2l2ZSwgbWF4SW5jbHVzaXZlLCBtaW5FeGNsdXNpdmUsIG1heEV4Y2x1c2l2ZToKCQkqIFRoZSB2YWx1ZSC3bXVzdLcgYmUgaW4gdGhlCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHRoZSC3YmFzZSB0eXBlty4KCQkqLwoJCS8qCgkJKiBUaGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIHRvIGRlbGl2ZXIgYSBjb21waWxlZCB2YWx1ZQoJCSogb24gdGhlIGZhY2V0LiBJbiB0aGlzIGltcGxlbWVudGF0aW9uIG9mIFhNTCBTY2hlbWF0YSB0aGUKCQkqIHR5cGUgaG9sZGluZyBhIGZhY2V0LCB3b24ndCBiZSBhIGJ1aWx0LWluIHR5cGUuCgkJKiBUaHVzIHRvIGVuc3VyZSB0aGF0IG90aGVyIEFQSQoJCSogY2FsbHMgKHJlbGF4bmcpIGRvIHdvcmssIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGEgYnVpbHQtaW4KCQkqIHR5cGUsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUgKmlzCgkJKiBhbHJlYWR5KiB0aGUgYmFzZSB0eXBlLgoJCSovCgkJaWYgKHR5cGVEZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCSAgICBiYXNlID0gdHlwZURlY2wtPmJhc2VUeXBlOwoJCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrRmFjZXQiLAoJCQkgICAgImEgdHlwZSB1c2VyIGRlcml2ZWQgdHlwZSBoYXMgbm8gYmFzZSB0eXBlIik7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfSBlbHNlCgkJICAgIGJhc2UgPSB0eXBlRGVjbDsKCSAgICAgICAgICAgICAgICAgCgkJaWYgKCEgY3R4dEdpdmVuKSB7CgkJICAgIC8qCgkJICAgICogQSBjb250ZXh0IGlzIG5lZWRlZCBpZiBjYWxsZWQgZnJvbSBSZWxheE5HLgoJCSAgICAqLwkJICAgIAoJCSAgICBwY3R4dCA9IHhtbFNjaGVtYU5ld1BhcnNlckN0eHQoIioiKTsKCQkgICAgaWYgKHBjdHh0ID09IE5VTEwpCgkJCXJldHVybiAoLTEpOwoJCX0KCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLAoJCSogc2luY2UgdGhleSBhcmUgbm90IGF2YWlsYWJsZToKCQkqIGZhY2V0LT5ub2RlIGlzIGp1c3QgdGhlIG5vZGUgaG9sZGluZyB0aGUgZmFjZXQKCQkqIGRlZmluaXRpb24sICpub3QqIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgKnZhbHVlKgoJCSogb2YgdGhlIGZhY2V0LgoJCSovCQkKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJCSAgICBBQ1RYVF9DQVNUIHBjdHh0LCBmYWNldC0+bm9kZSwgYmFzZSwKCQkgICAgZmFjZXQtPnZhbHVlLCAmKGZhY2V0LT52YWwpLCAxLCAxLCAwKTsKICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgewoJCSAgICBpZiAocmV0IDwgMCkgewoJCQkvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCQlpZiAoY3R4dEdpdmVuKSB7CQkJICAgIAoJCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwgZmFjZXQtPm5vZGUsIE5VTEwsCgkJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIgCgkJCQkiZmFpbGVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJCQkiZmFjZXQgJyVzJyBhZ2FpbnN0IHRoZSBiYXNlIHR5cGUiLAoJCQkJZmFjZXQtPnZhbHVlLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwoJCQl9CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgcmV0ID0gWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRTsKCQkgICAgLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkgICAgaWYgKGN0eHRHaXZlbikgewoJCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoKCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJCSAgICByZXQsIGZhY2V0LT5ub2RlLCBXWFNfQkFTSUNfQ0FTVCBmYWNldCwKCQkJICAgICJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgZG9lcyBub3QgdmFsaWRhdGUgIgoJCQkgICAgImFnYWluc3QgdGhlIGJhc2UgdHlwZSAnJXMnIiwKCQkJICAgIGZhY2V0LT52YWx1ZSwKCQkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCQliYXNlLT50YXJnZXROYW1lc3BhY2UsIGJhc2UtPm5hbWUpKTsKCQkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICB9CgkJICAgIGdvdG8gZXhpdDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmFjZXQtPnZhbCA9PSBOVUxMKSB7CgkJICAgIGlmIChjdHh0R2l2ZW4pIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCSAgICAidmFsdWUgd2FzIG5vdCBjb21wdXRlZCIpOwoJCSAgICB9CgkJICAgIFRPRE8KCQl9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBmYWNldC0+cmVnZXhwID0geG1sUmVnZXhwQ29tcGlsZShmYWNldC0+dmFsdWUpOwogICAgICAgICAgICBpZiAoZmFjZXQtPnJlZ2V4cCA9PSBOVUxMKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfUkVHRVhQX0lOVkFMSUQ7CgkJLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQlpZiAoY3R4dEdpdmVuKSB7CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQlyZXQsIGZhY2V0LT5ub2RlLCBXWFNfQkFTSUNfQ0FTVCB0eXBlRGVjbCwKCQkJIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCAncGF0dGVybicgaXMgbm90IGEgIgoJCQkidmFsaWQgcmVndWxhciBleHByZXNzaW9uIiwKCQkJZmFjZXQtPnZhbHVlLCBOVUxMKTsKCQl9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCgkgICAgaWYgKGZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFMpIHsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19QSU5URUdFUiksCgkJICAgIGZhY2V0LT52YWx1ZSwgJihmYWNldC0+dmFsKSk7CgkgICAgfSBlbHNlIHsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OTklOVEVHRVIpLAoJCSAgICBmYWNldC0+dmFsdWUsICYoZmFjZXQtPnZhbCkpOwoJICAgIH0KCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICAvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrRmFjZXQiLAoJCQkgICAgInZhbGlkYXRpbmcgZmFjZXQgdmFsdWUiKTsKCQkgICAgfQoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlyZXQgPSBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFOwoJCS8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJaWYgKGN0eHRHaXZlbikgewoJCSAgICAvKiBlcnJvciBjb2RlICovCgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycjQoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJcmV0LCBmYWNldC0+bm9kZSwgV1hTX0JBU0lDX0NBU1QgdHlwZURlY2wsCgkJCSJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgJyVzJyBpcyBub3QgYSB2YWxpZCAnJXMnIiwJCQkKCQkJZmFjZXQtPnZhbHVlLAoJCQl4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTKSA/IAoJCQkgICAgQkFEX0NBU1QgIm5vbk5lZ2F0aXZlSW50ZWdlciIgOgoJCQkgICAgQkFEX0NBU1QgInBvc2l0aXZlSW50ZWdlciIsCgkJCU5VTEwpOwoJCX0KCSAgICB9CgkgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOnsKICAgICAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJwcmVzZXJ2ZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicmVwbGFjZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJjb2xsYXBzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUU7CiAgICAgICAgICAgICAgICAgICAgLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkgICAgaWYgKGN0eHRHaXZlbikgewoJCQkvKiBlcnJvciB3YXMgcHJldmlvdXNseTogWE1MX1NDSEVNQVBfSU5WQUxJRF9XSElURV9TUEFDRSAqLwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJICAgIHJldCwgZmFjZXQtPm5vZGUsIFdYU19CQVNJQ19DQVNUIHR5cGVEZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCAnd2hpdGVzcGFjZScgaXMgbm90ICIKCQkJICAgICJ2YWxpZCIsIGZhY2V0LT52YWx1ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CmV4aXQ6CiAgICBpZiAoKCEgY3R4dEdpdmVuKSAmJiAocGN0eHQgIT0gTlVMTCkpCgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChwY3R4dCk7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKCghIGN0eHRHaXZlbikgJiYgKHBjdHh0ICE9IE5VTEwpKQoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0VmFsdWVzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRmFjZXRWYWx1ZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKCQkJICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0KQp7CiAgICBpbnQgcmVzLCBvbGRlcnJzID0gcGN0eHQtPm5iZXJyb3JzOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IHR5cGVEZWNsLT5uYW1lOwogICAgLyoKICAgICogTk9URTogSXQgaXMgaW50ZW5kZWQgdG8gdXNlIHRoZSBmYWNldHMgbGlzdCwgaW5zdGVhZAogICAgKiBvZiBmYWNldFNldC4KICAgICovCiAgICBpZiAodHlwZURlY2wtPmZhY2V0cyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWNldCA9IHR5cGVEZWNsLT5mYWNldHM7CgoJLyoKCSogVGVtcG9yYXJpbHkgYXNzaWduIHRoZSAic2NoZW1hIiB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CgkqIG9mIHRoZSBwYXJzZXIgY29udGV4dC4gVGhpcyBpcyBuZWVkZWQgZm9yIE5PVEFUSU9OIHZhbGlkYXRpb24uCgkqLwoJaWYgKHBjdHh0LT52Y3R4dCA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChwY3R4dCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0KCXBjdHh0LT52Y3R4dC0+c2NoZW1hID0gcGN0eHQtPnNjaGVtYTsKCXdoaWxlIChmYWNldCAhPSBOVUxMKSB7CgkgICAgcmVzID0geG1sU2NoZW1hQ2hlY2tGYWNldChmYWNldCwgdHlwZURlY2wsIHBjdHh0LCBuYW1lKTsKCSAgICBIRkFJTFVSRQoJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7Cgl9CglwY3R4dC0+dmN0eHQtPnNjaGVtYSA9IE5VTEw7CiAgICB9CiAgICBpZiAob2xkZXJycyAhPSBwY3R4dC0+bmJlcnJvcnMpCglyZXR1cm4ocGN0eHQtPmVycik7CiAgICByZXR1cm4oMCk7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZjoKICogQGN0eHRNR3JvdXA6IHRoZSBzZWFyY2hlZCBtb2RlbCBncm91cAogKiBAc2VsZk1Hcm91cDogdGhlIHNlY29uZCBzZWFyY2hlZCBtb2RlbCBncm91cAogKiBAcGFydGljbGU6IHRoZSBmaXJzdCBwYXJ0aWNsZQogKgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGJ5CiAqIHhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhciBvbmx5LgogKgogKiBSZXR1cm5zIHRoZSBwYXJ0aWNsZSB3aXRoIHRoZSBjaXJjdWxhciBtb2RlbCBncm91cCBkZWZpbml0aW9uIHJlZmVyZW5jZSwKICogb3RoZXJ3aXNlIE5VTEwuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHJlZUl0ZW1QdHIKeG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBncm91cERlZiwKCQkJICAgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgcGFydGljbGUpCnsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNpcmMgPSBOVUxMOwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgdGVybTsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgZ2RlZjsKCiAgICBmb3IgKDsgcGFydGljbGUgIT0gTlVMTDsgcGFydGljbGUgPSBwYXJ0aWNsZS0+bmV4dCkgewoJdGVybSA9IHBhcnRpY2xlLT5jaGlsZHJlbjsKCWlmICh0ZXJtID09IE5VTEwpCgkgICAgY29udGludWU7Cglzd2l0Y2ggKHRlcm0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQlnZGVmID0gKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIHRlcm07CgkJaWYgKGdkZWYgPT0gZ3JvdXBEZWYpCgkJICAgIHJldHVybiAocGFydGljbGUpOwoJCS8qCgkJKiBNYXJrIHRoaXMgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiB0byBhdm9pZCBpbmZpbml0ZQoJCSogcmVjdXJzaW9uIG9uIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkqLwoJCWlmIChnZGVmLT5mbGFncyAmIFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX01BUktFRCkKCQkgICAgY29udGludWU7CgkJaWYgKGdkZWYtPmNoaWxkcmVuICE9IE5VTEwpIHsKCQkgICAgZ2RlZi0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEOwoJCSAgICBjaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoZ3JvdXBEZWYsCgkJCWdkZWYtPmNoaWxkcmVuLT5jaGlsZHJlbik7CgkJICAgIGdkZWYtPmZsYWdzIF49IFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX01BUktFRDsKCQkgICAgaWYgKGNpcmMgIT0gTlVMTCkKCQkJcmV0dXJuIChjaXJjKTsKCQl9CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoZ3JvdXBEZWYsIHRlcm0tPmNoaWxkcmVuKTsKCQlpZiAoY2lyYyAhPSBOVUxMKQoJCSAgICByZXR1cm4gKGNpcmMpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyOgogKiBAaXRlbTogIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIHRvIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgaXRlbSwKCQkJICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBNb2RlbCBHcm91cCBDb3JyZWN0CiAgICAqIDIgQ2lyY3VsYXIgZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCB3aXRoaW4gdGhlIHtwYXJ0aWNsZXN9CiAgICAqIG9mIGEgZ3JvdXAgdGhlcmUgbXVzdCBub3QgYmUgYXQgYW55IGRlcHRoIGEgcGFydGljbGUgd2hvc2Uge3Rlcm19CiAgICAqIGlzIHRoZSBncm91cCBpdHNlbGYuCiAgICAqLwogICAgaWYgKChpdGVtID09IE5VTEwpIHx8CgkoaXRlbS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHx8CgkoaXRlbS0+Y2hpbGRyZW4gPT0gTlVMTCkpCglyZXR1cm47CiAgICB7Cgl4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaXJjOwoKCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihpdGVtLCBpdGVtLT5jaGlsZHJlbi0+Y2hpbGRyZW4pOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFRPRE86IFRoZSBlcnJvciByZXBvcnQgaXMgbm90IGFkZXF1YXRlOiB0aGlzIGNvbnN0cmFpbnQKCSAgICAqIGlzIGRlZmluZWQgZm9yIG1vZGVsIGdyb3VwcyBidXQgbm90IGRlZmluaXRpb25zLCBidXQgc2luY2UKCSAgICAqIHRoZXJlIGNhbm5vdCBiZSBhbnkgY2lyY3VsYXIgbW9kZWwgZ3JvdXBzIHdpdGhvdXQgYSBtb2RlbCBncm91cAoJICAgICogZGVmaW5pdGlvbiAoaWYgbm90IHVzaW5nIGEgY29uc3RydWN0aW9uIEFQSSksIHdlIGNoZWNrIHRob3NlCgkgICAgKiBkZWZpbnRpb25zIG9ubHkuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfTUdfUFJPUFNfQ09SUkVDVF8yLAoJCU5VTEwsIFdYU19JVEVNX05PREUoY2lyYyksCgkJIkNpcmN1bGFyIHJlZmVyZW5jZSB0byB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAnJXMnICIKCQkiZGVmaW5lZCIsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGl0ZW0tPnRhcmdldE5hbWVzcGFjZSwgaXRlbS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLiBUaGlzIGlzIGEgZmF0YWwgZXJyb3IuCgkgICAgKi8KCSAgICBjaXJjLT5jaGlsZHJlbiA9IE5VTEw7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFNb2RlbEdyb3VwVG9Nb2RlbEdyb3VwRGVmRml4dXA6CiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBtZzogIHRoZSBtb2RlbCBncm91cAogKgogKiBBc3NpZ25zIHRoZSBtb2RlbCBncm91cCBvZiBtb2RlbCBncm91cCBkZWZpbml0aW9ucyB0byB0aGUgInRlcm0iCiAqIG9mIHRoZSByZWZlcmVuY2luZyBwYXJ0aWNsZS4KICogSW4geG1sU2NoZW1hUmVzb2x2ZU1vZGVsR3JvdXBQYXJ0aWNsZVJlZmVyZW5jZXMgdGhlIG1vZGVsIGdyb3VwCiAqIGRlZmluaXRpb25zIHdlcmUgYXNzaWduZWQgdG8gdGhlICJ0ZXJtIiwgc2luY2UgbmVlZGVkIGZvciB0aGUKICogY2lyY3VsYXJpdHkgY2hlY2suCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogICAgIEFsbCBHcm91cCBMaW1pdGVkIChjb3MtYWxsLWxpbWl0ZWQpICgxLjIpCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFNb2RlbEdyb3VwVG9Nb2RlbEdyb3VwRGVmRml4dXAoCiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQgQVRUUklCVVRFX1VOVVNFRCwKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgbWcpCnsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0gV1hTX01PREVMR1JPVVBfUEFSVElDTEUobWcpOwoKICAgIHdoaWxlIChwYXJ0aWNsZSAhPSBOVUxMKSB7CglpZiAoKFdYU19QQVJUSUNMRV9URVJNKHBhcnRpY2xlKSA9PSBOVUxMKSB8fAoJICAgICgoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpKS0+dHlwZSAhPQoJCVhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkpCgl7CgkgICAgcGFydGljbGUgPSBXWFNfUFRDX0NBU1QgcGFydGljbGUtPm5leHQ7CgkgICAgY29udGludWU7Cgl9IAoJaWYgKFdYU19NT0RFTEdST1VQREVGX01PREVMKFdYU19QQVJUSUNMRV9URVJNKHBhcnRpY2xlKSkgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBSZW1vdmUgdGhlIHBhcnRpY2xlLgoJICAgICovCgkgICAgV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpID0gTlVMTDsKCSAgICBwYXJ0aWNsZSA9IFdYU19QVENfQ0FTVCBwYXJ0aWNsZS0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0KCS8qCgkqIEFzc2lnbiB0aGUgbW9kZWwgZ3JvdXAgdG8gdGhlIHt0ZXJtfSBvZiB0aGUgcGFydGljbGUuCgkqLwoJV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpID0KCSAgICBXWFNfVFJFRV9DQVNUIFdYU19NT0RFTEdST1VQREVGX01PREVMKFdYU19QQVJUSUNMRV9URVJNKHBhcnRpY2xlKSk7CgoJcGFydGljbGUgPSBXWFNfUFRDX0NBU1QgcGFydGljbGUtPm5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0F0dHJHcm91cENpcmN1bGFyUmVjdXI6CiAqIEBjdHh0R3I6IHRoZSBzZWFyY2hlZCBhdHRyaWJ1dGUgZ3JvdXAKICogQGF0dHI6IHRoZSBjdXJyZW50IGF0dHJpYnV0ZSBsaXN0IHRvIGJlIHByb2Nlc3NlZAogKgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGJ5CiAqIHhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgYXR0cmlidXRlIGdyb3UgcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFRTmFtZVJlZlB0cgp4bWxTY2hlbWFDaGVja0F0dHJHcm91cENpcmN1bGFyUmVjdXIoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY3R4dEdyLAoJCQkJICAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0KQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncjsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZiwgY2lyYzsKICAgIGludCBpOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBhdHRyaWJ1dGUgZ3JvdXAuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJcmVmID0gbGlzdC0+aXRlbXNbaV07CglpZiAoKHJlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGKSAmJgoJICAgIChyZWYtPml0ZW1UeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgJiYKCSAgICAocmVmLT5pdGVtICE9IE5VTEwpKQoJewoJICAgIGdyID0gV1hTX0FUVFJfR1JPVVBfQ0FTVCByZWYtPml0ZW07CgkgICAgaWYgKGdyID09IGN0eHRHcikKCQlyZXR1cm4ocmVmKTsKCSAgICBpZiAoZ3ItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRCkKCQljb250aW51ZTsJICAgIAoJICAgIC8qCgkgICAgKiBNYXJrIGFzIHZpc2l0ZWQgdG8gYXZvaWQgaW5maW5pdGUgcmVjdXJzaW9uIG9uCgkgICAgKiBjaXJjdWxhciByZWZlcmVuY2VzIG5vdCB5ZXQgZXhhbWluZWQuCgkgICAgKi8KCSAgICBpZiAoKGdyLT5hdHRyVXNlcykgJiYKCQkoZ3ItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0hBU19SRUZTKSkKCSAgICB7CgkJZ3ItPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkJY2lyYyA9IHhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXJSZWN1cihjdHh0R3IsCgkJICAgICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgZ3ItPmF0dHJVc2VzKTsJCQoJCWdyLT5mbGFncyBePSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfTUFSS0VEOwoJCWlmIChjaXJjICE9IE5VTEwpCgkJICAgIHJldHVybiAoY2lyYyk7CgkgICAgfQoJICAgIAoJfQogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXI6CiAqIGF0dHJHcjogIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lCiAqCiAqIENoZWNrcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBvZiBhdHRyaWJ1dGUgZ3JvdXBzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0F0dHJHcm91cENpcmN1bGFyKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJHciwKCQkJCXhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6CiAgICAqIEF0dHJpYnV0ZSBHcm91cCBEZWZpbml0aW9uIFJlcHJlc2VudGF0aW9uIE9LCiAgICAqIDMgQ2lyY3VsYXIgZ3JvdXAgcmVmZXJlbmNlIGlzIGRpc2FsbG93ZWQgb3V0c2lkZSA8cmVkZWZpbmU+LgogICAgKiBUaGF0IGlzLCB1bmxlc3MgdGhpcyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBwYXJlbnQgaXMKICAgICogPHJlZGVmaW5lPiwgdGhlbiBhbW9uZyB0aGUgW2NoaWxkcmVuXSwgaWYgYW55LCB0aGVyZSBtdXN0CiAgICAqIG5vdCBiZSBhbiA8YXR0cmlidXRlR3JvdXA+IHdpdGggcmVmIFthdHRyaWJ1dGVdIHdoaWNoIHJlc29sdmVzCiAgICAqIHRvIHRoZSBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIDxhdHRyaWJ1dGVHcm91cD4uIEluZGlyZWN0CiAgICAqIGNpcmN1bGFyaXR5IGlzIGFsc28gcnVsZWQgb3V0LiBUaGF0IGlzLCB3aGVuIFFOYW1lIHJlc29sdXRpb24KICAgICogKFNjaGVtYSBEb2N1bWVudCkgKKczLjE1LjMpIGlzIGFwcGxpZWQgdG8gYSC3UU5hbWW3IGFyaXNpbmcgZnJvbQogICAgKiBhbnkgPGF0dHJpYnV0ZUdyb3VwPnMgd2l0aCBhIHJlZiBbYXR0cmlidXRlXSBhbW9uZyB0aGUgW2NoaWxkcmVuXSwKICAgICogaXQgbXVzdCBub3QgYmUgdGhlIGNhc2UgdGhhdCBhILdRTmFtZbcgaXMgZW5jb3VudGVyZWQgYXQgYW55IGRlcHRoCiAgICAqIHdoaWNoIHJlc29sdmVzIHRvIHRoZSBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIDxhdHRyaWJ1dGVHcm91cD4uCiAgICAqLwogICAgaWYgKGF0dHJHci0+YXR0clVzZXMgPT0gTlVMTCkKCXJldHVybigwKTsKICAgIGVsc2UgaWYgKChhdHRyR3ItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0hBU19SRUZTKSA9PSAwKQoJcmV0dXJuKDApOwogICAgZWxzZSB7Cgl4bWxTY2hlbWFRTmFtZVJlZlB0ciBjaXJjOwoJCgljaXJjID0geG1sU2NoZW1hQ2hlY2tBdHRyR3JvdXBDaXJjdWxhclJlY3VyKGF0dHJHciwKCSAgICAoeG1sU2NoZW1hSXRlbUxpc3RQdHIpIGF0dHJHci0+YXR0clVzZXMpOwkKCWlmIChjaXJjICE9IE5VTEwpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIC8qCgkgICAgKiBUT0RPOiBSZXBvcnQgdGhlIHJlZmVyZW5jZWQgYXR0ciBncm91cCBhcyBRTmFtZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFX0dST1VQXzMsCgkJTlVMTCwgV1hTX0lURU1fTk9ERShXWFNfQkFTSUNfQ0FTVCBjaXJjKSwKCQkiQ2lyY3VsYXIgcmVmZXJlbmNlIHRvIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgJyVzJyAiCgkJImRlZmluZWQiLCB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBhdHRyR3IpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgLyoKCSAgICAqIE5PVEU6IFdlIHdpbGwgY3V0IHRoZSByZWZlcmVuY2UgdG8gYXZvaWQgZnVydGhlcgoJICAgICogY29uZnVzaW9uIG9mIHRoZSBwcm9jZXNzb3IuCgkgICAgKiBCQURTUEVDIFRPRE86IFRoZSBzcGVjIHNob3VsZCBkZWZpbmUgaG93IHRvIHByb2Nlc3MgaW4gdGhpcyBjYXNlLgoJICAgICovCgkgICAgY2lyYy0+aXRlbSA9IE5VTEw7CgkgICAgcmV0dXJuKGN0eHQtPmVycik7Cgl9CiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBFeHBhbmRSZWZzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJHcik7CgovKioKICogeG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzOgogKiBAcGN0eHQ6IHRoZSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIG5vZGUgb2YgdGhlIGNvbXBvbmVudCBob2xkaW5nIHRoZSBhdHRyaWJ1dGUgdXNlcwogKiBAY29tcGxldGVXaWxkOiB0aGUgaW50ZXJzZWN0ZWQgd2lsZGNhcmQgdG8gYmUgcmV0dXJuZWQgCiAqIEBsaXN0OiB0aGUgYXR0cmlidXRlIHVzZXMKICoKICogU3Vic3RpdHV0ZXMgY29udGFpbmVkIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzCiAqIGZvciB0aGVpciBhdHRyaWJ1dGUgdXNlcy4gV2lsY2FyZHMgYXJlIGludGVyc2VjdGVkLgogKiBBdHRyaWJ1dGUgdXNlIHByb2hpYml0aW9ucyBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBsaXN0CiAqIGFuZCByZXR1cm5lZCB2aWEgdGhlIEBwcm9oaWJzIGxpc3QuCiAqIFBvaW50bGVzc25lc3Mgb2YgYXR0ci4gcHJvaGlicywgaWYgYSBtYXRjaGluZyBhdHRyLiBkZWNsCiAqIGlzIGV4aXN0ZW50IGEgd2VsbCwgYXJlIGNoZWNrZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUV4cGFuZEF0dHJpYnV0ZUdyb3VwUmVmcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkJCSAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmNvbXBsZXRlV2lsZCwKCQkJCSAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCwKCQkJCSAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgcHJvaGlicykKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3I7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgc3VibGlzdDsKICAgIGludCBpLCBqOwogICAgaW50IGNyZWF0ZWQgPSAoKmNvbXBsZXRlV2lsZCA9PSBOVUxMKSA/IDAgOiAxOwoKICAgIGlmIChwcm9oaWJzKQoJcHJvaGlicy0+bmJJdGVtcyA9IDA7CgogICAgZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJdXNlID0gbGlzdC0+aXRlbXNbaV07CgoJaWYgKHVzZS0+dHlwZSA9PSBYTUxfU0NIRU1BX0VYVFJBX0FUVFJfVVNFX1BST0hJQikgewkgICAgCgkgICAgaWYgKHByb2hpYnMgPT0gTlVMTCkgewoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUV4cGFuZEF0dHJpYnV0ZUdyb3VwUmVmcyIsCgkJICAgICJ1bmV4cGVjdGVkIGF0dHIgcHJvaGliaXRpb24gZm91bmQiKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVtb3ZlIGZyb20gYXR0cmlidXRlIHVzZXMuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hSXRlbUxpc3RSZW1vdmUobGlzdCwgaSkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCSAgICBpLS07CgkgICAgLyoKCSAgICAqIE5vdGUgdGhhdCBkdXBsaWNhdGUgcHJvaGliaXRpb25zIHdlcmUgYWxyZWFkeQoJICAgICogaGFuZGxlZCBhdCBwYXJzaW5nIHRpbWUuCgkgICAgKi8JICAgIAoJICAgIC8qCgkgICAgKiBBZGQgdG8gbGlzdCBvZiBwcm9oaWJpdGlvbnMuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFJdGVtTGlzdEFkZFNpemUocHJvaGlicywgMiwgdXNlKTsKCSAgICBjb250aW51ZTsKCX0KCWlmICgodXNlLT50eXBlID09IFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUYpICYmCgkgICAgKChXWFNfUU5BTUVfQ0FTVCB1c2UpLT5pdGVtVHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApKQoJewoJICAgIGlmICgoV1hTX1FOQU1FX0NBU1QgdXNlKS0+aXRlbSA9PSBOVUxMKQoJCXJldHVybigtMSk7CgkgICAgZ3IgPSBXWFNfQVRUUl9HUk9VUF9DQVNUIChXWFNfUU5BTUVfQ0FTVCB1c2UpLT5pdGVtOwoJICAgIC8qCgkgICAgKiBFeHBhbmQgdGhlIHJlZmVyZW5jZWQgYXR0ci4gZ3JvdXAuCgkgICAgKiBUT0RPOiByZW1vdmUgdGhpcywgdGhpcyBpcyBkb25lIGluIGEgcHJldmlvdXMgc3RlcCwgc28KCSAgICAqIGFscmVhZHkgZG9uZSBoZXJlLgoJICAgICovCgkgICAgaWYgKChnci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCkgPT0gMCkgewoJCWlmICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cEV4cGFuZFJlZnMocGN0eHQsIGdyKSA9PSAtMSkKCQkgICAgcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIEJ1aWxkIHRoZSAnY29tcGxldGUnIHdpbGRjYXJkOyBpLmUuIGludGVyc2VjdCBtdWx0aXBsZQoJICAgICogd2lsZGNhcmRzLgoJICAgICovCgkgICAgaWYgKGdyLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkJaWYgKCpjb21wbGV0ZVdpbGQgPT0gTlVMTCkgewoJCSAgICAqY29tcGxldGVXaWxkID0gZ3ItPmF0dHJpYnV0ZVdpbGRjYXJkOwoJCX0gZWxzZSB7CgkJICAgIGlmICghIGNyZWF0ZWQpIHsKCQkJeG1sU2NoZW1hV2lsZGNhcmRQdHIgdG1wV2lsZDsKCgkJCSAvKgoJCQkqIENvcHkgdGhlIGZpcnN0IGVuY291bnRlcmVkIHdpbGRjYXJkIGFzIGNvbnRleHQsCgkJCSogZXhjZXB0IGZvciB0aGUgYW5ub3RhdGlvbi4KCQkJKgoJCQkqIEFsdGhvdWdoIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCBtaWdodCBub3QgY29ycmVzcG9uZAoJCQkqIHRvIGFueSBub2RlIGluIHRoZSBzY2hlbWEsIHdlIHdpbGwgYW5jaG9yIGl0IG9uCgkJCSogdGhlIG5vZGUgb2YgdGhlIG93bmVyIGNvbXBvbmVudC4KCQkJKi8KCQkJdG1wV2lsZCA9ICB4bWxTY2hlbWFBZGRXaWxkY2FyZChwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFLAoJCQkgICAgV1hTX0lURU1fTk9ERShpdGVtKSk7CgkJCWlmICh0bXBXaWxkID09IE5VTEwpCgkJCSAgICByZXR1cm4oLTEpOwoJCQlpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMocGN0eHQsCgkJCSAgICB0bXBXaWxkLCAqY29tcGxldGVXaWxkKSA9PSAtMSkKCQkJICAgIHJldHVybiAoLTEpOwoJCQl0bXBXaWxkLT5wcm9jZXNzQ29udGVudHMgPSAoKmNvbXBsZXRlV2lsZCktPnByb2Nlc3NDb250ZW50czsKCQkJKmNvbXBsZXRlV2lsZCA9IHRtcFdpbGQ7CgkJCWNyZWF0ZWQgPSAxOwoJCSAgICB9CgkJICAgIAoJCSAgICBpZiAoeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKHBjdHh0LCAqY29tcGxldGVXaWxkLAoJCQlnci0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4oLTEpOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEp1c3QgcmVtb3ZlIHRoZSByZWZlcmVuY2UgaWYgdGhlIHJlZmVyZW5jZWQgZ3JvdXAgZG9lcyBub3QKCSAgICAqIGNvbnRhaW4gYW55IGF0dHJpYnV0ZSB1c2VzLgoJICAgICovCgkgICAgaWYgKGdyLT5hdHRyVXNlcyA9PSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYUl0ZW1MaXN0UmVtb3ZlKGxpc3QsIGkpID09IC0xKQoJCSAgICByZXR1cm4oLTEpOwoJCWktLTsKCQljb250aW51ZTsKCSAgICB9CgkgICAgLyoKCSAgICAqIEFkZCB0aGUgYXR0cmlidXRlIHVzZXMuCgkgICAgKi8KCSAgICBzdWJsaXN0ID0gKCh4bWxTY2hlbWFJdGVtTGlzdFB0cikgZ3ItPmF0dHJVc2VzKTsKCSAgICBpZiAoc3VibGlzdC0+bmJJdGVtcyAhPSAwKSB7CgkJbGlzdC0+aXRlbXNbaV0gPSBzdWJsaXN0LT5pdGVtc1swXTsKCQlpZiAoc3VibGlzdC0+bmJJdGVtcyAhPSAxKSB7CgkJICAgIGZvciAoaiA9IDE7IGogPCBzdWJsaXN0LT5uYkl0ZW1zOyBqKyspIHsKCQkJaSsrOwoJCQlpZiAoeG1sU2NoZW1hSXRlbUxpc3RJbnNlcnQobGlzdCwKCQkJCXN1Ymxpc3QtPml0ZW1zW2pdLCBpKSA9PSAtMSkKCQkJICAgIHJldHVybigtMSk7CgkJICAgIH0KCQl9CgkgICAgfQkgICAgICAKCX0KCiAgICB9CiAgICAvKgogICAgKiBIYW5kbGUgcG9pbnRsZXNzIHByb2hpYml0aW9ucyBvZiBkZWNsYXJlZCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChwcm9oaWJzICYmIChwcm9oaWJzLT5uYkl0ZW1zICE9IDApICYmIChsaXN0LT5uYkl0ZW1zICE9IDApKSB7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQcm9oaWJQdHIgcHJvaGliOwoKCWZvciAoaSA9IHByb2hpYnMtPm5iSXRlbXMgLTE7IGkgPj0gMDsgaS0tKSB7CgkgICAgcHJvaGliID0gcHJvaGlicy0+aXRlbXNbaV07CgkgICAgZm9yIChqID0gMDsgaiA8IGxpc3QtPm5iSXRlbXM7IGorKykgewoJCXVzZSA9IGxpc3QtPml0ZW1zW2pdOwoKCQlpZiAoKHByb2hpYi0+bmFtZSA9PSBXWFNfQVRUUlVTRV9ERUNMX05BTUUodXNlKSkgJiYKCQkgICAgKHByb2hpYi0+dGFyZ2V0TmFtZXNwYWNlID09IFdYU19BVFRSVVNFX0RFQ0xfVE5TKHVzZSkpKQoJCXsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkJICAgIHhtbFNjaGVtYUN1c3RvbVdhcm5pbmcoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJWE1MX1NDSEVNQVBfV0FSTl9BVFRSX1BPSU5UTEVTU19QUk9ILAoJCQlwcm9oaWItPm5vZGUsIE5VTEwsCgkJCSJTa2lwcGluZyBwb2ludGxlc3MgYXR0cmlidXRlIHVzZSBwcm9oaWJpdGlvbiAiCgkJCSInJXMnLCBzaW5jZSBhIGNvcnJlc3BvbmRpbmcgYXR0cmlidXRlIHVzZSAiCgkJCSJleGlzdHMgYWxyZWFkeSBpbiB0aGUgdHlwZSBkZWZpbml0aW9uIiwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIHByb2hpYi0+dGFyZ2V0TmFtZXNwYWNlLCBwcm9oaWItPm5hbWUpLAoJCQlOVUxMLCBOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICAvKgoJCSAgICAqIFJlbW92ZSB0aGUgcHJvaGliaXRpb24uCgkJICAgICovCgkJICAgIGlmICh4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZShwcm9oaWJzLCBpKSA9PSAtMSkKCQkJcmV0dXJuKC0xKTsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCX0KICAgIH0KICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwRXhwYW5kUmVmczoKICogQHBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBhdHRyR3I6ICB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gCiAqCiAqIENvbXB1dGF0aW9uIG9mOgogKiB7YXR0cmlidXRlIHVzZXN9IHByb3BlcnR5CiAqIHthdHRyaWJ1dGUgd2lsZGNhcmR9IHByb3BlcnR5CiAqCiAqIFN1YnN0aXR1dGVzIGNvbnRhaW5lZCBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcwogKiBmb3IgdGhlaXIgYXR0cmlidXRlIHVzZXMuIFdpbGNhcmRzIGFyZSBpbnRlcnNlY3RlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBFeHBhbmRSZWZzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJHcikKeyAgCiAgICBpZiAoKGF0dHJHci0+YXR0clVzZXMgPT0gTlVMTCkgfHwKCShhdHRyR3ItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQpKQoJcmV0dXJuKDApOwoKICAgIGF0dHJHci0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQ7CiAgICBpZiAoeG1sU2NoZW1hRXhwYW5kQXR0cmlidXRlR3JvdXBSZWZzKHBjdHh0LCBXWFNfQkFTSUNfQ0FTVCBhdHRyR3IsCgkmKGF0dHJHci0+YXR0cmlidXRlV2lsZGNhcmQpLCBhdHRyR3ItPmF0dHJVc2VzLCBOVUxMKSA9PSAtMSkKCXJldHVybigtMSk7ICAgIAogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBFeHBhbmRSZWZzOgogKiBAcGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQGF0dHJHcjogIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiAKICoKICogU3Vic3RpdHV0ZXMgY29udGFpbmVkIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzCiAqIGZvciB0aGVpciBhdHRyaWJ1dGUgdXNlcy4gV2lsY2FyZHMgYXJlIGludGVyc2VjdGVkLgogKiAKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiAgICBBdHRyaWJ1dGUgR3JvdXAgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QgKGFnLXByb3BzLWNvcnJlY3QpIAogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0FHUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJHcikKeyAgCiAgICAvKgogICAgKiBTUEVDIGFnLXByb3BzLWNvcnJlY3QKICAgICogKDEpICJUaGUgdmFsdWVzIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAgICAqIG11c3QgYmUgYXMgZGVzY3JpYmVkIGluIHRoZSBwcm9wZXJ0eSB0YWJsZWF1IGluIFRoZSBBdHRyaWJ1dGUKICAgICogR3JvdXAgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50ICinMy42LjEpLCBtb2R1bG8gdGhlIGltcGFjdCBvZgogICAgKiBNaXNzaW5nIFN1Yi1jb21wb25lbnRzICinNS4zKTsiCiAgICAqLwogICAgCiAgICBpZiAoKGF0dHJHci0+YXR0clVzZXMgIT0gTlVMTCkgJiYKCShXWFNfTElTVF9DQVNUIGF0dHJHci0+YXR0clVzZXMpLT5uYkl0ZW1zID4gMSkKICAgIHsKCXhtbFNjaGVtYUl0ZW1MaXN0UHRyIHVzZXMgPSBXWFNfTElTVF9DQVNUIGF0dHJHci0+YXR0clVzZXM7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgdXNlLCB0bXA7CglpbnQgaSwgaiwgaGFzSWQgPSAwOwoKCWZvciAoaSA9IHVzZXMtPm5iSXRlbXMgLTE7IGkgPj0gMDsgaS0tKSB7CgkgICAgdXNlID0gdXNlcy0+aXRlbXNbaV07CSAgICAKCSAgICAvKgoJICAgICogU1BFQyBhZy1wcm9wcy1jb3JyZWN0CgkgICAgKiAoMikgIlR3byBkaXN0aW5jdCBtZW1iZXJzIG9mIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3Qgbm90IGhhdmUKCSAgICAqIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259cyBib3RoIG9mIHdob3NlIHtuYW1lfXMgbWF0Y2ggYW5kIHdob3NlCgkgICAgKiB7dGFyZ2V0IG5hbWVzcGFjZX1zIGFyZSBpZGVudGljYWwuIgoJICAgICovCgkgICAgaWYgKGkgPiAwKSB7CgkJZm9yIChqID0gaSAtMTsgaiA+PSAwOyBqLS0pIHsKCQkgICAgdG1wID0gdXNlcy0+aXRlbXNbal07CgkJICAgIGlmICgoV1hTX0FUVFJVU0VfREVDTF9OQU1FKHVzZSkgPT0KCQkJV1hTX0FUVFJVU0VfREVDTF9OQU1FKHRtcCkpICYmCgkJCShXWFNfQVRUUlVTRV9ERUNMX1ROUyh1c2UpID09CgkJCVdYU19BVFRSVVNFX0RFQ0xfVE5TKHRtcCkpKQoJCSAgICB7CgkJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJCQoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBwY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0FHX1BST1BTX0NPUlJFQ1QsCgkJCSAgICBhdHRyR3ItPm5vZGUsIFdYU19CQVNJQ19DQVNUIGF0dHJHciwKCQkJICAgICJEdXBsaWNhdGUgJXMiLAoJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50RGVzaWduYXRpb24oJnN0ciwgdXNlKSwKCQkJICAgIE5VTEwpOwoJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCS8qCgkJCSogUmVtb3ZlIHRoZSBkdXBsaWNhdGUuCgkJCSovCgkJCWlmICh4bWxTY2hlbWFJdGVtTGlzdFJlbW92ZSh1c2VzLCBpKSA9PSAtMSkKCQkJICAgIHJldHVybigtMSk7CgkJCWdvdG8gbmV4dF91c2U7CgkJICAgIH0KCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBTUEVDIGFnLXByb3BzLWNvcnJlY3QKCSAgICAqICgzKSAiVHdvIGRpc3RpbmN0IG1lbWJlcnMgb2YgdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCBub3QgaGF2ZQoJICAgICoge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn1zIGJvdGggb2Ygd2hvc2Uge3R5cGUgZGVmaW5pdGlvbn1zIGFyZSBvcgoJICAgICogYXJlIGRlcml2ZWQgZnJvbSBJRC4iCgkgICAgKiBUT0RPOiBEb2VzICdkZXJpdmVkJyBpbmNsdWRlIG1lbWJlci10eXBlcyBvZiB1bmlvbnM/CgkgICAgKi8KCSAgICBpZiAoV1hTX0FUVFJVU0VfVFlQRURFRih1c2UpICE9IE5VTEwpIHsJCQoJCWlmICh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoCgkJICAgIFdYU19BVFRSVVNFX1RZUEVERUYodXNlKSwgWE1MX1NDSEVNQVNfSUQpKQoJCXsJCQoJCSAgICBpZiAoaGFzSWQpIHsKCQkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkJCgkJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHBjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfQUdfUFJPUFNfQ09SUkVDVCwKCQkJICAgIGF0dHJHci0+bm9kZSwgV1hTX0JBU0lDX0NBU1QgYXR0ckdyLAoJCQkgICAgIlRoZXJlIG11c3Qgbm90IGV4aXN0IG1vcmUgdGhhbiBvbmUgYXR0cmlidXRlICIKCQkJICAgICJkZWNsYXJhdGlvbiBvZiB0eXBlICd4czpJRCcgIgoJCQkgICAgIihvciBkZXJpdmVkIGZyb20gJ3hzOklEJykuIFRoZSAlcyB2aW9sYXRlcyB0aGlzICIKCQkJICAgICJjb25zdHJhaW50IiwKCQkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudERlc2lnbmF0aW9uKCZzdHIsIHVzZSksCgkJCSAgICBOVUxMKTsKCQkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCQlpZiAoeG1sU2NoZW1hSXRlbUxpc3RSZW1vdmUodXNlcywgaSkgPT0gLTEpCgkJCSAgICByZXR1cm4oLTEpOwoJCSAgICB9CQkgICAgCgkJICAgIGhhc0lkID0gMTsKCQl9CgkgICAgfQpuZXh0X3VzZToge30KCX0KICAgIH0KICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVBdHRyR3JvdXBSZWZlcmVuY2VzOgogKiBAYXR0cmdycERlY2w6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBSZXNvbHZlcyByZWZlcmVuY2VzIHRvIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9ucy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVzb2x2ZUF0dHJHcm91cFJlZmVyZW5jZXMoeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmLAoJCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3JvdXA7CgogICAgaWYgKHJlZi0+aXRlbSAhPSBOVUxMKQogICAgICAgIHJldHVybigwKTsKICAgIGdyb3VwID0geG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXAoY3R4dC0+c2NoZW1hLAoJcmVmLT5uYW1lLAoJcmVmLT50YXJnZXROYW1lc3BhY2UpOwogICAgaWYgKGdyb3VwID09IE5VTEwpIHsKCXhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJICAgIE5VTEwsIHJlZi0+bm9kZSwKCSAgICAicmVmIiwgcmVmLT5uYW1lLCByZWYtPnRhcmdldE5hbWVzcGFjZSwKCSAgICByZWYtPml0ZW1UeXBlLCBOVUxMKTsKCXJldHVybihjdHh0LT5lcnIpOwogICAgfQogICAgcmVmLT5pdGVtID0gV1hTX0JBU0lDX0NBU1QgZ3JvdXA7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0F0dHJQcm9wc0NvcnJlY3Q6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiAgICBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gUHJvcGVydGllcyBDb3JyZWN0IChhLXByb3BzLWNvcnJlY3QpCiAqCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZS4KICogTk9URSB0aGF0IHRoaXMgbmVlZHMgdGhlIHNpbWxlIHR5cGUgZGVmaW5pdGlvbnMgdG8gYmUgYWxyZWFkeQogKiAgIGJ1aWxkZWQgYW5kIGNoZWNrZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQXR0clByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKCiAgICAvKgogICAgKiBTUEVDIGEtcHJvcHMtY29ycmVjdCAoMSkKICAgICogIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uIG11c3QKICAgICogYmUgYXMgZGVzY3JpYmVkIGluIHRoZSBwcm9wZXJ0eSB0YWJsZWF1IGluIFRoZSBBdHRyaWJ1dGUKICAgICogRGVjbGFyYXRpb24gU2NoZW1hIENvbXBvbmVudCAopzMuMi4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YKICAgICogTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuIgogICAgKi8KICAgIAogICAgaWYgKFdYU19BVFRSX1RZUEVERUYoYXR0cikgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAoYXR0ci0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJaW50IHJldDsKCgkvKgoJKiBTUEVDIGEtcHJvcHMtY29ycmVjdCAoMykKCSogIklmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQgdGhlbiB0aGVyZQoJKiBtdXN0IG5vdCBiZSBhIHt2YWx1ZSBjb25zdHJhaW50fS4iCgkqLwoJaWYgKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSgKCSAgICBXWFNfQVRUUl9UWVBFREVGKGF0dHIpLCBYTUxfU0NIRU1BU19JRCkpCgl7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfQV9QUk9QU19DT1JSRUNUXzMsCgkJTlVMTCwgV1hTX0JBU0lDX0NBU1QgYXR0ciwKCQkiVmFsdWUgY29uc3RyYWludHMgYXJlIG5vdCBhbGxvd2VkIGlmIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSJpcyBvciBpcyBkZXJpdmVkIGZyb20geHM6SUQiLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybihwY3R4dC0+ZXJyKTsKCX0KCS8qCgkqIFNQRUMgYS1wcm9wcy1jb3JyZWN0ICgyKQoJKiAiaWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbAoJKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdAoJKiB0byB0aGUge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLiIKCSogVE9ETzogRG9uJ3QgY2FyZSBhYm91dCB0aGUgKmNvbm9uaWNhbCogc3R1ZmYgaGVyZSwgdGhpcyByZXF1aXJlbWVudAoJKiB3aWxsIGJlIHJlbW92ZWQgaW4gV1hTIDEuMSBhbnl3YXkuCgkqLwoJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShBQ1RYVF9DQVNUIHBjdHh0LAoJICAgIGF0dHItPm5vZGUsIFdYU19BVFRSX1RZUEVERUYoYXR0ciksCgkgICAgYXR0ci0+ZGVmVmFsdWUsICYoYXR0ci0+ZGVmVmFsKSwKCSAgICAxLCAxLCAwKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tBdHRyUHJvcHNDb3JyZWN0IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgcGN0eHQsCgkJWE1MX1NDSEVNQVBfQV9QUk9QU19DT1JSRUNUXzIsCgkJTlVMTCwgV1hTX0JBU0lDX0NBU1QgYXR0ciwKCQkiVGhlIHZhbHVlIG9mIHRoZSB2YWx1ZSBjb25zdHJhaW50IGlzIG5vdCB2YWxpZCIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKHBjdHh0LT5lcnIpOwoJfQogICAgfQogICAKICAgIHJldHVybigwKTsKfQoKc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hQ2hlY2tTdWJzdEdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSB4bWxTY2hlbWFFbGVtZW50UHRyIGFuY2VzdG9yKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKCiAgICBpZiAoV1hTX1NVQlNUX0hFQUQoYW5jZXN0b3IpID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKFdYU19TVUJTVF9IRUFEKGFuY2VzdG9yKSA9PSBlbGVtRGVjbCkKCXJldHVybiAoYW5jZXN0b3IpOwoKICAgIGlmIChXWFNfU1VCU1RfSEVBRChhbmNlc3RvciktPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9DSVJDVUxBUikKCXJldHVybiAoTlVMTCk7CiAgICBXWFNfU1VCU1RfSEVBRChhbmNlc3RvciktPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQ0lSQ1VMQVI7CiAgICByZXQgPSB4bWxTY2hlbWFDaGVja1N1YnN0R3JvdXBDaXJjdWxhcihlbGVtRGVjbCwKCVdYU19TVUJTVF9IRUFEKGFuY2VzdG9yKSk7CiAgICBXWFNfU1VCU1RfSEVBRChhbmNlc3RvciktPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0VMRU1fQ0lSQ1VMQVI7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0OgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBkZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBFbGVtZW50IERlY2xhcmF0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCAoZS1wcm9wcy1jb3JyZWN0KQogKgogKiBTVEFUVVM6CiAqICAgbWlzc2luZzogKDYpCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWYgPSBXWFNfRUxFTV9UWVBFREVGKGVsZW1EZWNsKTsKICAgIC8qCiAgICAqIFNQRUMgKDEpICJUaGUgdmFsdWVzIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24KICAgICogbXVzdCBiZSBhcyBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gVGhlIEVsZW1lbnQKICAgICogRGVjbGFyYXRpb24gU2NoZW1hIENvbXBvbmVudCAopzMuMy4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZwogICAgKiBTdWItY29tcG9uZW50cyAopzUuMykuIgogICAgKi8KICAgIGlmIChXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCkgIT0gTlVMTCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkID0gV1hTX1NVQlNUX0hFQUQoZWxlbURlY2wpLCBjaXJjOwoKCXhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoaGVhZCwgcGN0eHQpOwoJLyoKCSogU1BFQyAoMykgIklmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gZ3JvdXAKCSogYWZmaWxpYXRpb259LCB0aGVuIHtzY29wZX0gbXVzdCBiZSBnbG9iYWwuIgoJKi8KCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpID09IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF8zLAoJCVdYU19CQVNJQ19DQVNUIGVsZW1EZWNsLCBOVUxMLAoJCSJPbmx5IGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9ucyBjYW4gaGF2ZSBhICIKCQkic3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9uIiwgTlVMTCk7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzM7Cgl9CgkvKgoJKiBUT0RPOiBTUEVDICg2KSAiQ2lyY3VsYXIgc3Vic3RpdHV0aW9uIGdyb3VwcyBhcmUgZGlzYWxsb3dlZC4KCSogVGhhdCBpcywgaXQgbXVzdCBub3QgYmUgcG9zc2libGUgdG8gcmV0dXJuIHRvIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24KCSogYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259CgkqIHByb3BlcnR5LiIKCSovCglpZiAoaGVhZCA9PSBlbGVtRGVjbCkKCSAgICBjaXJjID0gaGVhZDsKCWVsc2UgaWYgKFdYU19TVUJTVF9IRUFEKGhlYWQpICE9IE5VTEwpCgkgICAgY2lyYyA9IHhtbFNjaGVtYUNoZWNrU3Vic3RHcm91cENpcmN1bGFyKGhlYWQsIGhlYWQpOwoJZWxzZQoJICAgIGNpcmMgPSBOVUxMOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzYsCgkJV1hTX0JBU0lDX0NBU1QgY2lyYywgTlVMTCwKCQkiVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gJyVzJyBkZWZpbmVzIGEgY2lyY3VsYXIgIgoJCSJzdWJzdGl0dXRpb24gZ3JvdXAgdG8gZWxlbWVudCBkZWNsYXJhdGlvbiAnJXMnIiwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQSwgY2lyYyksCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckIsIGhlYWQpLAoJCU5VTEwpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKCSAgICBGUkVFX0FORF9OVUxMKHN0ckIpCgkgICAgcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzY7Cgl9CgkvKgoJKiBTUEVDICg0KSAiSWYgdGhlcmUgaXMgYSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwKCSogdGhlIHt0eXBlIGRlZmluaXRpb259CgkqIG9mIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gdGhlIHt0eXBlCgkqIGRlZmluaXRpb259IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgZ2l2ZW4gdGhlIHZhbHVlCgkqIG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnN9IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwCgkqIGFmZmlsaWF0aW9ufSwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKENvbXBsZXgpICinMy40LjYpCgkqIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgY29tcGxleCkgb3IgYXMgZGVmaW5lZCBpbgoJKiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMKCSogc2ltcGxlKS4iCgkqCgkqIE5PVEU6IHtzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9uc30gbWVhbnMgdGhlIHZhbHVlcyBvZiB0aGUKCSogYXR0cmlidXRlICJmaW5hbCIuCgkqLwoKCWlmICh0eXBlRGVmICE9IFdYU19FTEVNX1RZUEVERUYoV1hTX1NVQlNUX0hFQUQoZWxlbURlY2wpKSkgewoJICAgIGludCBzZXQgPSAwOwoKCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTikKCQlzZXQgfD0gU1VCU0VUX0VYVEVOU0lPTjsKCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX1JFU1RSSUNUSU9OKQoJCXNldCB8PSBTVUJTRVRfUkVTVFJJQ1RJT047CgoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU0Rlcml2ZWRPSyhBQ1RYVF9DQVNUIHBjdHh0LCB0eXBlRGVmLAoJCVdYU19FTEVNX1RZUEVERUYoaGVhZCksIHNldCkgIT0gMCkgewoJCXhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEwsICpzdHJDID0gTlVMTDsKCgkJcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzQ7CgkJeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzQsCgkJICAgIFdYU19CQVNJQ19DQVNUIGVsZW1EZWNsLCBOVUxMLAoJCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiAnJXMnIHdhcyAiCgkJICAgICJlaXRoZXIgcmVqZWN0ZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiBncm91cCAiCgkJICAgICJhZmZpbGlhdGlvbiAnJXMnLCBvciBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gaXRzIHR5cGUgIgoJCSAgICAiZGVmaW5pdGlvbiAnJXMnIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckEsIHR5cGVEZWYpLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQiwgaGVhZCksCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJDLCBXWFNfRUxFTV9UWVBFREVGKGhlYWQpKSk7CgkJRlJFRV9BTkRfTlVMTChzdHJBKQoJCUZSRUVfQU5EX05VTEwoc3RyQikKCQlGUkVFX0FORF9OVUxMKHN0ckMpCgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogU1BFQyAoNSkgIklmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvciB7dHlwZSBkZWZpbml0aW9ufSdzCiAgICAqIHtjb250ZW50IHR5cGV9CiAgICAqIGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LgogICAgKiBOb3RlOiBUaGUgdXNlIG9mIElEIGFzIGEgdHlwZSBkZWZpbml0aW9uIGZvciBlbGVtZW50cyBnb2VzIGJleW9uZAogICAgKiBYTUwgMS4wLCBhbmQgc2hvdWxkIGJlIGF2b2lkZWQgaWYgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgaXMgZGVzaXJlZCIKICAgICovCiAgICBpZiAoKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSAmJgoJKChXWFNfSVNfU0lNUExFKHR5cGVEZWYpICYmCgkgIHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlRGVmLCBYTUxfU0NIRU1BU19JRCkpIHx8CgkgKFdYU19JU19DT01QTEVYKHR5cGVEZWYpICYmCgkgIFdYU19IQVNfU0lNUExFX0NPTlRFTlQodHlwZURlZikgJiYKCSAgeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLAoJICAgIFhNTF9TQ0hFTUFTX0lEKSkpKSB7CgoJcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzU7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF81LAoJICAgIFdYU19CQVNJQ19DQVNUIGVsZW1EZWNsLCBOVUxMLAoJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIChvciB0eXBlIGRlZmluaXRpb24ncyBjb250ZW50IHR5cGUpIGlzIG9yICIKCSAgICAiaXMgZGVyaXZlZCBmcm9tIElEOyB2YWx1ZSBjb25zdHJhaW50cyBhcmUgbm90IGFsbG93ZWQgaW4gIgoJICAgICJjb25qdW5jdGlvbiB3aXRoIHN1Y2ggYSB0eXBlIGRlZmluaXRpb24iLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpIHsKCWludCB2Y3JldDsKCXhtbE5vZGVQdHIgbm9kZSA9IE5VTEw7CgoJLyoKCSogU1BFQyAoMikgIklmIHRoZXJlIGlzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGUgY2Fub25pY2FsIGxleGljYWwKCSogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlCgkqIHt0eXBlIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpCgkqICinMy4zLjYpLiIKCSovCglpZiAodHlwZURlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihwY3R4dCwgZWxlbURlY2wtPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0VsZW1Qcm9wc0NvcnJlY3QsICIKCQkidHlwZSBpcyBtaXNzaW5nLi4uIHNraXBwaW5nIHZhbGlkYXRpb24gb2YgIgoJCSJ0aGUgdmFsdWUgY29uc3RyYWludCIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJaWYgKGVsZW1EZWNsLT5ub2RlICE9IE5VTEwpIHsKCSAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkKCQlub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoZWxlbURlY2wtPm5vZGUsCgkJICAgIEJBRF9DQVNUICJmaXhlZCIpOwoJICAgIGVsc2UKCQlub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoZWxlbURlY2wtPm5vZGUsCgkJICAgIEJBRF9DQVNUICJkZWZhdWx0Iik7Cgl9Cgl2Y3JldCA9IHhtbFNjaGVtYVBhcnNlQ2hlY2tDT1NWYWxpZERlZmF1bHQocGN0eHQsIG5vZGUsCgkgICAgdHlwZURlZiwgZWxlbURlY2wtPnZhbHVlLCAmKGVsZW1EZWNsLT5kZWZWYWwpKTsKCWlmICh2Y3JldCAhPSAwKSB7CgkgICAgaWYgKHZjcmV0IDwgMCkgewoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUVsZW1DaGVja1ZhbENvbnN0ciIsCgkJICAgICJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgYW4gIgoJCSAgICAiZWxlbWVudCBkZWNsYXJhdGlvbiIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICByZXR1cm4gKHZjcmV0KTsKCX0KICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1TdWJzdEdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBkZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBTdWJzdGl0dXRpb24gR3JvdXAgKGNvcy1lcXVpdi1jbGFzcykKICoKICogSW4gTGlieG1sMiB0aGUgc3Vic3QuIGdyb3VwcyB3aWxsIGJlIHByZWNvbXB1dGVkLCBpbiB0ZXJtcyBvZiB0aGF0CiAqIGEgbGlzdCB3aWxsIGJlIGJ1aWx0IGZvciBlYWNoIHN1YnN0LiBncm91cCBoZWFkLCBob2xkaW5nIGFsbCBkaXJlY3QKICogcmVmZXJlbnRzIHRvIHRoaXMgaGVhZC4KICogTk9URSB0aGF0IHRoaXMgZnVuY3Rpb24gbmVlZHM6CiAqICAgMS4gY2lyY3VsYXIgc3Vic3QuIGdyb3VwcyB0byBiZSBjaGVja2VkIGJlZm9yZWhhbmQKICogICAyLiB0aGUgZGVjbGFyYXRpb24ncyB0eXBlIHRvIGJlIGRlcml2ZWQgZnJvbSB0aGUgaGVhZCdzIHR5cGUKICoKICogU1RBVFVTOgogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tFbGVtU3Vic3RHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgaWYgKChXWFNfU1VCU1RfSEVBRChlbGVtRGVjbCkgPT0gTlVMTCkgfHwKCS8qIFNQRUMgKDEpICJJdHMge2Fic3RyYWN0fSBpcyBmYWxzZS4iICovCgkoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkpCglyZXR1cm47CiAgICB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQ7Cgl4bWxTY2hlbWFUeXBlUHRyIGhlYWRUeXBlLCB0eXBlOwoJaW50IHNldCwgbWV0aFNldDsKCS8qCgkqIFNQRUMgKDIpICJJdCBpcyB2YWxpZGx5IHN1YnN0aXR1dGFibGUgZm9yIEhFQUQgc3ViamVjdCB0byBIRUFEJ3MKCSoge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYXMgdGhlIGJsb2NraW5nIGNvbnN0cmFpbnQsIGFzIGRlZmluZWQgaW4KCSogU3Vic3RpdHV0aW9uIEdyb3VwIE9LIChUcmFuc2l0aXZlKSAopzMuMy42KS4iCgkqLwoJZm9yIChoZWFkID0gV1hTX1NVQlNUX0hFQUQoZWxlbURlY2wpOyBoZWFkICE9IE5VTEw7CgkgICAgaGVhZCA9IFdYU19TVUJTVF9IRUFEKGhlYWQpKSB7CgkgICAgc2V0ID0gMDsKCSAgICBtZXRoU2V0ID0gMDsKCSAgICAvKgoJICAgICogVGhlIGJsb2NraW5nIGNvbnN0cmFpbnRzLgoJICAgICovCgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT04pCgkJY29udGludWU7CgkgICAgaGVhZFR5cGUgPSBoZWFkLT5zdWJ0eXBlczsKCSAgICB0eXBlID0gZWxlbURlY2wtPnN1YnR5cGVzOwoJICAgIGlmIChoZWFkVHlwZSA9PSB0eXBlKQoJCWdvdG8gYWRkX21lbWJlcjsKCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OKQoJCXNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OOwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OKQoJCXNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTjsKCSAgICAvKgoJICAgICogU1BFQzogU3Vic3RpdHV0aW9uIEdyb3VwIE9LIChUcmFuc2l0aXZlKSAoMi4zKQoJICAgICogIlRoZSBzZXQgb2YgYWxsIHtkZXJpdmF0aW9uIG1ldGhvZH1zIGludm9sdmVkIGluIHRoZQoJICAgICogZGVyaXZhdGlvbiBvZiBEJ3Mge3R5cGUgZGVmaW5pdGlvbn0gZnJvbSBDJ3Mge3R5cGUgZGVmaW5pdGlvbn0KCSAgICAqIGRvZXMgbm90IGludGVyc2VjdCB3aXRoIHRoZSB1bmlvbiBvZiB0aGUgYmxvY2tpbmcgY29uc3RyYWludCwKCSAgICAqIEMncyB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSAoaWYgQyBpcyBjb21wbGV4LCBvdGhlcndpc2UgdGhlCgkgICAgKiBlbXB0eSBzZXQpIGFuZCB0aGUge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gKHJlc3BlY3RpdmVseSB0aGUKCSAgICAqIGVtcHR5IHNldCkgb2YgYW55IGludGVybWVkaWF0ZSB7dHlwZSBkZWZpbml0aW9ufXMgaW4gdGhlCgkgICAgKiBkZXJpdmF0aW9uIG9mIEQncyB7dHlwZSBkZWZpbml0aW9ufSBmcm9tIEMncyB7dHlwZSBkZWZpbml0aW9ufS4iCgkgICAgKi8KCSAgICAvKgoJICAgICogT1BUSU1JWkUgVE9ETzogT3B0aW1pemUgdGhpcyBhIGJpdCwgc2luY2UsIGlmIHRyYXZlcnNpbmcgdGhlCgkgICAgKiBzdWJzdC5oZWFkIGF4aXMsIHRoZSBtZXRoU2V0IGRvZXMgbm90IG5lZWQgdG8gYmUgY29tcHV0ZWQgZm9yCgkgICAgKiB0aGUgZnVsbCBkZXB0aCBvdmVyIGFuZCBvdmVyLgoJICAgICovCgkgICAgLyoKCSAgICAqIFRoZSBzZXQgb2YgYWxsIHtkZXJpdmF0aW9uIG1ldGhvZH1zIGludm9sdmVkIGluIHRoZSBkZXJpdmF0aW9uCgkgICAgKi8KCSAgICB3aGlsZSAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUgIT0gaGVhZFR5cGUpKSB7CgkJaWYgKChXWFNfSVNfRVhURU5TSU9OKHR5cGUpKSAmJgoJCSAgICAoKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSA9PSAwKSkKCQkgICAgbWV0aFNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTjsKCgkJaWYgKFdYU19JU19SRVNUUklDVElPTih0eXBlKSAmJgoJCSAgICAoKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSA9PSAwKSkKCQkgICAgbWV0aFNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OOwoKCQl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgfQoJICAgIC8qCgkgICAgKiBUaGUge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gb2YgYWxsIGludGVybWVkaWF0ZSB0eXBlcyArCgkgICAgKiB0aGUgaGVhZCdzIHR5cGUuCgkgICAgKi8KCSAgICB0eXBlID0gZWxlbURlY2wtPnN1YnR5cGVzLT5iYXNlVHlwZTsKCSAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CgkJaWYgKFdYU19JU19DT01QTEVYKHR5cGUpKSB7CgkJICAgIGlmICgodHlwZS0+ZmxhZ3MgJgoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT04pICYmCgkJCSgoc2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT04pID09IDApKQoJCSAgICBzZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT047CgkJICAgIGlmICgodHlwZS0+ZmxhZ3MgJgoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikgJiYKCQkJKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSA9PSAwKSkKCQkgICAgc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT047CgkJfSBlbHNlCgkJICAgIGJyZWFrOwoJCWlmICh0eXBlID09IGhlYWRUeXBlKQoJCSAgICBicmVhazsKCQl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgfQoJICAgIGlmICgoc2V0ICE9IDApICYmCgkJKCgoc2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT04pICYmCgkJKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikpIHx8CgkJKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSAmJgoJCShtZXRoU2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikpKSkgewoJCWNvbnRpbnVlOwoJICAgIH0KYWRkX21lbWJlcjoKCSAgICB4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uTWVtYmVyKGN0eHQsIGhlYWQsIGVsZW1EZWNsKTsKCSAgICBpZiAoKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9TVUJTVF9HUk9VUF9IRUFEKSA9PSAwKQoJCWhlYWQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fU1VCU1RfR1JPVVBfSEVBRDsKCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQKICogQGl0ZW06ICBhbiBzY2hlbWEgZWxlbWVudCBkZWNsYXJhdGlvbi9wYXJ0aWNsZQogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIGNvbnN0cmFpbnRzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9DSEVDS0VEKQoJcmV0dXJuOwogICAgZWxlbURlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfQ0hFQ0tFRDsKICAgIGlmICh4bWxTY2hlbWFDaGVja0VsZW1Qcm9wc0NvcnJlY3QoY3R4dCwgZWxlbURlY2wpID09IDApCgl4bWxTY2hlbWFDaGVja0VsZW1TdWJzdEdyb3VwKGN0eHQsIGVsZW1EZWNsKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVNb2RlbEdyb3VwUGFydGljbGVSZWZlcmVuY2VzOgogKiBAcGFydGljbGU6ICBhIHBhcnRpY2xlIGNvbXBvbmVudAogKiBAY3R4dDogIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgcmVmZXJlbmNlcyBvZiBhIG1vZGVsIGdyb3VwJ3Mge3BhcnRpY2xlc30gdG8KICogbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMgYW5kIHRvIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZU1vZGVsR3JvdXBQYXJ0aWNsZVJlZmVyZW5jZXMoCiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIG1nKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IFdYU19NT0RFTEdST1VQX1BBUlRJQ0xFKG1nKTsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciByZWZJdGVtOwoKICAgIC8qCiAgICAqIFVSR0VOVCBUT0RPOiBUZXN0IHRoaXMuCiAgICAqLwogICAgd2hpbGUgKHBhcnRpY2xlICE9IE5VTEwpIHsKCWlmICgoV1hTX1BBUlRJQ0xFX1RFUk0ocGFydGljbGUpID09IE5VTEwpIHx8CgkgICAgKChXWFNfUEFSVElDTEVfVEVSTShwYXJ0aWNsZSkpLT50eXBlICE9CgkJWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRikpCgl7CgkgICAgZ290byBuZXh0X3BhcnRpY2xlOwoJfSAKCXJlZiA9IFdYU19RTkFNRV9DQVNUIFdYU19QQVJUSUNMRV9URVJNKHBhcnRpY2xlKTsKCS8qCgkqIFJlc29sdmUgdGhlIHJlZmVyZW5jZS4KCSogTlVMTCB0aGUge3Rlcm19IGJ5IGRlZmF1bHQuCgkqLwoJcGFydGljbGUtPmNoaWxkcmVuID0gTlVMTDsKCglyZWZJdGVtID0geG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoY3R4dC0+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+YnVja2V0KSA9PSAtMSkKCQkgICAgcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgcmVsID0gcmVsLT5uZXh0OwoJfSB3aGlsZSAocmVsICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpeHVwQ29tcG9uZW50cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgeG1sU2NoZW1hQnVja2V0UHRyIHJvb3RCdWNrZXQpCnsKICAgIHhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRQdHIgY29uID0gcGN0eHQtPmNvbnN0cnVjdG9yOwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbSwgKml0ZW1zOwogICAgaW50IG5iSXRlbXMsIGksIHJldCA9IDA7CiAgICB4bWxTY2hlbWFCdWNrZXRQdHIgb2xkYnVja2V0ID0gY29uLT5idWNrZXQ7CgojZGVmaW5lIEZJWEhGQUlMVVJFIGlmIChwY3R4dC0+ZXJyID09IFhNTF9TQ0hFTUFQX0lOVEVSTkFMKSBnb3RvIGV4aXRfZmFpbHVyZTsKCiAgICBpZiAoKGNvbi0+cGVuZGluZyA9PSBOVUxMKSB8fAoJKGNvbi0+cGVuZGluZy0+bmJJdGVtcyA9PSAwKSkKCXJldHVybigwKTsgICAgCgogICAgLyoKICAgICogU2luY2UgeG1sU2NoZW1hRml4dXBDb21wbGV4VHlwZSgpIHdpbGwgY3JlYXRlIG5ldyBwYXJ0aWNsZXMKICAgICogKGxvY2FsIGNvbXBvbmVudHMpLCBhbmQgdGhvc2UgcGFydGljbGUgY29tcG9uZW50cyBuZWVkIGEgYnVja2V0CiAgICAqIG9uIHRoZSBjb25zdHJ1Y3Rvciwgd2UnbGwgYXNzdXJlIGhlcmUgdGhhdCB0aGUgY29uc3RydWN0b3IgaGFzCiAgICAqIGEgYnVja2V0LgogICAgKiBUT0RPOiBUaGluayBhYm91dCBzdG9yaW5nIGxvY2FscyBfb25seV8gb24gdGhlIG1haW4gYnVja2V0LiAgICAKICAgICovICAgIAogICAgaWYgKGNvbi0+YnVja2V0ID09IE5VTEwpCgljb24tPmJ1Y2tldCA9IHJvb3RCdWNrZXQ7ICAgIAoKICAgIC8qIFRPRE86CiAgICAqIFNQRUMgKHNyYy1yZWRlZmluZSk6CiAgICAqICg2LjIpICJJZiBpdCBoYXMgbm8gc3VjaCBzZWxmLXJlZmVyZW5jZSwgdGhlbiBhbGwgb2YgdGhlCiAgICAqIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgogICAgCiAgICAqICg2LjIuMikgVGhlIHttb2RlbCBncm91cH0gb2YgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gd2hpY2gKICAgICogY29ycmVzcG9uZHMgdG8gaXQgcGVyIFhNTCBSZXByZXNlbnRhdGlvbiBvZiBNb2RlbCBHcm91cAogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy43LjIpIG11c3QgYmUgYSC3dmFsaWQKICAgICogcmVzdHJpY3Rpb263IG9mIHRoZSB7bW9kZWwgZ3JvdXB9IG9mIHRoYXQgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgogICAgKiBpbiBJLCBhcyBkZWZpbmVkIGluIFBhcnRpY2xlIFZhbGlkIChSZXN0cmljdGlvbikgKKczLjkuNikuIgogICAgKi8KICAgIHhtbFNjaGVtYUNoZWNrU1JDUmVkZWZpbmVGaXJzdChwY3R4dCk7CgogICAgLyoKICAgICogQWRkIGdsb2JhbCBjb21wb25lbnRzIHRvIHRoZSBzY2hlbWF0YSdzIGhhc2ggdGFibGVzLgogICAgKi8gICAgCiAgICB4bWxTY2hlbWFBZGRDb21wb25lbnRzKHBjdHh0LCByb290QnVja2V0KTsKCiAgICBwY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwogICAgaXRlbXMgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIgKikgY29uLT5wZW5kaW5nLT5pdGVtczsKICAgIG5iSXRlbXMgPSBjb24tPnBlbmRpbmctPm5iSXRlbXM7CiAgICAvKgogICAgKiBOb3cgdGhhdCB3ZSBoYXZlIHBhcnNlZCAqYWxsKiB0aGUgc2NoZW1hIGRvY3VtZW50KHMpIGFuZCBjb252ZXJ0ZWQKICAgICogdGhlbSB0byBzY2hlbWEgY29tcG9uZW50cywgd2UgY2FuIHJlc29sdmUgcmVmZXJlbmNlcywgYXBwbHkgY29tcG9uZW50CiAgICAqIGNvbnN0cmFpbnRzLCBjcmVhdGUgdGhlIEZTQSBmcm9tIHRoZSBjb250ZW50IG1vZGVsLCBldGMuCiAgICAqLyAgICAKICAgIC8qCiAgICAqIFJlc29sdmUgcmVmZXJlbmNlcyBvZi4uCiAgICAqCiAgICAqIDEuIGVsZW1lbnQgZGVjbGFyYXRpb25zOgogICAgKiAgIC0gdGhlIHR5cGUgZGVmaW5pdGlvbgogICAgKiAgIC0gdGhlIHN1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbgogICAgKiAyLiBzaW1wbGUvY29tcGxleCB0eXBlczoKICAgICogICAtIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbgogICAgKiAgIC0gdGhlIG1lbWJlclR5cGVzIG9mIHVuaW9uIHR5cGVzCiAgICAqICAgLSB0aGUgaXRlbVR5cGUgb2YgbGlzdCB0eXBlcwogICAgKiAzLiBhdHRyaWJ1dGVzIGRlY2xhcmF0aW9ucyBhbmQgYXR0cmlidXRlIHVzZXM6CiAgICAqICAgLSB0aGUgdHlwZSBkZWZpbml0aW9uCiAgICAqICAgLSBpZiBhbiBhdHRyaWJ1dGUgdXNlLCB0aGVuIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24KICAgICogNC4gYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXM6CiAgICAqICAgLSB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24KICAgICogNS4gcGFydGljbGVzOgogICAgKiAgIC0gdGhlIHRlcm0gb2YgdGhlIHBhcnRpY2xlIChlLmcuIGEgbW9kZWwgZ3JvdXApCiAgICAqIDYuIElEQyBrZXktcmVmZXJlbmNlczoKICAgICogICAtIHRoZSByZWZlcmVuY2VkIElEQyAna2V5JyBvciAndW5pcXVlJyBkZWZpbml0aW9uCiAgICAqIDcuIEF0dHJpYnV0ZSBwcm9oaWJpdGlvbnMgd2hpY2ggaGFkIGEgInJlZiIgYXR0cmlidXRlLgogICAgKi8gICAgICAgIAogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFSZXNvbHZlRWxlbWVudFJlZmVyZW5jZXMoCgkJICAgICh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJeG1sU2NoZW1hUmVzb2x2ZVR5cGVSZWZlcmVuY2VzKAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQl4bWxTY2hlbWFSZXNvbHZlQXR0clR5cGVSZWZlcmVuY2VzKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFX1VTRToKCQl4bWxTY2hlbWFSZXNvbHZlQXR0clVzZVJlZmVyZW5jZXMoCgkJICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIpIGl0ZW0sIHBjdHh0KTsKCQlGSVhIRkFJTFVSRTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY6CgkJaWYgKChXWFNfUU5BTUVfQ0FTVCBpdGVtKS0+aXRlbVR5cGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkKCQl7CgkJICAgIHhtbFNjaGVtYVJlc29sdmVBdHRyR3JvdXBSZWZlcmVuY2VzKAoJCQlXWFNfUU5BTUVfQ0FTVCBpdGVtLCBwY3R4dCk7CgkJfQoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkJeG1sU2NoZW1hUmVzb2x2ZU1vZGVsR3JvdXBQYXJ0aWNsZVJlZmVyZW5jZXMocGN0eHQsCgkJICAgIFdYU19NT0RFTF9HUk9VUF9DQVNUIGl0ZW0pOwoJCUZJWEhGQUlMVVJFOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJCXhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWZlcmVuY2VzKAoJCSAgICAoeG1sU2NoZW1hSURDUHRyKSBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0VYVFJBX0FUVFJfVVNFX1BST0hJQjoKCQkvKgoJCSogSGFuZGxlIGF0dHJpYnVlIHByb2hpYml0aW9uIHdoaWNoIGhhZCBhCgkJKiAicmVmIiBhdHRyaWJ1dGUuCgkJKi8KCQl4bWxTY2hlbWFSZXNvbHZlQXR0clVzZVByb2hpYlJlZmVyZW5jZXMoCgkJICAgIFdYU19BVFRSX1BST0hJQl9DQVNUIGl0ZW0sIHBjdHh0KTsKCQlGSVhIRkFJTFVSRTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgCiAgICAvKgogICAgKiBOb3cgdGhhdCBhbGwgcmVmZXJlbmNlcyBhcmUgcmVzb2x2ZWQgd2UKICAgICogY2FuIGNoZWNrIGZvciBjaXJjdWxhcml0eSBvZi4uLgogICAgKiAxLiB0aGUgYmFzZSBheGlzIG9mIHR5cGUgZGVmaW5pdGlvbnMgCiAgICAqIDIuIG5lc3RlZCBtb2RlbCBncm91cCBkZWZpbml0aW9ucwogICAgKiAzLiBuZXN0ZWQgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb25zCiAgICAqIFRPRE86IGNoZWNrIGZvciBjaXJjdWFsIHN1YnN0aXR1dGlvbiBncm91cHMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJLyoKCSogTGV0J3MgYmV0dGVyIHN0b3Agb24gdGhlIGZpcnN0IGVycm9yIGhlcmUuCgkqLwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXIoCgkJICAgICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBwY3R4dCk7CgkJRklYSEZBSUxVUkU7CgkJaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJCSAgICBnb3RvIGV4aXRfZXJyb3I7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCQkgICAgZ290byBleGl0X2Vycm9yOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUNoZWNrQXR0ckdyb3VwQ2lyY3VsYXIoCgkJICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSwgcGN0eHQpOwoJCUZJWEhGQUlMVVJFOwoJCWlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCQkgICAgZ290byBleGl0X2Vycm9yOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogTW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2VzOgogICAgKiBTdWNoIGEgcmVmZXJlbmNlIGlzIHJlZmxlY3RlZCBieSBhIHBhcnRpY2xlIGF0IHRoZSBjb21wb25lbnQKICAgICogbGV2ZWwuIFVudGlsIG5vdyB0aGUgJ3Rlcm0nIG9mIHN1Y2ggcGFydGljbGVzIHBvaW50ZWQKICAgICogdG8gdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb247IHRoaXMgd2FzIGRvbmUsIGluIG9yZGVyIHRvCiAgICAqIGVhc2UgY2lyY3VsYXJpdHkgY2hlY2tzLiBOb3cgd2UgbmVlZCB0byBzZXQgdGhlICd0ZXJtJyBvZgogICAgKiBzdWNoIHBhcnRpY2xlcyB0byB0aGUgbW9kZWwgZ3JvdXAgb2YgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgkKCQl4bWxTY2hlbWFNb2RlbEdyb3VwVG9Nb2RlbEdyb3VwRGVmRml4dXAocGN0eHQsCgkJICAgIFdYU19NT0RFTF9HUk9VUF9DQVNUIGl0ZW0pOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CiAgICAvKgogICAgKiBFeHBhbmQgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMgb2YgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb25zLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQlpZiAoKCEgV1hTX0FUVFJfR1JPVVBfRVhQQU5ERUQoaXRlbSkpICYmCgkJICAgIFdYU19BVFRSX0dST1VQX0hBU19SRUZTKGl0ZW0pKQoJCXsKCQkgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBFeHBhbmRSZWZzKHBjdHh0LAoJCQlXWFNfQVRUUl9HUk9VUF9DQVNUIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIC8qIAogICAgKiBGaXJzdCBjb21wdXRlIHRoZSB2YXJpZXR5IG9mIHNpbXBsZSB0eXBlcy4gVGhpcyBpcyBuZWVkZWQgYXMKICAgICogYSBzZXBlcmF0ZSBzdGVwLCBzaW5jZSBvdGhlcndpc2Ugd2Ugd29uJ3QgYmUgYWJsZSB0byBkZXRlY3QKICAgICogY2lyY3VsYXIgdW5pb24gdHlwZXMgaW4gYWxsIGNhc2VzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRF8xKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKSkgewoJCSAgICB4bWxTY2hlbWFGaXh1cFNpbXBsZVR5cGVTdGFnZU9uZShwY3R4dCwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIC8qCiAgICAqIERldGVjdCBjaXJjdWxhciB1bmlvbiB0eXBlcy4gTm90ZSB0aGF0IHRoaXMgbmVlZHMgdGhlIHZhcmlldHkgdG8KICAgICogYmUgYWxyZWFkeSBjb21wdXRlZC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCWlmICgoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pLT5tZW1iZXJUeXBlcyAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUNoZWNrVW5pb25UeXBlRGVmQ2lyY3VsYXIocGN0eHQsCQoJCQkoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSk7CgkJICAgIEZJWEhGQUlMVVJFOwoJCX0KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgCiAgICAvKgogICAgKiBEbyB0aGUgY29tcGxldGUgdHlwZSBmaXh1cCBmb3Igc2ltcGxlIHR5cGVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJaWYgKFdYU19JU19UWVBFX05PVF9GSVhFRChXWFNfVFlQRV9DQVNUIGl0ZW0pKSB7CgkJICAgIHhtbFNjaGVtYUZpeHVwU2ltcGxlVHlwZVN0YWdlVHdvKHBjdHh0LCBXWFNfVFlQRV9DQVNUIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKICAgIC8qCiAgICAqIEF0IHRoaXMgcG9pbnQgd2UgbmVlZCBhbGwgc2ltcGxlIHR5cGVzIHRvIGJlIGJ1aWxkZWQgYW5kIGNoZWNrZWQuCiAgICAqLwogICAgLyoKICAgICogQXBwbHkgY29udHJhaW50cyBmb3IgYXR0cmlidXRlIGRlY2xhcmF0aW9ucy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CQkKCQl4bWxTY2hlbWFDaGVja0F0dHJQcm9wc0NvcnJlY3QocGN0eHQsIFdYU19BVFRSX0NBU1QgaXRlbSk7CgkJRklYSEZBSUxVUkU7CgkJYnJlYWs7CSAgICAKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogQXBwbHkgY29uc3RyYWludHMgZm9yIGF0dHJpYnV0ZSB1c2VzLgogICAgKi8gICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVfVVNFOgoJCWlmICgoKHhtbFNjaGVtYUF0dHJpYnV0ZVVzZVB0cilpdGVtKS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFDaGVja0F0dHJVc2VQcm9wc0NvcnJlY3QocGN0eHQsCgkJCVdYU19BVFRSX1VTRV9DQVNUIGl0ZW0pOwoJCSAgICBGSVhIRkFJTFVSRTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKgogICAgKiBBcHBseSBjb25zdHJhaW50cyBmb3IgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb25zLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgaWYgKCggKFdYU19BVFRSX0dST1VQX0NBU1QgaXRlbSktPmF0dHJVc2VzICE9IE5VTEwpICYmCgkJKCAoV1hTX0xJU1RfQ0FTVCAoV1hTX0FUVFJfR1JPVVBfQ0FTVCBpdGVtKS0+YXR0clVzZXMpLT5uYkl0ZW1zID4gMSkpCgkgICAgewoJCXhtbFNjaGVtYUNoZWNrQUdQcm9wc0NvcnJlY3QocGN0eHQsIFdYU19BVFRSX0dST1VQX0NBU1QgaXRlbSk7CgkJRklYSEZBSUxVUkU7CgkgICAgfQoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKgogICAgKiBBcHBseSBjb25zdHJhaW50cyBmb3IgcmVkZWZpbml0aW9ucy4KICAgICovCiAgICBpZiAoV1hTX0NPTlNUUlVDVE9SKHBjdHh0KS0+cmVkZWZzICE9IE5VTEwpCgl4bWxTY2hlbWFDaGVja1NSQ1JlZGVmaW5lU2Vjb25kKHBjdHh0KTsKICAgIGlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdF9lcnJvcjsKCiAgICAvKgogICAgKiBGaXh1cCBjb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBjb24tPnBlbmRpbmctPml0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQlpZiAoV1hTX0lTX1RZUEVfTk9UX0ZJWEVEKFdYU19UWVBFX0NBU1QgaXRlbSkpIHsKCQkgICAgeG1sU2NoZW1hRml4dXBDb21wbGV4VHlwZShwY3R4dCwgV1hTX1RZUEVfQ0FTVCBpdGVtKTsKCQkgICAgRklYSEZBSUxVUkU7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXRfZXJyb3I7CgogICAgLyoKICAgICogVGhlIGxpc3QgY291bGQgaGF2ZSBjaGFuZ2VkLCBzaW5jZSB4bWxTY2hlbWFGaXh1cENvbXBsZXhUeXBlKCkKICAgICogd2lsbCBjcmVhdGUgcGFydGljbGVzIGFuZCBtb2RlbCBncm91cHMgaW4gc29tZSBjYXNlcy4KICAgICovCiAgICBpdGVtcyA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0ciAqKSBjb24tPnBlbmRpbmctPml0ZW1zOwogICAgbmJJdGVtcyA9IGNvbi0+cGVuZGluZy0+bmJJdGVtczsKCiAgICAvKgogICAgKiBBdCB0aGlzIHBvaW50IGFsbCBjb21wbGV4IHR5cGVzIG5lZWQgdG8gYmUgYnVpbGRlZCBhbmQgY2hlY2tlZC4KICAgICovCiAgICAvKgogICAgKiBBcHBseSBzb21lIGNvbnN0cmFpbnRzIGZvciBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCQoJCWlmICgoKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtKS0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9DSEVDS0VEKSA9PSAwKSB7CgkJICAgIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoCgkJCSh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLCBwY3R4dCk7CgkJICAgIEZJWEhGQUlMVVJFOwoJCX0KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogRmluYWxseSB3ZSBjYW4gYnVpbGQgdGhlIGF1dG9tYXRvbiBmcm9tIHRoZSBjb250ZW50IG1vZGVsIG9mCiAgICAqIGNvbXBsZXggdHlwZXMuCiAgICAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIHBjdHh0KTsKCQkvKiBGSVhIRkFJTFVSRTsgKi8KCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0X2Vycm9yOwogICAgLyoKICAgICogVVJHRU5UIFRPRE86IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQKICAgICovICAgICAgICAKICAgIGdvdG8gZXhpdDsgICAgCgpleGl0X2Vycm9yOiAgICAKICAgIHJldCA9IHBjdHh0LT5lcnI7CiAgICBnb3RvIGV4aXQ7CgpleGl0X2ZhaWx1cmU6CiAgICByZXQgPSAtMTsKCmV4aXQ6CiAgICAvKgogICAgKiBSZXNldCB0aGUgY29uc3RydWN0b3IuIFRoaXMgaXMgbmVlZGVkIGZvciBYU0kgYWNxdWlzaXRpb24sIHNpbmNlCiAgICAqIHRob3NlIGl0ZW1zIHdpbGwgYmUgcHJvY2Vzc2VkIG92ZXIgYW5kIG92ZXIgYWdhaW4gZm9yIGV2ZXJ5IFhTSQogICAgKiBpZiBub3QgY2xlYXJlZCBoZXJlLgogICAgKi8KICAgIGNvbi0+YnVja2V0ID0gb2xkYnVja2V0OwogICAgY29uLT5wZW5kaW5nLT5uYkl0ZW1zID0gMDsgICAgCiAgICBpZiAoY29uLT5zdWJzdEdyb3VwcyAhPSBOVUxMKSB7Cgl4bWxIYXNoRnJlZShjb24tPnN1YnN0R3JvdXBzLAoJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYVN1YnN0R3JvdXBGcmVlKTsKCWNvbi0+c3Vic3RHcm91cHMgPSBOVUxMOwogICAgfSAgICAKICAgIGlmIChjb24tPnJlZGVmcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFSZWRlZkxpc3RGcmVlKGNvbi0+cmVkZWZzKTsKCWNvbi0+cmVkZWZzID0gTlVMTDsKICAgIH0KICAgIHJldHVybihyZXQpOwp9Ci8qKgogKiB4bWxTY2hlbWFQYXJzZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogcGFyc2UgYSBzY2hlbWEgZGVmaW5pdGlvbiByZXNvdXJjZSBhbmQgYnVpbGQgYW4gaW50ZXJuYWwKICogWE1MIFNoZW1hIHN0cnV0dXJlIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIGluc3RhbmNlcy4KICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciBtYWluU2NoZW1hID0gTlVMTDsKICAgIHhtbFNjaGVtYUJ1Y2tldFB0ciBidWNrZXQgPSBOVUxMOwogICAgaW50IHJlczsKCiAgICAvKgogICAgKiBUaGlzIG9uZSBpcyB1c2VkIGlmIHRoZSBzY2hlbWEgdG8gYmUgcGFyc2VkIHdhcyBzcGVjaWZpZWQgdmlhCiAgICAqIHRoZSBBUEk7IGkuZS4gbm90IGF1dG9tYXRpY2FsbHkgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSBkb2N1bWVudC4KICAgICovCgogICAgeG1sU2NoZW1hSW5pdFR5cGVzKCk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIC8qIFRPRE86IEluaXQgdGhlIGNvbnRleHQuIElzIHRoaXMgYWxsIHdlIG5lZWQ/Ki8KICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGN0eHQtPmVyciA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKCiAgICAvKiBDcmVhdGUgdGhlICptYWluKiBzY2hlbWEuICovCiAgICBtYWluU2NoZW1hID0geG1sU2NoZW1hTmV3U2NoZW1hKGN0eHQpOwogICAgaWYgKG1haW5TY2hlbWEgPT0gTlVMTCkKCWdvdG8gZXhpdF9mYWlsdXJlOwogICAgLyoKICAgICogQ3JlYXRlIHRoZSBzY2hlbWEgY29uc3RydWN0b3IuCiAgICAqLwogICAgaWYgKGN0eHQtPmNvbnN0cnVjdG9yID09IE5VTEwpIHsKCWN0eHQtPmNvbnN0cnVjdG9yID0geG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dENyZWF0ZShjdHh0LT5kaWN0KTsKCWlmIChjdHh0LT5jb25zdHJ1Y3RvciA9PSBOVUxMKQoJICAgIHJldHVybihOVUxMKTsKCS8qIFRha2Ugb3duZXJzaGlwIG9mIHRoZSBjb25zdHJ1Y3RvciB0byBiZSBhYmxlIHRvIGZyZWUgaXQuICovCgljdHh0LT5vd25zQ29uc3RydWN0b3IgPSAxOwogICAgfQogICAgY3R4dC0+Y29uc3RydWN0b3ItPm1haW5TY2hlbWEgPSBtYWluU2NoZW1hOwogICAgLyoKICAgICogTG9jYXRlIGFuZCBhZGQgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXMgPSB4bWxTY2hlbWFBZGRTY2hlbWFEb2MoY3R4dCwgWE1MX1NDSEVNQV9TQ0hFTUFfTUFJTiwKCWN0eHQtPlVSTCwgY3R4dC0+ZG9jLCBjdHh0LT5idWZmZXIsIGN0eHQtPnNpemUsIE5VTEwsCglOVUxMLCBOVUxMLCAmYnVja2V0KTsKICAgIGlmIChyZXMgPT0gLTEpCglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIGlmIChyZXMgIT0gMCkKCWdvdG8gZXhpdDsgICAKCiAgICBpZiAoYnVja2V0ID09IE5VTEwpIHsKCS8qIFRPRE86IEVycm9yIGNvZGUsIGFjdHVhbGx5IHdlIGZhaWxlZCB0byAqbG9jYXRlKiB0aGUgc2NoZW1hLiAqLwoJaWYgKGN0eHQtPlVSTCkgCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgY3R4dCwgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCgkJTlVMTCwgTlVMTCwKCQkiRmFpbGVkIHRvIGxvY2F0ZSB0aGUgbWFpbiBzY2hlbWEgcmVzb3VyY2UgYXQgJyVzJyIsCgkJY3R4dC0+VVJMLCBOVUxMKTsKCWVsc2UKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCBjdHh0LCBYTUxfU0NIRU1BUF9GQUlMRURfTE9BRCwKCQlOVUxMLCBOVUxMLAoJCSJGYWlsZWQgdG8gbG9jYXRlIHRoZSBtYWluIHNjaGVtYSByZXNvdXJjZSIsCgkJICAgIE5VTEwsIE5VTEwpOwoJZ290byBleGl0OwogICAgfSAgICAgICAgCiAgICAvKiBUaGVuIGRvIHRoZSBwYXJzaW5nIGZvciBnb29kLiAqLwogICAgaWYgKHhtbFNjaGVtYVBhcnNlTmV3RG9jV2l0aENvbnRleHQoY3R4dCwgbWFpblNjaGVtYSwgYnVja2V0KSA9PSAtMSkKCWdvdG8gZXhpdF9mYWlsdXJlOwogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApCglnb3RvIGV4aXQ7CiAgICAKICAgIG1haW5TY2hlbWEtPmRvYyA9IGJ1Y2tldC0+ZG9jOwogICAgbWFpblNjaGVtYS0+cHJlc2VydmUgPSBjdHh0LT5wcmVzZXJ2ZTsKICAgIAogICAgY3R4dC0+c2NoZW1hID0gbWFpblNjaGVtYTsKCiAgICBpZiAoeG1sU2NoZW1hRml4dXBDb21wb25lbnRzKGN0eHQsIFdYU19DT05TVFJVQ1RPUihjdHh0KS0+bWFpbkJ1Y2tldCkgPT0gLTEpCglnb3RvIGV4aXRfZmFpbHVyZTsKCiAgICAvKgogICAgKiBUT0RPOiBUaGlzIGlzIG5vdCBuaWNlLCBzaW5jZSB3ZSBjYW5ub3QgZGlzdGluZ3Vpc2ggZnJvbSB0aGUKICAgICogcmVzdWx0IGlmIHRoZXJlIHdhcyBhbiBpbnRlcm5hbCBlcnJvciBvciBub3QuCiAgICAqLwpleGl0OiAgICAgICAKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CQoJaWYgKG1haW5TY2hlbWEpIHsKCSAgICB4bWxTY2hlbWFGcmVlKG1haW5TY2hlbWEpOwoJICAgIG1haW5TY2hlbWEgPSBOVUxMOwoJfQoJaWYgKGN0eHQtPmNvbnN0cnVjdG9yKSB7CgkgICAgeG1sU2NoZW1hQ29uc3RydWN0aW9uQ3R4dEZyZWUoY3R4dC0+Y29uc3RydWN0b3IpOwoJICAgIGN0eHQtPmNvbnN0cnVjdG9yID0gTlVMTDsKCSAgICBjdHh0LT5vd25zQ29uc3RydWN0b3IgPSAwOwoJfQogICAgfQogICAgY3R4dC0+c2NoZW1hID0gTlVMTDsKICAgIHJldHVybihtYWluU2NoZW1hKTsKZXhpdF9mYWlsdXJlOgogICAgLyogCiAgICAqIFF1aXRlIHZlcmJvc2UsIGJ1dCBzaG91bGQgY2F0Y2ggaW50ZXJuYWwgZXJyb3JzLCB3aGljaCB3ZXJlCiAgICAqIG5vdCBjb21tdW5pdGF0ZWQuCiAgICAqLwogICAgaWYgKG1haW5TY2hlbWEpIHsKICAgICAgICB4bWxTY2hlbWFGcmVlKG1haW5TY2hlbWEpOwoJbWFpblNjaGVtYSA9IE5VTEw7CiAgICB9CiAgICBpZiAoY3R4dC0+Y29uc3RydWN0b3IpIHsKCXhtbFNjaGVtYUNvbnN0cnVjdGlvbkN0eHRGcmVlKGN0eHQtPmNvbnN0cnVjdG9yKTsKCWN0eHQtPmNvbnN0cnVjdG9yID0gTlVMTDsKCWN0eHQtPm93bnNDb25zdHJ1Y3RvciA9IDA7CiAgICB9CiAgICBQRVJST1JfSU5UMigieG1sU2NoZW1hUGFyc2UiLAoJIkFuIGludGVybmFsIGVycm9yIG9jY3VyZWQiKTsgICAgCiAgICBjdHh0LT5zY2hlbWEgPSBOVUxMOwogICAgcmV0dXJuKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGNhbGxiYWNrCiAqIEB3YXJuOiAgdGhlIHdhcm5pbmcgY2FsbGJhY2sKICogQGN0eDogIGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcwogKgogKiBTZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9ucyB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+ZXJyQ3R4dCA9IGN0eDsKICAgIGlmIChjdHh0LT52Y3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoY3R4dC0+dmN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFBhcnNlclN0cnVjdHVyZWRFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNlcnJvcjogIHRoZSBzdHJ1Y3R1cmVkIGVycm9yIGZ1bmN0aW9uCiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dAogKgogKiBTZXQgdGhlIHN0cnVjdHVyZWQgZXJyb3IgY2FsbGJhY2sKICovCnZvaWQKeG1sU2NoZW1hU2V0UGFyc2VyU3RydWN0dXJlZEVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvciwKCQkJCSAgIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybjsKICAgIGN0eHQtPnNlcnJvciA9IHNlcnJvcjsKICAgIGN0eHQtPmVyckN0eHQgPSBjdHg7CiAgICBpZiAoY3R4dC0+dmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNldFZhbGlkU3RydWN0dXJlZEVycm9ycyhjdHh0LT52Y3R4dCwgc2Vycm9yLCBjdHgpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgWE1sLVNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgY2FsbGJhY2sgcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBjYWxsYmFjayByZXN1bHQKICogQGN0eDogY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzIHJlc3VsdAogKgogKiBHZXQgdGhlIGNhbGxiYWNrIGluZm9ybWF0aW9uIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSBwYXJzZXIgY29udGV4dAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZmFpbHVyZSwgMCBvdGhlcndpc2UKICovCmludAp4bWxTY2hlbWFHZXRQYXJzZXJFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCSB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4oLTEpOwoJaWYgKGVyciAhPSBOVUxMKQoJCSplcnIgPSBjdHh0LT5lcnJvcjsKCWlmICh3YXJuICE9IE5VTEwpCgkJKndhcm4gPSBjdHh0LT53YXJuaW5nOwoJaWYgKGN0eCAhPSBOVUxMKQoJCSpjdHggPSBjdHh0LT5lcnJDdHh0OwoJcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmc6CiAqIEB0eXBlOiAgdGhlIGZhY2V0IHR5cGUKICoKICogQ29udmVydCB0aGUgeG1sU2NoZW1hVHlwZVR5cGUgdG8gYSBjaGFyIHN0cmluZy4KICoKICogUmV0dXJucyB0aGUgY2hhciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZhY2V0IHR5cGUgaWYgdGhlCiAqICAgICB0eXBlIGlzIGEgZmFjZXQgYW5kIGFuICJJbnRlcm5hbCBFcnJvciIgc3RyaW5nIG90aGVyd2lzZS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSkKewogICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgInBhdHRlcm4iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtYXhFeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtYXhJbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtaW5FeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtaW5JbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAid2hpdGVTcGFjZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAiZW51bWVyYXRpb24iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJsZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtYXhMZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJtaW5MZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgInRvdGFsRGlnaXRzIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJmcmFjdGlvbkRpZ2l0cyIpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChCQURfQ0FTVCAiSW50ZXJuYWwgRXJyb3IiKTsKfQoKc3RhdGljIHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUKeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICAvKgogICAgKiBUaGUgbm9ybWFsaXphdGlvbiB0eXBlIGNhbiBiZSBjaGFuZ2VkIG9ubHkgZm9yIHR5cGVzIHdoaWNoIGFyZSBkZXJpdmVkCiAgICAqIGZyb20geHNkOnN0cmluZy4KICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCS8qCgkqIE5vdGUgdGhhdCB3ZSBhc3N1bWUgYSB3aGl0ZXNwYWNlIG9mIHByZXNlcnZlIGZvciBhbnlTaW1wbGVUeXBlLgoJKi8KCWlmICgodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSB8fAoJICAgICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkKCSAgICByZXR1cm4oWE1MX1NDSEVNQV9XSElURVNQQUNFX1BSRVNFUlZFKTsKCWVsc2UgaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PUk1TVFJJTkcpCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFKTsKCWVsc2UgewoJICAgIC8qCgkgICAgKiBGb3IgYWxsILdhdG9taWO3IGRhdGF0eXBlcyBvdGhlciB0aGFuIHN0cmluZyAoYW5kIHR5cGVzILdkZXJpdmVktwoJICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0bwoJICAgICogY29sbGFwc2UKCSAgICAqIE5vdGUgdGhhdCB0aGlzIGluY2x1ZGVzIGJ1aWx0LWluIGxpc3QgZGF0YXR5cGVzLgoJICAgICovCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRSk7Cgl9CiAgICB9IGVsc2UgaWYgKFdYU19JU19MSVNUKHR5cGUpKSB7CgkvKgoJKiBGb3IgbGlzdCB0eXBlcyB0aGUgZmFjZXQgIndoaXRlU3BhY2UiIGlzIGZpeGVkIHRvICJjb2xsYXBzZSIuCgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0UpOwogICAgfSBlbHNlIGlmIChXWFNfSVNfVU5JT04odHlwZSkpIHsKCXJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX1VOS05PV04pOwogICAgfSBlbHNlIGlmIChXWFNfSVNfQVRPTUlDKHR5cGUpKSB7CglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUFJFU0VSVkUpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUFJFU0VSVkUpOwoJZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUkVQTEFDRSkKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFKTsKCWVsc2UKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRSk7CiAgICB9CiAgICByZXR1cm4gKC0xKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNpbXBsZSB0eXBlIHZhbGlkYXRpb24JCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURPTSBWYWxpZGF0aW9uIGNvZGUJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogdGhlIGV4aXN0aW5nIHNjaGVtYQogKiBAbm9kZTogdGhlIG5vZGUgdGhhdCBmaXJlZCB0aGUgYXNzZW1ibGluZwogKiBAbnNOYW1lOiB0aGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIG5ldyBzY2hlbWEKICogQGxvY2F0aW9uOiB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbikKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgeG1sU2NoZW1hQnVja2V0UHRyIGJ1Y2tldCA9IE5VTEw7CgogICAgaWYgKCh2Y3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24iLAoJICAgICJubyBwYXJzZXIgY29udGV4dCBhdmFpbGFibGUiKTsKCXJldHVybigtMSk7CiAgICB9CiAgICBwY3R4dCA9IHZjdHh0LT5wY3R4dDsKICAgIGlmIChwY3R4dC0+Y29uc3RydWN0b3IgPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uIiwKCSAgICAibm8gY29uc3RydWN0b3IiKTsKCXJldHVybigtMSk7CiAgICB9CiAgICAvKgogICAgKiBBY3F1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgbG9jYXRpb24gPSB4bWxTY2hlbWFCdWlsZEFic29sdXRlVVJJKHBjdHh0LT5kaWN0LAoJbG9jYXRpb24sIG5vZGUpOwogICAgLyoKICAgICogTm90ZSB0aGF0IHdlIHBhc3MgWE1MX1NDSEVNQV9TQ0hFTUFfSU1QT1JUIGhlcmU7CiAgICAqIHRoZSBwcm9jZXNzIHdpbGwgYXV0b21hdGljYWxseSBjaGFuZ2UgdGhpcyB0bwogICAgKiBYTUxfU0NIRU1BX1NDSEVNQV9NQUlOIGlmIGl0IGlzIHRoZSBmaXJzdCBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hQWRkU2NoZW1hRG9jKHBjdHh0LCBYTUxfU0NIRU1BX1NDSEVNQV9JTVBPUlQsCglsb2NhdGlvbiwgTlVMTCwgTlVMTCwgMCwgbm9kZSwgTlVMTCwgbnNOYW1lLCAKCSZidWNrZXQpOwogICAgaWYgKHJldCAhPSAwKQoJcmV0dXJuKHJldCk7CiAgICBpZiAoYnVja2V0ID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiIsCgkgICAgIm5vIHNjaGVtYSBidWNrZXQgYWNxdWlyZWQiKTsKCXJldHVybigtMSk7CiAgICB9IAogICAgLyoKICAgICogVGhlIGZpcnN0IGxvY2F0ZWQgc2NoZW1hIHdpbGwgYmUgaGFuZGxlZCBhcyBpZiBhbGwgb3RoZXIKICAgICogc2NoZW1hcyBpbXBvcnRlZCBieSBYU0kgd2VyZSBpbXBvcnRlZCBieSB0aGlzIGZpcnN0IHNjaGVtYS4KICAgICovCiAgICBpZiAoKGJ1Y2tldCAhPSBOVUxMKSAmJgoJKFdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCA9PSBOVUxMKSkKCVdYU19DT05TVFJVQ1RPUihwY3R4dCktPmJ1Y2tldCA9IGJ1Y2tldDsKICAgIC8qCiAgICAqIFRPRE86IElzIHRoaXMgaGFuZGxlZCBsaWtlIGFuIGltcG9ydD8gSS5lLiBpcyBpdCBub3QgYW4gZXJyb3IKICAgICogaWYgdGhlIHNjaGVtYSBjYW5ub3QgYmUgbG9jYXRlZD8KICAgICovCiAgICBpZiAoKGJ1Y2tldCA9PSBOVUxMKSB8fCAoISBDQU5fUEFSU0VfU0NIRU1BKGJ1Y2tldCkpKQoJcmV0dXJuKDApOwogICAgLyoKICAgICogV2Ugd2lsbCByZXVzZSB0aGUgcGFyc2VyIGNvbnRleHQgZm9yIGV2ZXJ5IHNjaGVtYSBpbXBvcnRlZAogICAgKiBkaXJlY3RseSB2aWEgWFNJLiBTbyByZXNldCB0aGUgY29udGV4dC4KICAgICovCiAgICBwY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgcGN0eHQtPmVyciA9IDA7CiAgICBwY3R4dC0+ZG9jID0gYnVja2V0LT5kb2M7CiAgICAKICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlTmV3RG9jV2l0aENvbnRleHQocGN0eHQsIHNjaGVtYSwgYnVja2V0KTsgICAgICAgIAogICAgaWYgKHJldCA9PSAtMSkgewoJcGN0eHQtPmRvYyA9IE5VTEw7Cglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIH0KICAgIC8qIFBhcmFub2lkIGVycm9yIGNoYW5uZWxsaW5nLiAqLwogICAgaWYgKChyZXQgPT0gMCkgJiYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKSkKCXJldCA9IHBjdHh0LT5lcnI7ICAgIAogICAgaWYgKHBjdHh0LT5uYmVycm9ycyA9PSAwKSB7CQoJLyogCgkqIE9ubHkgYm90aGVyIHRvIGZpeHVwIHBlbmRpbmcgY29tcG9uZW50cywgaWYgdGhlcmUgd2FzCgkqIG5vIGVycm9yIHlldC4KCSogRm9yIGV2ZXJ5IFhTSSBhY3F1aXJlZCBzY2hlbWEgKGFuZCBpdHMgc3ViLXNjaGVtYXRhKSB3ZSB3aWxsCgkqIGZpeHVwIHRoZSBjb21wb25lbnRzLgoJKi8KCXhtbFNjaGVtYUZpeHVwQ29tcG9uZW50cyhwY3R4dCwgYnVja2V0KTsKCXJldCA9IHBjdHh0LT5lcnI7CgkvKgoJKiBOb3QgbmljZSwgYnV0IHdlIG5lZWQgc29tZWhvdyB0byBjaGFubmVsIHRoZSBzY2hlbWEgcGFyc2VyCgkqIGVycm9yIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQuCgkqLwoJaWYgKChyZXQgIT0gMCkgJiYgKHZjdHh0LT5lcnIgPT0gMCkpCgkgICAgdmN0eHQtPmVyciA9IHJldDsKCXZjdHh0LT5uYmVycm9ycyArPSBwY3R4dC0+bmJlcnJvcnM7CiAgICB9IGVsc2UgewoJLyogQWRkIHRvIHZhbGlkYXRpb24gZXJyb3Igc3VtLiAqLyAKCXZjdHh0LT5uYmVycm9ycyArPSBwY3R4dC0+bmJlcnJvcnM7CiAgICB9CiAgICBwY3R4dC0+ZG9jID0gTlVMTDsKICAgIHJldHVybihyZXQpOwpleGl0X2ZhaWx1cmU6CiAgICBwY3R4dC0+ZG9jID0gTlVMTDsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgeG1sU2NoZW1hQXR0ckluZm9QdHIKeG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwJCSAgICAgIAoJCQkgaW50IG1ldGFUeXBlKQp7CiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zID09IDApCglyZXR1cm4gKE5VTEwpOwogICAgewoJaW50IGk7Cgl4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCglmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPm5iQXR0ckluZm9zOyBpKyspIHsKCSAgICBpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CgkgICAgaWYgKGlhdHRyLT5tZXRhVHlwZSA9PSBtZXRhVHlwZSkKCQlyZXR1cm4gKGlhdHRyKTsKCX0KCiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSToKICogQHZjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hIHVzaW5nCiAqIHRoZSB4c2k6c2NoZW1hTG9jYXRpb24gb3IgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gYXR0cmlidXRlCiAqIG9mIGFuIGluc3RhbmNlLiBJZiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBpcyB1c2VkLCBAbm9OYW1lc3BhY2UKICogbXVzdCBiZSBzZXQgdG8gMS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeVhTSSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGNvbnN0IHhtbENoYXIgKm5zbmFtZSA9IE5VTEwsICpsb2NhdGlvbjsKICAgIGludCBjb3VudCA9IDA7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoKICAgIC8qCiAgICAqIFBhcnNlIHRoZSB2YWx1ZTsgd2Ugd2lsbCBhc3N1bWUgYW4gZXZlbiBudW1iZXIgb2YgdmFsdWVzCiAgICAqIHRvIGJlIGdpdmVuICh0aGlzIGlzIGhvdyBYZXJjZXMgYW5kIFhTViB3b3JrKS4KICAgICoKICAgICogVVJHRU5UIFRPRE86ICEhIFRoaXMgbmVlZHMgdG8gd29yayBmb3IgYm90aAogICAgKiBAbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBBTkQgQHNjaGVtYUxvY2F0aW9uIG9uIHRoZSBzYW1lCiAgICAqIGVsZW1lbnQgISEKICAgICovCiAgICBpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCVhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1NDSEVNQV9MT0MpOwogICAgaWYgKGlhdHRyID09IE5VTEwpCglpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCVhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX05PX05TX1NDSEVNQV9MT0MpOwogICAgaWYgKGlhdHRyID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgY3VyID0gaWF0dHItPnZhbHVlOwogICAgZG8gewoJaWYgKGlhdHRyLT5tZXRhVHlwZSA9PSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DKSB7CgkgICAgLyoKCSAgICAqIEdldCB0aGUgbmFtZXNwYWNlIG5hbWUuCgkgICAgKi8KCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIGNvdW50Kys7CgkgICAgbnNuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+c2NoZW1hLT5kaWN0LCBjdXIsIGVuZCAtIGN1cik7CgkgICAgY3VyID0gZW5kOwoJfQoJLyoKCSogR2V0IHRoZSBVUkkuCgkqLwoJd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJICAgIGN1cisrOwoJZW5kID0gY3VyOwoJd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkgICAgZW5kKys7CglpZiAoZW5kID09IGN1cikKCSAgICBicmVhazsKCWNvdW50Kys7Cglsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwoJY3VyID0gZW5kOwoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHZjdHh0LCB2Y3R4dC0+c2NoZW1hLAoJICAgIGlhdHRyLT5ub2RlLCBuc25hbWUsIGxvY2F0aW9uKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJIiwKCQkiYXNzZW1ibGluZyBzY2hlbWF0YSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfSB3aGlsZSAoKmN1ciAhPSAwKTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgY29uc3QgeG1sQ2hhciAqcHJlZml4KQp7CiAgICBpZiAodmN0eHQtPnNheCAhPSBOVUxMKSB7CglpbnQgaSwgajsKCXhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlOwoJCglmb3IgKGkgPSB2Y3R4dC0+ZGVwdGg7IGkgPj0gMDsgaS0tKSB7CgkgICAgaWYgKHZjdHh0LT5lbGVtSW5mb3NbaV0tPm5iTnNCaW5kaW5ncyAhPSAwKSB7CgkJaW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW2ldOwoJCWZvciAoaiA9IDA7IGogPCBpbm9kZS0+bmJOc0JpbmRpbmdzICogMjsgaiArPSAyKSB7CgkJICAgIGlmICgoKHByZWZpeCA9PSBOVUxMKSAmJgoJCQkgICAgKGlub2RlLT5uc0JpbmRpbmdzW2pdID09IE5VTEwpKSB8fAoJCQkoKHByZWZpeCAhPSBOVUxMKSAmJiB4bWxTdHJFcXVhbChwcmVmaXgsCgkJCSAgICBpbm9kZS0+bnNCaW5kaW5nc1tqXSkpKSB7CgoJCQkvKgoJCQkqIE5vdGUgdGhhdCB0aGUgbmFtZXNwYWNlIGJpbmRpbmdzIGFyZSBhbHJlYWR5CgkJCSogaW4gYSBzdHJpbmcgZGljdC4KCQkJKi8KCQkJcmV0dXJuIChpbm9kZS0+bnNCaW5kaW5nc1tqKzFdKTsJCQkKCQkgICAgfQoJCX0KCSAgICB9Cgl9CglyZXR1cm4gKE5VTEwpOwojaWZkZWYgTElCWE1MX1dSSVRFUl9FTkFCTEVECiAgICB9IGVsc2UgaWYgKHZjdHh0LT5yZWFkZXIgIT0gTlVMTCkgewoJeG1sQ2hhciAqbnNOYW1lOwoJCgluc05hbWUgPSB4bWxUZXh0UmVhZGVyTG9va3VwTmFtZXNwYWNlKHZjdHh0LT5yZWFkZXIsIHByZWZpeCk7CglpZiAobnNOYW1lICE9IE5VTEwpIHsKCSAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgoJICAgIHJldCA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIG5zTmFtZSwgLTEpOwoJICAgIHhtbEZyZWUobnNOYW1lKTsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXR1cm4gKE5VTEwpOwojZW5kaWYKICAgIH0gZWxzZSB7Cgl4bWxOc1B0ciBuczsKCglpZiAoKHZjdHh0LT5pbm9kZS0+bm9kZSA9PSBOVUxMKSB8fAoJICAgICh2Y3R4dC0+aW5vZGUtPm5vZGUtPmRvYyA9PSBOVUxMKSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSIsCgkJIm5vIG5vZGUgb3Igbm9kZSdzIGRvYyBhdmFsaWFibGUiKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbnMgPSB4bWxTZWFyY2hOcyh2Y3R4dC0+aW5vZGUtPm5vZGUtPmRvYywKCSAgICB2Y3R4dC0+aW5vZGUtPm5vZGUsIHByZWZpeCk7CglpZiAobnMgIT0gTlVMTCkKCSAgICByZXR1cm4gKG5zLT5ocmVmKTsKCXJldHVybiAoTlVMTCk7CiAgICB9Cn0KCi8qCiogVGhpcyBvbmUgd29ya3Mgb24gdGhlIHNjaGVtYSBvZiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0LgoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAJCQkgIAoJCQkgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgeG1sTm9kZVB0ciBub2RlLAoJCQkgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgIHhtbFNjaGVtYVZhbFB0ciAqdmFsLAoJCQkgIGludCB2YWxOZWVkZWQpCnsKICAgIGludCByZXQ7CgogICAgaWYgKHZjdHh0ICYmICh2Y3R4dC0+c2NoZW1hID09IE5VTEwpKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uIiwKCSAgICAiYSBzY2hlbWEgaXMgbmVlZGVkIG9uIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ICE9IDApCglyZXR1cm4gKHJldCk7CiAgICB7Cgl4bWxDaGFyICpsb2NhbE5hbWUgPSBOVUxMOwoJeG1sQ2hhciAqcHJlZml4ID0gTlVMTDsKCglsb2NhbE5hbWUgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CglpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICBjb25zdCB4bWxDaGFyICpuc05hbWUgPSBOVUxMOwoKCSAgICBpZiAodmN0eHQgIT0gTlVMTCkgCgkJbnNOYW1lID0geG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHZjdHh0LCBCQURfQ0FTVCBwcmVmaXgpOwoJICAgIGVsc2UgaWYgKG5vZGUgIT0gTlVMTCkgewoJCXhtbE5zUHRyIG5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBwcmVmaXgpOwoJCWlmIChucyAhPSBOVUxMKQoJCSAgICBuc05hbWUgPSBucy0+aHJlZjsKCSAgICB9IGVsc2UgewoJCXhtbEZyZWUocHJlZml4KTsKCQl4bWxGcmVlKGxvY2FsTmFtZSk7CgkJcmV0dXJuICgxKTsKCSAgICB9CgkgICAgaWYgKG5zTmFtZSA9PSBOVUxMKSB7CgkJeG1sRnJlZShwcmVmaXgpOwoJCXhtbEZyZWUobG9jYWxOYW1lKTsKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICBpZiAoeG1sU2NoZW1hR2V0Tm90YXRpb24oc2NoZW1hLCBsb2NhbE5hbWUsIG5zTmFtZSkgIT0gTlVMTCkgewoJCWlmICh2YWxOZWVkZWQgJiYgKHZhbCAhPSBOVUxMKSkgewoJCSAgICAoKnZhbCkgPSB4bWxTY2hlbWFOZXdOT1RBVElPTlZhbHVlKEJBRF9DQVNUIGxvY2FsTmFtZSwKCQkJQkFEX0NBU1QgeG1sU3RyZHVwKG5zTmFtZSkpOwoJCSAgICBpZiAoKnZhbCA9PSBOVUxMKQoJCQlyZXQgPSAtMTsKCQl9CgkgICAgfSBlbHNlCgkJcmV0ID0gMTsKCSAgICB4bWxGcmVlKHByZWZpeCk7CgkgICAgeG1sRnJlZShsb2NhbE5hbWUpOwoJfSBlbHNlIHsKCSAgICBpZiAoeG1sU2NoZW1hR2V0Tm90YXRpb24oc2NoZW1hLCB2YWx1ZSwgTlVMTCkgIT0gTlVMTCkgewoJCWlmICh2YWxOZWVkZWQgJiYgKHZhbCAhPSBOVUxMKSkgewoJCSAgICAoKnZhbCkgPSB4bWxTY2hlbWFOZXdOT1RBVElPTlZhbHVlKAoJCQlCQURfQ0FTVCB4bWxTdHJkdXAodmFsdWUpLCBOVUxMKTsKCQkgICAgaWYgKCp2YWwgPT0gTlVMTCkKCQkJcmV0ID0gLTE7CgkJfQoJICAgIH0gZWxzZQoJCXJldHVybiAoMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkFkZE5vZGVRTmFtZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIGNvbnN0IHhtbENoYXIqIGxuYW1lLAoJCSAgICAgICBjb25zdCB4bWxDaGFyKiBuc25hbWUpCnsKICAgIGludCBpOwoKICAgIGxuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbG5hbWUsIC0xKTsKICAgIGlmIChsbmFtZSA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKICAgIGlmIChuc25hbWUgIT0gTlVMTCkgewoJbnNuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbnNuYW1lLCAtMSk7CglpZiAobnNuYW1lID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bm9kZVFOYW1lcy0+bmJJdGVtczsgaSArPSAyKSB7CglpZiAoKHZjdHh0LT5ub2RlUU5hbWVzLT5pdGVtcyBbaV0gPT0gbG5hbWUpICYmCgkgICAgKHZjdHh0LT5ub2RlUU5hbWVzLT5pdGVtc1tpICsxXSA9PSBuc25hbWUpKQoJICAgIC8qIEFscmVhZHkgdGhlcmUgKi8KCSAgICByZXR1cm4oaSk7CiAgICB9CiAgICAvKiBBZGQgbmV3IGVudHJ5LiAqLwogICAgaSA9IHZjdHh0LT5ub2RlUU5hbWVzLT5uYkl0ZW1zOwogICAgeG1sU2NoZW1hSXRlbUxpc3RBZGQodmN0eHQtPm5vZGVRTmFtZXMsICh2b2lkICopIGxuYW1lKTsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0QWRkKHZjdHh0LT5ub2RlUU5hbWVzLCAodm9pZCAqKSBuc25hbWUpOwogICAgcmV0dXJuKGkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogIFZhbGlkYXRpb24gb2YgaWRlbnRpdHktY29uc3RyYWludHMgKElEQykgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQXVnbWVudElEQzoKICogQGlkY0RlZjogdGhlIElEQyBkZWZpbml0aW9uCiAqCiAqIENyZWF0ZXMgYW4gYXVnbWVudGVkIElEQyBkZWZpbml0aW9uIGl0ZW0uCiAqCiAqIFJldHVybnMgdGhlIGl0ZW0sIG9yIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXVnbWVudElEQyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmLAoJCSAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOwoKICAgIGFpZGMgPSAoeG1sU2NoZW1hSURDQXVnUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ0F1ZykpOwogICAgaWYgKGFpZGMgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCSAgICAieG1sU2NoZW1hQXVnbWVudElEQzogYWxsb2NhdGluZyBhbiBhdWdtZW50ZWQgSURDIGRlZmluaXRpb24iLAoJICAgIE5VTEwpOwoJcmV0dXJuOwogICAgfQogICAgYWlkYy0+a2V5cmVmRGVwdGggPSAtMTsKICAgIGFpZGMtPmRlZiA9IGlkY0RlZjsKICAgIGFpZGMtPm5leHQgPSBOVUxMOwogICAgaWYgKHZjdHh0LT5haWRjcyA9PSBOVUxMKQoJdmN0eHQtPmFpZGNzID0gYWlkYzsKICAgIGVsc2UgewoJYWlkYy0+bmV4dCA9IHZjdHh0LT5haWRjczsKCXZjdHh0LT5haWRjcyA9IGFpZGM7CiAgICB9CiAgICAvKgogICAgKiBTYXZlIGlmIHdlIGhhdmUga2V5cmVmcyBhdCBhbGwuCiAgICAqLwogICAgaWYgKCh2Y3R4dC0+aGFzS2V5cmVmcyA9PSAwKSAmJgoJKGlkY0RlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikpCgl2Y3R4dC0+aGFzS2V5cmVmcyA9IDE7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENOZXdCaW5kaW5nOgogKiBAaWRjRGVmOiB0aGUgSURDIGRlZmluaXRpb24gb2YgdGhpcyBiaW5kaW5nCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURDIGJpbmRpbmcuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBJREMgYmluZGluZywgTlVMTCBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIKeG1sU2NoZW1hSURDTmV3QmluZGluZyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmKQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyKSB4bWxNYWxsb2MoCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCSAgICAiYWxsb2NhdGluZyBhIFBTVkkgSURDIGJpbmRpbmcgaXRlbSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDQmluZGluZykpOwogICAgcmV0LT5kZWZpbml0aW9uID0gaWRjRGVmOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIG5vZGUgdGFibGUgaXRlbQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgSURDIG5vZGUgdGFibGUgaXRlbXMuCiAqIFRoZXkgYXJlIHN0b3JlZCB0byBhdm9pZCBjb3B5aW5nIHRoZW0gaWYgSURDIG5vZGUtdGFibGVzIGFyZSBtZXJnZWQKICogd2l0aCBjb3JyZXNwb25kaW5nIHBhcmVudCBJREMgbm9kZS10YWJsZXMgKGJ1YmJsaW5nKS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZU5vZGVUYWJsZUl0ZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaXRlbSkKewogICAgLyoKICAgICogQWRkIHRvIGdvYmFsIGxpc3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5pZGNOb2RlcyA9PSBOVUxMKSB7Cgl2Y3R4dC0+aWRjTm9kZXMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxNYWxsb2MoMjAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgdGhlIElEQyBub2RlIHRhYmxlIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnNpemVJZGNOb2RlcyA9IDIwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUlkY05vZGVzIDw9IHZjdHh0LT5uYklkY05vZGVzKSB7Cgl2Y3R4dC0+c2l6ZUlkY05vZGVzICo9IDI7Cgl2Y3R4dC0+aWRjTm9kZXMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5pZGNOb2RlcywgdmN0eHQtPnNpemVJZGNOb2RlcyAqCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHZjdHh0LT5pZGNOb2Rlc1t2Y3R4dC0+bmJJZGNOb2RlcysrXSA9IGl0ZW07CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1N0b3JlS2V5OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIGtleQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgYW4gSURDIGtleS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZUtleSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSkKewogICAgLyoKICAgICogQWRkIHRvIGdvYmFsIGxpc3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCXZjdHh0LT5pZGNLZXlzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikKCSAgICB4bWxNYWxsb2MoNDAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIHRoZSBJREMga2V5IHN0b3JhZ2UgbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnNpemVJZGNLZXlzID0gNDA7CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5zaXplSWRjS2V5cyA8PSB2Y3R4dC0+bmJJZGNLZXlzKSB7Cgl2Y3R4dC0+c2l6ZUlkY0tleXMgKj0gMjsKCXZjdHh0LT5pZGNLZXlzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5pZGNLZXlzLCB2Y3R4dC0+c2l6ZUlkY0tleXMgKgoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CglpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgdGhlIElEQyBrZXkgc3RvcmFnZSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICB2Y3R4dC0+aWRjS2V5c1t2Y3R4dC0+bmJJZGNLZXlzKytdID0ga2V5OwoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtOgogKiBAYmluZDogdGhlIElEQyBiaW5kaW5nCiAqIEBudEl0ZW06IHRoZSBub2RlLXRhYmxlIGl0ZW0KICoKICogQXBwZW5kcyB0aGUgSURDIG5vZGUtdGFibGUgaXRlbSB0byB0aGUgYmluZGluZy4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbSh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kLAoJCQkJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbnRJdGVtKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCWJpbmQtPnNpemVOb2RlcyA9IDEwOwoJYmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJImFsbG9jYXRpbmcgYW4gYXJyYXkgb2YgSURDIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfSBlbHNlIGlmIChiaW5kLT5zaXplTm9kZXMgPD0gYmluZC0+bmJOb2RlcykgewoJYmluZC0+c2l6ZU5vZGVzICo9IDI7CgliaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxSZWFsbG9jKGJpbmQtPm5vZGVUYWJsZSwgYmluZC0+c2l6ZU5vZGVzICoKCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmIChiaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkicmUtYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9CiAgICBiaW5kLT5ub2RlVGFibGVbYmluZC0+bmJOb2RlcysrXSA9IG50SXRlbTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FjcXVpcmVCaW5kaW5nOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBtYXRjaGVyOiB0aGUgSURDIG1hdGNoZXIKICoKICogTG9va3MgdXAgYW4gUFNWSSBJREMgYmluZGluZywgZm9yIHRoZSBJREMgZGVmaW5pdGlvbiBhbmQKICogb2YgdGhlIGdpdmVuIG1hdGNoZXIuIElmIG5vbmUgZm91bmQsIGEgbmV3IG9uZSBpcyBjcmVhdGVkCiAqIGFuZCBhZGRlZCB0byB0aGUgSURDIHRhYmxlLgogKgogKiBSZXR1cm5zIGFuIElEQyBiaW5kaW5nIG9yIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyCnhtbFNjaGVtYUlEQ0FjcXVpcmVCaW5kaW5nKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIpCnsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtOwoKICAgIGllbGVtID0gdmN0eHQtPmVsZW1JbmZvc1ttYXRjaGVyLT5kZXB0aF07CgogICAgaWYgKGllbGVtLT5pZGNUYWJsZSA9PSBOVUxMKSB7CglpZWxlbS0+aWRjVGFibGUgPSB4bWxTY2hlbWFJRENOZXdCaW5kaW5nKG1hdGNoZXItPmFpZGMtPmRlZik7CglpZiAoaWVsZW0tPmlkY1RhYmxlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXJldHVybihpZWxlbS0+aWRjVGFibGUpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQgPSBOVUxMOwoKCWJpbmQgPSBpZWxlbS0+aWRjVGFibGU7CglkbyB7CgkgICAgaWYgKGJpbmQtPmRlZmluaXRpb24gPT0gbWF0Y2hlci0+YWlkYy0+ZGVmKQoJCXJldHVybihiaW5kKTsKCSAgICBpZiAoYmluZC0+bmV4dCA9PSBOVUxMKSB7CgkJYmluZC0+bmV4dCA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcobWF0Y2hlci0+YWlkYy0+ZGVmKTsKCQlpZiAoYmluZC0+bmV4dCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKE5VTEwpOwoJCXJldHVybihiaW5kLT5uZXh0KTsKCSAgICB9CgkgICAgYmluZCA9IGJpbmQtPm5leHQ7Cgl9IHdoaWxlIChiaW5kICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKc3RhdGljIHhtbFNjaGVtYUl0ZW1MaXN0UHRyCnhtbFNjaGVtYUlEQ0FjcXVpcmVUYXJnZXRMaXN0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcikKewogICAgaWYgKG1hdGNoZXItPnRhcmdldHMgPT0gTlVMTCkKCW1hdGNoZXItPnRhcmdldHMgPSB4bWxTY2hlbWFJdGVtTGlzdENyZWF0ZSgpOwogICAgcmV0dXJuKG1hdGNoZXItPnRhcmdldHMpOwp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZUtleToKICogQGtleTogdGhlIElEQyBrZXkKICoKICogRnJlZXMgYW4gSURDIGtleSB0b2dldGhlciB3aXRoIGl0cyBjb21waWxlZCB2YWx1ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlEQ0ZyZWVLZXkoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkpCnsKICAgIGlmIChrZXktPnZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGtleS0+dmFsKTsKICAgIHhtbEZyZWUoa2V5KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nOgogKgogKiBGcmVlcyBhbiBJREMgYmluZGluZy4gTm90ZSB0aGF0IHRoZSBub2RlIHRhYmxlLWl0ZW1zCiAqIGFyZSBub3QgZnJlZWQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlQmluZGluZyh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlICE9IE5VTEwpCgl4bWxGcmVlKGJpbmQtPm5vZGVUYWJsZSk7CiAgICBpZiAoYmluZC0+ZHVwbHMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShiaW5kLT5kdXBscyk7CQogICAgeG1sRnJlZShiaW5kKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVJRENUYWJsZToKICogQGJpbmQ6IHRoZSBmaXJzdCBJREMgYmluZGluZyBpbiB0aGUgbGlzdAogKgogKiBGcmVlcyBhbiBJREMgdGFibGUsIGkuZS4gYWxsIHRoZSBJREMgYmluZGluZ3MgaW4gdGhlIGxpc3QuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlSURDVGFibGUoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgcHJldjsKCiAgICB3aGlsZSAoYmluZCAhPSBOVUxMKSB7CglwcmV2ID0gYmluZDsKCWJpbmQgPSBiaW5kLT5uZXh0OwoJeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcocHJldik7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlTWF0Y2hlckxpc3Q6CiAqIEBtYXRjaGVyOiB0aGUgZmlyc3QgSURDIG1hdGNoZXIgaW4gdGhlIGxpc3QKICoKICogRnJlZXMgYSBsaXN0IG9mIElEQyBtYXRjaGVycy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdCh4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIpCnsKICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbmV4dDsKCiAgICB3aGlsZSAobWF0Y2hlciAhPSBOVUxMKSB7CgluZXh0ID0gbWF0Y2hlci0+bmV4dDsKCWlmIChtYXRjaGVyLT5rZXlTZXFzICE9IE5VTEwpIHsKCSAgICBpbnQgaTsKCSAgICBmb3IgKGkgPSAwOyBpIDwgbWF0Y2hlci0+c2l6ZUtleVNlcXM7IGkrKykKCQlpZiAobWF0Y2hlci0+a2V5U2Vxc1tpXSAhPSBOVUxMKQoJCSAgICB4bWxGcmVlKG1hdGNoZXItPmtleVNlcXNbaV0pOwoJICAgIHhtbEZyZWUobWF0Y2hlci0+a2V5U2Vxcyk7CSAgICAKCX0KCWlmIChtYXRjaGVyLT50YXJnZXRzICE9IE5VTEwpIHsKCSAgICBpZiAobWF0Y2hlci0+aWRjVHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJCWludCBpOwoJCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGlkY05vZGU7CgkJLyoKCQkqIE5vZGUtdGFibGUgaXRlbXMgZm9yIGtleXJlZnMgYXJlIG5vdCBzdG9yZWQgZ2xvYmFsbHkKCQkqIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQsIHNpbmNlIHRoZXkgYXJlIG5vdCBidWJibGVkLgoJCSogV2UgbmVlZCB0byBmcmVlIHRoZW0gaGVyZS4KCQkqLwoJCWZvciAoaSA9IDA7IGkgPCBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zOyBpKyspIHsKCQkgICAgaWRjTm9kZSA9CgkJCSh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgbWF0Y2hlci0+dGFyZ2V0cy0+aXRlbXNbaV07CgkJICAgIHhtbEZyZWUoaWRjTm9kZS0+a2V5cyk7CgkJICAgIHhtbEZyZWUoaWRjTm9kZSk7CgkJfQoJICAgIH0KCSAgICB4bWxTY2hlbWFJdGVtTGlzdEZyZWUobWF0Y2hlci0+dGFyZ2V0cyk7Cgl9Cgl4bWxGcmVlKG1hdGNoZXIpOwoJbWF0Y2hlciA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdDoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAbWF0Y2hlcjogdGhlIElEQyBtYXRjaGVyCiAqIEBzZWw6IHRoZSBYUGF0aCBpbmZvcm1hdGlvbgogKiBAcGFyZW50OiB0aGUgcGFyZW50ICJzZWxlY3RvciIgc3RhdGUgb2JqZWN0IGlmIGFueQogKiBAdHlwZTogInNlbGVjdG9yIiBvciAiZmllbGQiCiAqCiAqIENyZWF0ZXMvcmV1c2VzIGFuZCBhY3RpdmF0ZXMgc3RhdGUgb2JqZWN0cyBmb3IgdGhlIGdpdmVuCiAqIFhQYXRoIGluZm9ybWF0aW9uOyBpZiB0aGUgWFBhdGggZXhwcmVzc2lvbiBjb25zaXN0cyBvZiB1bmlvbnMsCiAqIG11bHRpcGxlIHN0YXRlIG9iamVjdHMgYXJlIGNyZWF0ZWQgZm9yIGV2ZXJ5IHVuaW9uZWQgZXhwcmVzc2lvbi4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3QoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQl4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIsCgkJCXhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWwsCgkJCWludCB0eXBlKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG87CgogICAgLyoKICAgICogUmV1c2UgdGhlIHN0YXRlIG9iamVjdHMgZnJvbSB0aGUgcG9vbC4KICAgICovCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVQb29sICE9IE5VTEwpIHsKCXN0byA9IHZjdHh0LT54cGF0aFN0YXRlUG9vbDsKCXZjdHh0LT54cGF0aFN0YXRlUG9vbCA9IHN0by0+bmV4dDsKCXN0by0+bmV4dCA9IE5VTEw7CiAgICB9IGVsc2UgewkKCS8qCgkqIENyZWF0ZSBhIG5ldyBzdGF0ZSBvYmplY3QuCgkqLwoJc3RvID0gKHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ1N0YXRlT2JqKSk7CglpZiAoc3RvID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJImFsbG9jYXRpbmcgYW4gSURDIHN0YXRlIG9iamVjdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbWVtc2V0KHN0bywgMCwgc2l6ZW9mKHhtbFNjaGVtYUlEQ1N0YXRlT2JqKSk7CiAgICB9CQogICAgLyoKICAgICogQWRkIHRvIGdsb2JhbCBsaXN0LiAKICAgICovCQogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKQoJc3RvLT5uZXh0ID0gdmN0eHQtPnhwYXRoU3RhdGVzOwogICAgdmN0eHQtPnhwYXRoU3RhdGVzID0gc3RvOwoKICAgIC8qCiAgICAqIEZyZWUgdGhlIG9sZCB4cGF0aCB2YWxpZGF0aW9uIGNvbnRleHQuCiAgICAqLwogICAgaWYgKHN0by0+eHBhdGhDdHh0ICE9IE5VTEwpCgl4bWxGcmVlU3RyZWFtQ3R4dCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQpOwoKICAgIC8qCiAgICAqIENyZWF0ZSBhIG5ldyBYUGF0aCAocGF0dGVybikgdmFsaWRhdGlvbiBjb250ZXh0LgogICAgKi8KICAgIHN0by0+eHBhdGhDdHh0ID0gKHZvaWQgKikgeG1sUGF0dGVybkdldFN0cmVhbUN0eHQoCgkoeG1sUGF0dGVyblB0cikgc2VsLT54cGF0aENvbXApOwogICAgaWYgKHN0by0+eHBhdGhDdHh0ID09IE5VTEwpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0IiwKCSAgICAiZmFpbGVkIHRvIGNyZWF0ZSBhbiBYUGF0aCB2YWxpZGF0aW9uIGNvbnRleHQiKTsKCXJldHVybiAoLTEpOwogICAgfSAgICAKICAgIHN0by0+dHlwZSA9IHR5cGU7CiAgICBzdG8tPmRlcHRoID0gdmN0eHQtPmRlcHRoOwogICAgc3RvLT5tYXRjaGVyID0gbWF0Y2hlcjsKICAgIHN0by0+c2VsID0gc2VsOwogICAgc3RvLT5uYkhpc3RvcnkgPSAwOwogICAgCiNpZmRlZiBERUJVR19JREMKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFNUTyBwdXNoICclcydcbiIsCglzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlVHlwZTogdGhlIG5vZGVUeXBlIG9mIHRoZSBjdXJyZW50IG5vZGUKICoKICogRXZhbHVhdGVzIGFsbCBhY3RpdmUgWFBhdGggc3RhdGUgb2JqZWN0cy4KICoKICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIElDICJmaWVsZCIgc3RhdGUgb2JqZWN0cyB3aGljaCByZXNvbHZlZCB0bwogKiB0aGlzIG5vZGUsIDAgaWYgbm9uZSByZXNvbHZlZCBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICAgICAgeG1sRWxlbWVudFR5cGUgbm9kZVR5cGUpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bywgaGVhZCA9IE5VTEwsIGZpcnN0OwogICAgaW50IHJlcywgcmVzb2x2ZWQgPSAwLCBkZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgICAgICAKICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgPT0gTlVMTCkKCXJldHVybiAoMCk7CgogICAgaWYgKG5vZGVUeXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCWRlcHRoKys7CiNpZmRlZiBERUJVR19JREMKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgCgkgICAgIklEQzogRVZBTCBvbiAlcywgZGVwdGggJWQsIHR5cGUgJWRcbiIsCSAgICAKCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSksIGRlcHRoLCBub2RlVHlwZSk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCiAgICAvKgogICAgKiBQcm9jZXNzIGFsbCBhY3RpdmUgWFBhdGggc3RhdGUgb2JqZWN0cy4KICAgICovCiAgICBmaXJzdCA9IHZjdHh0LT54cGF0aFN0YXRlczsKICAgIHN0byA9IGZpcnN0OwogICAgd2hpbGUgKHN0byAhPSBoZWFkKSB7CiNpZmRlZiBERUJVR19JREMKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKQoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFsnJXMnXSBzZWxlY3RvciAnJXMnXG4iLCAKCQlzdG8tPm1hdGNoZXItPmFpZGMtPmRlZi0+bmFtZSwgc3RvLT5zZWwtPnhwYXRoKTsKCWVsc2UKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBbJyVzJ10gZmllbGQgJyVzJ1xuIiwgCgkJc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYtPm5hbWUsIHN0by0+c2VsLT54cGF0aCk7CiNlbmRpZgoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgcmVzID0geG1sU3RyZWFtUHVzaCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsKCWVsc2UKCSAgICByZXMgPSB4bWxTdHJlYW1QdXNoQXR0cigoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsKCglpZiAocmVzID09IC0xKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSIsCgkJImNhbGxpbmcgeG1sU3RyZWFtUHVzaCgpIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAocmVzID09IDApCgkgICAgZ290byBuZXh0X3N0bzsKCS8qCgkqIEZ1bGwgbWF0Y2guCgkqLwojaWZkZWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICIKCSAgICAiTUFUQ0hcbiIpOwojZW5kaWYKCS8qCgkqIFJlZ2lzdGVyIGEgbWF0Y2ggaW4gdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5LgoJKi8KCWlmIChzdG8tPmhpc3RvcnkgPT0gTlVMTCkgewoJICAgIHN0by0+aGlzdG9yeSA9IChpbnQgKikgeG1sTWFsbG9jKDUgKiBzaXplb2YoaW50KSk7CgkgICAgaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgImFsbG9jYXRpbmcgdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5IiwgTlVMTCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgc3RvLT5zaXplSGlzdG9yeSA9IDEwOwoJfSBlbHNlIGlmIChzdG8tPnNpemVIaXN0b3J5IDw9IHN0by0+bmJIaXN0b3J5KSB7CgkgICAgc3RvLT5zaXplSGlzdG9yeSAqPSAyOwoJICAgIHN0by0+aGlzdG9yeSA9IChpbnQgKikgeG1sUmVhbGxvYyhzdG8tPmhpc3RvcnksCgkJc3RvLT5zaXplSGlzdG9yeSAqIHNpemVvZihpbnQpKTsKCSAgICBpZiAoc3RvLT5oaXN0b3J5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAicmUtYWxsb2NhdGluZyB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkiLCBOVUxMKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCX0JCQoJc3RvLT5oaXN0b3J5W3N0by0+bmJIaXN0b3J5KytdID0gZGVwdGg7CgojaWZkZWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICAgcHVzaCBtYXRjaCAnJWQnXG4iLAoJICAgIHZjdHh0LT5kZXB0aCk7CiNlbmRpZgoKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKSB7CgkgICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbDsKCSAgICAvKgoJICAgICogQWN0aXZhdGUgc3RhdGUgb2JqZWN0cyBmb3IgdGhlIElEQyBmaWVsZHMgb2YKCSAgICAqIHRoZSBJREMgc2VsZWN0b3IuCgkgICAgKi8KI2lmZGVmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgICAgIgoJCSJhY3RpdmF0aW5nIGZpZWxkIHN0YXRlc1xuIik7CiNlbmRpZgoJICAgIHNlbCA9IHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5maWVsZHM7CgkgICAgd2hpbGUgKHNlbCAhPSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHZjdHh0LCBzdG8tPm1hdGNoZXIsCgkJICAgIHNlbCwgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSA9PSAtMSkKCQkgICAgcmV0dXJuICgtMSk7CgkJc2VsID0gc2VsLT5uZXh0OwoJICAgIH0KCX0gZWxzZSBpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgewoJICAgIC8qCgkgICAgKiBBbiBJREMga2V5IG5vZGUgd2FzIGZvdW5kIGJ5IHRoZSBJREMgZmllbGQuCgkgICAgKi8KI2lmZGVmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSJJREM6ICAgICBrZXkgZm91bmRcbiIpOwojZW5kaWYKCSAgICAvKgoJICAgICogTm90aWZ5IHRoYXQgdGhlIGNoYXJhY3RlciB2YWx1ZSBvZiB0aGlzIG5vZGUgaXMKCSAgICAqIG5lZWRlZC4KCSAgICAqLwoJICAgIGlmIChyZXNvbHZlZCA9PSAwKSB7CgkJaWYgKCh2Y3R4dC0+aW5vZGUtPmZsYWdzICYKCQkgICAgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEKSA9PSAwKQoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEOwoJICAgIH0KCSAgICByZXNvbHZlZCsrOwoJfQpuZXh0X3N0bzoKCWlmIChzdG8tPm5leHQgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBFdmFsdWF0ZSBmaWVsZCBzdGF0ZSBvYmplY3RzIGNyZWF0ZWQgb24gdGhpcyBub2RlIGFzIHdlbGwuCgkgICAgKi8KCSAgICBoZWFkID0gZmlyc3Q7CgkgICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwoJfSBlbHNlCgkgICAgc3RvID0gc3RvLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChyZXNvbHZlZCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICB4bWxDaGFyICoqYnVmLAoJCQkgICAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICpzZXEsCgkJCSAgICAgIGludCBjb3VudCkKewogICAgaW50IGksIHJlczsKICAgIHhtbENoYXIgKnZhbHVlID0gTlVMTDsKCiAgICAqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJbIik7CiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJcmVzID0geG1sU2NoZW1hR2V0Q2Fub25WYWx1ZVdodHNwRXh0KHNlcVtpXS0+dmFsLCAKCSAgICB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZShzZXFbaV0tPnR5cGUpLAoJICAgICZ2YWx1ZSk7CglpZiAocmVzID09IDApCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCB2YWx1ZSk7CgllbHNlIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFGb3JtYXRJRENLZXlTZXF1ZW5jZSIsCgkJImZhaWxlZCB0byBjb21wdXRlIGEgY2Fub25pY2FsIHZhbHVlIik7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiPz8/Iik7Cgl9CglpZiAoaSA8IGNvdW50IC0xKQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIicsICIpOwoJZWxzZQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCWlmICh2YWx1ZSAhPSBOVUxMKSB7CgkgICAgeG1sRnJlZSh2YWx1ZSk7CgkgICAgdmFsdWUgPSBOVUxMOwoJfQogICAgfQogICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiXSIpOwoKICAgIHJldHVybiAoQkFEX0NBU1QgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFYUGF0aFBvcDoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBQb3BzIGFsbCBYUGF0aCBzdGF0ZXMuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVhQYXRoUG9wKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvOwogICAgaW50IHJlczsKCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzID09IE5VTEwpCglyZXR1cm4oMCk7CiAgICBzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CiAgICBkbyB7CglyZXMgPSB4bWxTdHJlYW1Qb3AoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCWlmIChyZXMgPT0gLTEpCgkgICAgcmV0dXJuICgtMSk7CglzdG8gPSBzdG8tPm5leHQ7CiAgICB9IHdoaWxlIChzdG8gIT0gTlVMTCk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiB0aGUgc2ltcGxlL2NvbXBsZXggdHlwZSBvZiB0aGUgY3VycmVudCBub2RlIGlmIGFueSBhdCBhbGwKICogQHZhbDogdGhlIHByZWNvbXBpbGVkIHZhbHVlCiAqCiAqIFByb2Nlc3NlcyBhbmQgcG9wcyB0aGUgaGlzdG9yeSBpdGVtcyBvZiB0aGUgSURDIHN0YXRlIG9iamVjdHMuCiAqIElEQyBrZXktc2VxdWVuY2VzIGFyZSB2YWxpZGF0ZWQvY3JlYXRlZCBvbiBJREMgYmluZGluZ3MuCiAqIAogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICBpbnQgZGVwdGgpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bywgbmV4dHN0bzsKICAgIGludCByZXMsIG1hdGNoRGVwdGg7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSB2Y3R4dC0+aW5vZGUtPnR5cGVEZWYsIHNpbXBsZVR5cGUgPSBOVUxMOwoKICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CgojaWZkZWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IEJBQ0sgb24gJXMsIGRlcHRoICVkXG4iLAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSwgdmN0eHQtPmRlcHRoKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYgICAgCiAgICAvKgogICAgKiBFdmFsdWF0ZSB0aGUgc3RhdGUgb2JqZWN0cy4KICAgICovCiAgICB3aGlsZSAoc3RvICE9IE5VTEwpIHsKCXJlcyA9IHhtbFN0cmVhbVBvcCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQpOwoJaWYgKHJlcyA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkiLAoJCSJjYWxsaW5nIHhtbFN0cmVhbVBvcCgpIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiNpZmRlZiBERUJVR19JREMKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIHN0cmVhbSBwb3AgJyVzJ1xuIiwKCSAgICBzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCWlmIChzdG8tPm5iSGlzdG9yeSA9PSAwKQoJICAgIGdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCgltYXRjaERlcHRoID0gc3RvLT5oaXN0b3J5W3N0by0+bmJIaXN0b3J5IC0xXTsKCgkvKgoJKiBPbmx5IG1hdGNoZXMgYXQgdGhlIGN1cnJlbnQgZGVwdGggYXJlIG9mIGludGVyZXN0LgoJKi8KCWlmIChtYXRjaERlcHRoICE9IGRlcHRoKSB7CgkgICAgc3RvID0gc3RvLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQkKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSB7CgkgICAgLyoKCSAgICAqIE5PVEU6IEFjY29yZGluZyB0bwoJICAgICogICBodHRwOi8vd3d3LnczLm9yZy9CdWdzL1B1YmxpYy9zaG93X2J1Zy5jZ2k/aWQ9MjE5OAoJICAgICogICAuLi4gdGhlIHNpbXBsZS1jb250ZW50IG9mIGNvbXBsZXggdHlwZXMgaXMgYWxzbyBhbGxvd2VkLgoJICAgICovCgkgICAgCgkgICAgaWYgKFdYU19JU19DT01QTEVYKHR5cGUpKSB7CgkJaWYgKFdYU19IQVNfU0lNUExFX0NPTlRFTlQodHlwZSkpIHsKCQkgICAgLyoKCQkgICAgKiBTYW5pdHkgY2hlY2sgZm9yIGNvbXBsZXggdHlwZXMgd2l0aCBzaW1wbGUgY29udGVudC4KCQkgICAgKi8KCQkgICAgc2ltcGxlVHlwZSA9IHR5cGUtPmNvbnRlbnRUeXBlRGVmOwoJCSAgICBpZiAoc2ltcGxlVHlwZSA9PSBOVUxMKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkiLAoJCQkgICAgImZpZWxkIHJlc29sdmVzIHRvIGEgQ1Qgd2l0aCBzaW1wbGUgY29udGVudCAiCgkJCSAgICAiYnV0IHRoZSBDVCBpcyBtaXNzaW5nIHRoZSBTVCBkZWZpbml0aW9uIik7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfSBlbHNlCgkJICAgIHNpbXBsZVR5cGUgPSBOVUxMOwoJICAgIH0gZWxzZSAKCQlzaW1wbGVUeXBlID0gdHlwZTsKCSAgICBpZiAoc2ltcGxlVHlwZSA9PSBOVUxMKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQoJCS8qCgkJKiBOb3QgcXVhbGlmaWVkIGlmIHRoZSBmaWVsZCByZXNvbHZlcyB0byBhIG5vZGUgb2Ygbm9uCgkJKiBzaW1wbGUgdHlwZS4KCQkqLwkKCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0lEQywgTlVMTCwJCSAgICAKCQkgICAgV1hTX0JBU0lDX0NBU1Qgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYsCgkJICAgICJUaGUgWFBhdGggJyVzJyBvZiBhIGZpZWxkIG9mICVzIGRvZXMgZXZhbHVhdGUgdG8gYSBub2RlIG9mICIKCQkgICAgIm5vbi1zaW1wbGUgdHlwZSIsCgkJICAgIHN0by0+c2VsLT54cGF0aCwKCQkgICAgeG1sU2NoZW1hR2V0SURDRGVzaWduYXRpb24oJnN0ciwgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYpKTsKCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJc3RvLT5uYkhpc3RvcnktLTsKCQlnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgkgICAgfQoJICAgIAoJICAgIGlmICgoa2V5ID09IE5VTEwpICYmICh2Y3R4dC0+aW5vZGUtPnZhbCA9PSBOVUxMKSkgewoJCS8qCgkJKiBGYWlsZWQgdG8gcHJvdmlkZSB0aGUgbm9ybWFsaXplZCB2YWx1ZTsgbWF5YmUKCQkqIHRoZSB2YWx1ZSB3YXMgaW52YWxpZC4KCQkqLwoJCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfSURDLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCBzdG8tPm1hdGNoZXItPmFpZGMtPmRlZiwKCQkgICAgIldhcm5pbmc6IE5vIHByZWNvbXB1dGVkIHZhbHVlIGF2YWlsYWJsZSwgdGhlIHZhbHVlICIKCQkgICAgIndhcyBlaXRoZXIgaW52YWxpZCBvciBzb21ldGhpbmcgc3RyYW5nZSBoYXBwZW5kIik7CgkJc3RvLT5uYkhpc3RvcnktLTsKCQlnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIgPSBzdG8tPm1hdGNoZXI7CgkJeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5U2VxOwoJCWludCBwb3MsIGlkeDsKCQkKCQkvKgoJCSogVGhlIGtleSB3aWxsIGJlIGFuY2hvcmVkIG9uIHRoZSBtYXRjaGVyJ3MgbGlzdCBvZgoJCSoga2V5LXNlcXVlbmNlcy4gVGhlIHBvc2l0aW9uIGluIHRoaXMgbGlzdCBpcyBkZXRlcm1pbmVkCgkJKiBieSB0aGUgdGFyZ2V0IG5vZGUncyBkZXB0aCByZWxhdGl2ZSB0byB0aGUgbWF0Y2hlcidzCgkJKiBkZXB0aCBvZiBjcmVhdGlvbiAoaS5lLiB0aGUgZGVwdGggb2YgdGhlIHNjb3BlIGVsZW1lbnQpLgoJCSogCgkJKiBFbGVtZW50ICAgICAgICBEZXB0aCAgICBQb3MgICBMaXN0LWVudHJpZXMKCQkqIDxzY29wZT4gICAgICAgICAgMCAgICAgICAgICAgICAgTlVMTAoJCSogICA8YmFyPiAgICAgICAgICAxICAgICAgICAgICAgICBOVUxMCgkJKiAgICAgPHRhcmdldC8+ICAgIDIgICAgICAgMiAgICAgIHRhcmdldAoJCSogICA8YmFyPgogICAgICAgICAgICAgICAgKiA8L3Njb3BlPgoJCSoKCQkqIFRoZSBzaXplIG9mIHRoZSBsaXN0IGlzIG9ubHkgZGVwZW5kYW50IG9uIHRoZSBkZXB0aCBvZgoJCSogdGhlIHRyZWUuCgkJKiBBbiBlbnRyeSB3aWxsIGJlIE5VTExlZCBpbiBzZWxlY3Rvcl9sZWF2ZSwgaS5lLiB3aGVuCgkJKiB3ZSBoaXQgdGhlIHRhcmdldCdzIAoJCSovCQkgICAgCgkJcG9zID0gc3RvLT5kZXB0aCAtIG1hdGNoZXItPmRlcHRoOwoJCWlkeCA9IHN0by0+c2VsLT5pbmRleDsKCQkKCQkvKgoJCSogQ3JlYXRlL2dyb3cgdGhlIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMuCgkJKi8KCQlpZiAobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB7CgkJICAgIGlmIChwb3MgPiA5KSAKCQkJbWF0Y2hlci0+c2l6ZUtleVNlcXMgPSBwb3MgKiAyOwoJCSAgICBlbHNlCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzID0gMTA7CgkJICAgIG1hdGNoZXItPmtleVNlcXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKikgCgkJCXhtbE1hbGxvYyhtYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsJCQkKCQkgICAgaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewkJCgkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkJICAgICJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybigtMSk7CgkJICAgIH0KCQkgICAgbWVtc2V0KG1hdGNoZXItPmtleVNlcXMsIDAsCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikpOwoJCX0gZWxzZSBpZiAocG9zID49IG1hdGNoZXItPnNpemVLZXlTZXFzKSB7CQoJCSAgICBpbnQgaSA9IG1hdGNoZXItPnNpemVLZXlTZXFzOwoJCSAgICAKCQkgICAgbWF0Y2hlci0+c2l6ZUtleVNlcXMgKj0gMjsKCQkgICAgbWF0Y2hlci0+a2V5U2VxcyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqKQoJCQl4bWxSZWFsbG9jKG1hdGNoZXItPmtleVNlcXMsCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikpOwoJCSAgICBpZiAobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkJICAgICJyZWFsbG9jYXRpbmcgYW4gYXJyYXkgb2Yga2V5LXNlcXVlbmNlcyIsCgkJCSAgICBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBUaGUgYXJyYXkgbmVlZHMgdG8gYmUgTlVMTGVkLgoJCSAgICAqIFRPRE86IFVzZSBtZW1zZXQ/CgkJICAgICovCgkJICAgIGZvciAoOyBpIDwgbWF0Y2hlci0+c2l6ZUtleVNlcXM7IGkrKykgCgkJCW1hdGNoZXItPmtleVNlcXNbaV0gPSBOVUxMOwkJCQoJCX0KCQkKCQkvKgoJCSogR2V0L2NyZWF0ZSB0aGUga2V5LXNlcXVlbmNlLgoJCSovCgkJa2V5U2VxID0gbWF0Y2hlci0+a2V5U2Vxc1twb3NdOwkJICAgIAoJCWlmIChrZXlTZXEgPT0gTlVMTCkgewkKCQkgICAgZ290byBjcmVhdGVfc2VxdWVuY2U7CgkJfSBlbHNlIGlmIChrZXlTZXFbaWR4XSAhPSBOVUxMKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQ6CgkJICAgICogMyBGb3IgZWFjaCBub2RlIGluIHRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbGwKCQkgICAgKiBvZiB0aGUge2ZpZWxkc30sIHdpdGggdGhhdCBub2RlIGFzIHRoZSBjb250ZXh0CgkJICAgICogbm9kZSwgZXZhbHVhdGUgdG8gZWl0aGVyIGFuIGVtcHR5IG5vZGUtc2V0IG9yCgkJICAgICogYSBub2RlLXNldCB3aXRoIGV4YWN0bHkgb25lIG1lbWJlciwgd2hpY2ggbXVzdAoJCSAgICAqIGhhdmUgYSBzaW1wbGUgdHlwZS4KCQkgICAgKiAKCQkgICAgKiBUaGUga2V5IHdhcyBhbHJlYWR5IHNldDsgcmVwb3J0IGFuIGVycm9yLgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJCVdYU19CQVNJQ19DQVNUIG1hdGNoZXItPmFpZGMtPmRlZiwKCQkJIlRoZSBYUGF0aCAnJXMnIG9mIGEgZmllbGQgb2YgJXMgZXZhbHVhdGVzIHRvIGEgIgoJCQkibm9kZS1zZXQgd2l0aCBtb3JlIHRoYW4gb25lIG1lbWJlciIsCgkJCXN0by0+c2VsLT54cGF0aCwKCQkJeG1sU2NoZW1hR2V0SURDRGVzaWduYXRpb24oJnN0ciwgbWF0Y2hlci0+YWlkYy0+ZGVmKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCQkgICAgc3RvLT5uYkhpc3RvcnktLTsKCQkgICAgZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJCX0gZWxzZQoJCSAgICBnb3RvIGNyZWF0ZV9rZXk7CQkKCQkKY3JlYXRlX3NlcXVlbmNlOgoJCS8qCgkJKiBDcmVhdGUgYSBrZXktc2VxdWVuY2UuCgkJKi8KCQlrZXlTZXEgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSB4bWxNYWxsb2MoCgkJICAgIG1hdGNoZXItPmFpZGMtPmRlZi0+bmJGaWVsZHMgKiAKCQkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCQlpZiAoa2V5U2VxID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkJImFsbG9jYXRpbmcgYW4gSURDIGtleS1zZXF1ZW5jZSIsIE5VTEwpOwoJCSAgICByZXR1cm4oLTEpOwkJCQoJCX0JCgkJbWVtc2V0KGtleVNlcSwgMCwgbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkcyAqIAoJCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJCW1hdGNoZXItPmtleVNlcXNbcG9zXSA9IGtleVNlcTsKY3JlYXRlX2tleToKCQkvKgoJCSogQ3JlYXRlIGEga2V5IG9uY2UgcGVyIG5vZGUgb25seS4KCQkqLyAgCgkJaWYgKGtleSA9PSBOVUxMKSB7CgkJICAgIGtleSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSB4bWxNYWxsb2MoCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5KSk7CgkJICAgIGlmIChrZXkgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhIElEQyBrZXkiLCBOVUxMKTsKCQkJeG1sRnJlZShrZXlTZXEpOwoJCQltYXRjaGVyLT5rZXlTZXFzW3Bvc10gPSBOVUxMOwoJCQlyZXR1cm4oLTEpOwkJCQoJCSAgICB9CgkJICAgIC8qCgkJICAgICogQ29uc3VtZSB0aGUgY29tcGlsZWQgdmFsdWUuCgkJICAgICovCgkJICAgIGtleS0+dHlwZSA9IHNpbXBsZVR5cGU7CgkJICAgIGtleS0+dmFsID0gdmN0eHQtPmlub2RlLT52YWw7CgkJICAgIHZjdHh0LT5pbm9kZS0+dmFsID0gTlVMTDsKCQkgICAgLyoKCQkgICAgKiBTdG9yZSB0aGUga2V5IGluIGEgZ2xvYmFsIGxpc3QuCgkJICAgICovCgkJICAgIGlmICh4bWxTY2hlbWFJRENTdG9yZUtleSh2Y3R4dCwga2V5KSA9PSAtMSkgewoJCQl4bWxTY2hlbWFJRENGcmVlS2V5KGtleSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfQoJCWtleVNlcVtpZHhdID0ga2V5OwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikgewoJCQoJICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiprZXlTZXEgPSBOVUxMOwoJICAgIC8qIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7ICovCgkgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbnRJdGVtOwoJICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcjsKCSAgICB4bWxTY2hlbWFJRENQdHIgaWRjOwoJICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHRhcmdldHM7CgkgICAgaW50IHBvcywgaSwgaiwgbmJLZXlzOwoJICAgIC8qCgkgICAgKiBIZXJlIHdlIGhhdmUgdGhlIGZvbGxvd2luZyBzY2VuYXJpbzoKCSAgICAqIEFuIElEQyAnc2VsZWN0b3InIHN0YXRlIG9iamVjdCByZXNvbHZlZCB0byBhIHRhcmdldCBub2RlLAoJICAgICogZHVyaW5nIHRoZSB0aW1lIHRoaXMgdGFyZ2V0IG5vZGUgd2FzIGluIHRoZSAKCSAgICAqIGFuY2VzdG9yLW9yLXNlbGYgYXhpcywgdGhlICdmaWVsZCcgc3RhdGUgb2JqZWN0KHMpIGxvb2tlZCAKCSAgICAqIG91dCBmb3IgbWF0Y2hpbmcgbm9kZXMgdG8gY3JlYXRlIGEga2V5LXNlcXVlbmNlIGZvciB0aGlzIAoJICAgICogdGFyZ2V0IG5vZGUuIE5vdyB3ZSBhcmUgYmFjayB0byB0aGlzIHRhcmdldCBub2RlIGFuZCBuZWVkCgkgICAgKiB0byBwdXQgdGhlIGtleS1zZXF1ZW5jZSwgdG9nZXRoZXIgd2l0aCB0aGUgdGFyZ2V0IG5vZGUgCgkgICAgKiBpdHNlbGYsIGludG8gdGhlIG5vZGUtdGFibGUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgSURDIAoJICAgICogYmluZGluZy4KCSAgICAqLwoJICAgIG1hdGNoZXIgPSBzdG8tPm1hdGNoZXI7CgkgICAgaWRjID0gbWF0Y2hlci0+YWlkYy0+ZGVmOwoJICAgIG5iS2V5cyA9IGlkYy0+bmJGaWVsZHM7CgkgICAgcG9zID0gZGVwdGggLSBtYXRjaGVyLT5kZXB0aDsJCQoJICAgIC8qCgkgICAgKiBDaGVjayBpZiB0aGUgbWF0Y2hlciBoYXMgYW55IGtleS1zZXF1ZW5jZXMgYXQgYWxsLCBwbHVzCgkgICAgKiBpZiBpdCBoYXMgYSBrZXktc2VxdWVuY2UgZm9yIHRoZSBjdXJyZW50IHRhcmdldCBub2RlLgoJICAgICovCQkKCSAgICBpZiAoKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgfHwKCQkobWF0Y2hlci0+c2l6ZUtleVNlcXMgPD0gcG9zKSkgewoJCWlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVkpCgkJICAgIGdvdG8gc2VsZWN0b3Jfa2V5X2Vycm9yOwoJCWVsc2UKCQkgICAgZ290byBzZWxlY3Rvcl9sZWF2ZTsKCSAgICB9CgkgICAgCgkgICAga2V5U2VxID0gJihtYXRjaGVyLT5rZXlTZXFzW3Bvc10pOwkJCgkgICAgaWYgKCprZXlTZXEgPT0gTlVMTCkgewoJCWlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVkpCgkJICAgIGdvdG8gc2VsZWN0b3Jfa2V5X2Vycm9yOwoJCWVsc2UKCQkgICAgZ290byBzZWxlY3Rvcl9sZWF2ZTsKCSAgICB9CgkgICAgCgkgICAgZm9yIChpID0gMDsgaSA8IG5iS2V5czsgaSsrKSB7CgkJaWYgKCgqa2V5U2VxKVtpXSA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogTm90IHF1YWxpZmllZCwgaWYgbm90IGFsbCBmaWVsZHMgZGlkIHJlc29sdmUuCgkJICAgICovCgkJICAgIGlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVkpIHsKCQkJLyoKCQkJKiBBbGwgZmllbGRzIG9mIGEgImtleSIgSURDIG11c3QgcmVzb2x2ZS4KCQkJKi8KCQkJZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJICAgIH0JCSAgICAKCQkgICAgZ290byBzZWxlY3Rvcl9sZWF2ZTsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBBbGwgZmllbGRzIGRpZCByZXNvbHZlLgoJICAgICovCgkgICAgCgkgICAgLyoKCSAgICAqIDQuMSBJZiB0aGUge2lkZW50aXR5LWNvbnN0cmFpbnQgY2F0ZWdvcnl9IGlzIHVuaXF1ZSgva2V5KSwKCSAgICAqIHRoZW4gbm8gdHdvIG1lbWJlcnMgb2YgdGhlILdxdWFsaWZpZWQgbm9kZSBzZXS3IGhhdmUKCSAgICAqILdrZXktc2VxdWVuY2VztyB3aG9zZSBtZW1iZXJzIGFyZSBwYWlyd2lzZSBlcXVhbCwgYXMKCSAgICAqIGRlZmluZWQgYnkgRXF1YWwgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgoJICAgICoKCSAgICAqIEdldCB0aGUgSURDIGJpbmRpbmcgZnJvbSB0aGUgbWF0Y2hlciBhbmQgY2hlY2sgZm9yCgkgICAgKiBkdXBsaWNhdGUga2V5LXNlcXVlbmNlcy4KCSAgICAqLwojaWYgMAoJICAgIGJpbmQgPSB4bWxTY2hlbWFJRENBY3F1aXJlQmluZGluZyh2Y3R4dCwgbWF0Y2hlcik7CiNlbmRpZgoJICAgIHRhcmdldHMgPSB4bWxTY2hlbWFJRENBY3F1aXJlVGFyZ2V0TGlzdCh2Y3R4dCwgbWF0Y2hlcik7CgkgICAgaWYgKChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpICYmIAoJCSh0YXJnZXRzLT5uYkl0ZW1zICE9IDApKSB7CgkJeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBja2V5LCBia2V5LCAqYmtleVNlcTsKCQkKCQlpID0gMDsKCQlyZXMgPSAwOwoJCS8qCgkJKiBDb21wYXJlIHRoZSBrZXktc2VxdWVuY2VzLCBrZXkgYnkga2V5LgoJCSovCgkJZG8gewoJCSAgICBia2V5U2VxID0KCQkJKCh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgdGFyZ2V0cy0+aXRlbXNbaV0pLT5rZXlzOwoJCSAgICBmb3IgKGogPSAwOyBqIDwgbmJLZXlzOyBqKyspIHsKCQkJY2tleSA9ICgqa2V5U2VxKVtqXTsKCQkJYmtleSA9IGJrZXlTZXFbal07CQkJCQkJCQoJCQlyZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChja2V5LT52YWwsIGJrZXktPnZhbCk7CgkJCWlmIChyZXMgPT0gLTEpIHsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9IGVsc2UgaWYgKHJlcyA9PSAwKSB7CgkJCSAgICAvKgoJCQkgICAgKiBPbmUgb2YgdGhlIGtleXMgZGlmZmVycywgc28gdGhlIGtleS1zZXF1ZW5jZQoJCQkgICAgKiB3b24ndCBiZSBlcXVhbDsgZ2V0IG91dC4KCQkJICAgICovCgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJICAgIGlmIChyZXMgPT0gMSkgewoJCQkvKgoJCQkqIER1cGxpY2F0ZSBrZXktc2VxdWVuY2UgZm91bmQuCgkJCSovCgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGkrKzsKCQl9IHdoaWxlIChpIDwgdGFyZ2V0cy0+bmJJdGVtcyk7CgkJaWYgKGkgIT0gdGFyZ2V0cy0+bmJJdGVtcykgewoJCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgkJICAgIC8qICAgCgkJICAgICogVE9ETzogVHJ5IHRvIHJlcG9ydCB0aGUga2V5LXNlcXVlbmNlLgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJCVdYU19CQVNJQ19DQVNUIGlkYywKCQkJIkR1cGxpY2F0ZSBrZXktc2VxdWVuY2UgJXMgaW4gJXMiLAoJCQl4bWxTY2hlbWFGb3JtYXRJRENLZXlTZXF1ZW5jZSh2Y3R4dCwgJnN0ciwKCQkJICAgICgqa2V5U2VxKSwgbmJLZXlzKSwKCQkJeG1sU2NoZW1hR2V0SURDRGVzaWduYXRpb24oJnN0ckIsIGlkYykpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQik7CgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogQWRkIGEgbm9kZS10YWJsZSBpdGVtIHRvIHRoZSBJREMgYmluZGluZy4KCSAgICAqLwoJICAgIG50SXRlbSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgeG1sTWFsbG9jKAoJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZSkpOwoJICAgIGlmIChudEl0ZW0gPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIElEQyBub2RlLXRhYmxlIGl0ZW0iLCBOVUxMKTsKCQl4bWxGcmVlKCprZXlTZXEpOwoJCSprZXlTZXEgPSBOVUxMOwoJCXJldHVybigtMSk7CgkgICAgfQkKCSAgICBtZW1zZXQobnRJdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGUpKTsKCSAgICAKCSAgICAvKiAKCSAgICAqIFN0b3JlIHRoZSBub2RlLXRhYmxlIGl0ZW0gaW4gYSBnbG9iYWwgbGlzdC4KCSAgICAqLwoJICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCQlpZiAoeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtKHZjdHh0LCBudEl0ZW0pID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQludEl0ZW0tPm5vZGVRTmFtZUlEID0gLTE7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU2F2ZSBhIGNhY2hlZCBRTmFtZSBmb3IgdGhpcyBub2RlIG9uIHRoZSBJREMgbm9kZSwgdG8gYmUKCQkqIGFibGUgdG8gcmVwb3J0IGl0LCBldmVuIGlmIHRoZSBub2RlIGlzIG5vdCBzYXZlZC4KCQkqLwoJCW50SXRlbS0+bm9kZVFOYW1lSUQgPSB4bWxTY2hlbWFWQWRkTm9kZVFOYW1lKHZjdHh0LAoJCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoJCWlmIChudEl0ZW0tPm5vZGVRTmFtZUlEID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwkJICAgIAoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEluaXQgdGhlIG5vZGUtdGFibGUgaXRlbTogU2F2ZSB0aGUgbm9kZSwgcG9zaXRpb24gYW5kCgkgICAgKiBjb25zdW1lIHRoZSBrZXktc2VxdWVuY2UuCgkgICAgKi8KCSAgICBudEl0ZW0tPm5vZGUgPSB2Y3R4dC0+bm9kZTsKCSAgICBudEl0ZW0tPm5vZGVMaW5lID0gdmN0eHQtPmlub2RlLT5ub2RlTGluZTsKCSAgICBudEl0ZW0tPmtleXMgPSAqa2V5U2VxOwoJICAgICprZXlTZXEgPSBOVUxMOwojaWYgMAoJICAgIGlmICh4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtKGJpbmQsIG50SXRlbSkgPT0gLTEpIHsKI2VuZGlmCgkgICAgaWYgKHhtbFNjaGVtYUl0ZW1MaXN0QWRkKHRhcmdldHMsIG50SXRlbSkgPT0gLTEpIHsKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkJICAgIC8qIAoJCSAgICAqIEZyZWUgdGhlIGl0ZW0sIHNpbmNlIGtleXJlZiBpdGVtcyB3b24ndCBiZQoJCSAgICAqIHB1dCBvbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICB4bWxGcmVlKG50SXRlbS0+a2V5cyk7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQl9CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIAoJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CnNlbGVjdG9yX2tleV9lcnJvcjoKCSAgICB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkvKgoJCSogNC4yLjEgKEtFWSkgVGhlILd0YXJnZXQgbm9kZSBzZXS3IGFuZCB0aGUgCgkJKiC3cXVhbGlmaWVkIG5vZGUgc2V0tyBhcmUgZXF1YWwsIHRoYXQgaXMsIGV2ZXJ5IAoJCSogbWVtYmVyIG9mIHRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBpcyBhbHNvIGEgbWVtYmVyCgkJKiBvZiB0aGUgt3F1YWxpZmllZCBub2RlIHNldLcgYW5kIHZpY2UgdmVyc2EuCgkJKi8KCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJICAgIFdYU19CQVNJQ19DQVNUIGlkYywKCQkgICAgIk5vdCBhbGwgZmllbGRzIG9mICVzIGV2YWx1YXRlIHRvIGEgbm9kZSIsCgkJICAgIHhtbFNjaGVtYUdldElEQ0Rlc2lnbmF0aW9uKCZzdHIsIGlkYyksIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICB9CnNlbGVjdG9yX2xlYXZlOgoJICAgIC8qCgkgICAgKiBGcmVlIHRoZSBrZXktc2VxdWVuY2UgaWYgbm90IGFkZGVkIHRvIHRoZSBJREMgdGFibGUuCgkgICAgKi8KCSAgICBpZiAoKGtleVNlcSAhPSBOVUxMKSAmJiAoKmtleVNlcSAhPSBOVUxMKSkgewoJCXhtbEZyZWUoKmtleVNlcSk7CgkJKmtleVNlcSA9IE5VTEw7CgkgICAgfQoJfSAvKiBpZiBzZWxlY3RvciAqLwoJCglzdG8tPm5iSGlzdG9yeS0tOwoKZGVyZWdpc3Rlcl9jaGVjazoKCS8qCgkqIERlcmVnaXN0ZXIgc3RhdGUgb2JqZWN0cyBpZiB0aGV5IHJlYWNoIHRoZSBkZXB0aCBvZiBjcmVhdGlvbi4KCSovCglpZiAoKHN0by0+bmJIaXN0b3J5ID09IDApICYmIChzdG8tPmRlcHRoID09IGRlcHRoKSkgewojaWZkZWYgREVCVUdfSURDCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgU1RPIHBvcCAnJXMnXG4iLAoJCXN0by0+c2VsLT54cGF0aCk7CiNlbmRpZgoJICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gc3RvKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSIsCgkJICAgICJUaGUgc3RhdGUgb2JqZWN0IHRvIGJlIHJlbW92ZWQgaXMgbm90IHRoZSBmaXJzdCAiCgkJICAgICJpbiB0aGUgbGlzdCIpOwoJICAgIH0KCSAgICBuZXh0c3RvID0gc3RvLT5uZXh0OwoJICAgIC8qCgkgICAgKiBVbmxpbmsgZnJvbSB0aGUgbGlzdCBvZiBhY3RpdmUgWFBhdGggc3RhdGUgb2JqZWN0cy4KCSAgICAqLwoJICAgIHZjdHh0LT54cGF0aFN0YXRlcyA9IHN0by0+bmV4dDsKCSAgICBzdG8tPm5leHQgPSB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2w7CgkgICAgLyoKCSAgICAqIExpbmsgaXQgdG8gdGhlIHBvb2wgb2YgcmV1c2FibGUgc3RhdGUgb2JqZWN0cy4KCSAgICAqLwoJICAgIHZjdHh0LT54cGF0aFN0YXRlUG9vbCA9IHN0bzsJICAgIAoJICAgIHN0byA9IG5leHRzdG87Cgl9IGVsc2UKCSAgICBzdG8gPSBzdG8tPm5leHQ7CiAgICB9IC8qIHdoaWxlIChzdG8gIT0gTlVMTCkgKi8KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtRGVjbDogdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24KICoKICogQ3JlYXRlcyBoZWxwZXIgb2JqZWN0cyB0byBldmFsdWF0ZSBJREMgc2VsZWN0b3JzL2ZpZWxkcwogKiBzdWNjZXNzaXZlbHkuCiAqCiAqIFJldHVybnMgMCBpZiBPSyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIsIGxhc3QgPSBOVUxMOwogICAgeG1sU2NoZW1hSURDUHRyIGlkYywgcmVmSWRjOwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7CiAgICAgICAgCiAgICBpZGMgPSAoeG1sU2NoZW1hSURDUHRyKSBlbGVtRGVjbC0+aWRjczsKICAgIGlmIChpZGMgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICAKI2lmZGVmIERFQlVHX0lEQwogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAKCSAgICAiSURDOiBSRUdJU1RFUiBvbiAlcywgZGVwdGggJWRcbiIsCgkgICAgKGNoYXIgKikgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgdmN0eHQtPmlub2RlLT5uc05hbWUsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUpLCB2Y3R4dC0+ZGVwdGgpOwoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9CiNlbmRpZgogICAgaWYgKHZjdHh0LT5pbm9kZS0+aWRjTWF0Y2hlcnMgIT0gTlVMTCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyIsCgkgICAgIlRoZSBjaGFpbiBvZiBJREMgbWF0Y2hlcnMgaXMgZXhwZWN0ZWQgdG8gYmUgZW1wdHkiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgZG8gewoJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIC8qCgkgICAgKiBTaW5jZSBJRENzIGJ1YmJsZXMgYXJlIGV4cGVuc2l2ZSB3ZSBuZWVkIHRvIGtub3cgdGhlCgkgICAgKiBkZXB0aCBhdCB3aGljaCB0aGUgYnViYmxlcyBzaG91bGQgc3RvcDsgdGhpcyB3aWxsIGJlCgkgICAgKiB0aGUgZGVwdGggb2YgdGhlIHRvcC1tb3N0IGtleXJlZiBJREMuIElmIG5vIGtleXJlZgoJICAgICogcmVmZXJlbmNlcyBhIGtleS91bmlxdWUgSURDLCB0aGUga2V5cmVmRGVwdGggd2lsbAoJICAgICogYmUgLTEsIGluZGljYXRpbmcgdGhhdCBubyBidWJibGVzIGFyZSBuZWVkZWQuCgkgICAgKi8KCSAgICByZWZJZGMgPSAoeG1sU2NoZW1hSURDUHRyKSBpZGMtPnJlZi0+aXRlbTsKCSAgICBpZiAocmVmSWRjICE9IE5VTEwpIHsKCQkvKgoJCSogUmVtZW1iZXIgdGhhdCB3ZSBoYXZlIGtleXJlZnMgb24gdGhpcyBub2RlLgoJCSovCgkJdmN0eHQtPmlub2RlLT5oYXNLZXlyZWZzID0gMTsKCQkvKgoJCSogTG9va3VwIHRoZSByZWZlcmVuY2VkIGF1Z21lbnRlZCBJREMgaW5mby4KCQkqLwoJCWFpZGMgPSB2Y3R4dC0+YWlkY3M7CgkJd2hpbGUgKGFpZGMgIT0gTlVMTCkgewoJCSAgICBpZiAoYWlkYy0+ZGVmID09IHJlZklkYykKCQkJYnJlYWs7CgkJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJCX0KCQlpZiAoYWlkYyA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMiLAoJCQkiQ291bGQgbm90IGZpbmQgYW4gYXVnbWVudGVkIElEQyBpdGVtIGZvciBhbiBJREMgIgoJCQkiZGVmaW5pdGlvbiIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCQlpZiAoKGFpZGMtPmtleXJlZkRlcHRoID09IC0xKSB8fAoJCSAgICAodmN0eHQtPmRlcHRoIDwgYWlkYy0+a2V5cmVmRGVwdGgpKQoJCSAgICBhaWRjLT5rZXlyZWZEZXB0aCA9IHZjdHh0LT5kZXB0aDsKCSAgICB9Cgl9CgkvKgoJKiBMb29rdXAgdGhlIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgdGhlIElEQyBkZWZpbml0aW9uLgoJKi8KCWFpZGMgPSB2Y3R4dC0+YWlkY3M7Cgl3aGlsZSAoYWlkYyAhPSBOVUxMKSB7CgkgICAgaWYgKGFpZGMtPmRlZiA9PSBpZGMpCgkJYnJlYWs7CgkgICAgYWlkYyA9IGFpZGMtPm5leHQ7Cgl9CglpZiAoYWlkYyA9PSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyIsCgkJIkNvdWxkIG5vdCBmaW5kIGFuIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgYW4gSURDIGRlZmluaXRpb24iKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIENyZWF0ZSBhbiBJREMgbWF0Y2hlciBmb3IgZXZlcnkgSURDIGRlZmluaXRpb24uCgkqLwoJbWF0Y2hlciA9ICh4bWxTY2hlbWFJRENNYXRjaGVyUHRyKSAKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ01hdGNoZXIpKTsKCWlmIChtYXRjaGVyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiYWxsb2NhdGluZyBhbiBJREMgbWF0Y2hlciIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbWVtc2V0KG1hdGNoZXIsIDAsIHNpemVvZih4bWxTY2hlbWFJRENNYXRjaGVyKSk7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgIHZjdHh0LT5pbm9kZS0+aWRjTWF0Y2hlcnMgPSBtYXRjaGVyOwoJZWxzZQoJICAgIGxhc3QtPm5leHQgPSBtYXRjaGVyOwoJbGFzdCA9IG1hdGNoZXI7CgoJbWF0Y2hlci0+dHlwZSA9IElEQ19NQVRDSEVSOwoJbWF0Y2hlci0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CQoJbWF0Y2hlci0+YWlkYyA9IGFpZGM7CgltYXRjaGVyLT5pZGNUeXBlID0gYWlkYy0+ZGVmLT50eXBlOwojaWZkZWYgREVCVUdfSURDCQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgcmVnaXN0ZXIgbWF0Y2hlclxuIik7CiNlbmRpZiAKCS8qCgkqIEluaXQgdGhlIGF1dG9tYXRvbiBzdGF0ZSBvYmplY3QuIAoJKi8KCWlmICh4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh2Y3R4dCwgbWF0Y2hlciwgCgkgICAgaWRjLT5zZWxlY3RvciwgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKCglpZGMgPSBpZGMtPm5leHQ7CiAgICB9IHdoaWxlIChpZGMgIT0gTlVMTCk7CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ0ZpbGxOb2RlVGFibGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW0pCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7CiAgICBpbnQgcmVzLCBpLCBqLCBrLCBuYlRhcmdldHMsIG5iRmllbGRzLCBuYkR1cGxzLCBuYk5vZGVUYWJsZTsKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmtleXMsICpudGtleXM7CiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqdGFyZ2V0cywgKmR1cGxzOwogICAgCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIgPSBpZWxlbS0+aWRjTWF0Y2hlcnM7CiAgICAvKiB2Y3R4dC0+Y3JlYXRlSURDTm9kZVRhYmxlcyAqLwogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJLyoKCSogU2tpcCBrZXlyZWYgSURDcyBhbmQgZW1wdHkgSURDIHRhcmdldC1saXN0cy4KCSovCglpZiAoKG1hdGNoZXItPmFpZGMtPmRlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgfHwKCSAgICBXWFNfSUxJU1RfSVNfRU1QVFkobWF0Y2hlci0+dGFyZ2V0cykpCgl7CgkgICAgbWF0Y2hlciA9IG1hdGNoZXItPm5leHQ7CgkgICAgY29udGludWU7Cgl9CgkvKgoJKiBJZiB3ZSBfd2FudF8gdGhlIElEQyBub2RlLXRhYmxlIHRvIGJlIGNyZWF0ZWQgaW4gYW55IGNhc2UKCSogdGhlbiBkbyBzby4gT3RoZXJ3aXNlIGNyZWF0ZSB0aGVtIG9ubHkgaWYga2V5cmVmcyBuZWVkIHRoZW0uCgkqLwoJaWYgKCghIHZjdHh0LT5jcmVhdGVJRENOb2RlVGFibGVzKSAmJgoJICAgICgobWF0Y2hlci0+YWlkYy0+a2V5cmVmRGVwdGggPT0gLTEpIHx8CgkgICAgIChtYXRjaGVyLT5haWRjLT5rZXlyZWZEZXB0aCA+IHZjdHh0LT5kZXB0aCkpKQoJewoJICAgIG1hdGNoZXIgPSBtYXRjaGVyLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQoJLyoKCSogR2V0L2NyZWF0ZSB0aGUgSURDIGJpbmRpbmcgb24gdGhpcyBlbGVtZW50IGZvciB0aGUgSURDIGRlZmluaXRpb24uCgkqLwoJYmluZCA9IHhtbFNjaGVtYUlEQ0FjcXVpcmVCaW5kaW5nKHZjdHh0LCBtYXRjaGVyKTsKCglpZiAoISBXWFNfSUxJU1RfSVNfRU1QVFkoYmluZC0+ZHVwbHMpKSB7CgkgICAgZHVwbHMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgYmluZC0+ZHVwbHMtPml0ZW1zOwoJICAgIG5iRHVwbHMgPSBiaW5kLT5kdXBscy0+bmJJdGVtczsKCX0gZWxzZSB7CgkgICAgZHVwbHMgPSBOVUxMOwoJICAgIG5iRHVwbHMgPSAwOwkgICAgCgl9CglpZiAoYmluZC0+bm9kZVRhYmxlICE9IE5VTEwpIHsKCSAgICBuYk5vZGVUYWJsZSA9IGJpbmQtPm5iTm9kZXM7Cgl9IGVsc2UgewoJICAgIG5iTm9kZVRhYmxlID0gMDsKCX0KCglpZiAoKG5iTm9kZVRhYmxlID09IDApICYmIChuYkR1cGxzID09IDApKSB7CgkgICAgLyoKCSAgICAqIFRyYW5zZmVyIGFsbCBJREMgdGFyZ2V0LW5vZGVzIHRvIHRoZSBJREMgbm9kZS10YWJsZS4KCSAgICAqLwoJICAgIGJpbmQtPm5vZGVUYWJsZSA9CgkJKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIG1hdGNoZXItPnRhcmdldHMtPml0ZW1zOwkJCgkgICAgYmluZC0+c2l6ZU5vZGVzID0gbWF0Y2hlci0+dGFyZ2V0cy0+c2l6ZUl0ZW1zOwoJICAgIGJpbmQtPm5iTm9kZXMgPSBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zOwoKCSAgICBtYXRjaGVyLT50YXJnZXRzLT5pdGVtcyA9IE5VTEw7CgkgICAgbWF0Y2hlci0+dGFyZ2V0cy0+c2l6ZUl0ZW1zID0gMDsKCSAgICBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zID0gMDsJICAgIAoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogQ29tcGFyZSB0aGUga2V5LXNlcXVlbmNlcyBhbmQgYWRkIHRvIHRoZSBJREMgbm9kZS10YWJsZS4KCSAgICAqLwoJICAgIG5iVGFyZ2V0cyA9IG1hdGNoZXItPnRhcmdldHMtPm5iSXRlbXM7CgkgICAgdGFyZ2V0cyA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSBtYXRjaGVyLT50YXJnZXRzLT5pdGVtczsJCgkgICAgbmJGaWVsZHMgPSBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzOwoJICAgIGkgPSAwOwoJICAgIGRvIHsKCQlrZXlzID0gdGFyZ2V0c1tpXS0+a2V5czsKCQlpZiAobmJEdXBscykgewkJCQoJCSAgICAvKgoJCSAgICAqIFNlYXJjaCBpbiBhbHJlYWR5IGZvdW5kIGR1cGxpY2F0ZXMgZmlyc3QuCgkJICAgICovCgkJICAgIGogPSAwOwoJCSAgICBkbyB7CQkJCQkJCgkJCWlmIChuYkZpZWxkcyA9PSAxKSB7CgkJCSAgICByZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzWzBdLT52YWwsCgkJCQlkdXBsc1tqXS0+a2V5c1swXS0+dmFsKTsKCQkJICAgIGlmIChyZXMgPT0gLTEpCgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCQkvKgoJCQkJKiBFcXVhbCBrZXktc2VxdWVuY2UuCgkJCQkqLwoJCQkJZ290byBuZXh0X3RhcmdldDsKCQkJICAgIH0KCQkJfSBlbHNlIHsKCQkJICAgIHJlcyA9IDA7CgkJCSAgICBudGtleXMgPSBkdXBsc1tqXS0+a2V5czsKCQkJICAgIGZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCQlyZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzW2tdLT52YWwsCgkJCQkgICAgbnRrZXlzW2tdLT52YWwpOwoJCQkJaWYgKHJlcyA9PSAtMSkKCQkJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCQkJaWYgKHJlcyA9PSAwKSB7CgkJCQkgICAgLyoKCQkJCSAgICAqIE9uZSBvZiB0aGUga2V5cyBkaWZmZXJzLgoJCQkJICAgICovCgkJCQkgICAgYnJlYWs7CgkJCQl9CgkJCSAgICB9CgkJCSAgICBpZiAocmVzID09IDEpIHsKCQkJCS8qCgkJCQkqIEVxdWFsIGtleS1zZXF1ZW5jZSBmb3VuZC4KCQkJCSovCgkJCQlnb3RvIG5leHRfdGFyZ2V0OwoJCQkgICAgfQoJCQl9CgkJCWorKzsKCQkgICAgfSB3aGlsZSAoaiA8IG5iRHVwbHMpOwkJICAgIAoJCX0KCQlpZiAobmJOb2RlVGFibGUpIHsKCQkgICAgaiA9IDA7CgkJICAgIGRvIHsJCQkJCQkKCQkJaWYgKG5iRmllbGRzID09IDEpIHsKCQkJICAgIHJlcyA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGtleXNbMF0tPnZhbCwKCQkJCWJpbmQtPm5vZGVUYWJsZVtqXS0+a2V5c1swXS0+dmFsKTsKCQkJICAgIGlmIChyZXMgPT0gLTEpCgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgaWYgKHJlcyA9PSAwKSB7CgkJCQkvKgoJCQkJKiBUaGUga2V5LXNlcXVlbmNlIGRpZmZlcnMuCgkJCQkqLwoJCQkJZ290byBuZXh0X25vZGVfdGFibGVfZW50cnk7CgkJCSAgICB9CgkJCX0gZWxzZSB7CgkJCSAgICByZXMgPSAwOwoJCQkgICAgbnRrZXlzID0gYmluZC0+bm9kZVRhYmxlW2pdLT5rZXlzOwoJCQkgICAgZm9yIChrID0gMDsgayA8IG5iRmllbGRzOyBrKyspIHsKCQkJCXJlcyA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGtleXNba10tPnZhbCwKCQkJCSAgICBudGtleXNba10tPnZhbCk7CgkJCQlpZiAocmVzID09IC0xKQoJCQkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCQlpZiAocmVzID09IDApIHsKCQkJCSAgICAvKgoJCQkJICAgICogT25lIG9mIHRoZSBrZXlzIGRpZmZlcnMuCgkJCQkgICAgKi8KCQkJCSAgICBnb3RvIG5leHRfbm9kZV90YWJsZV9lbnRyeTsKCQkJCX0KCQkJICAgIH0KCQkJfQkJCQoJCQkvKgoJCQkqIEFkZCB0aGUgZHVwbGljYXRlIHRvIHRoZSBsaXN0IG9mIGR1cGxpY2F0ZXMuCgkJCSovCgkJCWlmIChiaW5kLT5kdXBscyA9PSBOVUxMKSB7CgkJCSAgICBiaW5kLT5kdXBscyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CgkJCSAgICBpZiAoYmluZC0+ZHVwbHMgPT0gTlVMTCkKCQkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCX0JCSAgICAKCQkJaWYgKHhtbFNjaGVtYUl0ZW1MaXN0QWRkKGJpbmQtPmR1cGxzLCBiaW5kLT5ub2RlVGFibGVbal0pID09IC0xKQoJCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJLyoKCQkJKiBSZW1vdmUgdGhlIGR1cGxpY2F0ZSBlbnRyeSBmcm9tIHRoZSBJREMgbm9kZS10YWJsZS4KCQkJKi8KCQkJYmluZC0+bm9kZVRhYmxlW2pdID0gYmluZC0+bm9kZVRhYmxlW2JpbmQtPm5iTm9kZXMgLTFdOwoJCQliaW5kLT5uYk5vZGVzLS07CgoJCQlnb3RvIG5leHRfdGFyZ2V0OwoKbmV4dF9ub2RlX3RhYmxlX2VudHJ5OgoJCQlqKys7CgkJICAgIH0gd2hpbGUgKGogPCBuYk5vZGVUYWJsZSk7CgkJfQoJCS8qCgkJKiBJZiBldmVyeXRoaW5nIGlzIGZpbmUsIHRoZW4gYWRkIHRoZSBJREMgdGFyZ2V0LW5vZGUgdG8KCQkqIHRoZSBJREMgbm9kZS10YWJsZS4KCQkqLwoJCWlmICh4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtKGJpbmQsIHRhcmdldHNbaV0pID09IC0xKQoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoKbmV4dF90YXJnZXQ6CgkJaSsrOwoJICAgIH0gd2hpbGUgKGkgPCBuYlRhcmdldHMpOwoJfQoJbWF0Y2hlciA9IG1hdGNoZXItPm5leHQ7CiAgICB9CiAgICByZXR1cm4oMCk7CgppbnRlcm5hbF9lcnJvcjoKICAgIHJldHVybigtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWJibGVJRENOb2RlVGFibGVzOiAKICogQGRlcHRoOiB0aGUgY3VycmVudCB0cmVlIGRlcHRoCiAqCiAqIE1lcmdlcyBJREMgYmluZGluZ3Mgb2YgYW4gZWxlbWVudCBhdCBAZGVwdGggaW50byB0aGUgY29ycmVzcG9uZGluZyBJREMgCiAqIGJpbmRpbmdzIG9mIGl0cyBwYXJlbnQgZWxlbWVudC4gSWYgYSBkdXBsaWNhdGUgbm90ZS10YWJsZSBlbnRyeSBpcyBmb3VuZCwgCiAqIGJvdGgsIHRoZSBwYXJlbnQgbm9kZS10YWJsZSBlbnRyeSBhbmQgY2hpbGQgZW50cnkgYXJlIGRpc2NhcmRlZCBmcm9tIHRoZSAKICogbm9kZS10YWJsZSBvZiB0aGUgcGFyZW50LgogKgogKiBSZXR1cm5zIDAgaWYgT0sgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7IC8qIElEQyBiaW5kaW5ncyBvZiB0aGUgY3VycmVudCBub2RlLiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgKnBhclRhYmxlLCBwYXJCaW5kID0gTlVMTDsgLyogcGFyZW50IElEQyBiaW5kaW5ncy4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG5vZGUsIHBhck5vZGUgPSBOVUxMLCAqZHVwbHMsICpwYXJOb2RlczsgLyogbm9kZS10YWJsZSBlbnRyaWVzLiAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7CiAgICBpbnQgaSwgaiwgaywgcmV0ID0gMCwgbmJGaWVsZHMsIG9sZE51bSwgb2xkRHVwbHM7CgogICAgYmluZCA9IHZjdHh0LT5pbm9kZS0+aWRjVGFibGU7ICAgICAgICAKICAgIGlmIChiaW5kID09IE5VTEwpIHsKCS8qIEZpbmUsIG5vIHRhYmxlLCBubyBidWJibGVzLiAqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIAogICAgcGFyVGFibGUgPSAmKHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoIC0xXS0+aWRjVGFibGUpOwogICAgLyoKICAgICogV2FsayBhbGwgYmluZGluZ3M7IGNyZWF0ZSBuZXcgb3IgYWRkIHRvIGV4aXN0aW5nIGJpbmRpbmdzLgogICAgKiBSZW1vdmUgZHVwbGljYXRlIGtleS1zZXF1ZW5jZXMuCiAgICAqLwogICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJCglpZiAoKGJpbmQtPm5iTm9kZXMgPT0gMCkgJiYgV1hTX0lMSVNUX0lTX0VNUFRZKGJpbmQtPmR1cGxzKSkKCSAgICBnb3RvIG5leHRfYmluZGluZzsKCS8qCgkqIENoZWNrIGlmIHRoZSBrZXkvdW5pcXVlIElEQyB0YWJsZSBuZWVkcyB0byBiZSBidWJibGVkLgoJKi8KCWlmICghIHZjdHh0LT5jcmVhdGVJRENOb2RlVGFibGVzKSB7CgkgICAgYWlkYyA9IHZjdHh0LT5haWRjczsKCSAgICBkbyB7CgkJaWYgKGFpZGMtPmRlZiA9PSBiaW5kLT5kZWZpbml0aW9uKSB7CgkJICAgIGlmICgoYWlkYy0+a2V5cmVmRGVwdGggPT0gLTEpIHx8IAoJCQkoYWlkYy0+a2V5cmVmRGVwdGggPj0gdmN0eHQtPmRlcHRoKSkgewoJCQlnb3RvIG5leHRfYmluZGluZzsKCQkgICAgfQoJCSAgICBicmVhazsKCQl9CgkJYWlkYyA9IGFpZGMtPm5leHQ7CgkgICAgfSB3aGlsZSAoYWlkYyAhPSBOVUxMKTsKCX0KCglpZiAocGFyVGFibGUgIT0gTlVMTCkKCSAgICBwYXJCaW5kID0gKnBhclRhYmxlOwoJLyoKCSogU2VhcmNoIGEgbWF0Y2hpbmcgcGFyZW50IGJpbmRpbmcgZm9yIHRoZQoJKiBJREMgZGVmaW5pdGlvbi4KCSovCgl3aGlsZSAocGFyQmluZCAhPSBOVUxMKSB7CSAgICAKCSAgICBpZiAocGFyQmluZC0+ZGVmaW5pdGlvbiA9PSBiaW5kLT5kZWZpbml0aW9uKQoJCWJyZWFrOwoJICAgIHBhckJpbmQgPSBwYXJCaW5kLT5uZXh0OwoJfQoKCWlmIChwYXJCaW5kICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogQ29tcGFyZSBldmVyeSBub2RlLXRhYmxlIGVudHJ5IG9mIHRoZSBjaGlsZCBub2RlLCAKCSAgICAqIGkuZS4gdGhlIGtleS1zZXF1ZW5jZSB3aXRoaW4sIC4uLgoJICAgICovCgkgICAgb2xkTnVtID0gcGFyQmluZC0+bmJOb2RlczsgLyogU2tpcCBuZXdseSBhZGRlZCBpdGVtcy4gKi8KCgkgICAgaWYgKCEgV1hTX0lMSVNUX0lTX0VNUFRZKHBhckJpbmQtPmR1cGxzKSkgewoJCW9sZER1cGxzID0gcGFyQmluZC0+ZHVwbHMtPm5iSXRlbXM7CgkJZHVwbHMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgcGFyQmluZC0+ZHVwbHMtPml0ZW1zOwoJICAgIH0gZWxzZSB7CgkJZHVwbHMgPSBOVUxMOwoJCW9sZER1cGxzID0gMDsJCQoJICAgIH0KCSAgICAKCSAgICBwYXJOb2RlcyA9IHBhckJpbmQtPm5vZGVUYWJsZTsKCSAgICBuYkZpZWxkcyA9IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOwoJICAgIAoJICAgIGZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQlub2RlID0gYmluZC0+bm9kZVRhYmxlW2ldOwoJCWlmIChub2RlID09IE5VTEwpCgkJICAgIGNvbnRpbnVlOwoJCS8qCgkJKiAuLi53aXRoIGV2ZXJ5IGtleS1zZXF1ZW5jZSBvZiB0aGUgcGFyZW50IG5vZGUsIGFscmVhZHkKCQkqIGV2YWx1YXRlZCB0byBiZSBhIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2UuCgkJKi8KCQlpZiAob2xkRHVwbHMpIHsKCQkgICAgaiA9IDA7IAoJCSAgICB3aGlsZSAoaiA8IG9sZER1cGxzKSB7CgkJCWlmIChuYkZpZWxkcyA9PSAxKSB7CgkJCSAgICByZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCgKCQkJCW5vZGUtPmtleXNbMF0tPnZhbCwKCQkJCWR1cGxzW2pdLT5rZXlzWzBdLT52YWwpOwoJCQkgICAgaWYgKHJldCA9PSAtMSkKCQkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCSAgICBpZiAocmV0ID09IDApIHsKCQkJCWorKzsKCQkJCWNvbnRpbnVlOwoJCQkgICAgfQoJCQl9IGVsc2UgewoJCQkgICAgcGFyTm9kZSA9IGR1cGxzW2pdOwoJCQkgICAgZm9yIChrID0gMDsgayA8IG5iRmllbGRzOyBrKyspIHsKCQkJCXJldCA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKAoJCQkJICAgIG5vZGUtPmtleXNba10tPnZhbCwKCQkJCSAgICBwYXJOb2RlLT5rZXlzW2tdLT52YWwpOwoJCQkJaWYgKHJldCA9PSAtMSkKCQkJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCQkJaWYgKHJldCA9PSAwKQoJCQkJICAgIGJyZWFrOwoJCQkgICAgfQoJCQl9CgkJCWlmIChyZXQgPT0gMSkKCQkJICAgIC8qIER1cGxpY2F0ZSBmb3VuZC4gKi8KCQkJICAgIGJyZWFrOwoJCQlqKys7CgkJICAgIH0KCQkgICAgaWYgKGogIT0gb2xkRHVwbHMpIHsKCQkJLyogRHVwbGljYXRlIGZvdW5kLiBTa2lwIHRoaXMgZW50cnkuICovCgkJCWNvbnRpbnVlOwoJCSAgICB9CgkJfQkJICAgIAoJCS8qCgkJKiAuLi4gYW5kIHdpdGggZXZlcnkga2V5LXNlcXVlbmNlIG9mIHRoZSBwYXJlbnQgbm9kZS4KCQkqLwoJCWlmIChvbGROdW0pIHsKCQkgICAgaiA9IDA7IAoJCSAgICB3aGlsZSAoaiA8IG9sZE51bSkgewoJCQlwYXJOb2RlID0gcGFyTm9kZXNbal07CgkJCWlmIChuYkZpZWxkcyA9PSAxKSB7CgkJCSAgICByZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCgKCQkJCW5vZGUtPmtleXNbMF0tPnZhbCwKCQkJCXBhck5vZGUtPmtleXNbMF0tPnZhbCk7CgkJCSAgICBpZiAocmV0ID09IC0xKQoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJICAgIGlmIChyZXQgPT0gMCkgewoJCQkJaisrOwoJCQkJY29udGludWU7CgkJCSAgICB9CgkJCX0gZWxzZSB7CQkJICAgIAoJCQkgICAgZm9yIChrID0gMDsgayA8IG5iRmllbGRzOyBrKyspIHsKCQkJCXJldCA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKAoJCQkJICAgIG5vZGUtPmtleXNba10tPnZhbCwKCQkJCSAgICBwYXJOb2RlLT5rZXlzW2tdLT52YWwpOwoJCQkJaWYgKHJldCA9PSAtMSkKCQkJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCQkJaWYgKHJldCA9PSAwKQoJCQkJICAgIGJyZWFrOwoJCQkgICAgfQoJCQl9CgkJCWlmIChyZXQgPT0gMSkKCQkJICAgIC8qIER1cGxpY2F0ZSBmb3VuZC4gKi8KCQkJICAgIGJyZWFrOwoJCQlqKys7CgkJICAgIH0KCQkgICAgaWYgKGogIT0gb2xkTnVtKSB7CgkJCS8qCgkJCSogSGFuZGxlIGR1cGxpY2F0ZXMuIE1vdmUgdGhlIGR1cGxpY2F0ZSBpbgoJCQkqIHRoZSBwYXJlbnQncyBub2RlLXRhYmxlIHRvIHRoZSBsaXN0IG9mCgkJCSogZHVwbGljYXRlcy4KCQkJKi8JCQkKCQkJb2xkTnVtLS07CgkJCXBhckJpbmQtPm5iTm9kZXMtLTsKCQkJLyoKCQkJKiBNb3ZlIGxhc3Qgb2xkIGl0ZW0gdG8gcG9zIG9mIGR1cGxpY2F0ZS4KCQkJKi8KCQkJcGFyTm9kZXNbal0gPSBwYXJOb2Rlc1tvbGROdW1dOwoJCQkKCQkJaWYgKHBhckJpbmQtPm5iTm9kZXMgIT0gb2xkTnVtKSB7CgkJCSAgICAvKgoJCQkgICAgKiBJZiBuZXcgaXRlbXMgZXhpc3QsIG1vdmUgbGFzdCBuZXcgaXRlbSB0byAKCQkJICAgICogbGFzdCBvZiBvbGQgaXRlbXMuCgkJCSAgICAqLwoJCQkgICAgcGFyTm9kZXNbb2xkTnVtXSA9IAoJCQkJcGFyTm9kZXNbcGFyQmluZC0+bmJOb2Rlc107CgkJCX0KCQkJaWYgKHBhckJpbmQtPmR1cGxzID09IE5VTEwpIHsKCQkJICAgIHBhckJpbmQtPmR1cGxzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCQkJICAgIGlmIChwYXJCaW5kLT5kdXBscyA9PSBOVUxMKQoJCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkJfQoJCQl4bWxTY2hlbWFJdGVtTGlzdEFkZChwYXJCaW5kLT5kdXBscywgcGFyTm9kZSk7CQkJCgkJICAgIH0gZWxzZSB7CgkJCS8qCgkJCSogQWRkIHRoZSBub2RlLXRhYmxlIGVudHJ5IChub2RlIGFuZCBrZXktc2VxdWVuY2UpIG9mIAoJCQkqIHRoZSBjaGlsZCBub2RlIHRvIHRoZSBub2RlIHRhYmxlIG9mIHRoZSBwYXJlbnQgbm9kZS4KCQkJKi8KCQkJaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CQkJCgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkJCQl4bWxNYWxsb2MoMTAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCQkJICAgIGlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkJCSAgICAiYWxsb2NhdGluZyBJREMgbGlzdCBvZiBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgfQoJCQkgICAgcGFyQmluZC0+c2l6ZU5vZGVzID0gMTsKCQkJfSBlbHNlIGlmIChwYXJCaW5kLT5uYk5vZGVzID49IHBhckJpbmQtPnNpemVOb2RlcykgewoJCQkgICAgcGFyQmluZC0+c2l6ZU5vZGVzICo9IDI7CgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkJCQl4bWxSZWFsbG9jKHBhckJpbmQtPm5vZGVUYWJsZSwgcGFyQmluZC0+c2l6ZU5vZGVzICogCgkJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCQkJICAgIGlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkJCSAgICAicmUtYWxsb2NhdGluZyBJREMgbGlzdCBvZiBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgfQkJCSAgICAKCQkJfQoJCQlwYXJOb2RlcyA9IHBhckJpbmQtPm5vZGVUYWJsZTsKCQkJLyoKCQkJKiBBcHBlbmQgdGhlIG5ldyBub2RlLXRhYmxlIGVudHJ5IHRvIHRoZSAnbmV3IG5vZGUtdGFibGUKCQkJKiBlbnRyaWVzJyBzZWN0aW9uLgoJCQkqLwoJCQlwYXJOb2Rlc1twYXJCaW5kLT5uYk5vZGVzKytdID0gbm9kZTsKCQkgICAgfQoKCQl9CQoJCQoJICAgIH0JCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBObyBiaW5kaW5nIGZvciB0aGUgSURDIHdhcyBmb3VuZDogY3JlYXRlIGEgbmV3IG9uZSBhbmQKCSAgICAqIGNvcHkgYWxsIG5vZGUtdGFibGVzLgoJICAgICovCgkgICAgcGFyQmluZCA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcoYmluZC0+ZGVmaW5pdGlvbik7CgkgICAgaWYgKHBhckJpbmQgPT0gTlVMTCkKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIAoJICAgIC8qCgkgICAgKiBUT0RPOiBIbW0sIGhvdyB0byBvcHRpbWl6ZSB0aGUgaW5pdGlhbCBudW1iZXIgb2YKCSAgICAqIGFsbG9jYXRlZCBlbnRyaWVzPwoJICAgICovCgkgICAgaWYgKGJpbmQtPm5iTm9kZXMgIT0gMCkgewoJCS8qCgkJKiBBZGQgYWxsIElEQyBub2RlLXRhYmxlIGVudHJpZXMuCgkJKi8KCQlpZiAoISB2Y3R4dC0+cHN2aUV4cG9zZUlEQ05vZGVUYWJsZXMpIHsKCQkgICAgLyoKCQkgICAgKiBKdXN0IG1vdmUgdGhlIGVudHJpZXMuCgkJICAgICogTk9URTogdGhpcyBpcyBxdWl0ZSBzYXZlIGhlcmUsIHNpbmNlCgkJICAgICogYWxsIHRoZSBrZXlyZWYgbG9va3VwcyBoYXZlIGFscmVhZHkgYmVlbgoJCSAgICAqIHBlcmZvcm1lZC4KCQkgICAgKi8KCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gYmluZC0+bm9kZVRhYmxlOwoJCSAgICBiaW5kLT5ub2RlVGFibGUgPSBOVUxMOwoJCSAgICBwYXJCaW5kLT5zaXplTm9kZXMgPSBiaW5kLT5zaXplTm9kZXM7CgkJICAgIGJpbmQtPnNpemVOb2RlcyA9IDA7CgkJICAgIHBhckJpbmQtPm5iTm9kZXMgPSBiaW5kLT5uYk5vZGVzOwoJCSAgICBiaW5kLT5uYk5vZGVzID0gMDsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqIENvcHkgdGhlIGVudHJpZXMuCgkJICAgICovCgkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQkJeG1sTWFsbG9jKGJpbmQtPm5iTm9kZXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCQkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCSAgICAiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSAiCgkJCSAgICAiaXRlbXMiLCBOVUxMKTsKCQkJeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcocGFyQmluZCk7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgcGFyQmluZC0+c2l6ZU5vZGVzID0gYmluZC0+bmJOb2RlczsKCQkgICAgcGFyQmluZC0+bmJOb2RlcyA9IGJpbmQtPm5iTm9kZXM7CgkJICAgIG1lbWNweShwYXJCaW5kLT5ub2RlVGFibGUsIGJpbmQtPm5vZGVUYWJsZSwKCQkJYmluZC0+bmJOb2RlcyAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJCX0KCSAgICB9CgkgICAgaWYgKGJpbmQtPmR1cGxzKSB7CgkJLyoKCQkqIE1vdmUgdGhlIGR1cGxpY2F0ZXMuCgkJKi8KCQlpZiAocGFyQmluZC0+ZHVwbHMgIT0gTlVMTCkKCQkgICAgeG1sU2NoZW1hSXRlbUxpc3RGcmVlKHBhckJpbmQtPmR1cGxzKTsKCQlwYXJCaW5kLT5kdXBscyA9IGJpbmQtPmR1cGxzOwoJCWJpbmQtPmR1cGxzID0gTlVMTDsJCQoJICAgIH0KCSAgICBpZiAoKnBhclRhYmxlID09IE5VTEwpCgkJKnBhclRhYmxlID0gcGFyQmluZDsKCSAgICBlbHNlIHsKCQlwYXJCaW5kLT5uZXh0ID0gKnBhclRhYmxlOwoJCSpwYXJUYWJsZSA9IHBhckJpbmQ7CgkgICAgfQkgICAKCX0JCgpuZXh0X2JpbmRpbmc6CgliaW5kID0gYmluZC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7CgppbnRlcm5hbF9lcnJvcjoKICAgIHJldHVybigtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZjoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbURlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqCiAqIENoZWNrIHRoZSBjdmMtaWRjLWtleXJlZiBjb25zdHJhaW50cy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWYoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOwogICAgCiAgICBtYXRjaGVyID0gdmN0eHQtPmlub2RlLT5pZGNNYXRjaGVyczsKICAgIC8qCiAgICAqIEZpbmQgYSBrZXlyZWYuCiAgICAqLwogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJaWYgKChtYXRjaGVyLT5pZGNUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSAmJgoJICAgIG1hdGNoZXItPnRhcmdldHMgJiYKCSAgICBtYXRjaGVyLT50YXJnZXRzLT5uYkl0ZW1zKQoJewoJICAgIGludCBpLCBqLCBrLCByZXMsIG5iRmllbGRzLCBoYXNEdXBsczsKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICpyZWZLZXlzLCAqa2V5czsKCSAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciByZWZOb2RlID0gTlVMTDsKCgkgICAgbmJGaWVsZHMgPSBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzOwoKCSAgICAvKgoJICAgICogRmluZCB0aGUgSURDIG5vZGUtdGFibGUgZm9yIHRoZSByZWZlcmVuY2VkIElEQyBrZXkvdW5pcXVlLgoJICAgICovCgkgICAgYmluZCA9IHZjdHh0LT5pbm9kZS0+aWRjVGFibGU7CgkgICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJCWlmICgoeG1sU2NoZW1hSURDUHRyKSBtYXRjaGVyLT5haWRjLT5kZWYtPnJlZi0+aXRlbSA9PSAKCQkgICAgYmluZC0+ZGVmaW5pdGlvbikKCQkgICAgYnJlYWs7CgkJYmluZCA9IGJpbmQtPm5leHQ7CgkgICAgfQoJICAgIGhhc0R1cGxzID0gKGJpbmQgJiYgYmluZC0+ZHVwbHMgJiYgYmluZC0+ZHVwbHMtPm5iSXRlbXMpID8gMSA6IDA7CgkgICAgLyoKCSAgICAqIFNlYXJjaCBmb3IgYSBtYXRjaGluZyBrZXktc2VxdWVuY2VzLgoJICAgICovCgkgICAgZm9yIChpID0gMDsgaSA8IG1hdGNoZXItPnRhcmdldHMtPm5iSXRlbXM7IGkrKykgewoJCXJlcyA9IDA7CgkJcmVmTm9kZSA9IG1hdGNoZXItPnRhcmdldHMtPml0ZW1zW2ldOwoJCWlmIChiaW5kICE9IE5VTEwpIHsKCQkgICAgcmVmS2V5cyA9IHJlZk5vZGUtPmtleXM7CgkJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5uYk5vZGVzOyBqKyspIHsKCQkJa2V5cyA9IGJpbmQtPm5vZGVUYWJsZVtqXS0+a2V5czsKCQkJZm9yIChrID0gMDsgayA8IG5iRmllbGRzOyBrKyspIHsKCQkJICAgIHJlcyA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGtleXNba10tPnZhbCwKCQkJCXJlZktleXNba10tPnZhbCk7CgkJCSAgICBpZiAocmVzID09IDApCgkJCQlicmVhazsKCQkJICAgIGVsc2UgaWYgKHJlcyA9PSAtMSkgewoJCQkJcmV0dXJuICgtMSk7CgkJCSAgICB9CgkJCX0KCQkJaWYgKHJlcyA9PSAxKSB7CgkJCSAgICAvKgoJCQkgICAgKiBNYXRjaCBmb3VuZC4KCQkJICAgICovCgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJICAgIGlmICgocmVzID09IDApICYmIGhhc0R1cGxzKSB7CgkJCS8qCgkJCSogU2VhcmNoIGluIGR1cGxpY2F0ZXMKCQkJKi8KCQkJZm9yIChqID0gMDsgaiA8IGJpbmQtPmR1cGxzLT5uYkl0ZW1zOyBqKyspIHsKCQkJICAgIGtleXMgPSAoKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKQoJCQkJYmluZC0+ZHVwbHMtPml0ZW1zW2pdKS0+a2V5czsKCQkJICAgIGZvciAoayA9IDA7IGsgPCBuYkZpZWxkczsgaysrKSB7CgkJCQlyZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXlzW2tdLT52YWwsCgkJCQkgICAgcmVmS2V5c1trXS0+dmFsKTsKCQkJCWlmIChyZXMgPT0gMCkKCQkJCSAgICBicmVhazsKCQkJCWVsc2UgaWYgKHJlcyA9PSAtMSkgewoJCQkJICAgIHJldHVybiAoLTEpOwoJCQkJfQoJCQkgICAgfQoJCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCQkvKgoJCQkJKiBNYXRjaCBpbiBkdXBsaWNhdGVzIGZvdW5kLgoJCQkJKi8KCQkJCXhtbENoYXIgKnN0ciA9IE5VTEwsICpzdHJCID0gTlVMTDsKCQkJCXhtbFNjaGVtYUtleXJlZkVycih2Y3R4dCwKCQkJCSAgICBYTUxfU0NIRU1BVl9DVkNfSURDLCByZWZOb2RlLAoJCQkJICAgICh4bWxTY2hlbWFUeXBlUHRyKSBtYXRjaGVyLT5haWRjLT5kZWYsCgkJCQkgICAgIk1vcmUgdGhhbiBvbmUgbWF0Y2ggZm91bmQgZm9yICIKCQkJCSAgICAia2V5LXNlcXVlbmNlICVzIG9mIGtleXJlZiAnJXMnIiwKCQkJCSAgICB4bWxTY2hlbWFGb3JtYXRJRENLZXlTZXF1ZW5jZSh2Y3R4dCwgJnN0ciwKCQkJCQlyZWZOb2RlLT5rZXlzLCBuYkZpZWxkcyksCgkJCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckIsCgkJCQkJbWF0Y2hlci0+YWlkYy0+ZGVmKSk7CgkJCQlGUkVFX0FORF9OVUxMKHN0cik7CgkJCQlGUkVFX0FORF9OVUxMKHN0ckIpOwoJCQkJYnJlYWs7CgkJCSAgICB9CgkJCX0KCQkgICAgfQoJCX0KCQkKCQlpZiAocmVzID09IDApIHsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoJCSAgICB4bWxTY2hlbWFLZXlyZWZFcnIodmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsIHJlZk5vZGUsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBtYXRjaGVyLT5haWRjLT5kZWYsCgkJCSJObyBtYXRjaCBmb3VuZCBmb3Iga2V5LXNlcXVlbmNlICVzIG9mIGtleXJlZiAnJXMnIiwKCQkJeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UodmN0eHQsICZzdHIsCgkJCSAgICByZWZOb2RlLT5rZXlzLCBuYkZpZWxkcyksCgkJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCLCBtYXRjaGVyLT5haWRjLT5kZWYpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckIpOwoJCX0KCSAgICB9Cgl9CgltYXRjaGVyID0gbWF0Y2hlci0+bmV4dDsKICAgIH0KICAgIC8qIFRPRE86IFJldHVybiBhbiBlcnJvciBpZiBhbnkgZXJyb3IgZW5jb3VudGVyZWQuICovCiAgICByZXR1cm4gKDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJWE1MIFJlYWRlciB2YWxpZGF0aW9uIGNvZGUgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgeG1sU2NoZW1hQXR0ckluZm9QdHIKeG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwogICAgLyoKICAgICogR3Jvdy9jcmVhdGUgbGlzdCBvZiBhdHRyaWJ1dGUgaW5mb3MuCiAgICAqLwogICAgaWYgKHZjdHh0LT5hdHRySW5mb3MgPT0gTlVMTCkgewoJdmN0eHQtPmF0dHJJbmZvcyA9ICh4bWxTY2hlbWFBdHRySW5mb1B0ciAqKQoJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0ckluZm9QdHIpKTsKCXZjdHh0LT5zaXplQXR0ckluZm9zID0gMTsKCWlmICh2Y3R4dC0+YXR0ckluZm9zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIGF0dHJpYnV0ZSBpbmZvIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUF0dHJJbmZvcyA8PSB2Y3R4dC0+bmJBdHRySW5mb3MpIHsKCXZjdHh0LT5zaXplQXR0ckluZm9zKys7Cgl2Y3R4dC0+YXR0ckluZm9zID0gKHhtbFNjaGVtYUF0dHJJbmZvUHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+YXR0ckluZm9zLAoJCXZjdHh0LT5zaXplQXR0ckluZm9zICogc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvUHRyKSk7CglpZiAodmN0eHQtPmF0dHJJbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyBhdHRyaWJ1dGUgaW5mbyBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZSB7CglpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbdmN0eHQtPm5iQXR0ckluZm9zKytdOwoJaWYgKGlhdHRyLT5sb2NhbE5hbWUgIT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8iLAoJCSJhdHRyIGluZm8gbm90IGNsZWFyZWQiKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaWF0dHItPm5vZGVUeXBlID0gWE1MX0FUVFJJQlVURV9OT0RFOwoJcmV0dXJuIChpYXR0cik7CiAgICB9CiAgICAvKgogICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlIGluZm8uCiAgICAqLwogICAgaWF0dHIgPSAoeG1sU2NoZW1hQXR0ckluZm9QdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICBpZiAoaWF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgImNyZWF0aW5nIG5ldyBhdHRyaWJ1dGUgaW5mbyIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChpYXR0ciwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICBpYXR0ci0+bm9kZVR5cGUgPSBYTUxfQVRUUklCVVRFX05PREU7CiAgICB2Y3R4dC0+YXR0ckluZm9zW3ZjdHh0LT5uYkF0dHJJbmZvcysrXSA9IGlhdHRyOwoKICAgIHJldHVybiAoaWF0dHIpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQl4bWxOb2RlUHRyIGF0dHJOb2RlLAoJCQlpbnQgbm9kZUxpbmUsCgkJCWNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSwKCQkJY29uc3QgeG1sQ2hhciAqbnNOYW1lLAkJCQoJCQlpbnQgb3duZWROYW1lcywKCQkJeG1sQ2hhciAqdmFsdWUsCgkJCWludCBvd25lZFZhbHVlKQp7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKHZjdHh0KTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVB1c2hBdHRyaWJ1dGUiLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oKSIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBhdHRyLT5ub2RlID0gYXR0ck5vZGU7CiAgICBhdHRyLT5ub2RlTGluZSA9IG5vZGVMaW5lOwogICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV047CiAgICBhdHRyLT5sb2NhbE5hbWUgPSBsb2NhbE5hbWU7CiAgICBhdHRyLT5uc05hbWUgPSBuc05hbWU7CiAgICBpZiAob3duZWROYW1lcykKCWF0dHItPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVM7CiAgICAvKgogICAgKiBFdmFsdWF0ZSBpZiBpdCdzIGFuIFhTSSBhdHRyaWJ1dGUuCiAgICAqLwogICAgaWYgKG5zTmFtZSAhPSBOVUxMKSB7CglpZiAoeG1sU3RyRXF1YWwobG9jYWxOYW1lLCBCQURfQ0FTVCAibmlsIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMOwkJCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJ0eXBlIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfU0NIRU1BX0xPQzsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iKSkgewoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uc05hbWUsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB7CgkJYXR0ci0+bWV0YVR5cGUgPSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxOYW1lc3BhY2VOcykpIHsKCSAgICBhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWE1MTlM7Cgl9CiAgICB9CiAgICBhdHRyLT52YWx1ZSA9IHZhbHVlOwogICAgaWYgKG93bmVkVmFsdWUpCglhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUzsKICAgIGlmIChhdHRyLT5tZXRhVHlwZSAhPSAwKQoJYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX01FVEE7CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhckVsZW1JbmZvKHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtKQp7CiAgICBpZWxlbS0+aGFzS2V5cmVmcyA9IDA7CiAgICBpZWxlbS0+YXBwbGllZFhQYXRoID0gMDsKICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTKSB7CglGUkVFX0FORF9OVUxMKGllbGVtLT5sb2NhbE5hbWUpOwoJRlJFRV9BTkRfTlVMTChpZWxlbS0+bnNOYW1lKTsKICAgIH0gZWxzZSB7CglpZWxlbS0+bG9jYWxOYW1lID0gTlVMTDsKCWllbGVtLT5uc05hbWUgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTKSB7CglGUkVFX0FORF9OVUxMKGllbGVtLT52YWx1ZSk7CiAgICB9IGVsc2UgewoJaWVsZW0tPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+dmFsICE9IE5VTEwpIHsKCS8qCgkqIFBTVkkgVE9ETzogQmUgY2FyZWZ1bCBub3QgdG8gZnJlZSBpdCB3aGVuIHRoZSB2YWx1ZSBpcwoJKiBleHBvc2VkIHZpYSBQU1ZJLgoJKi8KCXhtbFNjaGVtYUZyZWVWYWx1ZShpZWxlbS0+dmFsKTsKCWllbGVtLT52YWwgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5pZGNNYXRjaGVycyAhPSBOVUxMKSB7CgkvKgoJKiBVUkdFTlQgT1BUSU1JWkUgVE9ETzogVXNlIGEgcG9vbCBvZiBJREMgbWF0Y2hlcnMuCgkqLwoJeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0KGllbGVtLT5pZGNNYXRjaGVycyk7CglpZWxlbS0+aWRjTWF0Y2hlcnMgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5pZGNUYWJsZSAhPSBOVUxMKSB7CgkvKgoJKiBPUFRJTUlaRSBUT0RPOiBVc2UgYSBwb29sIG9mIElEQyB0YWJsZXM/Py4KCSovCgl4bWxTY2hlbWFJRENGcmVlSURDVGFibGUoaWVsZW0tPmlkY1RhYmxlKTsKCWllbGVtLT5pZGNUYWJsZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPnJlZ2V4Q3R4dCAhPSBOVUxMKSB7Cgl4bWxSZWdGcmVlRXhlY0N0eHQoaWVsZW0tPnJlZ2V4Q3R4dCk7CglpZWxlbS0+cmVnZXhDdHh0ID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+bnNCaW5kaW5ncyAhPSBOVUxMKSB7Cgl4bWxGcmVlKCh4bWxDaGFyICoqKWllbGVtLT5uc0JpbmRpbmdzKTsKCWllbGVtLT5uc0JpbmRpbmdzID0gTlVMTDsKCWllbGVtLT5uYk5zQmluZGluZ3MgPSAwOwoJaWVsZW0tPnNpemVOc0JpbmRpbmdzID0gMDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm86CiAqIEB2Y3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQ3JlYXRlcy9yZXVzZXMgYW5kIGluaXRpYWxpemVzIHRoZSBlbGVtZW50IGluZm8gaXRlbSBmb3IKICogdGhlIGN1cnJlY3QgdHJlZSBkZXB0aC4KICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBpbmZvIGl0ZW0gb3IgTlVMTCBvbiBBUEkgb3IgaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vZGVJbmZvUHRyCnhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbmZvID0gTlVMTDsKCiAgICBpZiAodmN0eHQtPmRlcHRoID4gdmN0eHQtPnNpemVFbGVtSW5mb3MpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8iLAoJICAgICJpbmNvbnNpc3RlbnQgZGVwdGggZW5jb3VudGVyZWQiKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7Cgl2Y3R4dC0+ZWxlbUluZm9zID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyICopCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyB0aGUgZWxlbWVudCBpbmZvIGFycmF5IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCW1lbXNldCh2Y3R4dC0+ZWxlbUluZm9zLCAwLCAxMCAqIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJdmN0eHQtPnNpemVFbGVtSW5mb3MgPSAxMDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVFbGVtSW5mb3MgPD0gdmN0eHQtPmRlcHRoKSB7CglpbnQgaSA9IHZjdHh0LT5zaXplRWxlbUluZm9zOwoKCXZjdHh0LT5zaXplRWxlbUluZm9zICo9IDI7Cgl2Y3R4dC0+ZWxlbUluZm9zID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+ZWxlbUluZm9zLCB2Y3R4dC0+c2l6ZUVsZW1JbmZvcyAqCgkgICAgc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyB0aGUgZWxlbWVudCBpbmZvIGFycmF5IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qCgkqIFdlIG5lZWQgdGhlIG5ldyBtZW1vcnkgdG8gYmUgTlVMTGVkLgoJKiBUT0RPOiBVc2UgbWVtc2V0IGluc3RlYWQ/CgkqLwoJZm9yICg7IGkgPCB2Y3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKQoJICAgIHZjdHh0LT5lbGVtSW5mb3NbaV0gPSBOVUxMOwogICAgfSBlbHNlCglpbmZvID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwoKICAgIGlmIChpbmZvID09IE5VTEwpIHsKCWluZm8gPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIpCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFOb2RlSW5mbykpOwoJaWYgKGluZm8gPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgYW4gZWxlbWVudCBpbmZvIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXSA9IGluZm87CiAgICB9IGVsc2UgewoJaWYgKGluZm8tPmxvY2FsTmFtZSAhPSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyIsCgkJImVsZW0gaW5mbyBoYXMgbm90IGJlZW4gY2xlYXJlZCIpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9CiAgICBtZW1zZXQoaW5mbywgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CiAgICBpbmZvLT5ub2RlVHlwZSA9IFhNTF9FTEVNRU5UX05PREU7CiAgICBpbmZvLT5kZXB0aCA9IHZjdHh0LT5kZXB0aDsKCiAgICByZXR1cm4gKGluZm8pOwp9CgojZGVmaW5lIEFDVElWQVRFX0FUVFJJQlVURShpdGVtKSB2Y3R4dC0+aW5vZGUgPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIpIGl0ZW07CiNkZWZpbmUgQUNUSVZBVEVfRUxFTSB2Y3R4dC0+aW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CiNkZWZpbmUgQUNUSVZBVEVfUEFSRU5UX0VMRU0gdmN0eHQtPmlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdOwoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQl4bWxTY2hlbWFWYWxUeXBlIHZhbFR5cGUsCgkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJeG1sU2NoZW1hVmFsUHRyIHZhbCwKCQkJdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJCWludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0LCBlcnJvciA9IDA7CgogICAgeG1sU2NoZW1hVHlwZVB0ciB0bXBUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluazsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgdW5zaWduZWQgbG9uZyBsZW4gPSAwOwogICAgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3czsKCiAgICAvKgogICAgKiBJbiBMaWJ4bWwyLCBkZXJpdmVkIGJ1aWx0LWluIHR5cGVzIGhhdmUgY3VycmVudGx5IG5vIGV4cGxpY2l0IGZhY2V0cy4KICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCglyZXR1cm4gKDApOwoKICAgIC8qCiAgICAqIE5PVEU6IERvIG5vdCBqdW1wIGF3YXksIGlmIHRoZSBmYWNldFNldCBvZiB0aGUgZ2l2ZW4gdHlwZSBpcwogICAgKiBlbXB0eTogdW50aWwgbm93LCAicGF0dGVybiIgYW5kICJlbnVtZXJhdGlvbiIgZmFjZXRzIG9mIHRoZQogICAgKiAqYmFzZSB0eXBlcyogbmVlZCB0byBiZSBjaGVja2VkIGFzIHdlbGwuCiAgICAqLwogICAgaWYgKHR5cGUtPmZhY2V0U2V0ID09IE5VTEwpCglnb3RvIHBhdHRlcm5fYW5kX2VudW07CgogICAgaWYgKCEgV1hTX0lTX0FUT01JQyh0eXBlKSkgewoJaWYgKFdYU19JU19MSVNUKHR5cGUpKQoJICAgIGdvdG8gV1hTX0lTX0xJU1Q7CgllbHNlCgkgICAgZ290byBwYXR0ZXJuX2FuZF9lbnVtOwogICAgfQogICAgLyoKICAgICogV2hpdGVzcGFjZSBoYW5kbGluZyBpcyBvbmx5IG9mIGltcG9ydGFuY2UgZm9yIHN0cmluZy1iYXNlZAogICAgKiB0eXBlcy4KICAgICovCiAgICB0bXBUeXBlID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eXBlKTsKICAgIGlmICgodG1wVHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSB8fAoJV1hTX0lTX0FOWV9TSU1QTEVfVFlQRSh0bXBUeXBlKSkgewoJd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKTsKICAgIH0gZWxzZQoJd3MgPSBYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0U7CiAgICAvKgogICAgKiBJZiB0aGUgdmFsdWUgd2FzIG5vdCBjb21wdXRlZCAoZm9yIHN0cmluZyBvcgogICAgKiBhbnlTaW1wbGVUeXBlIGJhc2VkIHR5cGVzKSwgdGhlbiB1c2UgdGhlIHByb3ZpZGVkCiAgICAqIHR5cGUuCiAgICAqLwogICAgaWYgKHZhbCA9PSBOVUxMKQoJdmFsVHlwZSA9IHZhbFR5cGU7CiAgICBlbHNlCgl2YWxUeXBlID0geG1sU2NoZW1hR2V0VmFsVHlwZSh2YWwpOwogICAgCiAgICByZXQgPSAwOwogICAgZm9yIChmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7CglmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCS8qCgkqIFNraXAgdGhlIHBhdHRlcm4gIndoaXRlU3BhY2UiOiBpdCBpcyB1c2VkIHRvCgkqIGZvcm1hdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgYmVmb3JlaGFuZC4KCSovCglzd2l0Y2ggKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJY29udGludWU7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMZW5ndGhGYWNldFdodHNwKGZhY2V0TGluay0+ZmFjZXQsCgkJICAgIHZhbFR5cGUsIHZhbHVlLCB2YWwsICZsZW4sIHdzKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRXaHRzcChmYWNldExpbmstPmZhY2V0LCB3cywKCQkgICAgdmFsVHlwZSwgdmFsdWUsIHZhbCwgd3MpOwoJCWJyZWFrOwoJfQoJaWYgKHJldCA8IDApIHsKCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJInZhbGlkYXRpbmcgYWdhaW5zdCBhIGF0b21pYyB0eXBlIGZhY2V0Iik7CgkgICAgcmV0dXJuICgtMSk7Cgl9IGVsc2UgaWYgKHJldCA+IDApIHsKCSAgICBpZiAoZmlyZUVycm9ycykKCQl4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCXZhbHVlLCBsZW4sIHR5cGUsIGZhY2V0TGluay0+ZmFjZXQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIGVsc2UKCQlyZXR1cm4gKHJldCk7CgkgICAgaWYgKGVycm9yID09IDApCgkJZXJyb3IgPSByZXQ7Cgl9CglyZXQgPSAwOwogICAgfQoKV1hTX0lTX0xJU1Q6CiAgICBpZiAoISBXWFNfSVNfTElTVCh0eXBlKSkKCWdvdG8gcGF0dGVybl9hbmRfZW51bTsKICAgIC8qCiAgICAqICJsZW5ndGgiLCAibWluTGVuZ3RoIiBhbmQgIm1heExlbmd0aCIgb2YgbGlzdCB0eXBlcy4KICAgICovCiAgICByZXQgPSAwOwogICAgZm9yIChmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7CglmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCQoJc3dpdGNoIChmYWNldExpbmstPmZhY2V0LT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CQkgICAgCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMaXN0U2ltcGxlVHlwZUZhY2V0KGZhY2V0TGluay0+ZmFjZXQsCgkJICAgIHZhbHVlLCBsZW5ndGgsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJY29udGludWU7Cgl9CglpZiAocmV0IDwgMCkgewoJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkidmFsaWRhdGluZyBhZ2FpbnN0IGEgbGlzdCB0eXBlIGZhY2V0Iik7CgkgICAgcmV0dXJuICgtMSk7Cgl9IGVsc2UgaWYgKHJldCA+IDApIHsKCSAgICBpZiAoZmlyZUVycm9ycykJCQoJCXhtbFNjaGVtYUZhY2V0RXJyKGFjdHh0LCByZXQsIG5vZGUsCgkJdmFsdWUsIGxlbmd0aCwgdHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgZWxzZQoJCXJldHVybiAocmV0KTsKCSAgICBpZiAoZXJyb3IgPT0gMCkKCQllcnJvciA9IHJldDsKCX0KCXJldCA9IDA7CiAgICB9CgpwYXR0ZXJuX2FuZF9lbnVtOgogICAgaWYgKGVycm9yID49IDApIHsKCWludCBmb3VuZCA9IDA7CgkvKgoJKiBQcm9jZXNzIGVudW1lcmF0aW9ucy4gRmFjZXQgdmFsdWVzIGFyZSBpbiB0aGUgdmFsdWUgc3BhY2UKCSogb2YgdGhlIGRlZmluaW5nIHR5cGUncyBiYXNlIHR5cGUuIFRoaXMgc2VlbXMgdG8gYmUgYSBidWcgaW4gdGhlCgkqIFhNTCBTY2hlbWEgMS4wIHNwZWMuIFVzZSB0aGUgd2hpdGVzcGFjZSB0eXBlIG9mIHRoZSBiYXNlIHR5cGUuCgkqIE9ubHkgdGhlIGZpcnN0IHNldCBvZiBlbnVtZXJhdGlvbnMgaW4gdGhlIGFuY2VzdG9yLW9yLXNlbGYgYXhpcwoJKiBpcyB1c2VkIGZvciB2YWxpZGF0aW9uLgoJKi8KCXJldCA9IDA7Cgl0bXBUeXBlID0gdHlwZTsKCWRvIHsKCSAgICBmb3IgKGZhY2V0ID0gdG1wVHlwZS0+ZmFjZXRzOyBmYWNldCAhPSBOVUxMOyBmYWNldCA9IGZhY2V0LT5uZXh0KSB7CgkJaWYgKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pCgkJICAgIGNvbnRpbnVlOwoJCWZvdW5kID0gMTsKCQlyZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChmYWNldC0+dmFsLCB2YWwpOwoJCWlmIChyZXQgPT0gMSkKCQkgICAgYnJlYWs7CgkJZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJCSJ2YWxpZGF0aW5nIGFnYWluc3QgYW4gZW51bWVyYXRpb24gZmFjZXQiKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJICAgIH0KCSAgICBpZiAocmV0ICE9IDApCgkJYnJlYWs7CgkgICAgdG1wVHlwZSA9IHRtcFR5cGUtPmJhc2VUeXBlOwoJfSB3aGlsZSAoKHRtcFR5cGUgIT0gTlVMTCkgJiYKCSAgICAodG1wVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKTsKCWlmIChmb3VuZCAmJiAocmV0ID09IDApKSB7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VOVU1FUkFUSU9OX1ZBTElEOwoJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJeG1sU2NoZW1hRmFjZXRFcnIoYWN0eHQsIHJldCwgbm9kZSwKCQkgICAgdmFsdWUsIDAsIHR5cGUsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0gZWxzZQoJCXJldHVybiAocmV0KTsKCSAgICBpZiAoZXJyb3IgPT0gMCkKCQllcnJvciA9IHJldDsKCX0KICAgIH0KCiAgICBpZiAoZXJyb3IgPj0gMCkgewoJaW50IGZvdW5kOwoJLyoKCSogUHJvY2VzcyBwYXR0ZXJzLiBQYXR0ZXJuIGZhY2V0cyBhcmUgT1JlZCBhdCB0eXBlIGxldmVsCgkqIGFuZCBBTkRlZCBpZiBkZXJpdmVkLiBXYWxrIHRoZSBiYXNlIHR5cGUgYXhpcy4KCSovCgl0bXBUeXBlID0gdHlwZTsKCWZhY2V0ID0gTlVMTDsKCWRvIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgZm9yIChmYWNldExpbmsgPSB0bXBUeXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7CgkJZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0KSB7CgkJaWYgKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKQoJCSAgICBjb250aW51ZTsKCQlmb3VuZCA9IDE7CgkJLyogCgkJKiBOT1RFIHRoYXQgZm9yIHBhdHRlcm5zLCBAdmFsdWUgbmVlZHMgdG8gYmUgdGhlCgkJKiBub3JtYWxpemVkIHZhdWxlLgoJCSovCgkJcmV0ID0geG1sUmVnZXhwRXhlYyhmYWNldExpbmstPmZhY2V0LT5yZWdleHAsIHZhbHVlKTsKCQlpZiAocmV0ID09IDEpCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVGYWNldHMiLAoJCQkidmFsaWRhdGluZyBhZ2FpbnN0IGEgcGF0dGVybiBmYWNldCIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9IGVsc2UgewoJCSAgICAvKiAKCQkgICAgKiBTYXZlIHRoZSBsYXN0IG5vbi12YWxpZGF0aW5nIGZhY2V0LgoJCSAgICAqLwoJCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkJfQoJICAgIH0KCSAgICBpZiAoZm91bmQgJiYgKHJldCAhPSAxKSkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19QQVRURVJOX1ZBTElEOwoJCWlmIChmaXJlRXJyb3JzKSB7CgkJICAgIHhtbFNjaGVtYUZhY2V0RXJyKGFjdHh0LCByZXQsIG5vZGUsCgkJCXZhbHVlLCAwLCB0eXBlLCBmYWNldCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJfSBlbHNlCgkJICAgIHJldHVybiAocmV0KTsKCQlpZiAoZXJyb3IgPT0gMCkKCQkgICAgZXJyb3IgPSByZXQ7CgkJYnJlYWs7CgkgICAgfQoJICAgIHRtcFR5cGUgPSB0bXBUeXBlLT5iYXNlVHlwZTsKCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwogICAgfQoKICAgIHJldHVybiAoZXJyb3IpOwp9CiAKc3RhdGljIHhtbENoYXIgKgp4bWxTY2hlbWFOb3JtYWxpemVWYWx1ZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlKQp7CiAgICBzd2l0Y2ggKHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpKSB7CQoJY2FzZSBYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0U6CgkgICAgcmV0dXJuICh4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSkpOwoJY2FzZSBYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUkVQTEFDRToKCSAgICByZXR1cm4gKHhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKHZhbHVlKSk7CglkZWZhdWx0OgoJICAgIHJldHVybiAoTlVMTCk7CiAgICB9Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVRTmFtZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCwKCQkgICAgICAgaW50IHZhbE5lZWRlZCkKewogICAgaW50IHJldDsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKICAgIHhtbENoYXIgKmxvY2FsLCAqcHJlZml4ID0gTlVMTDsKICAgIAogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZVFOYW1lIiwKCQkiY2FsbGluZyB4bWxWYWxpZGF0ZVFOYW1lKCkiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXJldHVybiggWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xKTsKICAgIH0KICAgIC8qCiAgICAqIE5PVEU6IHhtbFNwbGl0UU5hbWUyIHdpbGwgYWx3YXlzIHJldHVybiBhIGR1cGxpY2F0ZWQKICAgICogc3RyaW5ncy4KICAgICovCiAgICBsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKICAgIGlmIChsb2NhbCA9PSBOVUxMKQoJbG9jYWwgPSB4bWxTdHJkdXAodmFsdWUpOwogICAgLyoKICAgICogT1BUSU1JWkUgVE9ETzogVXNlIGZsYWdzIGZvcjoKICAgICogIC0gaXMgdGhlcmUgYW55IG5hbWVzcGFjZSBiaW5kaW5nPwogICAgKiAgLSBpcyB0aGVyZSBhIGRlZmF1bHQgbmFtZXNwYWNlPwogICAgKi8KICAgIG5zTmFtZSA9IHhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh2Y3R4dCwgcHJlZml4KTsKICAgIAogICAgaWYgKHByZWZpeCAhPSBOVUxMKSB7Cgl4bWxGcmVlKHByZWZpeCk7CgkvKgoJKiBBIG5hbWVzcGFjZSBtdXN0IGJlIGZvdW5kIGlmIHRoZSBwcmVmaXggaXMKCSogTk9UIE5VTEwuCgkqLwoJaWYgKG5zTmFtZSA9PSBOVUxMKSB7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LCByZXQsIE5VTEwsCgkJV1hTX0JBU0lDX0NBU1QgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSJUaGUgUU5hbWUgdmFsdWUgJyVzJyBoYXMgbm8gIgoJCSJjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiAiCgkJInNjb3BlIiwgdmFsdWUsIE5VTEwpOwoJICAgIGlmIChsb2NhbCAhPSBOVUxMKQoJCXhtbEZyZWUobG9jYWwpOwoJICAgIHJldHVybiAocmV0KTsKCX0KICAgIH0KICAgIGlmICh2YWxOZWVkZWQgJiYgdmFsKSB7CglpZiAobnNOYW1lICE9IE5VTEwpCgkgICAgKnZhbCA9IHhtbFNjaGVtYU5ld1FOYW1lVmFsdWUoCgkJQkFEX0NBU1QgeG1sU3RyZHVwKG5zTmFtZSksIEJBRF9DQVNUIGxvY2FsKTsKCWVsc2UKCSAgICAqdmFsID0geG1sU2NoZW1hTmV3UU5hbWVWYWx1ZShOVUxMLAoJCUJBRF9DQVNUIGxvY2FsKTsKICAgIH0gZWxzZQoJeG1sRnJlZShsb2NhbCk7CiAgICByZXR1cm4gKDApOwp9CgovKgoqIGN2Yy1zaW1wbGUtdHlwZQoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgeG1sU2NoZW1hVmFsUHRyICpyZXRWYWwsCgkJCSAgICAgaW50IGZpcmVFcnJvcnMsCgkJCSAgICAgaW50IG5vcm1hbGl6ZSwKCQkJICAgICBpbnQgaXNOb3JtYWxpemVkKQp7CiAgICBpbnQgcmV0ID0gMCwgdmFsTmVlZGVkID0gKHJldFZhbCkgPyAxIDogMDsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWwgPSBOVUxMOwogICAgLyogeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3czsgKi8KICAgIHhtbENoYXIgKm5vcm1WYWx1ZSA9IE5VTEw7CgojZGVmaW5lIE5PUk1BTElaRShhdHlwZSkgXAogICAgaWYgKCghIGlzTm9ybWFsaXplZCkgJiYgXAogICAgKG5vcm1hbGl6ZSB8fCAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRCkpKSB7IFwKCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKGF0eXBlLCB2YWx1ZSk7IFwKCWlmIChub3JtVmFsdWUgIT0gTlVMTCkgXAoJICAgIHZhbHVlID0gbm9ybVZhbHVlOyBcCglpc05vcm1hbGl6ZWQgPSAxOyBcCiAgICB9CiAgICAKICAgIGlmICgocmV0VmFsICE9IE5VTEwpICYmICgqcmV0VmFsICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUoKnJldFZhbCk7CgkqcmV0VmFsID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIDMuMTQuNCBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKICAgICogVmFsaWRhdGlvbiBSdWxlOiBTdHJpbmcgVmFsaWQKICAgICovCiAgICAvKgogICAgKiAxIEl0IGlzIHNjaGVtYS12YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQKICAgICogYnkgRGF0YXR5cGUgVmFsaWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgogICAgKi8KICAgIC8qCiAgICAqIDIuMSBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVFkgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRZIGdpdmVuCiAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgdGhlbgogICAgKiB0aGUgc3RyaW5nIG11c3QgYmUgYSC3ZGVjbGFyZWQgZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMiBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVElFUyBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVElFUwogICAgKiBnaXZlbiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNiksCiAgICAqIHRoZW4gZXZlcnkgd2hpdGVzcGFjZS1kZWxpbWl0ZWQgc3Vic3RyaW5nIG9mIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZAogICAgKiBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4zIG90aGVyd2lzZSBubyBmdXJ0aGVyIGNvbmRpdGlvbiBhcHBsaWVzLgogICAgKi8KICAgIGlmICgoISB2YWxOZWVkZWQpICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFKSkKCXZhbE5lZWRlZCA9IDE7CiAgICBpZiAodmFsdWUgPT0gTlVMTCkKCXZhbHVlID0gQkFEX0NBU1QgIiI7CiAgICBpZiAoV1hTX0lTX0FOWV9TSU1QTEVfVFlQRSh0eXBlKSB8fCBXWFNfSVNfQVRPTUlDKHR5cGUpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGJpVHlwZTsgLyogVGhlIGJ1aWx0LWluIHR5cGUuICovCgkvKgoJKiBTUEVDICgxLjIuMSkgImlmIHt2YXJpZXR5fSBpcyC3YXRvbWljtyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3CgkqIGEgbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0iCgkqLwoJLyoKCSogV2hpdGVzcGFjZS1ub3JtYWxpemUuCgkqLwoJTk9STUFMSVpFKHR5cGUpOwoJaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkgICAgLyoKCSAgICAqIEdldCB0aGUgYnVpbHQtaW4gdHlwZS4KCSAgICAqLwoJICAgIGJpVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIHdoaWxlICgoYmlUeXBlICE9IE5VTEwpICYmCgkJKGJpVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJCWJpVHlwZSA9IGJpVHlwZS0+YmFzZVR5cGU7CgoJICAgIGlmIChiaVR5cGUgPT0gTlVMTCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAiY291bGQgbm90IGdldCB0aGUgYnVpbHQtaW4gdHlwZSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJfSBlbHNlCgkgICAgYmlUeXBlID0gdHlwZTsKCS8qCgkqIE5PVEFUSU9OcyBuZWVkIHRvIGJlIHByb2Nlc3NlZCBoZXJlLCBzaW5jZSB0aGV5IG5lZWQKCSogdG8gbG9va3VwIGluIHRoZSBoYXNodGFibGUgb2YgTk9UQVRJT04gZGVjbGFyYXRpb25zIG9mIHRoZSBzY2hlbWEuCgkqLwoJaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsJICAgIAoJICAgIHN3aXRjaCAoYmlUeXBlLT5idWlsdEluVHlwZSkgewkJCgkJY2FzZSBYTUxfU0NIRU1BU19OT1RBVElPTjoJCSAgICAKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbigKCQkJKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQsCgkJCSgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPnNjaGVtYSwKCQkJTlVMTCwgdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQVNfUU5BTUU6CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUU5hbWUoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQsCgkJCXZhbHVlLCAmdmFsLCB2YWxOZWVkZWQpOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICAvKiB3cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOyAqLwoJCSAgICBpZiAodmFsTmVlZGVkKQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgJnZhbCwgTlVMTCk7CgkJICAgIGVsc2UKCQkJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGVOb05vcm0oYmlUeXBlLAoJCQkgICAgdmFsdWUsIE5VTEwsIE5VTEwpOwoJCSAgICBicmVhazsKCSAgICB9Cgl9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsJICAgIAoJICAgIHN3aXRjaCAoYmlUeXBlLT5idWlsdEluVHlwZSkgewkJICAgIAoJCWNhc2UgWE1MX1NDSEVNQVNfTk9UQVRJT046CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24oTlVMTCwKCQkJKCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSBhY3R4dCktPnNjaGVtYSwgbm9kZSwKCQkJdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIC8qIHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSk7ICovCgkJICAgIGlmICh2YWxOZWVkZWQpCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCAmdmFsLCBub2RlKTsKCQkgICAgZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgTlVMTCwgbm9kZSk7CgkJICAgIGJyZWFrOwoJICAgIH0JICAgCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBWYWxpZGF0aW9uIHZpYSBhIHB1YmxpYyBBUEkgaXMgbm90IGltcGxlbWVudGVkIHlldC4KCSAgICAqLwoJICAgIFRPRE8KCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkgICAgInZhbGlkYXRpbmcgYWdhaW5zdCBhIGJ1aWx0LWluIHR5cGUiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZiAoV1hTX0lTX0xJU1QodHlwZSkpCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJICAgIGVsc2UKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CSAgICAKCX0KCWlmICgocmV0ID09IDApICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUykpIHsKCSAgICAvKgoJICAgICogQ2hlY2sgZmFjZXRzLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJKHhtbFNjaGVtYVZhbFR5cGUpIGJpVHlwZS0+YnVpbHRJblR5cGUsIHZhbHVlLCB2YWwsCgkJMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJCSJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBhdG9taWMgc2ltcGxlIHR5cGUiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJaWYgKFdYU19JU19MSVNUKHR5cGUpKSAKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCWVsc2UKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwkJCgkgICAgfQoJfQoJaWYgKGZpcmVFcnJvcnMgJiYgKHJldCA+IDApKQoJICAgIHhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoYWN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUsIDEpOwogICAgfSBlbHNlIGlmIChXWFNfSVNfTElTVCh0eXBlKSkgewoKCXhtbFNjaGVtYVR5cGVQdHIgaXRlbVR5cGU7Cgljb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXBWYWx1ZSA9IE5VTEw7Cgl1bnNpZ25lZCBsb25nIGxlbiA9IDA7Cgl4bWxTY2hlbWFWYWxQdHIgcHJldlZhbCA9IE5VTEwsIGN1clZhbCA9IE5VTEw7CgkvKiAxLjIuMiBpZiB7dmFyaWV0eX0gaXMgt2xpc3S3IHRoZW4gdGhlIHN0cmluZyBtdXN0IGJlIGEgc2VxdWVuY2UKCSogb2Ygd2hpdGUgc3BhY2Ugc2VwYXJhdGVkIHRva2VucywgZWFjaCBvZiB3aGljaCC3bWF0Y2i3ZXMgYSBsaXRlcmFsCgkqIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2l0ZW0gdHlwZSBkZWZpbml0aW9ufQoJKi8KCS8qCgkqIE5vdGUgdGhhdCBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRCB3aWxsIGJlIHNldCBpZgoJKiB0aGUgbGlzdCB0eXBlIGhhcyBhbiBlbnVtIG9yIHBhdHRlcm4gZmFjZXQuCgkqLwoJTk9STUFMSVpFKHR5cGUpOwoJLyoKCSogVkFMIFRPRE86IE9wdGltaXplIHZhbGlkYXRpb24gb2YgZW1wdHkgdmFsdWVzLgoJKiBWQUwgVE9ETzogV2UgZG8gbm90IGhhdmUgY29tcHV0ZWQgdmFsdWVzIGZvciBsaXN0cy4KCSovCglpdGVtVHlwZSA9IFdYU19MSVNUX0lURU1UWVBFKHR5cGUpOwkKCWN1ciA9IHZhbHVlOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wVmFsdWUgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBsZW4rKzsKCgkgICAgaWYgKHZhbE5lZWRlZCkKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLCBpdGVtVHlwZSwKCQkgICAgdG1wVmFsdWUsICZjdXJWYWwsIGZpcmVFcnJvcnMsIDAsIDEpOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLCBpdGVtVHlwZSwKCQkgICAgdG1wVmFsdWUsIE5VTEwsIGZpcmVFcnJvcnMsIDAsIDEpOwoJICAgIEZSRUVfQU5EX05VTEwodG1wVmFsdWUpOwoJICAgIGlmIChjdXJWYWwgIT0gTlVMTCkgewoJCS8qCgkJKiBBZGQgdG8gbGlzdCBvZiBjb21wdXRlZCB2YWx1ZXMuCgkJKi8KCQlpZiAodmFsID09IE5VTEwpCgkJICAgIHZhbCA9IGN1clZhbDsKCQllbHNlCgkJICAgIHhtbFNjaGVtYVZhbHVlQXBwZW5kKHByZXZWYWwsIGN1clZhbCk7CgkJcHJldlZhbCA9IGN1clZhbDsKCQljdXJWYWwgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgYW4gaXRlbSBvZiBsaXN0IHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQlicmVhazsKCSAgICB9CSAgICAKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwoJRlJFRV9BTkRfTlVMTCh0bXBWYWx1ZSk7CglpZiAoKHJldCA9PSAwKSAmJiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFMpKSB7CgkgICAgLyoKCSAgICAqIEFwcGx5IGZhY2V0cyAocGF0dGVybiwgZW51bWVyYXRpb24pLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJWE1MX1NDSEVNQVNfVU5LTk9XTiwgdmFsdWUsIHZhbCwKCQlsZW4sIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCQkidmFsaWRhdGluZyBmYWNldHMgb2YgbGlzdCBzaW1wbGUgdHlwZSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgfQoJfQoJaWYgKGZpcmVFcnJvcnMgJiYgKHJldCA+IDApKSB7CgkgICAgLyogCgkgICAgKiBSZXBvcnQgdGhlIG5vcm1hbGl6ZWQgdmFsdWUuCgkgICAgKi8KCSAgICBub3JtYWxpemUgPSAxOwoJICAgIE5PUk1BTElaRSh0eXBlKTsKCSAgICB4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKGFjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlLCAxKTsKCX0KICAgIH0gZWxzZSBpZiAoV1hTX0lTX1VOSU9OKHR5cGUpKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXJMaW5rOwoJLyoKCSogVE9ETzogRm9yIGFsbCBkYXRhdHlwZXMgt2Rlcml2ZWS3IGJ5ILd1bmlvbrcgIHdoaXRlU3BhY2UgZG9lcwoJKiBub3QgYXBwbHkgZGlyZWN0bHk7IGhvd2V2ZXIsIHRoZSBub3JtYWxpemF0aW9uIGJlaGF2aW9yIG9mILd1bmlvbrcKCSogdHlwZXMgaXMgY29udHJvbGxlZCBieSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUKCSogt21lbWJlclR5cGVztyBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuCgkqCgkqIFRoaXMgbWVhbnMgdGhhdCB0aGUgdmFsdWUgaXMgbm9ybWFsaXplZCBieSB0aGUgZmlyc3QgdmFsaWRhdGluZwoJKiBtZW1iZXIgdHlwZSwgdGhlbiB0aGUgZmFjZXRzIG9mIHRoZSB1bmlvbiB0eXBlIGFyZSBhcHBsaWVkLiBUaGlzCgkqIG5lZWRzIGNoYW5naW5nIG9mIHRoZSB2YWx1ZSEKCSovCgoJLyoKCSogMS4yLjMgaWYge3ZhcmlldHl9IGlzILd1bmlvbrcgdGhlbiB0aGUgc3RyaW5nIG11c3Qgt21hdGNotyBhCgkqIGxpdGVyYWwgaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiBhdCBsZWFzdCBvbmUgbWVtYmVyIG9mCgkqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30KCSovCgltZW1iZXJMaW5rID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZSk7CglpZiAobWVtYmVyTGluayA9PSBOVUxMKSB7CgkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJInVuaW9uIHNpbXBsZSB0eXBlIGhhcyBubyBtZW1iZXIgdHlwZXMiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQkKCS8qCgkqIEFsd2F5cyBub3JtYWxpemUgdW5pb24gdHlwZSB2YWx1ZXMsIHNpbmNlIHdlIGN1cnJlbnRseQoJKiBjYW5ub3Qgc3RvcmUgdGhlIHdoaXRlc3BhY2UgaW5mb3JtYXRpb24gd2l0aCB0aGUgdmFsdWUKCSogaXRzZWxmOyBvdGhlcndpc2UgYSBsYXRlciB2YWx1ZS1jb21wYXJpc29uIHdvdWxkIGJlCgkqIG5vdCBwb3NzaWJsZS4KCSovCgl3aGlsZSAobWVtYmVyTGluayAhPSBOVUxMKSB7CgkgICAgaWYgKHZhbE5lZWRlZCkgCgkJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShhY3R4dCwgbm9kZSwKCQkgICAgbWVtYmVyTGluay0+dHlwZSwgdmFsdWUsICZ2YWwsIDAsIDEsIDApOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLAoJCSAgICBtZW1iZXJMaW5rLT50eXBlLCB2YWx1ZSwgTlVMTCwgMCwgMSwgMCk7CgkgICAgaWYgKHJldCA8PSAwKQoJCWJyZWFrOwoJICAgIG1lbWJlckxpbmsgPSBtZW1iZXJMaW5rLT5uZXh0OwoJfQoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkgICAgInZhbGlkYXRpbmcgbWVtYmVycyBvZiB1bmlvbiBzaW1wbGUgdHlwZSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCX0KCS8qCgkqIEFwcGx5IGZhY2V0cyAocGF0dGVybiwgZW51bWVyYXRpb24pLgoJKi8KCWlmICgocmV0ID09IDApICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUykpIHsKCSAgICAvKgoJICAgICogVGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utyB0eXBlcyBpcyBjb250cm9sbGVkIGJ5CgkgICAgKiB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUgt21lbWJlclR5cGVztwoJICAgICogYWdhaW5zdCB3aGljaCB0aGUgt3VuaW9utyBpcyBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkLgoJICAgICovCgkgICAgTk9STUFMSVpFKG1lbWJlckxpbmstPnR5cGUpOwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKGFjdHh0LCBub2RlLCB0eXBlLAoJCVhNTF9TQ0hFTUFTX1VOS05PV04sIHZhbHVlLCB2YWwsCgkJMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJCSJ2YWxpZGF0aW5nIGZhY2V0cyBvZiB1bmlvbiBzaW1wbGUgdHlwZSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzM7CQkKCSAgICB9Cgl9CglpZiAoZmlyZUVycm9ycyAmJiAocmV0ID4gMCkpCgkgICAgeG1sU2NoZW1hU2ltcGxlVHlwZUVycihhY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSwgMSk7CiAgICB9CgogICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZShub3JtVmFsdWUpOwogICAgaWYgKHJldCA9PSAwKSB7CglpZiAocmV0VmFsICE9IE5VTEwpCgkgICAgKnJldFZhbCA9IHZhbDsKCWVsc2UgaWYgKHZhbCAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZSh2YWwpOwogICAgfSBlbHNlIGlmICh2YWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2YWwpOwogICAgcmV0dXJuIChyZXQpOwppbnRlcm5hbF9lcnJvcjoKICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUobm9ybVZhbHVlKTsKICAgIGlmICh2YWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2YWwpOwogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkV4cGFuZFFOYW1lKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKipuc05hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKipsb2NhbE5hbWUpCnsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICgobnNOYW1lID09IE5VTEwpIHx8IChsb2NhbE5hbWUgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgICpuc05hbWUgPSBOVUxMOwogICAgKmxvY2FsTmFtZSA9IE5VTEw7CgogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ID09IC0xKQoJcmV0dXJuICgtMSk7CiAgICBpZiAocmV0ID4gMCkgewoJeG1sU2NoZW1hU2ltcGxlVHlwZUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwgTlVMTCwKCSAgICB2YWx1ZSwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCAxKTsKCXJldHVybiAoMSk7CiAgICB9CiAgICB7Cgl4bWxDaGFyICpsb2NhbCA9IE5VTEw7Cgl4bWxDaGFyICpwcmVmaXg7CgoJLyoKCSogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCByZXR1cm4gYSBkdXBsaWNhdGVkCgkqIHN0cmluZy4KCSovCglsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChsb2NhbCA9PSBOVUxMKQoJICAgICpsb2NhbE5hbWUgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5kaWN0LCB2YWx1ZSwgLTEpOwoJZWxzZSB7CgkgICAgKmxvY2FsTmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIGxvY2FsLCAtMSk7CgkgICAgeG1sRnJlZShsb2NhbCk7Cgl9CgoJKm5zTmFtZSA9IHhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh2Y3R4dCwgcHJlZml4KTsKCglpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxGcmVlKHByZWZpeCk7CgkgICAgLyoKCSAgICAqIEEgbmFtZXNwYWNlIG11c3QgYmUgZm91bmQgaWYgdGhlIHByZWZpeCBpcyBOT1QgTlVMTC4KCSAgICAqLwoJICAgIGlmICgqbnNOYW1lID09IE5VTEwpIHsKCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLCBOVUxMLAoJCSAgICBXWFNfQkFTSUNfQ0FTVCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJICAgICJUaGUgUU5hbWUgdmFsdWUgJyVzJyBoYXMgbm8gIgoJCSAgICAiY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUiLAoJCSAgICB2YWx1ZSwgTlVMTCk7CgkJcmV0dXJuICgyKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHIsCgkJCXhtbFNjaGVtYVR5cGVQdHIgKmxvY2FsVHlwZSwKCQkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgaW50IHJldCA9IDA7CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAoNCkKICAgICogQU5ECiAgICAqIFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KSAoY3ZjLWFzc2Vzcy1lbHQpCiAgICAqICAgKDEuMi4xLjIuMSkgLSAoMS4yLjEuMi40KQogICAgKiBIYW5kbGUgJ3hzaTp0eXBlJy4KICAgICovCiAgICBpZiAobG9jYWxUeXBlID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgICpsb2NhbFR5cGUgPSBOVUxMOwogICAgaWYgKGlhdHRyID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgZWxzZSB7Cgljb25zdCB4bWxDaGFyICpuc05hbWUgPSBOVUxMLCAqbG9jYWwgPSBOVUxMOwoJLyoKCSogVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhICp3YXJuaW5nKiB0aGF0IHRoZSB0eXBlIHdhcyBvdmVycmlkZW4KCSogYnkgdGhlIGluc3RhbmNlLgoJKi8KCUFDVElWQVRFX0FUVFJJQlVURShpYXR0cik7CgkvKgoJKiAoY3ZjLWVsdCkgKDMuMy40KSA6ICg0LjEpCgkqIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMikKCSovCglyZXQgPSB4bWxTY2hlbWFWRXhwYW5kUU5hbWUodmN0eHQsIGlhdHRyLT52YWx1ZSwKCSAgICAmbnNOYW1lLCAmbG9jYWwpOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hUU5hbWVFeHBhbmQoKSB0byB2YWxpZGF0ZSB0aGUgIgoJCSAgICAiYXR0cmlidXRlICd4c2k6dHlwZSciKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGV4aXQ7Cgl9CgkvKgoJKiAoY3ZjLWVsdCkgKDMuMy40KSA6ICg0LjIpCgkqIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMykKCSovCgkqbG9jYWxUeXBlID0geG1sU2NoZW1hR2V0VHlwZSh2Y3R4dC0+c2NoZW1hLCBsb2NhbCwgbnNOYW1lKTsKCWlmICgqbG9jYWxUeXBlID09IE5VTEwpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfRUxUXzRfMiwgTlVMTCwKCQlXWFNfQkFTSUNfQ0FTVCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIG9mIHRoZSB4c2k6dHlwZSBhdHRyaWJ1dGUgZG9lcyBub3QgIgoJCSJyZXNvbHZlIHRvIGEgdHlwZSBkZWZpbml0aW9uIiwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBuc05hbWUsIGxvY2FsKSwgTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgIHJldCA9IHZjdHh0LT5lcnI7CgkgICAgZ290byBleGl0OwoJfQoJaWYgKGVsZW1EZWNsICE9IE5VTEwpIHsKCSAgICBpbnQgc2V0ID0gMDsKCgkgICAgLyoKCSAgICAqIFNQRUMgY3ZjLWVsdCAoMy4zLjQpIDogKDQuMykgKFR5cGUgRGVyaXZhdGlvbiBPSykKCSAgICAqICJUaGUgt2xvY2FsIHR5cGUgZGVmaW5pdGlvbrcgbXVzdCBiZSB2YWxpZGx5CgkgICAgKiBkZXJpdmVkIGZyb20gdGhlIHt0eXBlIGRlZmluaXRpb259IGdpdmVuIHRoZSB1bmlvbiBvZgoJICAgICogdGhlIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9IGFuZCB0aGUge3R5cGUgZGVmaW5pdGlvbn0ncwoJICAgICoge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30sIGFzIGRlZmluZWQgaW4KCSAgICAqIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkgKKczLjQuNikKCSAgICAqIChpZiBpdCBpcyBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uKSwKCSAgICAqIG9yIGdpdmVuIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9IGFzIGRlZmluZWQgaW4gVHlwZQoJICAgICogRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikgKGlmIGl0IGlzIGEgc2ltcGxlIHR5cGUKCSAgICAqIGRlZmluaXRpb24pLiIKCSAgICAqCgkgICAgKiB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfTogdGhlICJibG9jayIgb24gdGhlIGVsZW1lbnQgZGVjbC4KCSAgICAqIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9OiB0aGUgImJsb2NrIiBvbiB0aGUgdHlwZSBkZWYuCgkgICAgKi8KCSAgICAvKgoJICAgICogT1BUSU1JWkUgVE9ETzogV2UgY291bGQgbWFwIHR5cGVzIGFscmVhZHkgZXZhbHVhdGVkCgkgICAgKiB0byBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBvdGhlciB0eXBlcyB0byBhdm9pZCBjaGVja2luZwoJICAgICogdGhpcyBvdmVyIGFuZCBvdmVyIGZvciB0aGUgc2FtZSB0eXBlcy4KCSAgICAqLwoJICAgIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pIHx8CgkJKGVsZW1EZWNsLT5zdWJ0eXBlcy0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikpCgkJc2V0IHw9IFNVQlNFVF9FWFRFTlNJT047CgoJICAgIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTikgfHwKCQkoZWxlbURlY2wtPnN1YnR5cGVzLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pKQoJCXNldCB8PSBTVUJTRVRfUkVTVFJJQ1RJT047CgoJICAgIC8qCgkgICAgKiBSRU1PVkVEIGFuZCBDSEFOR0VEIHNpbmNlIHRoaXMgcHJvZHVjZWQgYSBwYXJzZXIgY29udGV4dAoJICAgICogd2hpY2ggYWRkcyB0byB0aGUgc3RyaW5nIGRpY3Qgb2YgdGhlIHNjaGVtYS4gU28gdGhpcyB3b3VsZAoJICAgICogY2hhbmdlIHRoZSBzY2hlbWEgYW5kIHdlIGRvbid0IHdhbnQgdGhpcy4gV2UgZG9uJ3QgbmVlZAoJICAgICogdGhlIHBhcnNlciBjb250ZXh0IGFueW1vcmUuCgkgICAgKgoJICAgICogaWYgKCh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgJiYKCSAgICAqCSh4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQodmN0eHQpID09IC0xKSkKCSAgICAqCSAgICByZXR1cm4gKC0xKTsKCSAgICAqLwoKCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0soQUNUWFRfQ0FTVCB2Y3R4dCwgKmxvY2FsVHlwZSwKCQllbGVtRGVjbC0+c3VidHlwZXMsIHNldCkgIT0gMCkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgoJCXhtbFNjaGVtYUN1c3RvbUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzRfMywgTlVMTCwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gJyVzJywgc3BlY2lmaWVkIGJ5IHhzaTp0eXBlLCBpcyAiCgkJICAgICJibG9ja2VkIG9yIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUgdHlwZSBkZWZpbml0aW9uICIKCQkgICAgIm9mIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJKCpsb2NhbFR5cGUpLT50YXJnZXROYW1lc3BhY2UsCgkJCSgqbG9jYWxUeXBlKS0+bmFtZSksCgkJICAgIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQlyZXQgPSB2Y3R4dC0+ZXJyOwoJCSpsb2NhbFR5cGUgPSBOVUxMOwoJICAgIH0KCX0KICAgIH0KZXhpdDoKICAgIEFDVElWQVRFX0VMRU07CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2woeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsID0gdmN0eHQtPmlub2RlLT5kZWNsOwogICAgeG1sU2NoZW1hVHlwZVB0ciBhY3R1YWxUeXBlID0gV1hTX0VMRU1fVFlQRURFRihlbGVtRGVjbCk7CgogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMQogICAgKi8KICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xLCBOVUxMLAoJICAgICJObyBtYXRjaGluZyBkZWNsYXJhdGlvbiBhdmFpbGFibGUiKTsKICAgICAgICByZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMgogICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7CglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8yLCBOVUxMLAoJICAgICJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCIpOwogICAgICAgIHJldHVybiAodmN0eHQtPmVycik7CiAgICB9CiAgICBpZiAoYWN0dWFsVHlwZSA9PSBOVUxMKSB7CiAgICAJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIpOwogICAgCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSk7CiAgICB9CiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCWludCByZXQ7Cgl4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDMKCSogSGFuZGxlICd4c2k6bmlsJy4KCSovCglpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCSAgICBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OSUwpOwoJaWYgKGlhdHRyKSB7CgkgICAgQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKTsKCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQlBQ1RYVF9DQVNUIHZjdHh0LCBOVUxMLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJCWlhdHRyLT52YWx1ZSwgJihpYXR0ci0+dmFsKSwgMSwgMCwgMCk7CgkgICAgQUNUSVZBVEVfRUxFTTsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2wiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkgdG8gIgoJCSAgICAidmFsaWRhdGUgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSB7CgkJICAgIC8qCgkJICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMy4xCgkJICAgICovCgkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMSwgTlVMTCwKCQkJIlRoZSBlbGVtZW50IGlzIG5vdCAnbmlsbGFibGUnIik7CgkJICAgIC8qIERvZXMgbm90IHJldHVybiBhbiBlcnJvciBvbiBwdXJwb3NlLiAqLwoJCX0gZWxzZSB7CgkJICAgIGlmICh4bWxTY2hlbWFWYWx1ZUdldEFzQm9vbGVhbihpYXR0ci0+dmFsKSkgewoJCQkvKgoJCQkqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMi4yCgkJCSovCgkJCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCQkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCBOVUxMLAoJCQkJIlRoZSBlbGVtZW50IGNhbm5vdCBiZSAnbmlsbGVkJyBiZWNhdXNlICIKCQkJCSJ0aGVyZSBpcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQgZGVmaW5lZCAiCgkJCQkiZm9yIGl0Iik7CgkJCSAgICAgLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkJCX0gZWxzZQoJCQkgICAgdmN0eHQtPmlub2RlLT5mbGFncyB8PQoJCQkJWE1MX1NDSEVNQV9FTEVNX0lORk9fTklMTEVEOwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDQKCSogSGFuZGxlICd4c2k6dHlwZScuCgkqLwoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkgICAgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CglpZiAoaWF0dHIpIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIGxvY2FsVHlwZSA9IE5VTEw7CgoJICAgIHJldCA9IHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHZjdHh0LCBpYXR0ciwgJmxvY2FsVHlwZSwKCQllbGVtRGVjbCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJCSJwcm9jZXNzIHRoZSBhdHRyaWJ1dGUgJ3hzaTp0eXBlJyIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkgICAgfQoJICAgIGlmIChsb2NhbFR5cGUgIT0gTlVMTCkgewoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fTE9DQUxfVFlQRTsKCQlhY3R1YWxUeXBlID0gbG9jYWxUeXBlOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIElEQzogUmVnaXN0ZXIgaWRlbnRpdHktY29uc3RyYWludCBYUGF0aCBtYXRjaGVycy4KICAgICovCiAgICBpZiAoKGVsZW1EZWNsLT5pZGNzICE9IE5VTEwpICYmCgkoeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyh2Y3R4dCwgZWxlbURlY2wpID09IC0xKSkKCSAgICByZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIE5vIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgLyoKICAgICogUmVtZW1iZXIgdGhlIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgdmN0eHQtPmlub2RlLT50eXBlRGVmID0gYWN0dWFsVHlwZTsKCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZBdHRyaWJ1dGVzU2ltcGxlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CiAgICBpbnQgcmV0ID0gMCwgaTsKCiAgICAvKgogICAgKiBTUEVDIGN2Yy10eXBlICgzLjEuMSkKICAgICogIlRoZSBhdHRyaWJ1dGVzIG9mIG11c3QgYmUgZW1wdHksIGV4Y2VwdGluZyB0aG9zZSB3aG9zZSBuYW1lc3BhY2UKICAgICogbmFtZSBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kCiAgICAqIHdob3NlIGxvY2FsIG5hbWUgaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3IKICAgICogbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbi4iCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJaWYgKCEgaWF0dHItPm1ldGFUeXBlKSB7CgkgICAgQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKQoJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGlhdHRyLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMTsKICAgICAgICB9CiAgICB9CiAgICBBQ1RJVkFURV9FTEVNCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qCiogQ2xlYW51cCBjdXJyZW50bHkgdXNlZCBhdHRyaWJ1dGUgaW5mb3MuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IGk7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBhdHRyOwoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybjsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTKSB7CgkgICAgaWYgKGF0dHItPmxvY2FsTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUoKHhtbENoYXIgKikgYXR0ci0+bG9jYWxOYW1lKTsKCSAgICBpZiAoYXR0ci0+bnNOYW1lICE9IE5VTEwpCgkJeG1sRnJlZSgoeG1sQ2hhciAqKSBhdHRyLT5uc05hbWUpOwoJfQoJaWYgKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCSAgICBpZiAoYXR0ci0+dmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKCh4bWxDaGFyICopIGF0dHItPnZhbHVlKTsKCX0KCWlmIChhdHRyLT52YWwgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShhdHRyLT52YWwpOwoJICAgIGF0dHItPnZhbCA9IE5VTEw7Cgl9CgltZW1zZXQoYXR0ciwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICB9CiAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwp9CgovKgoqIDMuNC40IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKKiAgIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKSAoY3ZjLWNvbXBsZXgtdHlwZSkKKiAzLjIuNCBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gVmFsaWRhdGlvbiBSdWxlcwoqICAgVmFsaWRhdGlvbiBSdWxlOiBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoY3ZjLWF0dHJpYnV0ZSkKKiAgIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpIChjdmMtYXUpCioKKiBPbmx5ICJhc3Nlc3NlZCIgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIHdpbGwgYmUgdmlzaWJsZSB0bwoqIElEQ3MuIEkuZS4gbm90ICJsYXgiICh3aXRob3V0IGRlY2xhcmF0aW9uKSBhbmQgInNraXAiIHdpbGQgYXR0cmlidXRlcy4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSB2Y3R4dC0+aW5vZGUtPnR5cGVEZWY7ICAgIAogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgYXR0clVzZUxpc3Q7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVVc2VQdHIgYXR0clVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2wgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHIsIHRtcGlhdHRyOwogICAgaW50IGksIGosIGZvdW5kLCBuYkF0dHJzLCBuYlVzZXM7CiAgICBpbnQgeHBhdGhSZXMgPSAwLCByZXMsIHdpbGRJRHMgPSAwLCBmaXhlZDsKCiAgICAvKgogICAgKiBTUEVDIChjdmMtYXR0cmlidXRlKQogICAgKiAoMSkgIlRoZSBkZWNsYXJhdGlvbiBtdXN0IG5vdCBiZSC3YWJzZW50tyAoc2VlIE1pc3NpbmcKICAgICogU3ViLWNvbXBvbmVudHMgKKc1LjMpIGZvciBob3cgdGhpcyBjYW4gZmFpbCB0byBiZQogICAgKiB0aGUgY2FzZSkuIgogICAgKiAoMikgIkl0cyB7dHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBiZSBhYnNlbnQuIgogICAgKgogICAgKiBOT1RFICgxKSArICgyKTogVGhpcyBpcyBub3QgaGFuZGxlZCBoZXJlLCBzaW5jZSB3ZSBjdXJyZW50bHkgZG8gbm90CiAgICAqIGFsbG93IHZhbGlkYXRpb24gYWdhaW5zdCBzY2hlbWFzIHdoaWNoIGhhdmUgbWlzc2luZyBzdWItY29tcG9uZW50cy4KICAgICoKICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKICAgICogKDMpICJGb3IgZWFjaCBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBpbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbgogICAgKiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIGV4Y2VwdGluZyB0aG9zZSB3aG9zZSBbbmFtZXNwYWNlIG5hbWVdIGlzCiAgICAqIGlkZW50aWNhbCB0byBodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBhbmQgd2hvc2UKICAgICogW2xvY2FsIG5hbWVdIGlzIG9uZSBvZiB0eXBlLCBuaWwsIHNjaGVtYUxvY2F0aW9uIG9yCiAgICAqIG5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24sIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcKICAgICogbXVzdCBiZSB0cnVlOgogICAgKgogICAgKi8KICAgIGF0dHJVc2VMaXN0ID0gKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSB0eXBlLT5hdHRyVXNlczsKICAgIC8qCiAgICAqIEBuYkF0dHJzIGlzIHRoZSBudW1iZXIgb2YgYXR0cmlidXRlcyBwcmVzZW50IGluIHRoZSBpbnN0YW5jZS4KICAgICovCiAgICBuYkF0dHJzID0gdmN0eHQtPm5iQXR0ckluZm9zOwogICAgaWYgKGF0dHJVc2VMaXN0ICE9IE5VTEwpCgluYlVzZXMgPSBhdHRyVXNlTGlzdC0+bmJJdGVtczsKICAgIGVsc2UKCW5iVXNlcyA9IDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgbmJVc2VzOyBpKyspIHsKICAgICAgICBmb3VuZCA9IDA7CglhdHRyVXNlID0gYXR0clVzZUxpc3QtPml0ZW1zW2ldOwoJYXR0ckRlY2wgPSBXWFNfQVRUUlVTRV9ERUNMKGF0dHJVc2UpOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBuYkF0dHJzOyBqKyspIHsKCSAgICBpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3Nbal07CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgzKQoJICAgICogU2tpcCBtZXRhIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAoaWF0dHItPm1ldGFUeXBlKQoJCWNvbnRpbnVlOwoJICAgIGlmIChpYXR0ci0+bG9jYWxOYW1lWzBdICE9IGF0dHJEZWNsLT5uYW1lWzBdKQoJCWNvbnRpbnVlOwoJICAgIGlmICgheG1sU3RyRXF1YWwoaWF0dHItPmxvY2FsTmFtZSwgYXR0ckRlY2wtPm5hbWUpKQoJCWNvbnRpbnVlOwoJICAgIGlmICgheG1sU3RyRXF1YWwoaWF0dHItPm5zTmFtZSwgYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSkpCgkJY29udGludWU7CgkgICAgZm91bmQgPSAxOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJICAgICogKDMuMSkgIklmIHRoZXJlIGlzIGFtb25nIHRoZSB7YXR0cmlidXRlIHVzZXN9IGFuIGF0dHJpYnV0ZQoJICAgICogdXNlIHdpdGggYW4ge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gd2hvc2Uge25hbWV9IG1hdGNoZXMKCSAgICAqIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSdzIFtsb2NhbCBuYW1lXSBhbmQgd2hvc2UKCSAgICAqIHt0YXJnZXQgbmFtZXNwYWNlfSBpcyBpZGVudGljYWwgdG8gdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbgoJICAgICogaXRlbSdzIFtuYW1lc3BhY2UgbmFtZV0gKHdoZXJlIGFuILdhYnNlbnS3IHt0YXJnZXQgbmFtZXNwYWNlfQoJICAgICogaXMgdGFrZW4gdG8gYmUgaWRlbnRpY2FsIHRvIGEgW25hbWVzcGFjZSBuYW1lXSB3aXRoIG5vIHZhbHVlKSwKCSAgICAqIHRoZW4gdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0CgkgICAgKiB0byB0aGF0IGF0dHJpYnV0ZSB1c2UgYXMgcGVyIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpCgkgICAgKiAopzMuNS40KS4gSW4gdGhpcyBjYXNlIHRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBvZiB0aGF0CgkgICAgKiBhdHRyaWJ1dGUgdXNlIGlzIHRoZSC3Y29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9utyBmb3IgdGhlCgkgICAgKiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHJlc3BlY3QgdG8gU2NoZW1hLVZhbGlkaXR5CgkgICAgKiBBc3Nlc3NtZW50IChBdHRyaWJ1dGUpICinMy4yLjQpIGFuZAoJICAgICogQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpICinMy4yLjUpLgoJICAgICovCgkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRDsKCSAgICBpYXR0ci0+dXNlID0gYXR0clVzZTsKCSAgICAvKgoJICAgICogQ29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9uLgoJICAgICovCgkgICAgaWF0dHItPmRlY2wgPSBhdHRyRGVjbDsKCSAgICBpYXR0ci0+dHlwZURlZiA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCSAgICBicmVhazsKCX0KCglpZiAoZm91bmQpCgkgICAgY29udGludWU7CgoJaWYgKGF0dHJVc2UtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkgewoJICAgIC8qCgkgICAgKiBIYW5kbGUgbm9uLWV4aXN0ZW50LCByZXF1aXJlZCBhdHRyaWJ1dGVzLgoJICAgICoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkgICAgKiAoNCkgIlRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBvZiBlYWNoIGF0dHJpYnV0ZSB1c2UgaW4KCSAgICAqIHRoZSB7YXR0cmlidXRlIHVzZXN9IHdob3NlIHtyZXF1aXJlZH0gaXMgdHJ1ZSBtYXRjaGVzIG9uZQoJICAgICogb2YgdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtcyBpbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbgoJICAgICogaXRlbSdzIFthdHRyaWJ1dGVzXSBhcyBwZXIgY2xhdXNlIDMuMSBhYm92ZS4iCgkgICAgKi8KCSAgICB0bXBpYXR0ciA9IHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8odmN0eHQpOwoJICAgIGlmICh0bXBpYXR0ciA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgKCQkgICAgInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oKSIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICB0bXBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HOwoJICAgIHRtcGlhdHRyLT51c2UgPSBhdHRyVXNlOwoJICAgIHRtcGlhdHRyLT5kZWNsID0gYXR0ckRlY2w7CSAgICAKCX0gZWxzZSBpZiAoKGF0dHJVc2UtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCSAgICAoKGF0dHJVc2UtPmRlZlZhbHVlICE9IE5VTEwpIHx8CgkgICAgIChhdHRyRGVjbC0+ZGVmVmFsdWUgIT0gTlVMTCkpKSB7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBub24tZXhpc3RlbnQsIG9wdGlvbmFsLCBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICB0bXBpYXR0ciA9IHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8odmN0eHQpOwoJICAgIGlmICh0bXBpYXR0ciA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgKCQkgICAgInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oKSIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICB0bXBpYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQ7CgkgICAgdG1waWF0dHItPnVzZSA9IGF0dHJVc2U7CgkgICAgdG1waWF0dHItPmRlY2wgPSBhdHRyRGVjbDsKCSAgICB0bXBpYXR0ci0+dHlwZURlZiA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCSAgICB0bXBpYXR0ci0+bG9jYWxOYW1lID0gYXR0ckRlY2wtPm5hbWU7CgkgICAgdG1waWF0dHItPm5zTmFtZSA9IGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2U7Cgl9CiAgICB9CgogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKICAgIG5iVXNlcyA9IHZjdHh0LT5uYkF0dHJJbmZvczsKICAgIC8qCiAgICAqIFZhbGlkYXRlIGFnYWluc3QgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkvKgoJKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJKiAoMy4yLjEpICJUaGVyZSBtdXN0IGJlIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LiIKCSovCglmb3IgKGkgPSAwOyBpIDwgbmJBdHRyczsgaSsrKSB7CgkgICAgaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMykKCSAgICAqIFNraXAgbWV0YSBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKGlhdHRyLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pCgkJY29udGludWU7CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkgICAgKiAoMy4yLjIpICJUaGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSC3dmFsaWS3IHdpdGgKCSAgICAqIHJlc3BlY3QgdG8gaXQgYXMgZGVmaW5lZCBpbiBJdGVtIFZhbGlkIChXaWxkY2FyZCkgKKczLjEwLjQpLiIKCSAgICAqCgkgICAgKiBTUEVDIEl0ZW0gVmFsaWQgKFdpbGRjYXJkKSAoY3ZjLXdpbGRjYXJkKQoJICAgICogIi4uLiBpdHMgW25hbWVzcGFjZSBuYW1lXSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvCgkgICAgKiB0aGUgd2lsZGNhcmQgY29uc3RyYWludCwgYXMgZGVmaW5lZCBpbiBXaWxkY2FyZCBhbGxvd3MKCSAgICAqIE5hbWVzcGFjZSBOYW1lICinMy4xMC40KS4iCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZSh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCQkgICAgaWF0dHItPm5zTmFtZSkgPT0gMCkgewoJCS8qCgkJKiBIYW5kbGUgcHJvY2Vzc0NvbnRlbnRzLgoJCSoKCQkqIFNQRUMgKGN2Yy13aWxkY2FyZCk6CgkJKiBwcm9jZXNzQ29udGVudHMgfCBjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb246CgkJKiAic3RyaWN0IiAgICAgICAgICAibXVzdEZpbmQiCgkJKiAibGF4IiAgICAgICAgICAgICAibm9uZSIKCQkqICJza2lwIiAgICAgICAgICAgICJza2lwIgoJCSovCgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0KCQkgICAgWE1MX1NDSEVNQVNfQU5ZX1NLSVApIHsKCQkgICAgIC8qCgkJICAgICogY29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9uID0gInNraXAiCgkJICAgICoKCQkgICAgKiBTUEVDIFBTVkkgQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpCgkJICAgICogW3ZhbGlkaXR5XSA9ICJub3RLbm93biIKCQkgICAgKiBbdmFsaWRhdGlvbiBhdHRlbXB0ZWRdID0gIm5vbmUiCgkJICAgICovCgkJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9TS0lQOwoJCSAgICBjb250aW51ZTsKCQl9CgkJLyoKCQkqIEZpbmQgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJCSovCgkJaWF0dHItPmRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKHZjdHh0LT5zY2hlbWEsCgkJICAgIGlhdHRyLT5sb2NhbE5hbWUsIGlhdHRyLT5uc05hbWUpOwoJCWlmIChpYXR0ci0+ZGVjbCAhPSBOVUxMKSB7CgkJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQVNTRVNTRUQ7CgkJICAgIC8qCgkJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCQkgICAgKiAoNSkgIkxldCBbRGVmaW5pdGlvbjpdICB0aGUgd2lsZCBJRHMgYmUgdGhlIHNldCBvZgoJCSAgICAqIGFsbCBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB0byB3aGljaCBjbGF1c2UgMy4yCgkJICAgICogYXBwbGllZCBhbmQgd2hvc2Ugt3ZhbGlkYXRpb263IHJlc3VsdGVkIGluIGEKCQkgICAgKiC3Y29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9utyBvZiBtdXN0RmluZCBvciBubwoJCSAgICAqILdjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb263IGF0IGFsbCwgYW5kIHdob3NlCgkJICAgICogW2xvY2FsIG5hbWVdIGFuZCBbbmFtZXNwYWNlIG5hbWVdIHJlc29sdmUgKGFzCgkJICAgICogZGVmaW5lZCBieSBRTmFtZSByZXNvbHV0aW9uIChJbnN0YW5jZSkgKKczLjE1LjQpKSB0bwoJCSAgICAqIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiB3aG9zZSB7dHlwZSBkZWZpbml0aW9ufSBpcwoJCSAgICAqIG9yIGlzIGRlcml2ZWQgZnJvbSBJRC4gVGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZwoJCSAgICAqIG11c3QgYmUgdHJ1ZToiCgkJICAgICovCgkJICAgIGlhdHRyLT50eXBlRGVmID0gV1hTX0FUVFJfVFlQRURFRihpYXR0ci0+ZGVjbCk7CgkJICAgIGlmICh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoCgkJCWlhdHRyLT50eXBlRGVmLCBYTUxfU0NIRU1BU19JRCkpIHsKCQkJLyoKCQkJKiBTUEVDICg1LjEpICJUaGVyZSBtdXN0IGJlIG5vIG1vcmUgdGhhbiBvbmUKCQkJKiBpdGVtIGluILd3aWxkIElEc7cuIgoJCQkqLwoJCQlpZiAod2lsZElEcyAhPSAwKSB7CgkJCSAgICAvKiBWQUwgVE9ETyAqLwoJCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9EVVBMSUNBVEVfSUQ7CgkJCSAgICBUT0RPCgkJCSAgICBjb250aW51ZTsKCQkJfQoJCQl3aWxkSURzKys7CgkJCS8qCgkJCSogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCQkJKiAoNS4yKSAiSWYgt3dpbGQgSURztyBpcyBub24tZW1wdHksIHRoZXJlIG11c3Qgbm90CgkJCSogYmUgYW55IGF0dHJpYnV0ZSB1c2VzIGFtb25nIHRoZSB7YXR0cmlidXRlIHVzZXN9CgkJCSogd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0ncyB7dHlwZSBkZWZpbml0aW9ufQoJCQkqIGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRC4iCgkJCSovCgkJCWZvciAoaiA9IDA7IGogPCBhdHRyVXNlTGlzdC0+bmJJdGVtczsgaisrKSB7CgkJCSAgICBpZiAoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKAoJCQkJV1hTX0FUVFJVU0VfVFlQRURFRihhdHRyVXNlTGlzdC0+aXRlbXNbal0pLAoJCQkJWE1MX1NDSEVNQVNfSUQpKSB7CgkJCQkvKiBVUkdFTlQgVkFMIFRPRE86IGltcGxlbWVudCAqLwoJCQkJaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9BTkRfVVNFX0lEOwoJCQkJVE9ETwoJCQkJYnJlYWs7CgkJCSAgICB9CgkJCX0KCQkgICAgfQoJCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PQoJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9MQVhfTk9fREVDTDsKCQkgICAgLyoKCQkgICAgKiBTUEVDIFBTVkkgQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpCgkJICAgICogW3ZhbGlkaXR5XSA9ICJub3RLbm93biIKCQkgICAgKiBbdmFsaWRhdGlvbiBhdHRlbXB0ZWRdID0gIm5vbmUiCgkJICAgICovCgkJfSBlbHNlIHsKCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9TVFJJQ1RfTk9fREVDTDsKCQl9CgkgICAgfQoJfQogICAgfQoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybiAoMCk7CgogICAgLyoKICAgICogVmFsaWRhdGUgdmFsdWVzLCBjcmVhdGUgZGVmYXVsdCBhdHRyaWJ1dGVzLCBldmFsdWF0ZSBJRENzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJLyoKCSogVkFMIFRPRE86IE5vdGUgdGhhdCB3ZSB3b24ndCB0cnkgdG8gcmVzb2x2ZSBJRENzIHRvCgkqICJsYXgiIGFuZCAic2tpcCIgdmFsaWRhdGVkIGF0dHJpYnV0ZXMuIENoZWNrIHdoYXQgdG8KCSogZG8gaW4gdGhpcyBjYXNlLgoJKi8KCWlmICgoaWF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfQVNTRVNTRUQpICYmCgkgICAgKGlhdHRyLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQpKQoJICAgIGNvbnRpbnVlOwoJLyoKCSogVkFMIFRPRE86IFdoYXQgdG8gZG8gaWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBtaXNzaW5nPwoJKi8KCWlmIChpYXR0ci0+dHlwZURlZiA9PSBOVUxMKSB7CgkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfTk9fVFlQRTsKCSAgICBjb250aW51ZTsKCX0KCglBQ1RJVkFURV9BVFRSSUJVVEUoaWF0dHIpOwoJZml4ZWQgPSAwOwoJeHBhdGhSZXMgPSAwOwoKCWlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBFdmFsdWF0ZSBJRENzLgoJICAgICovCgkgICAgeHBhdGhSZXMgPSB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKHZjdHh0LAoJCVhNTF9BVFRSSUJVVEVfTk9ERSk7CgkgICAgaWYgKHhwYXRoUmVzID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9CgoJaWYgKGlhdHRyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQpIHsKCSAgICAvKgoJICAgICogRGVmYXVsdC9maXhlZCBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKHhwYXRoUmVzKSB7CgkJaWYgKGlhdHRyLT51c2UtPmRlZlZhbHVlICE9IE5VTEwpIHsKCQkgICAgaWF0dHItPnZhbHVlID0gKHhtbENoYXIgKikgaWF0dHItPnVzZS0+ZGVmVmFsdWU7CgkJICAgIGlhdHRyLT52YWwgPSBpYXR0ci0+dXNlLT5kZWZWYWw7CgkJfSBlbHNlIHsKCQkgICAgaWF0dHItPnZhbHVlID0gKHhtbENoYXIgKikgaWF0dHItPmRlY2wtPmRlZlZhbHVlOwoJCSAgICBpYXR0ci0+dmFsID0gaWF0dHItPmRlY2wtPmRlZlZhbDsKCQl9CgkJLyoKCQkqIElEQ3Mgd2lsbCBjb25zdW1lIHRoZSBwcmVjb21wdXRlZCBkZWZhdWx0IHZhbHVlLAoJCSogc28gd2UgbmVlZCB0byBjbG9uZSBpdC4KCQkqLwoJCWlmIChpYXR0ci0+dmFsID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkJImRlZmF1bHQvZml4ZWQgdmFsdWUgb24gYW4gYXR0cmlidXRlIHVzZSB3YXMgIgoJCQkibm90IHByZWNvbXB1dGVkIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWlhdHRyLT52YWwgPSB4bWxTY2hlbWFDb3B5VmFsdWUoaWF0dHItPnZhbCk7CgkJaWYgKGlhdHRyLT52YWwgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFDb3B5VmFsdWUoKSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIFBTVkk6IEFkZCB0aGUgZGVmYXVsdCBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4KCSAgICAqIFZBTCBUT0RPOiBTaG91bGQgd2UgdXNlIHRoZSAqbm9ybWFsaXplZCogdmFsdWU/IFRoaXMgY3VycmVudGx5CgkgICAgKiAgIHVzZXMgdGhlICppbml0aWFsKiB2YWx1ZS4KCSAgICAqLwoJICAgIGlmICgodmN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgJiYKCQkoaWF0dHItPm5vZGUgIT0gTlVMTCkgJiYgKGlhdHRyLT5ub2RlLT5kb2MgIT0gTlVMTCkpIHsKCQl4bWxDaGFyICpub3JtVmFsdWU7CgkJY29uc3QgeG1sQ2hhciAqdmFsdWU7CgoJCXZhbHVlID0gaWF0dHItPnZhbHVlOwoJCS8qCgkJKiBOb3JtYWxpemUgdGhlIHZhbHVlLgoJCSovCgkJbm9ybVZhbHVlID0geG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoaWF0dHItPnR5cGVEZWYsCgkJICAgIGlhdHRyLT52YWx1ZSk7CgkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCSAgICB2YWx1ZSA9IEJBRF9DQVNUIG5vcm1WYWx1ZTsKCgkJaWYgKGlhdHRyLT5uc05hbWUgPT0gTlVMTCkgewoJCSAgICBpZiAoeG1sTmV3UHJvcChpYXR0ci0+bm9kZS0+cGFyZW50LAoJCQlpYXR0ci0+bG9jYWxOYW1lLCB2YWx1ZSkgPT0gTlVMTCkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkgICAgImNhbGxsaW5nIHhtbE5ld1Byb3AoKSIpOwoJCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJCSAgICB4bWxGcmVlKG5vcm1WYWx1ZSk7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICB4bWxOc1B0ciBuczsKCgkJICAgIG5zID0geG1sU2VhcmNoTnNCeUhyZWYoaWF0dHItPm5vZGUtPmRvYywKCQkJaWF0dHItPm5vZGUtPnBhcmVudCwgaWF0dHItPm5zTmFtZSk7CgkJICAgIGlmIChucyA9PSBOVUxMKSB7CgkJCXhtbENoYXIgcHJlZml4WzEyXTsKCQkJaW50IGNvdW50ZXIgPSAwOwoKCQkJLyoKCQkJKiBDcmVhdGUgYSBuYW1lc3BhY2UgZGVjbGFyYXRpb24gb24gdGhlIHZhbGlkYXRpb24KCQkJKiByb290IG5vZGUgaWYgbm8gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGluIHNjb3BlLgoJCQkqLwoJCQlkbyB7CgkJCSAgICBzbnByaW50ZigoY2hhciAqKSBwcmVmaXgsIDEyLCAicCVkIiwgY291bnRlcisrKTsKCQkJICAgIG5zID0geG1sU2VhcmNoTnMoaWF0dHItPm5vZGUtPmRvYywKCQkJCWlhdHRyLT5ub2RlLT5wYXJlbnQsIEJBRF9DQVNUIHByZWZpeCk7CgkJCSAgICBpZiAoY291bnRlciA+IDEwMDApIHsKCQkJCVZFUlJPUl9JTlQoCgkJCQkgICAgInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJCQkgICAgImNvdWxkIG5vdCBjb21wdXRlIGEgbnMgcHJlZml4IGZvciBhICIKCQkJCSAgICAiZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGUiKTsKCQkJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkJCSAgICB4bWxGcmVlKG5vcm1WYWx1ZSk7CgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgfQoJCQl9IHdoaWxlIChucyAhPSBOVUxMKTsKCQkJbnMgPSB4bWxOZXdOcyh2Y3R4dC0+dmFsaWRhdGlvblJvb3QsCgkJCSAgICBpYXR0ci0+bnNOYW1lLCBCQURfQ0FTVCBwcmVmaXgpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogVE9ETzoKCQkgICAgKiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy93d3cteG1sLXNjaGVtYS1jb21tZW50cy8yMDA1SnVsU2VwLzA0MDYuaHRtbAoJCSAgICAqIElmIHdlIGhhdmUgUU5hbWVzOiBkbyB3ZSBuZWVkIHRvIGVuc3VyZSB0aGVyZSdzIGEKCQkgICAgKiBwcmVmaXggZGVmaW5lZCBmb3IgdGhlIFFOYW1lPwoJCSAgICAqLwoJCSAgICB4bWxOZXdOc1Byb3AoaWF0dHItPm5vZGUtPnBhcmVudCwgbnMsCgkJCWlhdHRyLT5sb2NhbE5hbWUsIHZhbHVlKTsKCQl9CgkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCSAgICB4bWxGcmVlKG5vcm1WYWx1ZSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBHbyBkaXJlY3RseSB0byBJREMgZXZhbHVhdGlvbi4KCSAgICAqLwoJICAgIGdvdG8gZXZhbF9pZGNzOwoJfQoJLyoKCSogVmFsaWRhdGUgdGhlIHZhbHVlLgoJKi8KCWlmICh2Y3R4dC0+dmFsdWUgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBGcmVlIGxhc3QgY29tcHV0ZWQgdmFsdWU7IGp1c3QgZm9yIHNhZmV0eSByZWFzb25zLgoJICAgICovCgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKHZjdHh0LT52YWx1ZSk7CgkgICAgdmN0eHQtPnZhbHVlID0gTlVMTDsKCX0KCS8qCgkqIE5vdGUgdGhhdCB0aGUgYXR0cmlidXRlICp1c2UqIGNhbiBiZSB1bmF2YWlsYWJsZSwgaWYKCSogdGhlIGF0dHJpYnV0ZSB3YXMgYSB3aWxkIGF0dHJpYnV0ZS4KCSovCglpZiAoKGlhdHRyLT5kZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpIHx8CgkgICAgKChpYXR0ci0+dXNlICE9IE5VTEwpICYmCgkgICAgIChpYXR0ci0+dXNlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpKSkKCSAgICBmaXhlZCA9IDE7CgllbHNlCgkgICAgZml4ZWQgPSAwOwoJLyoKCSogU1BFQyAoY3ZjLWF0dHJpYnV0ZSkKCSogKDMpICJUaGUgaXRlbSdzILdub3JtYWxpemVkIHZhbHVltyBtdXN0IGJlIGxvY2FsbHkgt3ZhbGlktwoJKiB3aXRoIHJlc3BlY3QgdG8gdGhhdCB7dHlwZSBkZWZpbml0aW9ufSBhcyBwZXIgCgkqIFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIgoJKgoJKiBWQUwgVE9ETzogRG8gd2UgYWxyZWFkeSBoYXZlIHRoZQoJKiAibm9ybWFsaXplZCBhdHRyaWJ1dGUgdmFsdWUiIGhlcmU/CgkqLwoJaWYgKHhwYXRoUmVzIHx8IGZpeGVkKSB7CgkgICAgaWF0dHItPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRDsKCSAgICAvKgoJICAgICogUmVxdWVzdCBhIGNvbXB1dGVkIHZhbHVlLgoJICAgICovCgkgICAgcmVzID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQlBQ1RYVF9DQVNUIHZjdHh0LAoJCWlhdHRyLT5ub2RlLCBpYXR0ci0+dHlwZURlZiwgaWF0dHItPnZhbHVlLCAmKGlhdHRyLT52YWwpLAoJCTEsIDEsIDApOwoJfSBlbHNlIHsKCSAgICByZXMgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJCUFDVFhUX0NBU1QgdmN0eHQsCgkJaWF0dHItPm5vZGUsIGlhdHRyLT50eXBlRGVmLCBpYXR0ci0+dmFsdWUsIE5VTEwsCgkJMSwgMCwgMCk7Cgl9CgkgICAgCglpZiAocmVzICE9IDApIHsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hU3RyZWFtVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCSAgICAvKgoJICAgICogU1BFQyBQU1ZJIEFzc2Vzc21lbnQgT3V0Y29tZSAoQXR0cmlidXRlKQoJICAgICogW3ZhbGlkaXR5XSA9ICJpbnZhbGlkIgoJICAgICovCgkgICAgZ290byBldmFsX2lkY3M7Cgl9CgoJaWYgKGZpeGVkKSB7CSAgICAKCSAgICAvKgoJICAgICogU1BFQyBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoVXNlKSAoY3ZjLWF1KQoJICAgICogIkZvciBhbiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB0byBiZbd2YWxpZLcKCSAgICAqIHdpdGggcmVzcGVjdCB0byBhbiBhdHRyaWJ1dGUgdXNlIGl0cyAqbm9ybWFsaXplZCoKCSAgICAqIHZhbHVltyBtdXN0IG1hdGNoIHRoZSAqY2Fub25pY2FsKiBsZXhpY2FsCgkgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXR0cmlidXRlIHVzZSdzIHt2YWx1ZQoJICAgICogY29uc3RyYWludH12YWx1ZSwgaWYgaXQgaXMgcHJlc2VudCBhbmQgZml4ZWQuIgoJICAgICoKCSAgICAqIFZBTCBUT0RPOiBUaGUgcmVxdWlyZW1lbnQgZm9yIHRoZSAqY2Fub25pY2FsKiB2YWx1ZQoJICAgICogd2lsbCBiZSByZW1vdmVkIGluIFhNTCBTY2hlbWEgMS4xLgoJICAgICovCgkgICAgLyoKCSAgICAqIFNQRUMgQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKGN2Yy1hdHRyaWJ1dGUpCgkgICAgKiAoNCkgIlRoZSBpdGVtJ3MgKmFjdHVhbCogdmFsdWW3IG11c3QgbWF0Y2ggdGhlICp2YWx1ZSogb2YKCSAgICAqIHRoZSB7dmFsdWUgY29uc3RyYWludH0sIGlmIGl0IGlzIHByZXNlbnQgYW5kIGZpeGVkLiIKCSAgICAqLwoJICAgIGlmIChpYXR0ci0+dmFsID09IE5VTEwpIHsKCQkvKiBWQUwgVE9ETzogQSB2YWx1ZSB3YXMgbm90IHByZWNvbXB1dGVkLiAqLwoJCVRPRE8KCQlnb3RvIGV2YWxfaWRjczsKCSAgICB9CgkgICAgaWYgKChpYXR0ci0+dXNlICE9IE5VTEwpICYmCgkJKGlhdHRyLT51c2UtPmRlZlZhbHVlICE9IE5VTEwpKSB7CgkJaWYgKGlhdHRyLT51c2UtPmRlZlZhbCA9PSBOVUxMKSB7CgkJICAgIC8qIFZBTCBUT0RPOiBBIGRlZmF1bHQgdmFsdWUgd2FzIG5vdCBwcmVjb21wdXRlZC4gKi8KCQkgICAgVE9ETwoJCSAgICBnb3RvIGV2YWxfaWRjczsKCQl9CgkJaWF0dHItPnZjVmFsdWUgPSBpYXR0ci0+dXNlLT5kZWZWYWx1ZTsKCQkvKgoJCWlmICh4bWxTY2hlbWFDb21wYXJlVmFsdWVzV2h0c3AoYXR0ci0+dmFsLAoJCSAgICAoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MsCgkJICAgIGF0dHItPnVzZS0+ZGVmVmFsLAoJCSAgICAoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MpICE9IDApIHsKCQkqLwoJCWlmICghIHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGlhdHRyLT52YWwsIGlhdHRyLT51c2UtPmRlZlZhbCkpCgkJICAgIGlhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX0ZJWEVEX1ZBTFVFOwoJICAgIH0gZWxzZSB7CgkJaWYgKGlhdHRyLT5kZWNsLT5kZWZWYWwgPT0gTlVMTCkgewoJCSAgICAvKiBWQUwgVE9ETzogQSBkZWZhdWx0IHZhbHVlIHdhcyBub3QgcHJlY29tcHV0ZWQuICovCgkJICAgIFRPRE8KCQkgICAgZ290byBldmFsX2lkY3M7CgkJfQoJCWlhdHRyLT52Y1ZhbHVlID0gaWF0dHItPmRlY2wtPmRlZlZhbHVlOwoJCS8qCgkJaWYgKHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXNXaHRzcChhdHRyLT52YWwsCgkJICAgICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cywKCQkgICAgYXR0ckRlY2wtPmRlZlZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzKSAhPSAwKSB7CgkJKi8KCQlpZiAoISB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChpYXR0ci0+dmFsLCBpYXR0ci0+ZGVjbC0+ZGVmVmFsKSkKCQkgICAgaWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUU7CgkgICAgfQoJICAgIC8qCgkgICAgKiBbdmFsaWRpdHldID0gInZhbGlkIgoJICAgICovCgl9CmV2YWxfaWRjczoKCS8qCgkqIEV2YWx1YXRlIElEQ3MuCgkqLwoJaWYgKHhwYXRoUmVzKSB7CgkgICAgaWYgKHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkodmN0eHQsCgkJdmN0eHQtPmRlcHRoICsxKSA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJfSBlbHNlIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkKCSAgICB4bWxTY2hlbWFYUGF0aFBvcCh2Y3R4dCk7CiAgICB9CgogICAgLyoKICAgICogUmVwb3J0IGVycm9ycy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPm5iQXR0ckluZm9zOyBpKyspIHsKCWlhdHRyID0gdmN0eHQtPmF0dHJJbmZvc1tpXTsKCWlmICgoaWF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSkgfHwKCSAgICAoaWF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfQVNTRVNTRUQpIHx8CgkgICAgKGlhdHRyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1dJTERfU0tJUCkgfHwKCSAgICAoaWF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9MQVhfTk9fREVDTCkpCgkgICAgY29udGludWU7CglBQ1RJVkFURV9BVFRSSUJVVEUoaWF0dHIpOwoJc3dpdGNoIChpYXR0ci0+c3RhdGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkc6IHsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkgICAgQUNUSVZBVEVfRUxFTTsKCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfNCwgTlVMTCwgTlVMTCwKCQkJIlRoZSBhdHRyaWJ1dGUgJyVzJyBpcyByZXF1aXJlZCBidXQgbWlzc2luZyIsCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCSAgICBpYXR0ci0+ZGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkgICAgaWF0dHItPmRlY2wtPm5hbWUpLAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGJyZWFrOwoJCX0KCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX05PX1RZUEU6CgkJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19BVFRSSUJVVEVfMiwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRToKCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0FVLCBOVUxMLCBOVUxMLAoJCSAgICAiVGhlIHZhbHVlICclcycgZG9lcyBub3QgbWF0Y2ggdGhlIGZpeGVkICIKCQkgICAgInZhbHVlIGNvbnN0cmFpbnQgJyVzJyIsIAoJCSAgICBpYXR0ci0+dmFsdWUsIGlhdHRyLT52Y1ZhbHVlKTsJCQoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9TVFJJQ1RfTk9fREVDTDoKCQlWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX1dJTERDQVJELCBOVUxMLAoJCSAgICAiTm8gbWF0Y2hpbmcgZ2xvYmFsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBhdmFpbGFibGUsIGJ1dCAiCgkJICAgICJkZW1hbmRlZCBieSB0aGUgc3RyaWN0IHdpbGRjYXJkIik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV046CgkJaWYgKGlhdHRyLT5tZXRhVHlwZSkKCQkgICAgYnJlYWs7CgkJLyoKCQkqIE1BWUJFIFZBTCBUT0RPOiBPbmUgbWlnaHQgcmVwb3J0IGRpZmZlcmVudCBlcnJvciBtZXNzYWdlcwoJCSogZm9yIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgoJCSovCgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hSWxsZWdhbEF0dHJFcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMSwgaWF0dHIsIE5VTEwpOwoJCX0gZWxzZSB7CgkJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKEFDVFhUX0NBU1QgdmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfM18yXzIsIGlhdHRyLCBOVUxMKTsKCQl9CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KCiAgICBBQ1RJVkFURV9FTEVNOwogICAgcmV0dXJuICgwKTsKaW50ZXJuYWxfZXJyb3I6CiAgICBBQ1RJVkFURV9FTEVNOwogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICBpbnQgKnNraXApCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHZjdHh0LT5pbm9kZS0+ZGVjbDsKICAgIC8qCiAgICAqIFRoZSBuYW1lc3BhY2Ugb2YgdGhlIGVsZW1lbnQgd2FzIGFscmVhZHkgaWRlbnRpZmllZCB0byBiZQogICAgKiBtYXRjaGluZyB0aGUgd2lsZGNhcmQuCiAgICAqLwogICAgaWYgKChza2lwID09IE5VTEwpIHx8ICh3aWxkID09IE5VTEwpIHx8Cgkod2lsZC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQiLAoJICAgICJiYWQgYXJndW1lbnRzIik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgICpza2lwID0gMDsKICAgIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgPT0gWE1MX1NDSEVNQVNfQU5ZX1NLSVApIHsKCS8qCgkqIFVSR0VOVCBWQUwgVE9ETzogRWl0aGVyIHdlIG5lZWQgdG8gcG9zaXRpb24gdGhlIHN0cmVhbSB0byB0aGUKCSogbmV4dCBzaWJsaW5nLCBvciB3YWxrIHRoZSB3aG9sZSBzdWJ0cmVlLgoJKi8KCSpza2lwID0gMTsKCXJldHVybiAoMCk7CiAgICB9CiAgICB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wgPSBOVUxMOwoKCWRlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKHZjdHh0LT5zY2hlbWEsCgkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsJICAgIAoJaWYgKGRlY2wgIT0gTlVMTCkgewoJICAgIHZjdHh0LT5pbm9kZS0+ZGVjbCA9IGRlY2w7CgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgPT0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkgewoJLyogVkFMIFRPRE86IENoYW5nZSB0byBwcm9wZXIgZXJyb3IgY29kZS4gKi8KCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzEsIE5VTEwsIC8qIFdYU19CQVNJQ19DQVNUIHdpbGQgKi8KCSAgICAiTm8gbWF0Y2hpbmcgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb24gYXZhaWxhYmxlLCBidXQgIgoJICAgICJkZW1hbmRlZCBieSB0aGUgc3RyaWN0IHdpbGRjYXJkIik7CglyZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7Cgl4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCS8qCgkqIFNQRUMgVmFsaWRhdGlvbiBSdWxlOiBTY2hlbWEtVmFsaWRpdHkgQXNzZXNzbWVudCAoRWxlbWVudCkKCSogKDEuMi4xLjIuMSkgLSAoMS4yLjEuMi4zICkKCSoKCSogVXNlIHRoZSB4c2k6dHlwZSBhdHRyaWJ1dGUgZm9yIHRoZSB0eXBlIGRlZmluaXRpb24uCgkqLwoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkgICAgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CglpZiAoaWF0dHIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSh2Y3R4dCwgaWF0dHIsCgkJJih2Y3R4dC0+aW5vZGUtPnR5cGVEZWYpLCBOVUxMKSA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJICAgICJwcm9jZXNzIHRoZSBhdHRyaWJ1dGUgJ3hzaTpuaWwnIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBEb24ndCByZXR1cm4gYW4gZXJyb3Igb24gcHVycG9zZS4KCSAgICAqLwoJICAgIHJldHVybiAoMCk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBTUEVDIFZhbGlkYXRpb24gUnVsZTogU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEVsZW1lbnQpCiAgICAqCiAgICAqIEZhbGxiYWNrIHRvICJhbnlUeXBlIi4KICAgICovCiAgICB2Y3R4dC0+aW5vZGUtPnR5cGVEZWYgPQoJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICByZXR1cm4gKDApOwp9CgovKgoqIHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0OgoqCiogVGhpcyB3aWxsIGJlIGNhbGxlZCBpZjogbm90IG5pbGxlZCwgbm8gY29udGVudCBhbmQgYSBkZWZhdWx0L2ZpeGVkCiogdmFsdWUgaXMgcHJvdmlkZWQuCiovCgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsKQp7ICAgCiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlID0gdmN0eHQtPmlub2RlOwoKICAgIC8qCiAgICAqIGNvcy12YWxpZC1kZWZhdWx0OgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogICAgKiBGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0IHdpdGggcmVzcGVjdCB0byBhIHR5cGUgCiAgICAqIGRlZmluaXRpb24gdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLyAgICAKICAgIGlmIFdYU19JU19DT01QTEVYKGlub2RlLT50eXBlRGVmKSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIFNQRUMgKDIuMSkgIml0cyB7Y29udGVudCB0eXBlfSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgoJKiBvciBtaXhlZC4iCgkqIFNQRUMgKDIuMi4yKSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIG1peGVkLCB0aGVuIHRoZSB7Y29udGVudAoJKiB0eXBlfSdzIHBhcnRpY2xlIG11c3QgYmUgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBieSAKCSogUGFydGljbGUgRW1wdGlhYmxlICinMy45LjYpLiIKCSovCglpZiAoKCEgV1hTX0hBU19TSU1QTEVfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpICYmCgkgICAgKCghIFdYU19IQVNfTUlYRURfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHx8CgkgICAgICghIFdYU19FTVBUSUFCTEUoaW5vZGUtPnR5cGVEZWYpKSkpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9DT1NfVkFMSURfREVGQVVMVF8yXzE7CgkgICAgLyogTk9URSB0aGF0IHRoaXMgY292ZXJzICgyLjIuMikgYXMgd2VsbC4gKi8KCSAgICBWRVJST1IocmV0LCBOVUxMLAoJCSJGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0LCB0aGUgdHlwZSBkZWZpbml0aW9uICIKCQkibXVzdCBiZSBhIHNpbXBsZSB0eXBlIG9yIGEgY29tcGxleCB0eXBlIHdpdGggc2ltcGxlIGNvbnRlbnQgIgoJCSJvciBtaXhlZCBjb250ZW50IGFuZCBhIHBhcnRpY2xlIGVtcHRpYWJsZSIpOwoJICAgIHJldHVybihyZXQpOwoJfQogICAgfQkKICAgIC8qCiAgICAqIDEgSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIHN0cmluZyAKICAgICogbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcgCiAgICAqIFZhbGlkICinMy4xNC40KS4KICAgICoKICAgICogQU5ECiAgICAqCiAgICAqIDIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIAogICAgKiBzdHJpbmcgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gCiAgICAqIGFzIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KICAgICovICAKICAgIGlmIChXWFNfSVNfU0lNUExFKGlub2RlLT50eXBlRGVmKSkgewoKCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoQUNUWFRfQ0FTVCB2Y3R4dCwKCSAgICBOVUxMLCBpbm9kZS0+dHlwZURlZiwgdmFsdWUsIHZhbCwgMSwgMSwgMCk7CgogICAgfSBlbHNlIGlmIChXWFNfSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoKCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoQUNUWFRfQ0FTVCB2Y3R4dCwKCSAgICBOVUxMLCBpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGVEZWYsIHZhbHVlLCB2YWwsIDEsIDEsIDApOwogICAgfQogICAgaWYgKHJldCA8IDApIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0IiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKICAgIH0gICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDb250ZW50TW9kZWxDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGl0ZW0sCgkJCSAgICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSkKewogICAgaW5vZGUtPmRlY2wgPSBpdGVtOwojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCglpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgewoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSJBVVRPTUFUT04gY2FsbGJhY2sgZm9yICclcycgW2RlY2xhcmF0aW9uXVxuIiwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCWlub2RlLT5sb2NhbE5hbWUsIGlub2RlLT5uc05hbWUpKTsKCX0gZWxzZSB7CgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gY2FsbGJhY2sgZm9yICclcycgW3dpbGRjYXJkXVxuIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgaW5vZGUtPmxvY2FsTmFtZSwgaW5vZGUtPm5zTmFtZSkpOwoKCX0KCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsgICAgCiAgICB2Y3R4dC0+aW5vZGUgPSB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKHZjdHh0KTsKICAgIGlmICh2Y3R4dC0+aW5vZGUgPT0gTlVMTCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8oKSIpOwoJcmV0dXJuICgtMSk7CiAgICB9ICAgCiAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUpCnsKICAgIGlmIChpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19WQUxVRV9ORUVERUQpCglyZXR1cm4gKHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkgICAgQUNUWFRfQ0FTVCB2Y3R4dCwgTlVMTCwKCSAgICB0eXBlLCB2YWx1ZSwgJihpbm9kZS0+dmFsKSwgMSwgMSwgMCkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJICAgIEFDVFhUX0NBU1QgdmN0eHQsIE5VTEwsCgkgICAgdHlwZSwgdmFsdWUsIE5VTEwsIDEsIDAsIDApKTsKfQoKCgovKiAKKiBQcm9jZXNzIEVORCBvZiBlbGVtZW50LgoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlID0gdmN0eHQtPmlub2RlOwoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCXhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHZjdHh0KTsKICAgIGlmIChpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEKSB7CgkvKgoJKiBUaGlzIGVsZW1lbnQgd2FzIG5vdCBleHBlY3RlZDsKCSogd2Ugd2lsbCBub3QgdmFsaWRhdGUgY2hpbGQgZWxlbWVudHMgb2YgYnJva2VuIHBhcmVudHMuCgkqIFNraXAgdmFsaWRhdGlvbiBvZiBhbGwgY29udGVudCBvZiB0aGUgcGFyZW50LgoJKi8KCXZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGggLTE7Cglnb3RvIGVuZF9lbGVtOwogICAgfSAgICAKICAgIGlmICgoaW5vZGUtPnR5cGVEZWYgPT0gTlVMTCkgfHwKCShpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfQkFEX1RZUEUpKSB7CgkvKgoJKiAxLiB0aGUgdHlwZSBkZWZpbml0aW9uIG1pZ2h0IGJlIG1pc3NpbmcgaWYgdGhlIGVsZW1lbnQgd2FzCgkqICAgIGVycm9yIHByb25lCgkqIDIuIGl0IG1pZ2h0IGJlIGFic3RyYWN0LgoJKi8KCWdvdG8gZW5kX2VsZW07CiAgICB9CiAgICAvKgogICAgKiBDaGVjayB0aGUgY29udGVudCBtb2RlbC4KICAgICovCiAgICBpZiAoKGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHx8CgkoaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykpIHsKCgkvKgoJKiBXb3JrYXJvdW5kIGZvciAiYW55VHlwZSIuCgkqLwoJaWYgKGlub2RlLT50eXBlRGVmLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKQoJICAgIGdvdG8gY2hhcmFjdGVyX2NvbnRlbnQ7CQkJCgkKCWlmICgoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UKSA9PSAwKSB7CgkgICAgeG1sQ2hhciAqdmFsdWVzWzEwXTsKCSAgICBpbnQgdGVybWluYWwsIG5idmFsID0gMTAsIG5ibmVnOwoKCSAgICBpZiAoaW5vZGUtPnJlZ2V4Q3R4dCA9PSBOVUxMKSB7CgkJLyoKCQkqIENyZWF0ZSB0aGUgcmVnZXggY29udGV4dC4KCQkqLwoJCWlub2RlLT5yZWdleEN0eHQgPQoJCSAgICB4bWxSZWdOZXdFeGVjQ3R4dChpbm9kZS0+dHlwZURlZi0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykgeG1sU2NoZW1hVkNvbnRlbnRNb2RlbENhbGxiYWNrLAoJCSAgICB2Y3R4dCk7CgkJaWYgKGlub2RlLT5yZWdleEN0eHQgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtIiwKCQkJImZhaWxlZCB0byBjcmVhdGUgYSByZWdleCBjb250ZXh0Iik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBjcmVhdGUgb24gJyVzJ1xuIiwgaW5vZGUtPmxvY2FsTmFtZSk7CiNlbmRpZgkgICAgCgkgICAgfQoJICAgIC8qCgkgICAgKiBHZXQgaG9sZCBvZiB0aGUgc3RpbGwgZXhwZWN0ZWQgY29udGVudCwgc2luY2UgYSBmdXJ0aGVyCgkgICAgKiBjYWxsIHRvIHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKCkgd2lsbCBsb29zZSB0aGlzIGluZm9ybWF0aW9uLgoJICAgICovIAoJICAgIHhtbFJlZ0V4ZWNOZXh0VmFsdWVzKGlub2RlLT5yZWdleEN0eHQsCgkJJm5idmFsLCAmbmJuZWcsICZ2YWx1ZXNbMF0sICZ0ZXJtaW5hbCk7CgkgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoaW5vZGUtPnJlZ2V4Q3R4dCwgTlVMTCwgTlVMTCk7CgkgICAgaWYgKHJldCA8PSAwKSB7CQkKCQkvKgoJCSogU3RpbGwgbWlzc2luZyBzb21ldGhpbmcuCgkJKi8KCQlyZXQgPSAxOwoJCWlub2RlLT5mbGFncyB8PQoJCSAgICBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQ7CgkJeG1sU2NoZW1hQ29tcGxleFR5cGVFcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfRUxFTUVOVF9DT05URU5ULCBOVUxMLCBOVUxMLAoJCSAgICAiTWlzc2luZyBjaGlsZCBlbGVtZW50KHMpIiwKCQkgICAgbmJ2YWwsIG5ibmVnLCB2YWx1ZXMpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBtaXNzaW5nIEVSUk9SIG9uICclcydcbiIsCgkJICAgIGlub2RlLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICB9IGVsc2UgewoJCS8qCgkJKiBDb250ZW50IG1vZGVsIGlzIHNhdGlzZmllZC4KCQkqLwoJCXJldCA9IDA7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAiQVVUT01BVE9OIHN1Y2NlZWRlZCBvbiAnJXMnXG4iLAoJCSAgICBpbm9kZS0+bG9jYWxOYW1lKTsKI2VuZGlmCgkgICAgfQoKCX0KICAgIH0KICAgIGlmIChpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKQoJZ290byBlbmRfZWxlbTsKCmNoYXJhY3Rlcl9jb250ZW50OgoKICAgIGlmICh2Y3R4dC0+dmFsdWUgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZVZhbHVlKHZjdHh0LT52YWx1ZSk7Cgl2Y3R4dC0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogQ2hlY2sgY2hhcmFjdGVyIGNvbnRlbnQuCiAgICAqLwogICAgaWYgKGlub2RlLT5kZWNsID09IE5VTEwpIHsKCS8qCgkqIFNwZWVkdXAgaWYgbm8gZGVjbGFyYXRpb24gZXhpc3RzLgoJKi8KCWlmIChXWFNfSVNfU0lNUExFKGlub2RlLT50eXBlRGVmKSkgewkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYsIGlub2RlLT52YWx1ZSk7Cgl9IGVsc2UgaWYgKFdYU19IQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLAoJCWlub2RlLT52YWx1ZSk7Cgl9CQkKCWlmIChyZXQgPCAwKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KCWdvdG8gZW5kX2VsZW07CiAgICB9CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1IAogICAgKiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEgCiAgICAqIElmIHRoZSBkZWNsYXJhdGlvbiBoYXMgYSB7dmFsdWUgY29uc3RyYWludH0sIAogICAgKiB0aGUgaXRlbSBoYXMgbmVpdGhlciBlbGVtZW50IG5vciBjaGFyYWN0ZXIgW2NoaWxkcmVuXSBhbmQgCiAgICAqIGNsYXVzZSAzLjIgaGFzIG5vdCBhcHBsaWVkLCB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBpZiAoKGlub2RlLT5kZWNsLT52YWx1ZSAhPSBOVUxMKSAmJgoJKGlub2RlLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZKSAmJiAKCSghIElOT0RFX05JTExFRChpbm9kZSkpKSB7CgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMSAKCSogSWYgdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBpcyBhILdsb2NhbCB0eXBlIGRlZmluaXRpb263CgkqIHRoZW4gdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0KCSogdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGRlZmF1bHQgZm9yIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgCgkqIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLiAKCSovCgkvKiAKCSogTk9URTogJ2xvY2FsJyBhYm92ZSBtZWFucyB0eXBlcyBhY3F1aXJlZCBieSB4c2k6dHlwZS4KCSogTk9URTogQWx0aG91Z2ggdGhlICpjYW5vbmljYWwqIHZhbHVlIGlzIHN0YXRlZCwgaXQgaXMgbm90CgkqIHJlbGV2YW50IGlmIGNhbm9uaWNhbCBvciBub3QuIEFkZGl0aW9uYWxseSBYTUwgU2NoZW1hIDEuMQoJKiB3aWxsIHJlbW92ZWQgdGhpcyByZXF1aXJlbWVudCBhcyB3ZWxsLgoJKi8KCWlmIChpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19MT0NBTF9UWVBFKSB7CgoJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KHZjdHh0LAoJCWlub2RlLT5kZWNsLT52YWx1ZSwgJihpbm9kZS0+dmFsKSk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBlbmRfZWxlbTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFN0b3AgaGVyZSwgdG8gYXZvaWQgcmVkdW5kYW50IHZhbGlkYXRpb24gb2YgdGhlIHZhbHVlCgkgICAgKiAoc2VlIGZvbGxvd2luZykuCgkgICAgKi8KCSAgICBnb3RvIGRlZmF1bHRfcHN2aTsKCX0JCgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMiAKCSogVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSB1c2VkIGFzIGl0cyAKCSogt25vcm1hbGl6ZWQgdmFsdWW3IG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIAoJKiC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpCgkqICinMy4zLjQpLgoJKi8JICAgIAoJaWYgKFdYU19JU19TSU1QTEUoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYsIGlub2RlLT5kZWNsLT52YWx1ZSk7Cgl9IGVsc2UgaWYgKFdYU19IQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLAoJCWlub2RlLT5kZWNsLT52YWx1ZSk7CSAgICAKCX0KCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZW5kX2VsZW07Cgl9CgpkZWZhdWx0X3Bzdmk6CgkvKgoJKiBQU1ZJOiBDcmVhdGUgYSB0ZXh0IG5vZGUgb24gdGhlIGluc3RhbmNlIGVsZW1lbnQuCgkqLwoJaWYgKCh2Y3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSAmJgoJICAgIChpbm9kZS0+bm9kZSAhPSBOVUxMKSkgewoJICAgIHhtbE5vZGVQdHIgdGV4dENoaWxkOwoJICAgIHhtbENoYXIgKm5vcm1WYWx1ZTsKCSAgICAvKgoJICAgICogVkFMIFRPRE86IE5vcm1hbGl6ZSB0aGUgdmFsdWUuCgkgICAgKi8JICAgIAoJICAgIG5vcm1WYWx1ZSA9IHhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKGlub2RlLT50eXBlRGVmLAoJCWlub2RlLT5kZWNsLT52YWx1ZSk7CgkgICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSB7CgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChCQURfQ0FTVCBub3JtVmFsdWUpOwoJCXhtbEZyZWUobm9ybVZhbHVlKTsKCSAgICB9IGVsc2UKCQl0ZXh0Q2hpbGQgPSB4bWxOZXdUZXh0KGlub2RlLT5kZWNsLT52YWx1ZSk7CgkgICAgaWYgKHRleHRDaGlsZCA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbE5ld1RleHQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfSBlbHNlCgkJeG1sQWRkQ2hpbGQoaW5vZGUtPm5vZGUsIHRleHRDaGlsZCk7CSAgICAKCX0KCQogICAgfSBlbHNlIGlmICghIElOT0RFX05JTExFRChpbm9kZSkpIHsJCgkvKgoJKiA1LjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCgkqIHRvIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgCgkqIFZhbGlkIChUeXBlKSAopzMuMy40KS4KCSovCQoJaWYgKFdYU19JU19TSU1QTEUoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgIC8qCgkgICAgKiBTUEVDIChjdmMtdHlwZSkgKDMuMSkKCSAgICAqICJJZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgLi4uIgoJICAgICogKDMuMS4zKSAiSWYgY2xhdXNlIDMuMiBvZiBFbGVtZW50IExvY2FsbHkgVmFsaWQKCSAgICAqIChFbGVtZW50KSAopzMuMy40KSBkaWQgbm90IGFwcGx5LCB0aGVuIHRoZSC3bm9ybWFsaXplZCB2YWx1ZbcKCSAgICAqIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkCgkgICAgKiBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgoJICAgICovCSAgICAKCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCSAgICBpbm9kZSwgaW5vZGUtPnR5cGVEZWYsIGlub2RlLT52YWx1ZSk7Cgl9IGVsc2UgaWYgKFdYU19IQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy10eXBlKSAoMy4yKSAiSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIGNvbXBsZXggdHlwZQoJICAgICogZGVmaW5pdGlvbiwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUKCSAgICAqILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgcGVyCgkgICAgKiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkgKKczLjQuNCk7IgoJICAgICoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgyLjIpCgkgICAgKiAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgLi4uIAoJICAgICogdGhlILdub3JtYWxpemVkIHZhbHVltyBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzCgkgICAgKiC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gYXMKCSAgICAqIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4iCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCWlub2RlLCBpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGVEZWYsIGlub2RlLT52YWx1ZSk7Cgl9CQoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBlbmRfZWxlbTsKCX0KCS8qCgkqIDUuMi4yIElmIHRoZXJlIGlzIGEgZml4ZWQge3ZhbHVlIGNvbnN0cmFpbnR9IGFuZCBjbGF1c2UgMy4yIGhhcyAKCSogbm90IGFwcGxpZWQsIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSovCglpZiAoKGlub2RlLT5kZWNsLT52YWx1ZSAhPSBOVUxMKSAmJgoJICAgIChpbm9kZS0+ZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSkgewoKCSAgICAvKgoJICAgICogVE9ETzogV2Ugd2lsbCBuZWVkIGEgY29tcHV0ZWQgdmFsdWUsIHdoZW4gY29tcGFyaXNvbiBpcwoJICAgICogZG9uZSBvbiBjb21wdXRlZCB2YWx1ZXMuCgkgICAgKi8KCSAgICAvKgoJICAgICogNS4yLjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAoJICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgoJICAgICovCgkgICAgaWYgKGlub2RlLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQpIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzE7CgkJVkVSUk9SKHJldCwgTlVMTCwKCQkgICAgIlRoZSBjb250ZW50IG11c3Qgbm90IGNvbnRhaW50IGVsZW1lbnQgbm9kZXMgc2luY2UgIgoJCSAgICAidGhlcmUgaXMgYSBmaXhlZCB2YWx1ZSBjb25zdHJhaW50Iik7CgkJZ290byBlbmRfZWxlbTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiA1LjIuMi4yIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCAKCQkqIGJlIHRydWU6CgkJKi8JCQoJCWlmIChXWFNfSEFTX01JWEVEX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIG1peGVkLCB0aGVuIHRoZSAqaW5pdGlhbCB2YWx1ZSogb2YgdGhlIAoJCSAgICAqIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gCgkJICAgICogb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKgoJCSAgICAqIC4uLiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBpcyB0aGUgc3RyaW5nIGNvbXBvc2VkIG9mLCBpbiBvcmRlciwgdGhlIAoJCSAgICAqIFtjaGFyYWN0ZXIgY29kZV0gb2YgZWFjaCBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gaXRlbSBpbiAKCQkgICAgKiB0aGUgW2NoaWxkcmVuXSBvZiB0aGF0IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbS4KCQkgICAgKi8JCSAgIAoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChpbm9kZS0+dmFsdWUsIGlub2RlLT5kZWNsLT52YWx1ZSkpewoJCQkvKiAKCQkJKiBWQUwgVE9ETzogUmVwb3J0IGludmFsaWQgJiBleHBlY3RlZCB2YWx1ZXMgYXMgd2VsbC4KCQkJKiBWQUwgVE9ETzogSW1wbGVtZW50IHRoZSBjYW5vbmljYWwgc3R1ZmYuCgkJCSovCgkJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8xOwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwgCgkJCSAgICByZXQsIE5VTEwsIE5VTEwsCgkJCSAgICAiVGhlIGluaXRpYWwgdmFsdWUgJyVzJyBkb2VzIG5vdCBtYXRjaCB0aGUgZml4ZWQgIgoJCQkgICAgInZhbHVlIGNvbnN0cmFpbnQgJyVzJyIsCgkJCSAgICBpbm9kZS0+dmFsdWUsIGlub2RlLT5kZWNsLT52YWx1ZSk7CgkJCWdvdG8gZW5kX2VsZW07CgkJICAgIH0KCQl9IGVsc2UgaWYgKFdYU19IQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4yIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCgkJICAgICogKmFjdHVhbCB2YWx1ZSogb2YgdGhlIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIAoJCSAgICAqIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBWQUwgVE9ETzogKmFjdHVhbCB2YWx1ZSogaXMgdGhlIG5vcm1hbGl6ZWQgdmFsdWUsIGltcGwuCgkJICAgICogICAgICAgICAgIHRoaXMuCgkJICAgICogVkFMIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJICAgICogVkFMIFRPRE86IEltcGxlbWVudCBhIGNvbXBhcmlzb24gd2l0aCB0aGUgY29tcHV0ZWQgdmFsdWVzLgoJCSAgICAqLwoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChpbm9kZS0+dmFsdWUsCgkJCSAgICBpbm9kZS0+ZGVjbC0+dmFsdWUpKSB7CgkJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8yOwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoQUNUWFRfQ0FTVCB2Y3R4dCwKCQkJICAgIHJldCwgTlVMTCwgTlVMTCwKCQkJICAgICJUaGUgYWN0dWFsIHZhbHVlICclcycgZG9lcyBub3QgbWF0Y2ggdGhlIGZpeGVkICIKCQkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLCAKCQkJICAgIGlub2RlLT52YWx1ZSwKCQkJICAgIGlub2RlLT5kZWNsLT52YWx1ZSk7CgkJCWdvdG8gZW5kX2VsZW07CgkJICAgIH0JCSAgICAKCQl9CgkgICAgfQkgICAgCgl9CiAgICB9CiAgICAKZW5kX2VsZW06CiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkgewoJLyogVE9ETzogcmFpc2UgZXJyb3I/ICovCglyZXR1cm4gKDApOwogICAgfQogICAgaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKQoJdmN0eHQtPnNraXBEZXB0aCA9IC0xOwogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIGhpc3Rvcnkgb2YgWFBhdGggc3RhdGUgb2JqZWN0cy4KICAgICovICAgIAogICAgaWYgKGlub2RlLT5hcHBsaWVkWFBhdGggJiYKCSh4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHZjdHh0LCB2Y3R4dC0+ZGVwdGgpID09IC0xKSkKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICAvKgogICAgKiBNQVlCRSBUT0RPOgogICAgKiBTUEVDICg2KSAiVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aAogICAgKiByZXNwZWN0IHRvIGVhY2ggb2YgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb25zfSBhcyBwZXIKICAgICogSWRlbnRpdHktY29uc3RyYWludCBTYXRpc2ZpZWQgKKczLjExLjQpLiIKICAgICovCiAgICAvKgogICAgKiBQU1ZJIFRPRE86IElmIHdlIGV4cG9zZSBJREMgbm9kZS10YWJsZXMgdmlhIFBTVkkgdGhlbiB0aGUgdGFibGVzCiAgICAqICAgbmVlZCB0byBiZSBidWlsdCBpbiBhbnkgY2FzZS4KICAgICogICBXZSB3aWxsIGN1cnJlbnRseSBidWlsZCBJREMgbm9kZS10YWJsZXMgYW5kIGJ1YmJsZSB0aGVtIG9ubHkgaWYKICAgICogICBrZXlyZWZzIGRvIGV4aXN0LgogICAgKi8KICAgIAogICAgLyoKICAgICogQWRkIHRoZSBjdXJyZW50IElEQyB0YXJnZXQtbm9kZXMgdG8gdGhlIElEQyBub2RlLXRhYmxlcy4KICAgICovCiAgICBpZiAoKGlub2RlLT5pZGNNYXRjaGVycyAhPSBOVUxMKSAmJgoJKHZjdHh0LT5oYXNLZXlyZWZzIHx8IHZjdHh0LT5jcmVhdGVJRENOb2RlVGFibGVzKSkKICAgIHsKCWlmICh4bWxTY2hlbWFJRENGaWxsTm9kZVRhYmxlcyh2Y3R4dCwgaW5vZGUpID09IC0xKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBJREMga2V5cmVmcy4KICAgICovCiAgICBpZiAodmN0eHQtPmlub2RlLT5oYXNLZXlyZWZzKQoJaWYgKHhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmKHZjdHh0KSA9PSAtMSkKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwogICAgLyoKICAgICogTWVyZ2UvZnJlZSB0aGUgSURDIHRhYmxlLgogICAgKi8KICAgIGlmIChpbm9kZS0+aWRjVGFibGUgIT0gTlVMTCkgewojaWZkZWYgREVCVUdfSURDX05PREVfVEFCTEUKCXhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlKHN0ZG91dCwKCSAgICBpbm9kZS0+bnNOYW1lLAoJICAgIGlub2RlLT5sb2NhbE5hbWUsCgkgICAgaW5vZGUtPmlkY1RhYmxlKTsKI2VuZGlmCglpZiAoKHZjdHh0LT5kZXB0aCA+IDApICYmCgkgICAgKHZjdHh0LT5oYXNLZXlyZWZzIHx8IHZjdHh0LT5jcmVhdGVJRENOb2RlVGFibGVzKSkKCXsKCSAgICAvKgoJICAgICogTWVyZ2UgdGhlIElEQyBub2RlIHRhYmxlIHdpdGggdGhlIHRhYmxlIG9mIHRoZSBwYXJlbnQgbm9kZS4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFCdWJibGVJRENOb2RlVGFibGVzKHZjdHh0KSA9PSAtMSkKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJfQkKICAgIH0KICAgIC8qCiAgICAqIENsZWFyIHRoZSBjdXJyZW50IGllbGVtLgogICAgKiBWQUwgVE9ETzogRG9uJ3QgZnJlZSB0aGUgUFNWSSBJREMgdGFibGVzIGlmIHRoZXkgYXJlCiAgICAqIHJlcXVlc3RlZCBmb3IgdGhlIFBTVkkuCiAgICAqLwogICAgeG1sU2NoZW1hQ2xlYXJFbGVtSW5mbyhpbm9kZSk7CiAgICAvKgogICAgKiBTa2lwIGZ1cnRoZXIgcHJvY2Vzc2luZyBpZiB3ZSBhcmUgb24gdGhlIHZhbGlkYXRpb24gcm9vdC4KICAgICovCiAgICBpZiAodmN0eHQtPmRlcHRoID09IDApIHsKCXZjdHh0LT5kZXB0aC0tOwoJdmN0eHQtPmlub2RlID0gTlVMTDsKCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiBSZXNldCB0aGUga2V5cmVmRGVwdGggaWYgbmVlZGVkLgogICAgKi8KICAgIGlmICh2Y3R4dC0+YWlkY3MgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDQXVnUHRyIGFpZGMgPSB2Y3R4dC0+YWlkY3M7CglkbyB7CgkgICAgaWYgKGFpZGMtPmtleXJlZkRlcHRoID09IHZjdHh0LT5kZXB0aCkgewoJCS8qCgkJKiBBICdrZXlyZWZEZXB0aCcgb2YgYSBrZXkvdW5pcXVlIElEQyBtYXRjaGVzIHRoZSBjdXJyZW50CgkJKiBkZXB0aCwgdGhpcyBtZWFucyB0aGF0IHdlIGFyZSBsZWF2aW5nIHRoZSBzY29wZSBvZiB0aGUKCQkqIHRvcC1tb3N0IGtleXJlZiBJREMgd2hpY2ggcmVmZXJzIHRvIHRoaXMgSURDLgoJCSovCgkJYWlkYy0+a2V5cmVmRGVwdGggPSAtMTsKCSAgICB9CgkgICAgYWlkYyA9IGFpZGMtPm5leHQ7Cgl9IHdoaWxlIChhaWRjICE9IE5VTEwpOwogICAgfQogICAgdmN0eHQtPmRlcHRoLS07ICAgICAgICAKICAgIHZjdHh0LT5pbm9kZSA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKICAgIC8qCiAgICAqIFZBTCBUT0RPOiA3IElmIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaXMgdGhlILd2YWxpZGF0aW9uIHJvb3S3LCBpdCBtdXN0IGJlIAogICAgKiC3dmFsaWS3IHBlciBWYWxpZGF0aW9uIFJvb3QgVmFsaWQgKElEL0lEUkVGKSAopzMuMy40KS4KICAgICovCiAgICByZXR1cm4gKHJldCk7CgppbnRlcm5hbF9lcnJvcjoKICAgIHZjdHh0LT5lcnIgPSAtMTsKICAgIHJldHVybiAoLTEpOwp9CgovKgoqIDMuNC40IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKSAoY3ZjLWNvbXBsZXgtdHlwZSkKKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIHBpZWxlbTsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcHR5cGU7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDw9IDApIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCSAgICAibm90IGludGVuZGVkIGZvciB0aGUgdmFsaWRhdGlvbiByb290Iik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHBpZWxlbSA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoIC0xXTsKICAgIGlmIChwaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCglwaWVsZW0tPmZsYWdzIF49IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgLyoKICAgICogSGFuZGxlICduaWxsZWQnIGVsZW1lbnRzLgogICAgKi8KICAgIGlmIChJTk9ERV9OSUxMRUQocGllbGVtKSkgewoJLyoKCSogU1BFQyAoY3ZjLWVsdCkgKDMuMy40KSA6ICgzLjIuMSkKCSovCglBQ1RJVkFURV9QQVJFTlRfRUxFTTsKCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzE7CglWRVJST1IocmV0LCBOVUxMLAoJICAgICJOZWl0aGVyIGNoYXJhY3RlciBub3IgZWxlbWVudCBjb250ZW50IGlzIGFsbG93ZWQsICIKCSAgICAiYmVjYXVzZSB0aGUgZWxlbWVudCB3YXMgJ25pbGxlZCciKTsKCUFDVElWQVRFX0VMRU07Cglnb3RvIHVuZXhwZWN0ZWRfZWxlbTsKICAgIH0KCiAgICBwdHlwZSA9IHBpZWxlbS0+dHlwZURlZjsKCiAgICBpZiAocHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpIHsKCS8qCgkqIFdvcmthcm91bmQgZm9yICJhbnlUeXBlIjogd2UgaGF2ZSBjdXJyZW50bHkgbm8gY29udGVudCBtb2RlbAoJKiBhc3NpZ25lZCBmb3IgImFueVR5cGUiLCBzbyBoYW5kbGUgaXQgZXhwbGljaXRlbHkuCgkqICJhbnlUeXBlIiBoYXMgYW4gdW5ib3VuZGVkLCBsYXggImFueSIgd2lsZGNhcmQuCgkqLwoJdmN0eHQtPmlub2RlLT5kZWNsID0geG1sU2NoZW1hR2V0RWxlbSh2Y3R4dC0+c2NoZW1hLAoJICAgIHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLAoJICAgIHZjdHh0LT5pbm9kZS0+bnNOYW1lKTsKCglpZiAodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCSAgICAvKgoJICAgICogUHJvY2VzcyAieHNpOnR5cGUiLgoJICAgICogU1BFQyAoY3ZjLWFzc2Vzcy1lbHQpICgxLjIuMS4yLjEpIC0gKDEuMi4xLjIuMykKCSAgICAqLwoJICAgIGlhdHRyID0geG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJCVhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1RZUEUpOwoJICAgIGlmIChpYXR0ciAhPSBOVUxMKSB7CgkJcmV0ID0geG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUodmN0eHQsIGlhdHRyLAoJCSAgICAmKHZjdHh0LT5pbm9kZS0+dHlwZURlZiksIE5VTEwpOwoJCWlmIChyZXQgIT0gMCkgewoJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKCkgdG8gIgoJCQkgICAgInByb2Nlc3MgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgcmV0dXJuIChyZXQpOwoJCX0KCSAgICB9IGVsc2UgewoJCSAvKgoJCSAqIEZhbGxiYWNrIHRvICJhbnlUeXBlIi4KCQkgKgoJCSAqIFNQRUMgKGN2Yy1hc3Nlc3MtZWx0KQoJCSAqICJJZiB0aGUgaXRlbSBjYW5ub3QgYmUgt3N0cmljdGx5IGFzc2Vzc2VktywgWy4uLl0KCQkgKiBhbiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBzY2hlbWEgdmFsaWRpdHkgbWF5IGJlIGxheGx5CgkJICogYXNzZXNzZWQgaWYgaXRzILdjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb263IGlzIG5vdAoJCSAqIHNraXAgYnkgt3ZhbGlkYXRpbme3IHdpdGggcmVzcGVjdCB0byB0aGUgt3VyLXR5cGUKCQkgKiBkZWZpbml0aW9utyBhcyBwZXIgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKSAopzMuMy40KS4iCgkJKi8KCQl2Y3R4dC0+aW5vZGUtPnR5cGVEZWYgPQoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCSAgICB9Cgl9CglyZXR1cm4gKDApOwogICAgfQoKICAgIHN3aXRjaCAocHR5cGUtPmNvbnRlbnRUeXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKCSAgICAvKgoJICAgICogU1BFQyAoMi4xKSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVtcHR5LCB0aGVuIHRoZQoJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudAoJICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLiIKCSAgICAqLwoJICAgIEFDVElWQVRFX1BBUkVOVF9FTEVNCgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzE7CgkgICAgVkVSUk9SKHJldCwgTlVMTCwKCQkiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbXB0eSIpOwoJICAgIEFDVElWQVRFX0VMRU0KCSAgICBnb3RvIHVuZXhwZWN0ZWRfZWxlbTsKCSAgICBicmVhazsKCgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzogewoJICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIHJlZ2V4Q3R4dDsKCSAgICB4bWxDaGFyICp2YWx1ZXNbMTBdOwoJICAgIGludCB0ZXJtaW5hbCwgbmJ2YWwgPSAxMCwgbmJuZWc7CgoJICAgIC8qIFZBTCBUT0RPOiBPcHRpbWl6ZWQgImFueVR5cGUiIHZhbGlkYXRpb24uKi8KCgkgICAgaWYgKHB0eXBlLT5jb250TW9kZWwgPT0gTlVMTCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkgICAgInR5cGUgaGFzIGVsZW0gY29udGVudCBidXQgbm8gY29udGVudCBtb2RlbCIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAvKgoJICAgICogU2FmZXR5IGJlbGYgZm9yIGV2YWx1YXRpb24gaWYgdGhlIGNvbnQuIG1vZGVsIHdhcyBhbHJlYWR5CgkgICAgKiBleGFtaW5lZCB0byBiZSBpbnZhbGlkLgoJICAgICovCgkgICAgaWYgKHBpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkJICAgICJ2YWxpZGF0aW5nIGVsZW0sIGJ1dCBlbGVtIGNvbnRlbnQgaXMgYWxyZWFkeSBpbnZhbGlkIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoKCSAgICByZWdleEN0eHQgPSBwaWVsZW0tPnJlZ2V4Q3R4dDsKCSAgICBpZiAocmVnZXhDdHh0ID09IE5VTEwpIHsKCQkvKgoJCSogQ3JlYXRlIHRoZSByZWdleCBjb250ZXh0LgoJCSovCgkJcmVnZXhDdHh0ID0geG1sUmVnTmV3RXhlY0N0eHQocHR5cGUtPmNvbnRNb2RlbCwKCQkgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpIHhtbFNjaGVtYVZDb250ZW50TW9kZWxDYWxsYmFjaywKCQkgICAgdmN0eHQpOwoJCWlmIChyZWdleEN0eHQgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkJCSJmYWlsZWQgdG8gY3JlYXRlIGEgcmVnZXggY29udGV4dCIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJcGllbGVtLT5yZWdleEN0eHQgPSByZWdleEN0eHQ7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiQVVUT01BVEEgY3JlYXRlIG9uICclcydcbiIsCgkJICAgIHBpZWxlbS0+bG9jYWxOYW1lKTsKI2VuZGlmCgkgICAgfQoKCSAgICAvKgoJICAgICogU1BFQyAoMi40KSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVsZW1lbnQtb25seSBvciBtaXhlZCwKCSAgICAqIHRoZW4gdGhlIHNlcXVlbmNlIG9mIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncwoJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0sIGlmIGFueSwgdGFrZW4gaW4KCSAgICAqIG9yZGVyLCBpcyC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUge2NvbnRlbnQgdHlwZX0ncwoJICAgICogcGFydGljbGUsIGFzIGRlZmluZWQgaW4gRWxlbWVudCBTZXF1ZW5jZSBMb2NhbGx5IFZhbGlkCgkgICAgKiAoUGFydGljbGUpICinMy45LjQpLiIKCSAgICAqLwoJICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nMihyZWdleEN0eHQsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsCgkJdmN0eHQtPmlub2RlLT5uc05hbWUsCgkJdmN0eHQtPmlub2RlKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkgICAgaWYgKHJldCA8IDApCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJIkFVVE9NQVRPTiBwdXNoIEVSUk9SIGZvciAnJXMnIG9uICclcydcbiIsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHBpZWxlbS0+bG9jYWxOYW1lKTsKCSAgICBlbHNlCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJIkFVVE9NQVRPTiBwdXNoIE9LIGZvciAnJXMnIG9uICclcydcbiIsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHBpZWxlbS0+bG9jYWxOYW1lKTsKI2VuZGlmCgkgICAgaWYgKHZjdHh0LT5lcnIgPT0gWE1MX1NDSEVNQVZfSU5URVJOQUwpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFJlZ0V4ZWNQdXNoU3RyaW5nMigpIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sUmVnRXhlY0VyckluZm8ocmVnZXhDdHh0LCBOVUxMLCAmbmJ2YWwsICZuYm5lZywKCQkgICAgJnZhbHVlc1swXSwgJnRlcm1pbmFsKTsKCQl4bWxTY2hlbWFDb21wbGV4VHlwZUVycihBQ1RYVF9DQVNUIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsIE5VTEwsTlVMTCwKCQkgICAgIlRoaXMgZWxlbWVudCBpcyBub3QgZXhwZWN0ZWQiLAoJCSAgICBuYnZhbCwgbmJuZWcsIHZhbHVlcyk7CgkJcmV0ID0gdmN0eHQtPmVycjsKCQlnb3RvIHVuZXhwZWN0ZWRfZWxlbTsKCSAgICB9IGVsc2UKCQlyZXQgPSAwOwoJfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CgkgICAgQUNUSVZBVEVfUEFSRU5UX0VMRU0KCSAgICBpZiAoV1hTX0lTX0NPTVBMRVgocHR5cGUpKSB7CgkJLyoKCQkqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgyLjIpCgkJKiAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbgoJCSogdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gZWxlbWVudCBpbmZvcm1hdGlvbgoJCSogaXRlbSBbY2hpbGRyZW5dLCAuLi4iCgkJKi8KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMjsKCQlWRVJST1IocmV0LCBOVUxMLCAiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIik7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU1BFQyAoY3ZjLXR5cGUpICgzLjEuMikgIlRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdAoJCSogaGF2ZSBubyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4iCgkJKi8KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMjsKCQlWRVJST1IocmV0LCBOVUxMLCAiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgc2ltcGxlIik7CgkgICAgfQoJICAgIEFDVElWQVRFX0VMRU0KCSAgICByZXQgPSB2Y3R4dC0+ZXJyOwoJICAgIGdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIGJyZWFrOwoKCWRlZmF1bHQ6CgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7CnVuZXhwZWN0ZWRfZWxlbToKICAgIC8qCiAgICAqIFBvcCB0aGlzIGVsZW1lbnQgYW5kIHNldCB0aGUgc2tpcERlcHRoIHRvIHNraXAKICAgICogYWxsIGZ1cnRoZXIgY29udGVudCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuCiAgICAqLwogICAgdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX05PVF9FWFBFQ1RFRDsKICAgIHBpZWxlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UOwogICAgcmV0dXJuIChyZXQpOwp9CgojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1QgMQojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX0NSRUFURUQgMgojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFIDMKCnN0YXRpYyBpbnQKeG1sU2NoZW1hVlB1c2hUZXh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgIGludCBub2RlVHlwZSwgY29uc3QgeG1sQ2hhciAqdmFsdWUsIGludCBsZW4sCgkJICBpbnQgbW9kZSwgaW50ICpjb25zdW1lZCkKewogICAgLyoKICAgICogVW5mb3J0dW5hdGVseSB3ZSBoYXZlIHRvIGR1cGxpY2F0ZSB0aGUgdGV4dCBzb21ldGltZXMuCiAgICAqIE9QVElNSVpFOiBNYXliZSB3ZSBjb3VsZCBza2lwIGl0LCBpZjoKICAgICogICAxLiBjb250ZW50IHR5cGUgaXMgc2ltcGxlCiAgICAqICAgMi4gd2hpdGVzcGFjZSBpcyAiY29sbGFwc2UiCiAgICAqICAgMy4gaXQgY29uc2lzdHMgb2Ygd2hpdGVzcGFjZSBvbmx5CiAgICAqCiAgICAqIFByb2Nlc3MgY2hhcmFjdGVyIGNvbnRlbnQuCiAgICAqLwogICAgaWYgKGNvbnN1bWVkICE9IE5VTEwpCgkqY29uc3VtZWQgPSAwOwogICAgaWYgKElOT0RFX05JTExFRCh2Y3R4dC0+aW5vZGUpKSB7CgkvKiAKCSogU1BFQyBjdmMtZWx0ICgzLjMuNCAtIDMuMi4xKQoJKiAiVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gY2hhcmFjdGVyIG9yCgkqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLiIKCSovCglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMSwgTlVMTCwKCSAgICAiTmVpdGhlciBjaGFyYWN0ZXIgbm9yIGVsZW1lbnQgY29udGVudCBpcyBhbGxvd2VkICIKCSAgICAiYmVjYXVzZSB0aGUgZWxlbWVudCBpcyAnbmlsbGVkJyIpOwoJcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDIuMSkgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbXB0eSwgdGhlbiB0aGUKICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgogICAgKi8KICAgIGlmICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09CgkgICAgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7ICAgIAoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8xLCBOVUxMLAoJICAgICJDaGFyYWN0ZXIgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZW1wdHkiKTsKCXJldHVybiAodmN0eHQtPmVycik7CiAgICB9CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0KCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpIHsKCWlmICgobm9kZVR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAoISB4bWxTY2hlbWFJc0JsYW5rKCh4bWxDaGFyICopIHZhbHVlLCBsZW4pKSkgewoJICAgIC8qIAoJICAgICogU1BFQyBjdmMtY29tcGxleC10eXBlICgyLjMpIAoJICAgICogIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIAoJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gCgkgICAgKiBpdGVtIFtjaGlsZHJlbl0gb3RoZXIgdGhhbiB0aG9zZSB3aG9zZSBbY2hhcmFjdGVyIAoJICAgICogY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgCgkgICAgKiBFZGl0aW9uKV0uIgoJICAgICovCgkgICAgVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8zLCBOVUxMLAoJCSJDaGFyYWN0ZXIgY29udGVudCBvdGhlciB0aGFuIHdoaXRlc3BhY2UgaXMgbm90IGFsbG93ZWQgIgoJCSJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgJ2VsZW1lbnQtb25seSciKTsKCSAgICByZXR1cm4gKHZjdHh0LT5lcnIpOwoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIAogICAgaWYgKCh2YWx1ZSA9PSBOVUxMKSB8fCAodmFsdWVbMF0gPT0gMCkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogU2F2ZSB0aGUgdmFsdWUuCiAgICAqIE5PVEUgdGhhdCBldmVuIGlmIHRoZSBjb250ZW50IHR5cGUgaXMgKm1peGVkKiwgd2UgbmVlZCB0aGUKICAgICogKmluaXRpYWwgdmFsdWUqIGZvciBkZWZhdWx0L2ZpeGVkIHZhbHVlIGNvbnN0cmFpbnRzLgogICAgKi8KICAgIGlmICgodmN0eHQtPmlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkoKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKSB8fAoJKHZjdHh0LT5pbm9kZS0+ZGVjbC0+dmFsdWUgPT0gTlVMTCkpKQoJcmV0dXJuICgwKTsKICAgIAogICAgaWYgKHZjdHh0LT5pbm9kZS0+dmFsdWUgPT0gTlVMTCkgewoJLyoKCSogU2V0IHRoZSB2YWx1ZS4KCSovCglzd2l0Y2ggKG1vZGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1Q6CgkJLyoKCQkqIFdoZW4gd29ya2luZyBvbiBhIHRyZWUuCgkJKi8KCQl2Y3R4dC0+aW5vZGUtPnZhbHVlID0gdmFsdWU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9DUkVBVEVEOgoJCS8qCgkJKiBXaGVuIHdvcmtpbmcgd2l0aCB0aGUgcmVhZGVyLgoJCSogVGhlIHZhbHVlIHdpbGwgYmUgZnJlZWQgYnkgdGhlIGVsZW1lbnQgaW5mby4KCQkqLwoJCXZjdHh0LT5pbm9kZS0+dmFsdWUgPSB2YWx1ZTsKCQlpZiAoY29uc3VtZWQgIT0gTlVMTCkKCQkgICAgKmNvbnN1bWVkID0gMTsKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9CgkJICAgIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEU6CgkJLyoKCQkqIFdoZW4gd29ya2luZyB3aXRoIFNBWC4KCQkqIFRoZSB2YWx1ZSB3aWxsIGJlIGZyZWVkIGJ5IHRoZSBlbGVtZW50IGluZm8uCgkJKi8KCQlpZiAobGVuICE9IC0xKQoJCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0gQkFEX0NBU1QgeG1sU3RybmR1cCh2YWx1ZSwgbGVuKTsKCQllbHNlCgkJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPSBCQURfQ0FTVCB4bWxTdHJkdXAodmFsdWUpOwoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0KCQkgICAgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0gZWxzZSB7CglpZiAobGVuIDwgMCkKCSAgICBsZW4gPSB4bWxTdHJsZW4odmFsdWUpOwoJLyoKCSogQ29uY2F0IHRoZSB2YWx1ZS4KCSovCQoJaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUykgewoJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPSBCQURfQ0FTVCB4bWxTdHJuY2F0KAoJCSh4bWxDaGFyICopIHZjdHh0LT5pbm9kZS0+dmFsdWUsIHZhbHVlLCBsZW4pOwoJfSBlbHNlIHsKCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0KCQlCQURfQ0FTVCB4bWxTdHJuY2F0TmV3KHZjdHh0LT5pbm9kZS0+dmFsdWUsIHZhbHVlLCBsZW4pOwoJICAgIHZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7Cgl9CiAgICB9CQoKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IHJldCA9IDA7CgogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJgoJKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCSAgICAiaW4gc2tpcC1zdGF0ZSIpOwoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIGlmICh2Y3R4dC0+eHNpQXNzZW1ibGUpIHsKCS8qIAoJKiBXZSB3aWxsIHN0b3AgdmFsaWRhdGlvbiBpZiB0aGVyZSB3YXMgYW4gZXJyb3IgZHVyaW5nCgkqIGR5bmFtaWMgc2NoZW1hIGNvbnN0cnVjdGlvbi4KCSogTm90ZSB0aGF0IHdlIHNpbXBseSBzZXQgQHNraXBEZXB0aCB0byAwLCB0aGlzIGNvdWxkCgkqIG1lYW4gdGhhdCBhIHN0cmVhbWluZyBkb2N1bWVudCB2aWEgU0FYIHdvdWxkIGJlCgkqIHN0aWxsIHJlYWQgdG8gdGhlIGVuZCBidXQgaXQgd29uJ3QgYmUgdmFsaWRhdGVkIGFueSBtb3JlLgoJKiBUT0RPOiBJZiB3ZSBhcmUgc3VyZSBob3cgdG8gc3RvcCB0aGUgdmFsaWRhdGlvbiBhdCBvbmNlCgkqICAgZm9yIGFsbCBpbnB1dCBzY2VuYXJpb3MsIHRoZW4gdGhpcyBzaG91bGQgYmUgY2hhbmdlZCB0bwoJKiAgIGluc3RhbnRseSBzdG9wIHRoZSB2YWxpZGF0aW9uLgoJKi8KCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0kodmN0eHQpOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA9PSAtMSkKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIHZjdHh0LT5za2lwRGVwdGggPSAwOwoJICAgIHJldHVybihyZXQpOwoJfQogICAgfQogICAgaWYgKHZjdHh0LT5kZXB0aCA+IDApIHsKCS8qCgkqIFZhbGlkYXRlIHRoaXMgZWxlbWVudCBhZ2FpbnN0IHRoZSBjb250ZW50IG1vZGVsCgkqIG9mIHRoZSBwYXJlbnQuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0odmN0eHQpOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFTdHJlYW1WYWxpZGF0ZUNoaWxkRWxlbWVudCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBleGl0OwoJfQoJaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKQoJICAgIGdvdG8gZXhpdDsKCWlmICgodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpICYmCgkgICAgKHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9PSBOVUxMKSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJInRoZSBjaGlsZCBlbGVtZW50IHdhcyB2YWxpZCBidXQgbmVpdGhlciB0aGUgIgoJCSJkZWNsYXJhdGlvbiBub3IgdGhlIHR5cGUgd2FzIHNldCIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogR2V0IHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgdmFsaWRhdGlvbiByb290LgoJKi8KCXZjdHh0LT5pbm9kZS0+ZGVjbCA9IHhtbFNjaGVtYUdldEVsZW0odmN0eHQtPnNjaGVtYSwKCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwKCSAgICB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CglpZiAodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzE7CgkgICAgVkVSUk9SKHJldCwgTlVMTCwKCQkiTm8gbWF0Y2hpbmcgZ2xvYmFsIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSAiCgkJImZvciB0aGUgdmFsaWRhdGlvbiByb290Iik7CgkgICAgZ290byBleGl0OwoJfQogICAgfQoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkKCWdvdG8gdHlwZV92YWxpZGF0aW9uOwoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmRlY2wtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkgewoJaW50IHNraXA7CgkvKgoJKiBXaWxkY2FyZHMuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQodmN0eHQsICZza2lwKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZXhpdDsKCX0KCWlmIChza2lwKSB7CgkgICAgdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKCSAgICBnb3RvIGV4aXQ7Cgl9CgkvKgoJKiBUaGUgZGVjbGFyYXRpb24gbWlnaHQgYmUgc2V0IGJ5IHRoZSB3aWxkY2FyZCB2YWxpZGF0aW9uLAoJKiB3aGVuIHRoZSBwcm9jZXNzQ29udGVudHMgaXMgImxheCIgb3IgInN0cmljdCIuCgkqLwoJaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgewoJICAgIC8qCgkgICAgKiBDbGVhciB0aGUgImRlY2wiIGZpZWxkIHRvIG5vdCBjb25mdXNlIGZ1cnRoZXIgcHJvY2Vzc2luZy4KCSAgICAqLwoJICAgIHZjdHh0LT5pbm9kZS0+ZGVjbCA9IE5VTEw7CgkgICAgZ290byB0eXBlX3ZhbGlkYXRpb247Cgl9CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhZ2FpbnN0IHRoZSBkZWNsYXJhdGlvbi4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsKHZjdHh0KTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKHJldCA8IDApIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2woKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGV4aXQ7CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhZ2FpbnN0IHRoZSB0eXBlIGRlZmluaXRpb24uCiAgICAqLwp0eXBlX3ZhbGlkYXRpb246CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9PSBOVUxMKSB7Cgl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9CQURfVFlQRTsKCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzE7CiAgICAJVkVSUk9SKHJldCwgTlVMTCwKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7Cglnb3RvIGV4aXQ7CiAgICB9ICAgIAogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUKSB7Cgl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9CQURfVFlQRTsKCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzI7CiAgICAJICAgIFZFUlJPUihyZXQsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic3RyYWN0Iik7CQoJZ290byBleGl0OwogICAgfQogICAgLyoKICAgICogRXZhbHVhdGUgSURDcy4gRG8gaXQgaGVyZSwgc2luY2UgbmV3IElEQyBtYXRjaGVycyBhcmUgcmVnaXN0ZXJlZAogICAgKiBkdXJpbmcgdmFsaWRhdGlvbiBhZ2FpbnN0IHRoZSBkZWNsYXJhdGlvbi4gVGhpcyBtdXN0IGJlIGRvbmUKICAgICogX2JlZm9yZV8gYXR0cmlidXRlIHZhbGlkYXRpb24uCiAgICAqLwogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKHZjdHh0LCBYTUxfRUxFTUVOVF9OT0RFKTsKCXZjdHh0LT5pbm9kZS0+YXBwbGllZFhQYXRoID0gMTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChXWFNfSVNfQ09NUExFWCh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYpKSB7CglpZiAoKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB8fAoJICAgICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmF0dHJVc2VzICE9IE5VTEwpKSB7CgoJICAgIHJldCA9IHhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCh2Y3R4dCk7Cgl9CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7CgoJcmV0ID0geG1sU2NoZW1hVkF0dHJpYnV0ZXNTaW1wbGUodmN0eHQpOwogICAgfQogICAgLyoKICAgICogQ2xlYXIgcmVnaXN0ZXJlZCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCXhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHZjdHh0KTsKICAgIGlmIChyZXQgPT0gLTEpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkgICAgImNhbGxpbmcgYXR0cmlidXRlcyB2YWxpZGF0aW9uIik7Cglnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgLyoKICAgICogRG9uJ3QgcmV0dXJuIGFuIGVycm9yIGlmIGF0dHJpYnV0ZXMgYXJlIGludmFsaWQgb24gcHVycG9zZS4KICAgICovCiAgICByZXQgPSAwOwoKZXhpdDoKICAgIGlmIChyZXQgIT0gMCkKCXZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgcmV0dXJuICgtMSk7Cn0KCiNpZmRlZiBYTUxfU0NIRU1BX1JFQURFUl9FTkFCTEVECnN0YXRpYyBpbnQKeG1sU2NoZW1hVlJlYWRlcldhbGsoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBjb25zdCBpbnQgV0hUU1AgPSAxMywgU0lHTl9XSFRTUCA9IDE0LCBFTkRfRUxFTSA9IDE1OwogICAgaW50IGRlcHRoLCBub2RlVHlwZSwgcmV0ID0gMCwgY29uc3VtZWQ7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbTsKCiAgICB2Y3R4dC0+ZGVwdGggPSAtMTsKICAgIHJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwogICAgLyoKICAgICogTW92ZSB0byB0aGUgZG9jdW1lbnQgZWxlbWVudC4KICAgICovCiAgICB3aGlsZSAocmV0ID09IDEpIHsKCW5vZGVUeXBlID0geG1sVGV4dFJlYWRlck5vZGVUeXBlKHZjdHh0LT5yZWFkZXIpOwoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgZ290byByb290X2ZvdW5kOwoJcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CiAgICB9CiAgICBnb3RvIGV4aXQ7Cgpyb290X2ZvdW5kOgoKICAgIGRvIHsKCWRlcHRoID0geG1sVGV4dFJlYWRlckRlcHRoKHZjdHh0LT5yZWFkZXIpOwoJbm9kZVR5cGUgPSB4bWxUZXh0UmVhZGVyTm9kZVR5cGUodmN0eHQtPnJlYWRlcik7CgoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICAKCSAgICB2Y3R4dC0+ZGVwdGgrKzsKCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgaWVsZW0tPmxvY2FsTmFtZSA9IHhtbFRleHRSZWFkZXJMb2NhbE5hbWUodmN0eHQtPnJlYWRlcik7CgkgICAgaWVsZW0tPm5zTmFtZSA9IHhtbFRleHRSZWFkZXJOYW1lc3BhY2VVcmkodmN0eHQtPnJlYWRlcik7CgkgICAgaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVM7CgkgICAgLyoKCSAgICAqIElzIHRoZSBlbGVtZW50IGVtcHR5PwoJICAgICovCgkgICAgcmV0ID0geG1sVGV4dFJlYWRlcklzRW1wdHlFbGVtZW50KHZjdHh0LT5yZWFkZXIpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJJc0VtcHR5RWxlbWVudCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWYgKHJldCkgewoJCWllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJlZ2lzdGVyIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwoJICAgIHJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZiAocmV0ID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxUZXh0UmVhZGVyTW92ZVRvRmlyc3RBdHRyaWJ1dGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGlmIChyZXQgPT0gMSkgewoJCWRvIHsKCQkgICAgLyoKCQkgICAgKiBWQUwgVE9ETzogSG93IGRvIHdlIGtub3cgdGhhdCB0aGUgcmVhZGVyIHdvcmtzIG9uIGEKCQkgICAgKiBub2RlIHRyZWUsIHRvIGJlIGFibGUgdG8gcGFzcyBhIG5vZGUgaGVyZT8KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUodmN0eHQsIE5VTEwsCgkJCShjb25zdCB4bWxDaGFyICopIHhtbFRleHRSZWFkZXJMb2NhbE5hbWUodmN0eHQtPnJlYWRlciksCgkJCXhtbFRleHRSZWFkZXJOYW1lc3BhY2VVcmkodmN0eHQtPnJlYWRlciksIDEsCgkJCXhtbFRleHRSZWFkZXJWYWx1ZSh2Y3R4dC0+cmVhZGVyKSwgMSkgPT0gLTEpIHsKCgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoKSIpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIHJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9OZXh0QXR0cmlidXRlKHZjdHh0LT5yZWFkZXIpOwoJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQl9IHdoaWxlIChyZXQgPT0gMSk7CgkJLyoKCQkqIEJhY2sgdG8gZWxlbWVudCBwb3NpdGlvbi4KCQkqLwoJCXJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9FbGVtZW50KHZjdHh0LT5yZWFkZXIpOwoJCWlmIChyZXQgPT0gLTEpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkiY2FsbGluZyB4bWxUZXh0UmVhZGVyTW92ZVRvRWxlbWVudCgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIGVsZW1lbnQuCgkgICAgKi8KCSAgICByZXQ9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWdvdG8gZXhpdDsKCSAgICB9CgkgICAgaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKSB7CgkJaW50IGN1ckRlcHRoOwoJCS8qCgkJKiBTa2lwIGFsbCBjb250ZW50LgoJCSovCgkJaWYgKChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkgPT0gMCkgewoJCSAgICByZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKCQkgICAgY3VyRGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7CgkJICAgIHdoaWxlICgocmV0ID09IDEpICYmIChjdXJEZXB0aCAhPSBkZXB0aCkpIHsKCQkJcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CgkJCWN1ckRlcHRoID0geG1sVGV4dFJlYWRlckRlcHRoKHZjdHh0LT5yZWFkZXIpOwoJCSAgICB9CgkJICAgIGlmIChyZXQgPCAwKSB7CgkJCS8qCgkJCSogVkFMIFRPRE86IEEgcmVhZGVyIGVycm9yIG9jY3VyZWQ7IHdoYXQgdG8gZG8gaGVyZT8KCQkJKi8KCQkJcmV0ID0gMTsKCQkJZ290byBleGl0OwoJCSAgICB9CgkJfQoJCWdvdG8gbGVhdmVfZWxlbTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJFQURFUiBWQUwgVE9ETzogSXMgYW4gRU5EX0VMRU0gcmVhbGx5IG5ldmVyIGNhbGxlZAoJICAgICogaWYgdGhlIGVsZW0gaXMgZW1wdHk/CgkgICAgKi8KCSAgICBpZiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgkJZ290byBsZWF2ZV9lbGVtOwoJfSBlbHNlIGlmIChub2RlVHlwZSA9PSBFTkRfRUxFTSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIEVORCBvZiBlbGVtZW50LgoJICAgICovCmxlYXZlX2VsZW06CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBleGl0OwoJICAgIH0KCSAgICBpZiAodmN0eHQtPmRlcHRoID49IDApCgkJaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgZWxzZQoJCWllbGVtID0gTlVMTDsKCX0gZWxzZSBpZiAoKG5vZGVUeXBlID09IFhNTF9URVhUX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFdIVFNQKSB8fAoJICAgIChub2RlVHlwZSA9PSBTSUdOX1dIVFNQKSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIGNoYXJhY3RlciBjb250ZW50LgoJICAgICovCgkgICAgeG1sQ2hhciAqdmFsdWU7CgoJICAgIGlmICgobm9kZVR5cGUgPT0gV0hUU1ApIHx8IChub2RlVHlwZSA9PSBTSUdOX1dIVFNQKSkKCQlub2RlVHlwZSA9IFhNTF9URVhUX05PREU7CgoJICAgIHZhbHVlID0geG1sVGV4dFJlYWRlclZhbHVlKHZjdHh0LT5yZWFkZXIpOwoJICAgIHJldCA9IHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgbm9kZVR5cGUsIEJBRF9DQVNUIHZhbHVlLAoJCS0xLCBYTUxfU0NIRU1BX1BVU0hfVEVYVF9DUkVBVEVELCAmY29uc3VtZWQpOwoJICAgIGlmICghIGNvbnN1bWVkKQoJCXhtbEZyZWUodmFsdWUpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UgaWYgKChub2RlVHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpKSB7CgkgICAgLyoKCSAgICAqIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggZW50aXRpZXM/CgkgICAgKi8KCSAgICBUT0RPCgl9CgkvKgoJKiBSZWFkIG5leHQgbm9kZS4KCSovCglyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKICAgIH0gd2hpbGUgKHJldCA9PSAxKTsKCmV4aXQ6CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgcmV0dXJuICgtMSk7Cn0KI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIHZhbGlkYXRpb24gaGFuZGxlcnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKgoqIFByb2Nlc3MgdGV4dCBjb250ZW50LgoqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVUZXh0KHZvaWQgKmN0eCwgCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBjaCwgCgkJICAgICAgIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgl2Y3R4dC0+aW5vZGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgaWYgKHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgWE1MX1RFWFRfTk9ERSwgY2gsIGxlbiwKCVhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFLCBOVUxMKSA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlQ0RhdGFTZWN0aW9uIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJdmN0eHQtPmVyciA9IC0xOwoJeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9Cn0KCi8qCiogUHJvY2VzcyBDREFUQSBjb250ZW50LgoqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24odm9pZCAqY3R4LCAKCQkJICAgICBjb25zdCB4bWxDaGFyICogY2gsIAoJCQkgICAgIGludCBsZW4pCnsgICAKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgl2Y3R4dC0+aW5vZGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgaWYgKHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSwgY2gsIGxlbiwKCVhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFLCBOVUxMKSA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlQ0RhdGFTZWN0aW9uIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJdmN0eHQtPmVyciA9IC0xOwoJeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZSh2b2lkICpjdHggQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIC8qIFNBWCBWQUwgVE9ETzogV2hhdCB0byBkbyBoZXJlPyAqLwogICAgVE9ETwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyh2b2lkICpjdHgsCgkJCQkgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSwgCgkJCQkgY29uc3QgeG1sQ2hhciAqIHByZWZpeCBBVFRSSUJVVEVfVU5VU0VELCAKCQkJCSBjb25zdCB4bWxDaGFyICogVVJJLCAKCQkJCSBpbnQgbmJfbmFtZXNwYWNlcywgCgkJCQkgY29uc3QgeG1sQ2hhciAqKiBuYW1lc3BhY2VzLCAKCQkJCSBpbnQgbmJfYXR0cmlidXRlcywgCgkJCQkgaW50IG5iX2RlZmF1bHRlZCBBVFRSSUJVVEVfVU5VU0VELCAKCQkJCSBjb25zdCB4bWxDaGFyICoqIGF0dHJpYnV0ZXMpCnsgIAogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwogICAgaW50IHJldDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtOwogICAgaW50IGksIGo7CiAgICAKICAgIC8qCiAgICAqIFNBWCBWQUwgVE9ETzogV2hhdCB0byBkbyB3aXRoIG5iX2RlZmF1bHRlZD8KICAgICovCiAgICAvKgogICAgKiBTa2lwIGVsZW1lbnRzIGlmIGluc2lkZSBhICJza2lwIiB3aWxkY2FyZCBvciBpbnZhbGlkLgogICAgKi8KICAgIHZjdHh0LT5kZXB0aCsrOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgLyoKICAgICogUHVzaCB0aGUgZWxlbWVudC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyIsCgkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0oKSIpOwoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIGllbGVtID0gdmN0eHQtPmlub2RlOwogICAgLyoKICAgICogVE9ETzogSXMgdGhpcyBPSz8KICAgICovCiAgICBpZWxlbS0+bm9kZUxpbmUgPSB4bWxTQVgyR2V0TGluZU51bWJlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICBpZWxlbS0+bG9jYWxOYW1lID0gbG9jYWxuYW1lOwogICAgaWVsZW0tPm5zTmFtZSA9IFVSSTsKICAgIGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKICAgIC8qCiAgICAqIFJlZ2lzdGVyIG5hbWVzcGFjZXMgb24gdGhlIGVsZW0gaW5mby4KICAgICovICAgIAogICAgaWYgKG5iX25hbWVzcGFjZXMgIT0gMCkgewoJLyoKCSogQWx0aG91Z2ggdGhlIHBhcnNlciBidWlsZHMgaXRzIG93biBuYW1lc3BhY2UgbGlzdCwKCSogd2UgaGF2ZSBubyBhY2Nlc3MgdG8gaXQsIHNvIHdlJ2xsIHVzZSBhbiBvd24gb25lLgoJKi8KICAgICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG5iX25hbWVzcGFjZXM7IGkrKywgaiArPSAyKSB7CSAgICAKCSAgICAvKgoJICAgICogU3RvcmUgcHJlZml4IGFuZCBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwkgICAKCSAgICBpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbE1hbGxvYygxMCAqCgkJCXNpemVvZihjb25zdCB4bWxDaGFyICopKTsKCQlpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCQkiYWxsb2NhdGluZyBuYW1lc3BhY2UgYmluZGluZ3MgZm9yIFNBWCB2YWxpZGF0aW9uIiwKCQkJTlVMTCk7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWllbGVtLT5uYk5zQmluZGluZ3MgPSAwOwoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyA9IDU7CgkgICAgfSBlbHNlIGlmIChpZWxlbS0+c2l6ZU5zQmluZGluZ3MgPD0gaWVsZW0tPm5iTnNCaW5kaW5ncykgewoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyAqPSAyOwoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbFJlYWxsb2MoCgkJCSh2b2lkICopIGllbGVtLT5uc0JpbmRpbmdzLAoJCQlpZWxlbS0+c2l6ZU5zQmluZGluZ3MgKiAyICogc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJCWlmIChpZWxlbS0+bnNCaW5kaW5ncyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJCSJyZS1hbGxvY2F0aW5nIG5hbWVzcGFjZSBiaW5kaW5ncyBmb3IgU0FYIHZhbGlkYXRpb24iLAoJCQlOVUxMKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoKCSAgICBpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMl0gPSBuYW1lc3BhY2VzW2pdOwoJICAgIGlmIChuYW1lc3BhY2VzW2orMV1bMF0gPT0gMCkgewoJCS8qCgkJKiBIYW5kbGUgeG1sbnM9IiIuCgkJKi8KCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0gTlVMTDsKCSAgICB9IGVsc2UKCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0KCQkgICAgbmFtZXNwYWNlc1tqKzFdOwoJICAgIGllbGVtLT5uYk5zQmluZGluZ3MrKzsJICAgIAkgICAgCgl9CiAgICB9CiAgICAvKgogICAgKiBSZWdpc3RlciBhdHRyaWJ1dGVzLgogICAgKiBTQVggVkFMIFRPRE86IFdlIGFyZSBub3QgYWRkaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgogICAgKiBhdHRyaWJ1dGVzIHlldC4KICAgICovCiAgICBpZiAobmJfYXR0cmlidXRlcyAhPSAwKSB7Cgl4bWxDaGFyICp2YWx1ZTsKCiAgICAgICAgZm9yIChqID0gMCwgaSA9IDA7IGkgPCBuYl9hdHRyaWJ1dGVzOyBpKyssIGogKz0gNSkgewoJICAgIC8qCgkgICAgKiBEdXBsaWNhdGUgdGhlIHZhbHVlLgoJICAgICovCSAKCSAgICB2YWx1ZSA9IHhtbFN0cm5kdXAoYXR0cmlidXRlc1tqKzNdLAoJCWF0dHJpYnV0ZXNbais0XSAtIGF0dHJpYnV0ZXNbaiszXSk7CgkgICAgLyoKCSAgICAqIFRPRE86IFNldCB0aGUgbm9kZSBsaW5lLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwKCQlOVUxMLCBpZWxlbS0+bm9kZUxpbmUsIGF0dHJpYnV0ZXNbal0sIGF0dHJpYnV0ZXNbaisyXSwgMCwKCQl2YWx1ZSwgMSk7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW0odmN0eHQpOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAocmV0ID09IC0xKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlU3RhcnRFbGVtZW50TnMiLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KCWdvdG8gZXhpdDsKICAgIH0gICAgCgpleGl0OgogICAgcmV0dXJuOwppbnRlcm5hbF9lcnJvcjoKICAgIHZjdHh0LT5lcnIgPSAtMTsKICAgIHhtbFN0b3BQYXJzZXIodmN0eHQtPnBhcnNlckN0eHQpOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnModm9pZCAqY3R4LAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIHByZWZpeCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHg7CiAgICBpbnQgcmVzOwoKICAgIC8qCiAgICAqIFNraXAgZWxlbWVudHMgaWYgaW5zaWRlIGEgInNraXAiIHdpbGRjYXJkIG9yIGlmIGludmFsaWQuCiAgICAqLwogICAgaWYgKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpIHsKCWlmICh2Y3R4dC0+ZGVwdGggPiB2Y3R4dC0+c2tpcERlcHRoKSB7CgkgICAgdmN0eHQtPmRlcHRoLS07CgkgICAgcmV0dXJuOwoJfSBlbHNlCgkgICAgdmN0eHQtPnNraXBEZXB0aCA9IC0xOwogICAgfQogICAgLyoKICAgICogU0FYIFZBTCBUT0RPOiBKdXN0IGEgdGVtcG9yYXJ5IGNoZWNrLgogICAgKi8KICAgIGlmICgoIXhtbFN0ckVxdWFsKHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCBsb2NhbG5hbWUpKSB8fAoJKCF4bWxTdHJFcXVhbCh2Y3R4dC0+aW5vZGUtPm5zTmFtZSwgVVJJKSkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZUVuZEVsZW1lbnROcyIsCgkgICAgImVsZW0gcG9wIG1pc21hdGNoIik7CiAgICB9CiAgICByZXMgPSB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHZjdHh0KTsKICAgIGlmIChyZXMgIT0gMCkgewoJaWYgKHJlcyA8IDApIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnMiLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGV4aXQ7CiAgICB9CmV4aXQ6CiAgICByZXR1cm47CmludGVybmFsX2Vycm9yOgogICAgdmN0eHQtPmVyciA9IC0xOwogICAgeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEuCiAqCiAqIFJldHVybnMgdGhlIHZhbGlkYXRpb24gY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVZhbGlkQ3R4dFB0cgp4bWxTY2hlbWFOZXdWYWxpZEN0eHQoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyB2YWxpZGF0aW9uIGNvbnRleHQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUjsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIHJldC0+bm9kZVFOYW1lcyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0OgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQ7CiAqIGxlYXZlcyBzb21lIGZpZWxkcyBhbGl2ZSBpbnRlbmRlZCBmb3IgcmV1c2Ugb2YgdGhlIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhclZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGlmICh2Y3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICAvKgogICAgKiBUT0RPOiBTaG91bGQgd2UgY2xlYXIgdGhlIGZsYWdzPwogICAgKiAgIE1pZ2h0IGJlIHByb2JsZW1hdGljIGlmIG9uZSByZXVzZXMgdGhlIGNvbnRleHQKICAgICogICBhbmQgYXNzdW1lcyB0aGF0IHRoZSBvcHRpb25zIHJlbWFpbiB0aGUgc2FtZS4KICAgICovCiAgICB2Y3R4dC0+ZmxhZ3MgPSAwOwogICAgdmN0eHQtPnZhbGlkYXRpb25Sb290ID0gTlVMTDsKICAgIHZjdHh0LT5kb2MgPSBOVUxMOwojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECiAgICB2Y3R4dC0+cmVhZGVyID0gTlVMTDsKI2VuZGlmCiAgICB2Y3R4dC0+aGFzS2V5cmVmcyA9IDA7ICAgIAoKICAgIGlmICh2Y3R4dC0+dmFsdWUgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+dmFsdWUpOwoJdmN0eHQtPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIEF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb24uCiAgICAqLwogICAgaWYgKHZjdHh0LT5haWRjcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENBdWdQdHIgY3VyID0gdmN0eHQtPmFpZGNzLCBuZXh0OwoJZG8gewoJICAgIG5leHQgPSBjdXItPm5leHQ7CgkgICAgeG1sRnJlZShjdXIpOwoJICAgIGN1ciA9IG5leHQ7Cgl9IHdoaWxlIChjdXIgIT0gTlVMTCk7Cgl2Y3R4dC0+YWlkY3MgPSBOVUxMOwogICAgfQogICAgaWYgKHZjdHh0LT5pZGNOb2RlcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYklkY05vZGVzOyBpKyspIHsKCSAgICBpdGVtID0gdmN0eHQtPmlkY05vZGVzW2ldOwoJICAgIHhtbEZyZWUoaXRlbS0+a2V5cyk7CgkgICAgeG1sRnJlZShpdGVtKTsKCX0KCXhtbEZyZWUodmN0eHQtPmlkY05vZGVzKTsKCXZjdHh0LT5pZGNOb2RlcyA9IE5VTEw7CiAgICB9CiAgICAvKgogICAgKiBOb3RlIHRoYXQgd2Ugd29uJ3QgZGVsZXRlIHRoZSBYUGF0aCBzdGF0ZSBwb29sIGhlcmUuCiAgICAqLwogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlSURDU3RhdGVPYmpMaXN0KHZjdHh0LT54cGF0aFN0YXRlcyk7Cgl2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogQXR0cmlidXRlIGluZm8uCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7Cgl4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyh2Y3R4dCk7CiAgICB9CiAgICAvKgogICAgKiBFbGVtZW50IGluZm8uCiAgICAqLwogICAgaWYgKHZjdHh0LT5lbGVtSW5mb3MgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFOb2RlSW5mb1B0ciBlaTsKCglmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykgewoJICAgIGVpID0gdmN0eHQtPmVsZW1JbmZvc1tpXTsKCSAgICBpZiAoZWkgPT0gTlVMTCkKCQlicmVhazsKCSAgICB4bWxTY2hlbWFDbGVhckVsZW1JbmZvKGVpKTsKCX0KICAgIH0gICAgCiAgICB4bWxTY2hlbWFJdGVtTGlzdENsZWFyKHZjdHh0LT5ub2RlUU5hbWVzKTsKICAgIC8qIFJlY3JlYXRlIHRoZSBkaWN0LiAqLwogICAgeG1sRGljdEZyZWUodmN0eHQtPmRpY3QpOwogICAgLyoKICAgICogVE9ETzogSXMgaXMgc2F2ZSB0byByZWNyZWF0ZSBpdD8gRG8gd2UgaGF2ZSBhIHNjZW5hcmlvCiAgICAqIHdoZXJlIHRoZSB1c2VyIHByb3ZpZGVzIHRoZSBkaWN0PwogICAgKi8KICAgIHZjdHh0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KGN0eHQtPnBjdHh0KTsKICAgIGlmIChjdHh0LT5pZGNOb2RlcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjTm9kZXM7IGkrKykgewoJICAgIGl0ZW0gPSBjdHh0LT5pZGNOb2Rlc1tpXTsKCSAgICB4bWxGcmVlKGl0ZW0tPmtleXMpOwoJICAgIHhtbEZyZWUoaXRlbSk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmlkY05vZGVzKTsKICAgIH0KICAgIGlmIChjdHh0LT5pZGNLZXlzICE9IE5VTEwpIHsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjS2V5czsgaSsrKQoJICAgIHhtbFNjaGVtYUlEQ0ZyZWVLZXkoY3R4dC0+aWRjS2V5c1tpXSk7Cgl4bWxGcmVlKGN0eHQtPmlkY0tleXMpOwogICAgfQoKICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlcyk7CiAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QoY3R4dC0+eHBhdGhTdGF0ZVBvb2wpOwoKICAgIC8qCiAgICAqIEF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb24uCiAgICAqLwogICAgaWYgKGN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBjdXIgPSBjdHh0LT5haWRjcywgbmV4dDsKCWRvIHsKCSAgICBuZXh0ID0gY3VyLT5uZXh0OwoJICAgIHhtbEZyZWUoY3VyKTsKCSAgICBjdXIgPSBuZXh0OwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPmF0dHJJbmZvcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGF0dHI7CgoJLyogSnVzdCBhIHBhcmFub2lkIGNhbGwgdG8gdGhlIGNsZWFudXAuICovCglpZiAoY3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCSAgICB4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyhjdHh0KTsKCWZvciAoaSA9IDA7IGkgPCBjdHh0LT5zaXplQXR0ckluZm9zOyBpKyspIHsKCSAgICBhdHRyID0gY3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIHhtbEZyZWUoYXR0cik7Cgl9Cgl4bWxGcmVlKGN0eHQtPmF0dHJJbmZvcyk7CiAgICB9CiAgICBpZiAoY3R4dC0+ZWxlbUluZm9zICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hTm9kZUluZm9QdHIgZWk7CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykgewoJICAgIGVpID0gY3R4dC0+ZWxlbUluZm9zW2ldOwoJICAgIGlmIChlaSA9PSBOVUxMKQoJCWJyZWFrOwoJICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8oZWkpOwoJICAgIHhtbEZyZWUoZWkpOwoJfQoJeG1sRnJlZShjdHh0LT5lbGVtSW5mb3MpOwogICAgfQogICAgaWYgKGN0eHQtPm5vZGVRTmFtZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjdHh0LT5ub2RlUU5hbWVzKTsKICAgIGlmIChjdHh0LT5kaWN0ICE9IE5VTEwpCgl4bWxEaWN0RnJlZShjdHh0LT5kaWN0KTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1ZhbGlkOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQ2hlY2sgaWYgYW55IGVycm9yIHdhcyBkZXRlY3RlZCBkdXJpbmcgdmFsaWRhdGlvbi4KICogCiAqIFJldHVybnMgMSBpZiB2YWxpZCBzbyBmYXIsIDAgaWYgZXJyb3JzIHdlcmUgZGV0ZWN0ZWQsIGFuZCAtMSBpbiBjYXNlCiAqICAgICAgICAgb2YgaW50ZXJuYWwgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hSXNWYWxpZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4oLTEpOwogICAgcmV0dXJuKGN0eHQtPmVyciA9PSAwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPmVyckN0eHQgPSBjdHg7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNldFBhcnNlckVycm9ycyhjdHh0LT5wY3R4dCwgZXJyLCB3YXJuLCBjdHgpOwp9CgovKioKICogeG1sU2NoZW1hU2V0VmFsaWRTdHJ1Y3R1cmVkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2Vycm9yOiAgdGhlIHN0cnVjdHVyZWQgZXJyb3IgZnVuY3Rpb24KICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0CiAqCiAqIFNldCB0aGUgc3RydWN0dXJlZCBlcnJvciBjYWxsYmFjawogKi8Kdm9pZAp4bWxTY2hlbWFTZXRWYWxpZFN0cnVjdHVyZWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoJY3R4dC0+c2Vycm9yID0gc2Vycm9yOwogICAgY3R4dC0+ZXJyb3IgPSBOVUxMOwogICAgY3R4dC0+d2FybmluZyA9IE5VTEw7CiAgICBjdHh0LT5lcnJDdHh0ID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJTdHJ1Y3R1cmVkRXJyb3JzKGN0eHQtPnBjdHh0LCBzZXJyb3IsIGN0eCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRWYWxpZEVycm9yczoKICogQGN0eHQ6CWEgWE1MLVNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGZ1bmN0aW9uIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgZnVuY3Rpb24gcmVzdWx0CiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dCByZXN1bHQKICoKICogR2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yIGFuZCAwIG90aGVyd2lzZQogKi8KaW50CnhtbFNjaGVtYUdldFZhbGlkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQl4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyAqIGVyciwKCQkJeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuICgtMSk7CglpZiAoZXJyICE9IE5VTEwpCgkJKmVyciA9IGN0eHQtPmVycm9yOwoJaWYgKHdhcm4gIT0gTlVMTCkKCQkqd2FybiA9IGN0eHQtPndhcm5pbmc7CglpZiAoY3R4ICE9IE5VTEwpCgkJKmN0eCA9IGN0eHQtPmVyckN0eHQ7CglyZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkT3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFWYWxpZE9wdGlvbgogKgogKiBTZXRzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFTZXRWYWxpZE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSBpbnQgb3B0aW9ucykKCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFWYWxpZE9wdGlvbi4KICAgICogVE9ETzogSXMgdGhlcmUgYW4gb3RoZXIsIG1vcmUgZWFzeSB0byBtYWludGFpbiwKICAgICogd2F5PwogICAgKi8KICAgIGZvciAoaSA9IDE7IGkgPCAoaW50KSBzaXplb2YoaW50KSAqIDg7IGkrKykgewogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogR2V0IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQgb3B0aW9ucy4KICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9yIC0xIG9uIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpCgp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZEb2NXYWxrKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbSA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIG5vZGUsIHZhbFJvb3Q7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CgogICAgLyogRE9DIFZBTCBUT0RPOiBNb3ZlIHRoaXMgdG8gdGhlIHN0YXJ0IGZ1bmN0aW9uLiAqLwogICAgdmFsUm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KHZjdHh0LT5kb2MpOwogICAgaWYgKHZhbFJvb3QgPT0gTlVMTCkgewoJLyogVkFMIFRPRE86IEVycm9yIGNvZGU/ICovCglWRVJST1IoMSwgTlVMTCwgIlRoZSBkb2N1bWVudCBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudCIpOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHZjdHh0LT5kZXB0aCA9IC0xOwogICAgdmN0eHQtPnZhbGlkYXRpb25Sb290ID0gdmFsUm9vdDsKICAgIG5vZGUgPSB2YWxSb290OwogICAgd2hpbGUgKG5vZGUgIT0gTlVMTCkgewoJaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJICAgIGdvdG8gbmV4dF9zaWJsaW5nOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoKCSAgICAvKgoJICAgICogSW5pdCB0aGUgbm9kZS1pbmZvLgoJICAgICovCgkgICAgdmN0eHQtPmRlcHRoKys7CgkgICAgaWYgKHhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtKHZjdHh0KSA9PSAtMSkKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGllbGVtID0gdmN0eHQtPmlub2RlOwoJICAgIGllbGVtLT5ub2RlID0gbm9kZTsKCSAgICBpZWxlbS0+bm9kZUxpbmUgPSBub2RlLT5saW5lOwoJICAgIGllbGVtLT5sb2NhbE5hbWUgPSBub2RlLT5uYW1lOwoJICAgIGlmIChub2RlLT5ucyAhPSBOVUxMKQoJCWllbGVtLT5uc05hbWUgPSBub2RlLT5ucy0+aHJlZjsKCSAgICBpZWxlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CgkgICAgLyoKCSAgICAqIFJlZ2lzdGVyIGF0dHJpYnV0ZXMuCgkgICAgKiBET0MgVkFMIFRPRE86IFdlIGRvIG5vdCByZWdpc3RlciBuYW1lc3BhY2UgZGVjbGFyYXRpb24KCSAgICAqIGF0dHJpYnV0ZXMgeWV0LgoJICAgICovCgkgICAgdmN0eHQtPm5iQXR0ckluZm9zID0gMDsKCSAgICBpZiAobm9kZS0+cHJvcGVydGllcyAhPSBOVUxMKSB7CgkJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CgkJZG8gewoJCSAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkKCQkJbnNOYW1lID0gYXR0ci0+bnMtPmhyZWY7CgkJICAgIGVsc2UKCQkJbnNOYW1lID0gTlVMTDsKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwKCQkJKHhtbE5vZGVQdHIpIGF0dHIsCgkJCS8qIAoJCQkqIE5vdGUgdGhhdCB3ZSBnaXZlIGl0IHRoZSBsaW5lIG51bWJlciBvZiB0aGUKCQkJKiBwYXJlbnQgZWxlbWVudC4KCQkJKi8KCQkJaWVsZW0tPm5vZGVMaW5lLAoJCQlhdHRyLT5uYW1lLCBuc05hbWUsIDAsCgkJCXhtbE5vZGVMaXN0R2V0U3RyaW5nKGF0dHItPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpLCAxKTsKCQkgICAgaWYgKHJldCA9PSAtMSkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFEb2NXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoKSIpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCX0gd2hpbGUgKGF0dHIpOwoJICAgIH0KCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIGVsZW1lbnQuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW0odmN0eHQpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPT0gLTEpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hRG9jV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCS8qCgkJKiBEb24ndCBzdG9wIHZhbGlkYXRpb247IGp1c3Qgc2tpcCB0aGUgY29udGVudAoJCSogb2YgdGhpcyBlbGVtZW50LgoJCSovCgkJZ290byBsZWF2ZV9ub2RlOwoJICAgIH0KCSAgICBpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmCgkJKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCQlnb3RvIGxlYXZlX25vZGU7Cgl9IGVsc2UgaWYgKChub2RlLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CgkgICAgKG5vZGUtPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyBjaGFyYWN0ZXIgY29udGVudC4KCSAgICAqLwoJICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCQlpZWxlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CgkgICAgcmV0ID0geG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBub2RlLT50eXBlLCBub2RlLT5jb250ZW50LAoJCS0xLCBYTUxfU0NIRU1BX1BVU0hfVEVYVF9QRVJTSVNULCBOVUxMKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZEb2NXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVlB1c2hUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBTaG91bGQgd2Ugc2tpcCBmdXJ0aGVyIHZhbGlkYXRpb24gb2YgdGhlCgkgICAgKiBlbGVtZW50IGNvbnRlbnQgaGVyZT8KCSAgICAqLwoJfSBlbHNlIGlmICgobm9kZS0+dHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CgkgICAgKG5vZGUtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkpIHsKCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggZW50aXRpZXM/CgkgICAgKi8KCSAgICBUT0RPCgl9IGVsc2UgewoJICAgIGdvdG8gbGVhdmVfbm9kZTsKCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBYSW5jbHVkZSBub2RlcywgZXRjLgoJICAgICovCgl9CgkvKgoJKiBXYWxrIHRoZSBkb2MuCgkqLwoJaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsKCSAgICBub2RlID0gbm9kZS0+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+aWdub3JhYmxlV2hpdGVzcGFjZShjdHh0LT51c2VyX2RhdGEsIHZhbHVlLCBsZW4pOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbihjdHh0LT5jdHh0LCB2YWx1ZSwgbGVuKTsKfQoKc3RhdGljIHZvaWQKcmVmZXJlbmNlU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+cmVmZXJlbmNlICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPnJlZmVyZW5jZShjdHh0LT51c2VyX2RhdGEsIG5hbWUpOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFTQVhIYW5kbGVSZWZlcmVuY2UoY3R4dC0+dXNlcl9kYXRhLCBuYW1lKTsKfQoKc3RhdGljIHZvaWQKc3RhcnRFbGVtZW50TnNTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKiBsb2NhbG5hbWUsIAoJCSAgICBjb25zdCB4bWxDaGFyICogcHJlZml4LCBjb25zdCB4bWxDaGFyICogVVJJLCAKCQkgICAgaW50IG5iX25hbWVzcGFjZXMsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlcywgCgkJICAgIGludCBuYl9hdHRyaWJ1dGVzLCBpbnQgbmJfZGVmYXVsdGVkLCAKCQkgICAgY29uc3QgeG1sQ2hhciAqKiBhdHRyaWJ1dGVzKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5zdGFydEVsZW1lbnROcyAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5zdGFydEVsZW1lbnROcyhjdHh0LT51c2VyX2RhdGEsIGxvY2FsbmFtZSwgcHJlZml4LAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSwgbmJfbmFtZXNwYWNlcywgbmFtZXNwYWNlcywKCQkJCSAgICAgICBuYl9hdHRyaWJ1dGVzLCBuYl9kZWZhdWx0ZWQsCgkJCQkgICAgICAgYXR0cmlidXRlcyk7CiAgICBpZiAoY3R4dC0+Y3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU0FYSGFuZGxlU3RhcnRFbGVtZW50TnMoY3R4dC0+Y3R4dCwgbG9jYWxuYW1lLCBwcmVmaXgsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkksIG5iX25hbWVzcGFjZXMsIG5hbWVzcGFjZXMsCgkJCQkJIG5iX2F0dHJpYnV0ZXMsIG5iX2RlZmF1bHRlZCwKCQkJCQkgYXR0cmlidXRlcyk7Cn0KCnN0YXRpYyB2b2lkCmVuZEVsZW1lbnROc1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSwgCgkJICAgIGNvbnN0IHhtbENoYXIgKiBwcmVmaXgsIGNvbnN0IHhtbENoYXIgKiBVUkkpIHsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmVuZEVsZW1lbnROcyAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5lbmRFbGVtZW50TnMoY3R4dC0+dXNlcl9kYXRhLCBsb2NhbG5hbWUsIHByZWZpeCwgVVJJKTsKICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnMoY3R4dC0+Y3R4dCwgbG9jYWxuYW1lLCBwcmVmaXgsIFVSSSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTQVhQbHVnOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2F4OiAgYSBwb2ludGVyIHRvIHRoZSBvcmlnaW5hbCB4bWxTQVhIYW5kbGVyUHRyCiAqIEB1c2VyX2RhdGE6ICBhIHBvaW50ZXIgdG8gdGhlIG9yaWdpbmFsIFNBWCB1c2VyIGRhdGEgcG9pbnRlcgogKgogKiBQbHVnIGEgU0FYIGJhc2VkIHZhbGlkYXRpb24gbGF5ZXIgaW4gYSBTQVggcGFyc2luZyBldmVudCBmbG93LgogKiBUaGUgb3JpZ2luYWwgQHNheHB0ciBhbmQgQGRhdGFwdHIgZGF0YSBhcmUgcmVwbGFjZWQgYnkgbmV3IHBvaW50ZXJzCiAqIGJ1dCB0aGUgY2FsbHMgdG8gdGhlIG9yaWdpbmFsIHdpbGwgYmUgbWFpbnRhaW5lZC4KICoKICogUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBkYXRhIHN0cnVjdHVyZSBuZWVkZWQgdG8gdW5wbHVnIHRoZSB2YWxpZGF0aW9uIGxheWVyCiAqICAgICAgICAgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9ycy4KICovCnhtbFNjaGVtYVNBWFBsdWdQdHIKeG1sU2NoZW1hU0FYUGx1Zyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkgeG1sU0FYSGFuZGxlclB0ciAqc2F4LCB2b2lkICoqdXNlcl9kYXRhKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIHJldDsKICAgIHhtbFNBWEhhbmRsZXJQdHIgb2xkX3NheDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNheCA9PSBOVUxMKSB8fCAodXNlcl9kYXRhID09IE5VTEwpKQogICAgICAgIHJldHVybihOVUxMKTsKCiAgICAvKgogICAgICogV2Ugb25seSBhbGxvdyB0byBwbHVnIGludG8gU0FYMiBldmVudCBzdHJlYW1zCiAgICAgKi8KICAgIG9sZF9zYXggPSAqc2F4OwogICAgaWYgKChvbGRfc2F4ICE9IE5VTEwpICYmIChvbGRfc2F4LT5pbml0aWFsaXplZCAhPSBYTUxfU0FYMl9NQUdJQykpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgaWYgKChvbGRfc2F4ICE9IE5VTEwpICYmIAogICAgICAgIChvbGRfc2F4LT5zdGFydEVsZW1lbnROcyA9PSBOVUxMKSAmJiAob2xkX3NheC0+ZW5kRWxlbWVudE5zID09IE5VTEwpICYmCiAgICAgICAgKChvbGRfc2F4LT5zdGFydEVsZW1lbnQgIT0gTlVMTCkgfHwgKG9sZF9zYXgtPmVuZEVsZW1lbnQgIT0gTlVMTCkpKQogICAgICAgIHJldHVybihOVUxMKTsKCiAgICAvKgogICAgICogZXZlcnl0aGluZyBzZWVtcyByaWdodCBhbGxvY2F0ZSB0aGUgbG9jYWwgZGF0YSBuZWVkZWQgZm9yIHRoYXQgbGF5ZXIKICAgICAqLwogICAgcmV0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hU0FYUGx1Z1N0cnVjdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVNBWFBsdWdTdHJ1Y3QpKTsKICAgIHJldC0+bWFnaWMgPSBYTUxfU0FYX1BMVUdfTUFHSUM7CiAgICByZXQtPnNjaGVtYXNfc2F4LmluaXRpYWxpemVkID0gWE1MX1NBWDJfTUFHSUM7CiAgICByZXQtPmN0eHQgPSBjdHh0OwogICAgcmV0LT51c2VyX3NheF9wdHIgPSBzYXg7CiAgICByZXQtPnVzZXJfc2F4ID0gb2xkX3NheDsKICAgIGlmIChvbGRfc2F4ID09IE5VTEwpIHsJCiAgICAgICAgLyoKCSAqIGdvIGRpcmVjdCwgbm8gbmVlZCBmb3IgdGhlIHNwbGl0IGJsb2NrIGFuZCBmdW5jdGlvbnMuCgkgKi8KCXJldC0+c2NoZW1hc19zYXguc3RhcnRFbGVtZW50TnMgPSB4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROczsKCXJldC0+c2NoZW1hc19zYXguZW5kRWxlbWVudE5zID0geG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zOwoJLyoKCSAqIE5vdGUgdGhhdCB3ZSB1c2UgdGhlIHNhbWUgdGV4dC1mdW5jdGlvbiBmb3IgYm90aCwgdG8gcHJldmVudAoJICogdGhlIHBhcnNlciBmcm9tIHRlc3RpbmcgZm9yIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgoJICovCglyZXQtPnNjaGVtYXNfc2F4Lmlnbm9yYWJsZVdoaXRlc3BhY2UgPSB4bWxTY2hlbWFTQVhIYW5kbGVUZXh0OwoJcmV0LT5zY2hlbWFzX3NheC5jaGFyYWN0ZXJzID0geG1sU2NoZW1hU0FYSGFuZGxlVGV4dDsKCglyZXQtPnNjaGVtYXNfc2F4LmNkYXRhQmxvY2sgPSB4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb247CglyZXQtPnNjaGVtYXNfc2F4LnJlZmVyZW5jZSA9IHhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZTsKCglyZXQtPnVzZXJfZGF0YSA9IGN0eHQ7CgkqdXNlcl9kYXRhID0gY3R4dDsKICAgIH0gZWxzZSB7CiAgICAgICAvKgogICAgICAgICogZm9yIGVhY2ggY2FsbGJhY2sgdW51c2VkIGJ5IFNjaGVtYXMgaW5pdGlhbGl6ZSBpdCB0byB0aGUgU3BsaXQKCSogcm91dGluZSBvbmx5IGlmIG5vbiBOVUxMIGluIHRoZSB1c2VyIGJsb2NrLCB0aGlzIGNhbiBzcGVlZCB1cCAKCSogdGhpbmdzIGF0IHRoZSBTQVggbGV2ZWwuCgkqLwogICAgICAgIGlmIChvbGRfc2F4LT5pbnRlcm5hbFN1YnNldCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmludGVybmFsU3Vic2V0ID0gaW50ZXJuYWxTdWJzZXRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+aXNTdGFuZGFsb25lICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaXNTdGFuZGFsb25lID0gaXNTdGFuZGFsb25lU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmhhc0ludGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaGFzSW50ZXJuYWxTdWJzZXQgPSBoYXNJbnRlcm5hbFN1YnNldFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5oYXNFeHRlcm5hbFN1YnNldCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4Lmhhc0V4dGVybmFsU3Vic2V0ID0gaGFzRXh0ZXJuYWxTdWJzZXRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+cmVzb2x2ZUVudGl0eSAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnJlc29sdmVFbnRpdHkgPSByZXNvbHZlRW50aXR5U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmdldEVudGl0eSAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmdldEVudGl0eSA9IGdldEVudGl0eVNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5lbnRpdHlEZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZW50aXR5RGVjbCA9IGVudGl0eURlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+bm90YXRpb25EZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgubm90YXRpb25EZWNsID0gbm90YXRpb25EZWNsU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmF0dHJpYnV0ZURlY2wgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5hdHRyaWJ1dGVEZWNsID0gYXR0cmlidXRlRGVjbFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5lbGVtZW50RGVjbCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmVsZW1lbnREZWNsID0gZWxlbWVudERlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+dW5wYXJzZWRFbnRpdHlEZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgudW5wYXJzZWRFbnRpdHlEZWNsID0gdW5wYXJzZWRFbnRpdHlEZWNsU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPnNldERvY3VtZW50TG9jYXRvciAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnNldERvY3VtZW50TG9jYXRvciA9IHNldERvY3VtZW50TG9jYXRvclNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5zdGFydERvY3VtZW50ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguc3RhcnREb2N1bWVudCA9IHN0YXJ0RG9jdW1lbnRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+ZW5kRG9jdW1lbnQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5lbmREb2N1bWVudCA9IGVuZERvY3VtZW50U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPnByb2Nlc3NpbmdJbnN0cnVjdGlvbiAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IHByb2Nlc3NpbmdJbnN0cnVjdGlvblNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5jb21tZW50ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguY29tbWVudCA9IGNvbW1lbnRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+d2FybmluZyAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4Lndhcm5pbmcgPSB3YXJuaW5nU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmVycm9yICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZXJyb3IgPSBlcnJvclNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5mYXRhbEVycm9yICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZmF0YWxFcnJvciA9IGZhdGFsRXJyb3JTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+Z2V0UGFyYW1ldGVyRW50aXR5ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZ2V0UGFyYW1ldGVyRW50aXR5ID0gZ2V0UGFyYW1ldGVyRW50aXR5U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmV4dGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZXh0ZXJuYWxTdWJzZXQgPSBleHRlcm5hbFN1YnNldFNwbGl0OwoKCS8qCgkgKiB0aGUgNiBzY2hlbWFzIGNhbGxiYWNrIGhhdmUgdG8gZ28gdG8gdGhlIHNwbGl0dGVyIGZ1bmN0aW9ucwoJICogTm90ZSB0aGF0IHdlIHVzZSB0aGUgc2FtZSB0ZXh0LWZ1bmN0aW9uIGZvciBpZ25vcmFibGVXaGl0ZXNwYWNlCgkgKiBpZiBwb3NzaWJsZSwgdG8gcHJldmVudCB0aGUgcGFyc2VyIGZyb20gdGVzdGluZyBmb3IgaWdub3JhYmxlCgkgKiB3aGl0ZXNwYWNlLgoJICovCiAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5jaGFyYWN0ZXJzID0gY2hhcmFjdGVyc1NwbGl0OwoJaWYgKChvbGRfc2F4LT5pZ25vcmFibGVXaGl0ZXNwYWNlICE9IE5VTEwpICYmCgkgICAgKG9sZF9zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgIT0gb2xkX3NheC0+Y2hhcmFjdGVycykpCgkgICAgcmV0LT5zY2hlbWFzX3NheC5pZ25vcmFibGVXaGl0ZXNwYWNlID0gaWdub3JhYmxlV2hpdGVzcGFjZVNwbGl0OwoJZWxzZQoJICAgIHJldC0+c2NoZW1hc19zYXguaWdub3JhYmxlV2hpdGVzcGFjZSA9IGNoYXJhY3RlcnNTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmNkYXRhQmxvY2sgPSBjZGF0YUJsb2NrU3BsaXQ7CiAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5yZWZlcmVuY2UgPSByZWZlcmVuY2VTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnN0YXJ0RWxlbWVudE5zID0gc3RhcnRFbGVtZW50TnNTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmVuZEVsZW1lbnROcyA9IGVuZEVsZW1lbnROc1NwbGl0OwoKCXJldC0+dXNlcl9kYXRhX3B0ciA9IHVzZXJfZGF0YTsKCXJldC0+dXNlcl9kYXRhID0gKnVzZXJfZGF0YTsKCSp1c2VyX2RhdGEgPSByZXQ7CiAgICB9CgogICAgLyoKICAgICAqIHBsdWcgdGhlIHBvaW50ZXJzIGJhY2suCiAgICAgKi8KICAgICpzYXggPSAmKHJldC0+c2NoZW1hc19zYXgpOwogICAgY3R4dC0+c2F4ID0gKnNheDsKICAgIGN0eHQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfVkFMSURfQ1RYVF9GTEFHX1NUUkVBTTsKICAgIHhtbFNjaGVtYVByZVJ1bihjdHh0KTsKICAgIHJldHVybihyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU0FYVW5wbHVnOgogKiBAcGx1ZzogIGEgZGF0YSBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgeG1sU2NoZW1hU0FYUGx1ZwogKgogKiBVbnBsdWcgYSBTQVggYmFzZWQgdmFsaWRhdGlvbiBsYXllciBpbiBhIFNBWCBwYXJzaW5nIGV2ZW50IGZsb3cuCiAqIFRoZSBvcmlnaW5hbCBwb2ludGVycyB1c2VkIGluIHRoZSBjYWxsIGFyZSByZXN0b3JlZC4KICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcyBhbmQgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLgogKi8KaW50CnhtbFNjaGVtYVNBWFVucGx1Zyh4bWxTY2hlbWFTQVhQbHVnUHRyIHBsdWcpCnsKICAgIHhtbFNBWEhhbmRsZXJQdHIgKnNheDsKICAgIHZvaWQgKip1c2VyX2RhdGE7CgogICAgaWYgKChwbHVnID09IE5VTEwpIHx8IChwbHVnLT5tYWdpYyAhPSBYTUxfU0FYX1BMVUdfTUFHSUMpKQogICAgICAgIHJldHVybigtMSk7CiAgICBwbHVnLT5tYWdpYyA9IDA7CgogICAgeG1sU2NoZW1hUG9zdFJ1bihwbHVnLT5jdHh0KTsKICAgIC8qIHJlc3RvcmUgdGhlIGRhdGEgKi8KICAgIHNheCA9IHBsdWctPnVzZXJfc2F4X3B0cjsKICAgICpzYXggPSBwbHVnLT51c2VyX3NheDsKICAgIGlmIChwbHVnLT51c2VyX3NheCAhPSBOVUxMKSB7Cgl1c2VyX2RhdGEgPSBwbHVnLT51c2VyX2RhdGFfcHRyOwoJKnVzZXJfZGF0YSA9IHBsdWctPnVzZXJfZGF0YTsKICAgIH0KCiAgICAvKiBmcmVlIGFuZCByZXR1cm4gKi8KICAgIHhtbEZyZWUocGx1Zyk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGlucHV0OiAgdGhlIGlucHV0IHRvIHVzZSBmb3IgcmVhZGluZyB0aGUgZGF0YQogKiBAZW5jOiAgYW4gb3B0aW9uYWwgZW5jb2RpbmcgaW5mb3JtYXRpb24KICogQHNheDogIGEgU0FYIGhhbmRsZXIgZm9yIHRoZSByZXN1bHRpbmcgZXZlbnRzCiAqIEB1c2VyX2RhdGE6ICB0aGUgY29udGV4dCB0byBwcm92aWRlIHRvIHRoZSBTQVggaGFuZGxlci4KICoKICogVmFsaWRhdGUgYW4gaW5wdXQgYmFzZWQgb24gYSBmbG93IG9mIFNBWCBldmVudCBmcm9tIHRoZSBwYXJzZXIKICogYW5kIGZvcndhcmQgdGhlIGV2ZW50cyB0byB0aGUgQHNheCBoYW5kbGVyIHdpdGggdGhlIHByb3ZpZGVkIEB1c2VyX2RhdGEKICogdGhlIHVzZXIgcHJvdmlkZWQgQHNheCBoYW5kbGVyIG11c3QgYmUgYSBTQVgyIG9uZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dCwgeG1sQ2hhckVuY29kaW5nIGVuYywKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU0FYSGFuZGxlclB0ciBzYXgsIHZvaWQgKnVzZXJfZGF0YSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBwbHVnID0gTlVMTDsKICAgIHhtbFNBWEhhbmRsZXJQdHIgb2xkX3NheCA9IE5VTEw7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBjdHh0ID0gTlVMTDsKICAgIHhtbFBhcnNlcklucHV0UHRyIGlucHV0U3RyZWFtID0gTlVMTDsKICAgIGludCByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChpbnB1dCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgICogcHJlcGFyZSB0aGUgcGFyc2VyCiAgICAgKi8KICAgIHBjdHh0ID0geG1sTmV3UGFyc2VyQ3R4dCgpOwogICAgaWYgKHBjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBvbGRfc2F4ID0gcGN0eHQtPnNheDsKICAgIHBjdHh0LT5zYXggPSBzYXg7CiAgICBwY3R4dC0+dXNlckRhdGEgPSB1c2VyX2RhdGE7CiNpZiAwCiAgICBpZiAob3B0aW9ucykKICAgICAgICB4bWxDdHh0VXNlT3B0aW9ucyhwY3R4dCwgb3B0aW9ucyk7CiNlbmRpZgogICAgcGN0eHQtPmxpbmVudW1iZXJzID0gMTsgICAgCgogICAgaW5wdXRTdHJlYW0gPSB4bWxOZXdJT0lucHV0U3RyZWFtKHBjdHh0LCBpbnB1dCwgZW5jKTs7CiAgICBpZiAoaW5wdXRTdHJlYW0gPT0gTlVMTCkgewogICAgICAgIHJldCA9IC0xOwoJZ290byBkb25lOwogICAgfQogICAgaW5wdXRQdXNoKHBjdHh0LCBpbnB1dFN0cmVhbSk7CiAgICBjdHh0LT5wYXJzZXJDdHh0ID0gcGN0eHQ7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwoKICAgIC8qCiAgICAgKiBQbHVnIHRoZSB2YWxpZGF0aW9uIGFuZCBsYXVuY2ggdGhlIHBhcnNpbmcKICAgICAqLwogICAgcGx1ZyA9IHhtbFNjaGVtYVNBWFBsdWcoY3R4dCwgJihwY3R4dC0+c2F4KSwgJihwY3R4dC0+dXNlckRhdGEpKTsKICAgIGlmIChwbHVnID09IE5VTEwpIHsKICAgICAgICByZXQgPSAtMTsKCWdvdG8gZG9uZTsKICAgIH0KICAgIGN0eHQtPmlucHV0ID0gaW5wdXQ7CiAgICBjdHh0LT5lbmMgPSBlbmM7CiAgICBjdHh0LT5zYXggPSBwY3R4dC0+c2F4OwogICAgY3R4dC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9WQUxJRF9DVFhUX0ZMQUdfU1RSRUFNOwogICAgcmV0ID0geG1sU2NoZW1hVlN0YXJ0KGN0eHQpOwoKICAgIGlmICgocmV0ID09IDApICYmICghIGN0eHQtPnBhcnNlckN0eHQtPndlbGxGb3JtZWQpKSB7CglyZXQgPSBjdHh0LT5wYXJzZXJDdHh0LT5lcnJObzsKCWlmIChyZXQgPT0gMCkKCSAgICByZXQgPSAxOwogICAgfSAgICAKCmRvbmU6CiAgICBjdHh0LT5wYXJzZXJDdHh0ID0gTlVMTDsKICAgIGN0eHQtPnNheCA9IE5VTEw7CiAgICBjdHh0LT5pbnB1dCA9IE5VTEw7CiAgICBpZiAocGx1ZyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hU0FYVW5wbHVnKHBsdWcpOwogICAgfQogICAgLyogY2xlYW51cCAqLwogICAgaWYgKHBjdHh0ICE9IE5VTEwpIHsKCXBjdHh0LT5zYXggPSBvbGRfc2F4OwoJeG1sRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVGaWxlOgogKiBAY3R4dDogYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBmaWxlbmFtZTogdGhlIFVSSSBvZiB0aGUgaW5zdGFuY2UKICogQG9wdGlvbnM6IGEgZnV0dXJlIHNldCBvZiBvcHRpb25zLCBjdXJyZW50bHkgdW51c2VkCiAqCiAqIERvIGEgc2NoZW1hcyB2YWxpZGF0aW9uIG9mIHRoZSBnaXZlbiByZXNvdXJjZSwgaXQgd2lsbCB1c2UgdGhlCiAqIFNBWCBzdHJlYW1hYmxlIHZhbGlkYXRpb24gaW50ZXJuYWxseS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZUZpbGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogZmlsZW5hbWUsCgkJICAgICAgaW50IG9wdGlvbnMgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaW50IHJldDsKICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZmlsZW5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAKICAgIGlucHV0ID0geG1sUGFyc2VySW5wdXRCdWZmZXJDcmVhdGVGaWxlbmFtZShmaWxlbmFtZSwKCVhNTF9DSEFSX0VOQ09ESU5HX05PTkUpOwogICAgaWYgKGlucHV0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKGN0eHQsIGlucHV0LCBYTUxfQ0hBUl9FTkNPRElOR19OT05FLAoJTlVMTCwgTlVMTCk7ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgojZGVmaW5lIGJvdHRvbV94bWxzY2hlbWFzCiNpbmNsdWRlICJlbGZnY2NoYWNrLmgiCiNlbmRpZiAvKiBMSUJYTUxfU0NIRU1BU19FTkFCTEVEICovCg==