LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlCiAqICAgICBuZWVkIHRvIHZhbGlkYXRlIGFsbCBzY2hlbWEgYXR0cmlidXRlcyAocmVmLCB0eXBlLCBuYW1lKQogKiAgICAgYWdhaW5zdCB0aGVpciB0eXBlcy4KICogICAtIEVsaW1pbmF0ZSBpdGVtIGNyZWF0aW9uIGZvcjogPz8KICoKICogTk9URVM6CiAqICAgLSBFbGltYXRlZCBpdGVtIGNyZWF0aW9uIGZvcjogPHJlc3RyaWN0aW9uPiwgPGV4dGVuc2lvbj4sCiAqICAgICA8c2ltcGxlQ29udGVudD4sIDxjb21wbGV4Q29udGVudD4sIDxsaXN0PiwgPHVuaW9uPgogKgogKi8KI2RlZmluZSBJTl9MSUJYTUwKI2luY2x1ZGUgImxpYnhtbC5oIgoKI2lmZGVmIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQKCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CiNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CgojaW5jbHVkZSA8bGlieG1sL3htbHNjaGVtYXMuaD4KI2luY2x1ZGUgPGxpYnhtbC9zY2hlbWFzSW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hc3R5cGVzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sYXV0b21hdGEuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxyZWdleHAuaD4KI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CiNpZmRlZiBMSUJYTUxfUEFUVEVSTl9FTkFCTEVECiNpbmNsdWRlIDxsaWJ4bWwvcGF0dGVybi5oPgojZW5kaWYKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAojaW5jbHVkZSA8bGlieG1sL3htbHJlYWRlci5oPgojZW5kaWYKCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMAoKLyogI2RlZmluZSBERUJVR19JREMgMSAqLwoKLyogI2RlZmluZSBERUJVR19JTkNMVURFUyAxICovCgovKiAjZGVmaW5lIEVOQUJMRV9QQVJUSUNMRV9SRVNUUklDVElPTiAxICovCgojZGVmaW5lIERVTVBfQ09OVEVOVF9NT0RFTAoKI2RlZmluZSBYTUxfU0NIRU1BX1NBWF9FTkFCTEVECgojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECi8qICNkZWZpbmUgWE1MX1NDSEVNQV9SRUFERVJfRU5BQkxFRCAqLwojZW5kaWYKCiNkZWZpbmUgVU5CT1VOREVEICgxIDw8IDMwKQojZGVmaW5lIFRPRE8gCQkJCQkJCQlcCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwJCQkJXAoJICAgICJVbmltcGxlbWVudGVkIGJsb2NrIGF0ICVzOiVkXG4iLAkJCQlcCiAgICAgICAgICAgIF9fRklMRV9fLCBfX0xJTkVfXyk7CgojZGVmaW5lIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSAoY29uc3QgeG1sQ2hhciAqKSAiIyMiCgovKgogKiBUaGUgWE1MIFNjaGVtYXMgbmFtZXNwYWNlcwogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSI7CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hSW5zdGFuY2VOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbE5hbWVzcGFjZU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyI7CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJlbGVtZW50IGRlY2wuIjsKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCA9IChjb25zdCB4bWxDaGFyICopCiAgICAiYXR0cmlidXRlIGRlY2wuIjsKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUVsZW1EZXNBdHRyUmVmID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJhdHRyaWJ1dGUgdXNlIjsKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUVsZW1EZXNDVCA9IChjb25zdCB4bWxDaGFyICopCiAgICAiY29tcGxleCB0eXBlIjsKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUVsZW1Nb2RlbEdyRGVmID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJtb2RlbCBncm91cCI7CiNpZiAwCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtTW9kZWxHclJlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAibW9kZWwgZ3JvdXAgcmVmLiI7CiNlbmRpZgoKI2RlZmluZSBJU19TQ0hFTUEobm9kZSwgdHlwZSkJCQkJCQlcCiAgICgobm9kZSAhPSBOVUxMKSAmJiAobm9kZS0+bnMgIT0gTlVMTCkgJiYJCQkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIChjb25zdCB4bWxDaGFyICopIHR5cGUpKSAmJgkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKQoKI2RlZmluZSBGUkVFX0FORF9OVUxMKHN0cikJCQkJCQlcCiAgICBpZiAoc3RyICE9IE5VTEwpIHsJCQkJCQkJXAoJeG1sRnJlZSgoeG1sQ2hhciAqKSBzdHIpOwkJCQkJCQlcCglzdHIgPSBOVUxMOwkJCQkJCQlcCiAgICB9CgojZGVmaW5lIElTX0FOWVRZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgIFwKICAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBJU19DT01QTEVYX1RZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fCAgICBcCiAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBJU19TSU1QTEVfVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8ICAgICBcCiAgICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgIFwKICAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlICE9IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSkKCiNkZWZpbmUgSVNfQU5ZX1NJTVBMRV9UWVBFKGl0ZW0pICAgICAgICAgICAgICAgICAgIFwKICAgICgoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmICAgICAgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpCgojZGVmaW5lIElTX05PVF9UWVBFRklYRUQoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgICAgXAogICAgICgoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0lOVEVSTkFMX1JFU09MVkVEKSA9PSAwKSkKCiNkZWZpbmUgSEFTX0NPTVBMRVhfQ09OVEVOVChpdGVtKQkJCSBcCiAgICAoKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgfHwgIFwKICAgICAoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB8fCAgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKQoKI2RlZmluZSBIQVNfU0lNUExFX0NPTlRFTlQoaXRlbSkJCQkgXAogICAgKChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fCAgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKQoKI2RlZmluZSBIQVNfTUlYRURfQ09OVEVOVChpdGVtKQkoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKQoKI2RlZmluZSBJU19QQVJUSUNMRV9FTVBUSUFCTEUoaXRlbSkgXAogICAgKHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBpdGVtLT5zdWJ0eXBlcykpCgojZGVmaW5lIEdFVF9OT0RFKGl0ZW0pIHhtbFNjaGVtYUdldENvbXBvbmVudE5vZGUoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgaXRlbSkKCiNkZWZpbmUgR0VUX0xJU1RfSVRFTV9UWVBFKGl0ZW0pIGl0ZW0tPnN1YnR5cGVzCgojZGVmaW5lIFZBUklFVFlfQVRPTUlDKGl0ZW0pIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpCiNkZWZpbmUgVkFSSUVUWV9MSVNUKGl0ZW0pIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKQojZGVmaW5lIFZBUklFVFlfVU5JT04oaXRlbSkgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKQoKI2RlZmluZSBJU19NT0RFTF9HUk9VUChpdGVtKSAgICAgICAgICAgICAgICAgICAgIFwKICAgICgoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8IFwKICAgICAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSB8fCAgIFwKICAgICAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSkKCiNkZWZpbmUgSU5PREVfTklMTEVEKGl0ZW0pIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRCkKCiNkZWZpbmUgRUxFTV9UWVBFKGl0ZW0pIGl0ZW0tPnN1YnR5cGVzCgojZGVmaW5lIEdFVF9QQVJUSUNMRShpdGVtKSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0tPnN1YnR5cGVzOwoKI2RlZmluZSBTVUJTVF9HUk9VUF9BRkYoaXRlbSkgaXRlbS0+cmVmRGVjbAoKI2lmIDAKI2RlZmluZSBXWFNfR0VUX05FWFQoaXRlbSkgeG1sU2NoZW1hR2V0TmV4dENvbXBvbmVudCgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBpdGVtKQojZW5kaWYKCiNkZWZpbmUgU1VCU0VUX1JFU1RSSUNUSU9OICAxPDwwCiNkZWZpbmUgU1VCU0VUX0VYVEVOU0lPTiAgICAxPDwxCiNkZWZpbmUgU1VCU0VUX1NVQlNUSVRVVElPTiAxPDwyCiNkZWZpbmUgU1VCU0VUX0xJU1QgICAgICAgICAxPDwzCiNkZWZpbmUgU1VCU0VUX1VOSU9OICAgICAgICAxPDw0CgojZGVmaW5lIFhNTF9TQ0hFTUFTX1BBUlNFX0VSUk9SCQkxCgojZGVmaW5lIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyBYTUxfUEFSU0VfTk9FTlQKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFOb2RlSW5mbyB4bWxTY2hlbWFOb2RlSW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFOb2RlSW5mbyAqeG1sU2NoZW1hTm9kZUluZm9QdHI7CgoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1MaXN0IHhtbFNjaGVtYUFzc2VtYmxlOwp0eXBlZGVmIHhtbFNjaGVtYUFzc2VtYmxlICp4bWxTY2hlbWFBc3NlbWJsZVB0cjsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJdGVtTGlzdCB4bWxTY2hlbWFJdGVtTGlzdDsKdHlwZWRlZiB4bWxTY2hlbWFJdGVtTGlzdCAqeG1sU2NoZW1hSXRlbUxpc3RQdHI7CgpzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1MaXN0IHsKICAgIHZvaWQgKippdGVtczsgIC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBuYkl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgc2l6ZUl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQWJzdHJhY3RDdHh0IHhtbFNjaGVtYUFic3RyYWN0Q3R4dDsKdHlwZWRlZiB4bWxTY2hlbWFBYnN0cmFjdEN0eHQgKnhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cjsKc3RydWN0IF94bWxTY2hlbWFBYnN0cmFjdEN0eHQgewogICAgaW50IHR5cGU7Cn07CgojZGVmaW5lIFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIgMQojZGVmaW5lIFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IgMgoKc3RydWN0IF94bWxTY2hlbWFQYXJzZXJDdHh0IHsKICAgIGludCB0eXBlOwogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFNjaGVtYVZhbGlkRXJyb3IgZXJyOwogICAgaW50IG5iZXJyb3JzOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHRvcHNjaGVtYTsJLyogVGhlIG1haW4gc2NoZW1hICovCiAgICB4bWxIYXNoVGFibGVQdHIgbmFtZXNwYWNlczsJLyogSGFzaCB0YWJsZSBvZiBuYW1lc3BhY2VzIHRvIHNjaGVtYXMgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIGNvbnN0IHhtbENoYXIgKmNvbnRhaW5lcjsgICAvKiB0aGUgY3VycmVudCBlbGVtZW50LCBncm91cCwgLi4uICovCiAgICBpbnQgY291bnRlcjsKCiAgICBjb25zdCB4bWxDaGFyICpVUkw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHByZXNlcnZlOwkJLyogV2hldGhlciB0aGUgZG9jIHNob3VsZCBiZSBmcmVlZCAgKi8KCiAgICBjb25zdCBjaGFyICpidWZmZXI7CiAgICBpbnQgc2l6ZTsKCiAgICAvKgogICAgICogVXNlZCB0byBidWlsZCBjb21wbGV4IGVsZW1lbnQgY29udGVudCBtb2RlbHMKICAgICAqLwogICAgeG1sQXV0b21hdGFQdHIgYW07CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBlbmQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXRlOwoKICAgIHhtbERpY3RQdHIgZGljdDsJCS8qIGRpY3Rpb25uYXJ5IGZvciBpbnRlcm5lZCBzdHJpbmcgbmFtZXMgKi8KICAgIGludCAgICAgICAgaW5jbHVkZXM7CS8qIHRoZSBpbmNsdXNpb24gbGV2ZWwsIDAgZm9yIHJvb3Qgb3IgaW1wb3J0cyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHBhcmVudEl0ZW07IC8qIFRoZSBjdXJyZW50IHBhcmVudCBzY2hlbWEgaXRlbSAqLwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzZW1ibGU7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKICAgIGNvbnN0IHhtbENoYXIgKipsb2NhbEltcG9ydHM7IC8qIGxpc3Qgb2YgbG9jYWxseSBpbXBvcnRlZCBuYW1lc3BhY2VzICovCiAgICBpbnQgc2l6ZUxvY2FsSW1wb3J0czsKICAgIGludCBuYkxvY2FsSW1wb3J0czsKICAgIHhtbEhhc2hUYWJsZVB0ciBzdWJzdEdyb3VwczsKICAgIGludCBpc1M0UzsKfTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOIDEKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkcgNAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRSA1CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfTk9fVFlQRSA2CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUUgNwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCA4CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRSA5CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9TVFJJQ1RfTk9fREVDTCAxMAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSEFTX0FUVFJfVVNFIDExCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9IQVNfQVRUUl9ERUNMIDEyCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVAgMTMKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1dJTERfTEFYX05PX0RFQ0wgMTQKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0RVUExJQ0FURV9JRCAxNQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfQU5EX1VTRV9JRCAxNgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSAxNwoKLyoqCiAqIHhtbFNjaGVtYUJhc2ljSXRlbToKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3Igc2NoZW1hIGNvbXBvbmVudHMuCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQmFzaWNJdGVtIHhtbFNjaGVtYUJhc2ljSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFCYXNpY0l0ZW0gKnhtbFNjaGVtYUJhc2ljSXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFCYXNpY0l0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKfTsKCi8qKgogKiB4bWxTY2hlbWFBbm5vdEl0ZW06CiAqCiAqIFRoZSBhYnN0cmFjdCBiYXNlIHR5cGUgZm9yIGFubm90YXRlZCBzY2hlbWEgY29tcG9uZW50cy4KICogKEV4dGVuZHMgeG1sU2NoZW1hQmFzaWNJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUFubm90SXRlbSB4bWxTY2hlbWFBbm5vdEl0ZW07CnR5cGVkZWYgeG1sU2NoZW1hQW5ub3RJdGVtICp4bWxTY2hlbWFBbm5vdEl0ZW1QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQW5ub3RJdGVtIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKfTsKCi8qKgogKiB4bWxTY2hlbWFUcmVlSXRlbToKICoKICogVGhlIGFic3RyYWN0IGJhc2UgdHlwZSBmb3IgdHJlZS1saWtlIHN0cnVjdHVyZWQgc2NoZW1hIGNvbXBvbmVudHMuCiAqIChFeHRlbmRzIHhtbFNjaGVtYUFubm90SXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFUcmVlSXRlbSB4bWxTY2hlbWFUcmVlSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFUcmVlSXRlbSAqeG1sU2NoZW1hVHJlZUl0ZW1QdHI7CnN0cnVjdCBfeG1sU2NoZW1hVHJlZUl0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVFOYW1lUmVmOgogKgogKiBBIGNvbXBvbmVudCByZWZlcmVuY2UgaXRlbSAobm90IGEgc2NoZW1hIGNvbXBvbmVudCkKICogKEV4dGVuZHMgeG1sU2NoZW1hQmFzaWNJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVFOYW1lUmVmIHhtbFNjaGVtYVFOYW1lUmVmOwp0eXBlZGVmIHhtbFNjaGVtYVFOYW1lUmVmICp4bWxTY2hlbWFRTmFtZVJlZlB0cjsKc3RydWN0IF94bWxTY2hlbWFRTmFtZVJlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW07CiAgICB4bWxTY2hlbWFUeXBlVHlwZSBpdGVtVHlwZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7Cn07CgovKioKICogeG1sU2NoZW1hUGFydGljbGU6CiAqCiAqIEEgcGFydGljbGUgY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQYXJ0aWNsZSB4bWxTY2hlbWFQYXJ0aWNsZTsKdHlwZWRlZiB4bWxTY2hlbWFQYXJ0aWNsZSAqeG1sU2NoZW1hUGFydGljbGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUGFydGljbGUgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbmV4dCBwYXJ0aWNsZSAoT1IgImVsZW1lbnQgZGVjbCIgT1IgIndpbGRjYXJkIikgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiB0aGUgInRlcm0iICgibW9kZWwgZ3JvdXAiIE9SICJncm91cCBkZWZpbml0aW9uIikgKi8KICAgIGludCBtaW5PY2N1cnM7CiAgICBpbnQgbWF4T2NjdXJzOwogICAgeG1sTm9kZVB0ciBub2RlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYU1vZGVsR3JvdXA6CiAqCiAqIEEgbW9kZWwgZ3JvdXAgY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFUcmVlSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwIHhtbFNjaGVtYU1vZGVsR3JvdXA7CnR5cGVkZWYgeG1sU2NoZW1hTW9kZWxHcm91cCAqeG1sU2NoZW1hTW9kZWxHcm91cFB0cjsKc3RydWN0IF94bWxTY2hlbWFNb2RlbEdyb3VwIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7IC8qIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgWE1MX1NDSEVNQV9UWVBFX0FMTCAqLwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBuZXh0OyAvKiBub3QgdXNlZCAqLwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2hpbGRyZW47IC8qIGZpcnN0IHBhcnRpY2xlIChPUiAiZWxlbWVudCBkZWNsIiBPUiAid2lsZGNhcmQiKSAqLwogICAgeG1sTm9kZVB0ciBub2RlOwp9OwoKI2RlZmluZSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQgMTw8MAovKioKICogeG1sU2NoZW1hTW9kZWxHcm91cERlZjoKICoKICogQSBtb2RlbCBncm91cCBkZWZpbml0aW9uIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWYgKnhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOyAvKiBYTUxfU0NIRU1BX1RZUEVfR1JPVVAgKi8KICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbm90IHVzZWQgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiB0aGUgIm1vZGVsIGdyb3VwIiAqLwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBmbGFnczsKfTsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJREMgeG1sU2NoZW1hSURDOwp0eXBlZGVmIHhtbFNjaGVtYUlEQyAqeG1sU2NoZW1hSURDUHRyOwoKLyoqCiAqIHhtbFNjaGVtYUlEQ1NlbGVjdDoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgImZpZWxkIiBhbmQgInNlbGVjdG9yIiBpdGVtLCBob2xkaW5nIHRoZQogKiBYUGF0aCBleHByZXNzaW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1NlbGVjdCB4bWxTY2hlbWFJRENTZWxlY3Q7CnR5cGVkZWYgeG1sU2NoZW1hSURDU2VsZWN0ICp4bWxTY2hlbWFJRENTZWxlY3RQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU2VsZWN0IHsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBuZXh0OwogICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKICAgIGludCBpbmRleDsgLyogYW4gaW5kZXggcG9zaXRpb24gaWYgc2lnbmlmaWNhbnQgZm9yIElEQyBrZXktc2VxdWVuY2VzICovCiAgICBjb25zdCB4bWxDaGFyICp4cGF0aDsgLyogdGhlIFhQYXRoIGV4cHJlc3Npb24gKi8KICAgIHZvaWQgKnhwYXRoQ29tcDsgLyogdGhlIGNvbXBpbGVkIFhQYXRoIGV4cHJlc3Npb24gKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFJREM6CiAqCiAqIFRoZSBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gY29tcG9uZW50LgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFBbm5vdEl0ZW0pCiAqLwoKc3RydWN0IF94bWxTY2hlbWFJREMgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hSURDUHRyIG5leHQ7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbGVjdG9yOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGZpZWxkczsKICAgIGludCBuYkZpZWxkczsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZjsKfTsKCi8qKgogKiB4bWxTY2hlbWFJRENBdWc6CiAqCiAqIFRoZSBhdWdtZW50ZWQgSURDIGluZm9ybWF0aW9uIHVzZWQgZm9yIHZhbGlkYXRpb24uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDQXVnIHhtbFNjaGVtYUlEQ0F1ZzsKdHlwZWRlZiB4bWxTY2hlbWFJRENBdWcgKnhtbFNjaGVtYUlEQ0F1Z1B0cjsKc3RydWN0IF94bWxTY2hlbWFJRENBdWcgewogICAgeG1sU2NoZW1hSURDQXVnUHRyIG5leHQ7IC8qIG5leHQgaW4gYSBsaXN0ICovCiAgICB4bWxTY2hlbWFJRENQdHIgZGVmOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIGludCBidWJibGVEZXB0aDsgLyogdGhlIGxvd2VzdCB0cmVlIGxldmVsIHRvIHdoaWNoIElEQwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZXMgbmVlZCB0byBiZSBidWJibGVkIHVwd2FyZHMgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDS2V5U2VxdWVuY2U6CiAqCiAqIFRoZSBrZXkgc2VxdWVuY2Ugb2YgYSBub2RlIHRhYmxlIGl0ZW0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB4bWxTY2hlbWFQU1ZJSURDS2V5Owp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENLZXkgKnhtbFNjaGVtYVBTVklJRENLZXlQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENOb2RlOgogKgogKiBUaGUgbm9kZSB0YWJsZSBpdGVtIG9mIGEgbm9kZSB0YWJsZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDTm9kZSB4bWxTY2hlbWFQU1ZJSURDTm9kZTsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDTm9kZSAqeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ05vZGUgewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5czsKfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZzoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgYmluZGluZyBpdGVtIG9mIHRoZSBbaWRlbnRpdHktY29uc3RyYWludCB0YWJsZV0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmc7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgKnhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENCaW5kaW5nIHsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIG5leHQ7IC8qIG5leHQgYmluZGluZyBvZiBhIHNwZWNpZmljIG5vZGUgKi8KICAgIHhtbFNjaGVtYUlEQ1B0ciBkZWZpbml0aW9uOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICpub2RlVGFibGU7IC8qIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMgKi8KICAgIGludCBuYk5vZGVzOyAvKiBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IHNpemVOb2RlczsgLyogc2l6ZSBvZiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IG5iRHVwbHM7IC8qIG51bWJlciBvZiBhbHJlYWR5IGlkZW50aWZpZWQgZHVwbGljYXRlcyBpbiB0aGUgbm9kZQogICAgICAgICAgICAgICAgICAgIHRhYmxlICovCiAgICAvKiBpbnQgbmJLZXlzOyBudW1iZXIgb2Yga2V5cyBpbiBlYWNoIGtleS1zZXF1ZW5jZSAqLwp9OwoKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IgMQojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCAyCgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9NQVRDSEVTIC0yCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX0JMT0NLRUQgLTMKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENNYXRjaGVyIHhtbFNjaGVtYUlEQ01hdGNoZXI7CnR5cGVkZWYgeG1sU2NoZW1hSURDTWF0Y2hlciAqeG1sU2NoZW1hSURDTWF0Y2hlclB0cjsKCi8qKgogKiB4bWxTY2hlbWFJRENTdGF0ZU9iajoKICoKICogVGhlIHN0YXRlIG9iamVjdCB1c2VkIHRvIGV2YWx1YXRlIFhQYXRoIGV4cHJlc3Npb25zLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1N0YXRlT2JqIHhtbFNjaGVtYUlEQ1N0YXRlT2JqOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ1N0YXRlT2JqICp4bWxTY2hlbWFJRENTdGF0ZU9ialB0cjsKc3RydWN0IF94bWxTY2hlbWFJRENTdGF0ZU9iaiB7CiAgICBpbnQgdHlwZTsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIG5leHQ7IC8qIG5leHQgaWYgaW4gYSBsaXN0ICovCiAgICBpbnQgZGVwdGg7IC8qIGRlcHRoIG9mIGNyZWF0aW9uICovCiAgICBpbnQgKmhpc3Rvcnk7IC8qIGxpc3Qgb2YgKGRlcHRoLCBzdGF0ZS1pZCkgdHVwbGVzICovCiAgICBpbnQgbmJIaXN0b3J5OwogICAgaW50IHNpemVIaXN0b3J5OwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyOyAvKiB0aGUgY29ycmVzcG9uZGVudCBmaWVsZC9zZWxlY3RvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaGVyICovCiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsOwogICAgdm9pZCAqeHBhdGhDdHh0Owp9OwoKI2RlZmluZSBJRENfTUFUQ0hFUiAwCgovKioKICogeG1sU2NoZW1hSURDTWF0Y2hlcjoKICoKICogVXNlZCB0byAgSURDIHNlbGVjdG9ycyAoYW5kIGZpZWxkcykgc3VjY2Vzc2l2ZWx5LgogKi8Kc3RydWN0IF94bWxTY2hlbWFJRENNYXRjaGVyIHsKICAgIGludCB0eXBlOwogICAgaW50IGRlcHRoOyAvKiB0aGUgdHJlZSBkZXB0aCBhdCBjcmVhdGlvbiB0aW1lICovCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOyAvKiB0aGUgYXVnbWVudGVkIElEQyBpdGVtICovCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxczsgLyogdGhlIGtleS1zZXF1ZW5jZXMgb2YgdGhlIHRhcmdldAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzICovCiAgICBpbnQgc2l6ZUtleVNlcXM7CiAgICBpbnQgdGFyZ2V0RGVwdGg7Cn07CgovKgoqIEVsZW1lbnQgaW5mbyBmbGFncy4KKi8KI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTICAxPDwwCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMgMTw8MQojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRAkgICAgICAgMTw8MgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0xPQ0FMX1RZUEUJICAgICAgIDE8PDMKCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEICAgICAgMTw8NAojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZICAgICAgICAgICAgIDE8PDUKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfQ09OVEVOVCAgICAgICAxPDw2CgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQgIDE8PDcKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQgIDE8PDgKI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEICAxPDw5CiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFICAxPDwxMAoKLyoqCiAqIHhtbFNjaGVtYU5vZGVJbmZvOgogKgogKiBIb2xkcyBpbmZvcm1hdGlvbiBvZiBhbiBlbGVtZW50IG5vZGUuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBub2RlVHlwZTsKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbDsgLyogdGhlIHByZS1jb21wdXRlZCB2YWx1ZSBpZiBhbnkgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZjsgLyogdGhlIGNvbXBsZXgvc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpZiBhbnkgKi8KICAgIGludCBmbGFnczsgLyogY29tYmluYXRpb24gb2Ygbm9kZSBpbmZvIGZsYWdzICovCiAgICBpbnQgdmFsTmVlZGVkOwogICAgaW50IG5vcm1WYWw7CgogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOyAvKiB0aGUgZWxlbWVudC9hdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGlkY1RhYmxlOyAvKiB0aGUgdGFibGUgb2YgUFNWSSBJREMgYmluZGluZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgdGhlIHNjb3BlIGVsZW1lbnQqLwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBpZGNNYXRjaGVyczsgLyogdGhlIElEQyBtYXRjaGVycyBmb3IgdGhlIHNjb3BlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50ICovCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleEN0eHQ7CgogICAgY29uc3QgeG1sQ2hhciAqKm5zQmluZGluZ3M7IC8qIE5hbWVzcGFjZSBiaW5kaW5ncyBvbiB0aGlzIGVsZW1lbnQgKi8KICAgIGludCBuYk5zQmluZGluZ3M7CiAgICBpbnQgc2l6ZU5zQmluZGluZ3M7Cn07CgovKgoqIEBtZXRhVHlwZSB2YWx1ZXMgb2YgeG1sU2NoZW1hQXR0ckluZm8uCiovCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSAxCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMIDIKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DIDMKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DIDQKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TIDUKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRySW5mbyB4bWxTY2hlbWFBdHRySW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFBdHRySW5mbyAqeG1sU2NoZW1hQXR0ckluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXR0ckluZm8gewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IG5vZGVUeXBlOwogICAgY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lOwogICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsOyAvKiB0aGUgcHJlLWNvbXB1dGVkIHZhbHVlIGlmIGFueSAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVmOyAvKiB0aGUgY29tcGxleC9zaW1wbGUgdHlwZSBkZWZpbml0aW9uIGlmIGFueSAqLwogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBub2RlIGluZm8gZmxhZ3MgKi8KCiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgZGVjbDsgLyogdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiAqLwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHVzZTsgIC8qIHRoZSBhdHRyaWJ1dGUgdXNlICovCiAgICBpbnQgc3RhdGU7CiAgICBpbnQgbWV0YVR5cGU7CiAgICBjb25zdCB4bWxDaGFyICp2Y1ZhbHVlOyAvKiB0aGUgdmFsdWUgY29uc3RyYWludCB2YWx1ZSAqLwogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgcGFyZW50Owp9OwoKCiNkZWZpbmUgWE1MX1NDSEVNQV9WQUxJRF9DVFhUX0ZMQUdfU1RSRUFNIDEKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dDoKICoKICogQSBTY2hlbWFzIHZhbGlkYXRpb24gY29udGV4dAogKi8Kc3RydWN0IF94bWxTY2hlbWFWYWxpZEN0eHQgewogICAgaW50IHR5cGU7CiAgICB2b2lkICp1c2VyRGF0YTsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CiAgICB4bWxDaGFyRW5jb2RpbmcgZW5jOwogICAgeG1sU0FYSGFuZGxlclB0ciBzYXg7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CiAgICB2b2lkICp1c2VyX2RhdGE7CgogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKCiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIC8qIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsgKi8KCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleHA7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsdWU7CgogICAgaW50IHZhbHVlV1M7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbE5vZGVQdHIgdmFsaWRhdGlvblJvb3Q7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgaW50IHhzaUFzc2VtYmxlOwoKICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyICplbGVtSW5mb3M7IC8qIGFycmF5IG9mIGVsZW1lbnQgaW5mb3JtYXRpb25zICovCiAgICBpbnQgc2l6ZUVsZW1JbmZvczsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlOyAvKiB0aGUgY3VycmVudCBlbGVtZW50IGluZm9ybWF0aW9uICovCgogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGNzOyAvKiBhIGxpc3Qgb2YgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbnMgKi8KCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlczsgLyogZmlyc3QgYWN0aXZlIHN0YXRlIG9iamVjdC4gKi8KICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHhwYXRoU3RhdGVQb29sOyAvKiBmaXJzdCBzdG9yZWQgc3RhdGUgb2JqZWN0LiAqLwoKICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICppZGNOb2RlczsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyovCiAgICBpbnQgbmJJZGNOb2RlczsKICAgIGludCBzaXplSWRjTm9kZXM7CgogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqaWRjS2V5czsgLyogbGlzdCBvZiBhbGwgSURDIG5vZGUtdGFibGUgZW50cmllcyAqLwogICAgaW50IG5iSWRjS2V5czsKICAgIGludCBzaXplSWRjS2V5czsKCiAgICBpbnQgZmxhZ3M7CgogICAgeG1sRGljdFB0ciBkaWN0OwoKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAogICAgeG1sVGV4dFJlYWRlclB0ciByZWFkZXI7CiNlbmRpZgoKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyICphdHRySW5mb3M7CiAgICBpbnQgbmJBdHRySW5mb3M7CiAgICBpbnQgc2l6ZUF0dHJJbmZvczsKCiAgICBpbnQgc2tpcERlcHRoOwp9OwoKLyoKICogVGhlc2UgYXJlIHRoZSBlbnRyaWVzIGluIHRoZSBzY2hlbWFzIGltcG9ydFNjaGVtYXMgaGFzaCB0YWJsZQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUltcG9ydCB4bWxTY2hlbWFJbXBvcnQ7CnR5cGVkZWYgeG1sU2NoZW1hSW1wb3J0ICp4bWxTY2hlbWFJbXBvcnRQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgLyogbm90IHVzZWQgYW55IG1vcmUgKi8KICAgIHhtbERvY1B0ciBkb2M7CiAgICBpbnQgaXNNYWluOwp9OwoKLyoKICogVGhlc2UgYXJlIHRoZSBlbnRyaWVzIGFzc29jaWF0ZWQgdG8gaW5jbHVkZXMgaW4gYSBzY2hlbWFzCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB4bWxTY2hlbWFJbmNsdWRlOwp0eXBlZGVmIHhtbFNjaGVtYUluY2x1ZGUgKnhtbFNjaGVtYUluY2x1ZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIG5leHQ7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbERvY1B0ciBkb2M7CiAgICBjb25zdCB4bWxDaGFyICpvcmlnVGFyZ2V0TmFtZXNwYWNlOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVN1YnN0R3JvdXA6CiAqCiAqCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hU3Vic3RHcm91cCB4bWxTY2hlbWFTdWJzdEdyb3VwOwp0eXBlZGVmIHhtbFNjaGVtYVN1YnN0R3JvdXAgKnhtbFNjaGVtYVN1YnN0R3JvdXBQdHI7CnN0cnVjdCBfeG1sU2NoZW1hU3Vic3RHcm91cCB7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQ7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBtZW1iZXJzOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNvbWUgcHJlZGVjbGFyYXRpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCk7CnN0YXRpYyB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlCnhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLAoJCQkgaW50IHdpdGhQYXJ0aWNsZSk7CnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVMaW5rUHRyCnhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUludGVybmFsRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSwKCQkJICAgICBpbnQgc3Vic2V0KTsKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLAoJCQkJICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlIZWxwZXIgZnVuY3Rpb25zCQkJICAgICAgICAqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmc6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICByZXR1cm4oQkFEX0NBU1QgInNpbXBsZSB0eXBlIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImVsZW1lbnQgZGVjbGFyYXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCSAgICByZXR1cm4oQkFEX0NBU1QgIm5vdGF0aW9uIGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChzZXF1ZW5jZSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChjaG9pY2UpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJtb2RlbCBncm91cCAoYWxsKSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJwYXJ0aWNsZSIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENvbXBvbmVudE5vZGU6CiAqIEBpdGVtOiBhIHNjaGVtYSBjb21wb25lbnQKICoKICogUmV0dXJucyBub2RlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2NoZW1hIGNvbXBvbmVudC4KICogTk9URSB0aGF0IHN1Y2ggYSBub2RlIG5lZWQgbm90IGJlIGF2YWlsYWJsZTsgcGx1cywgYSBjb21wb25lbnQncwogKiBub2RlIG5lZWQgbm90IHRvIHJlZmxlY3QgdGhlIGNvbXBvbmVudCBkaXJlY3RseSwgc2luY2UgdGhlcmUgaXMgbm8KICogb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgWE1MIFNjaGVtYSByZXByZXNlbnRhdGlvbiBhbmQKICogdGhlIGNvbXBvbmVudCByZXByZXNlbnRhdGlvbi4KICovCnN0YXRpYyB4bWxOb2RlUHRyCnhtbFNjaGVtYUdldENvbXBvbmVudE5vZGUoeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSktPm5vZGUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0pLT5ub2RlKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgaXRlbSktPm5vZGUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtKS0+bm9kZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUY6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUlEQ1B0cikgaXRlbSktPm5vZGUpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gKE5VTEwpOwogICAgfQp9CgojaWYgMAovKioKICogeG1sU2NoZW1hR2V0TmV4dENvbXBvbmVudDoKICogQGl0ZW06IGEgc2NoZW1hIGNvbXBvbmVudAogKgogKiBSZXR1cm5zIHRoZSBuZXh0IHNpYmxpbmcgb2YgdGhlIHNjaGVtYSBjb21wb25lbnQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQmFzaWNJdGVtUHRyCnhtbFNjaGVtYUdldE5leHRDb21wb25lbnQoeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpICgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSktPm5leHQpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5uZXh0KTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSAoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pLT5uZXh0KTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuIChOVUxMKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFOgoJICAgIHJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgaXRlbSktPm5leHQpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgcmV0dXJuIChOVUxMKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIHJldHVybiAoTlVMTCk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpICgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0pLT5uZXh0KTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpICgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+bmV4dCk7CglkZWZhdWx0OgoJICAgIHJldHVybiAoTlVMTCk7CiAgICB9Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hR2V0QXR0ck5hbWU6CiAqIEBhdHRyOiAgdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UKICoKICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlOyBpZiB0aGUgYXR0cmlidXRlCiAqIGlzIGEgcmVmZXJlbmNlLCB0aGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBnbG9iYWwgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRBdHRyTmFtZSh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKQoJcmV0dXJuKGF0dHItPnJlZik7CiAgICBlbHNlCglyZXR1cm4oYXR0ci0+bmFtZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkk6CiAqIEB0eXBlOiAgdGhlIHR5cGUgKGVsZW1lbnQgb3IgYXR0cmlidXRlKQogKgogKiBSZXR1cm5zIHRoZSB0YXJnZXQgbmFtZXNwYWNlIFVSSSBvZiB0aGUgdHlwZTsgaWYgdGhlIHR5cGUgaXMgYSByZWZlcmVuY2UsCiAqIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSByZWZlcmVuY2VkIHR5cGUgd2lsbCBiZSByZXR1cm5lZC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKQp7CiAgICBpZiAoYXR0ci0+cmVmICE9IE5VTEwpCglyZXR1cm4gKGF0dHItPnJlZk5zKTsKICAgIGVsc2UKCXJldHVybihhdHRyLT50YXJnZXROYW1lc3BhY2UpOwp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0UU5hbWU6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBuYW1lc3BhY2VOYW1lOiAgdGhlIG5hbWVzcGFjZSBuYW1lCiAqIEBsb2NhbE5hbWU6IHRoZSBsb2NhbCBuYW1lCiAqCiAqIFJldHVybnMgdGhlIGdpdmVuIFFOYW1lIGluIHRoZSBmb3JtYXQgIntuYW1lc3BhY2VOYW1lfWxvY2FsTmFtZSIgb3IKICoganVzdCAibG9jYWxOYW1lIiBpZiBAbmFtZXNwYWNlTmFtZSBpcyBOVUxMLgogKgogKiBSZXR1cm5zIHRoZSBsb2NhbE5hbWUgaWYgQG5hbWVzcGFjZU5hbWUgaXMgTlVMTCwgYSBmb3JtYXR0ZWQKICogc3RyaW5nIG90aGVyd2lzZS4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyKgp4bWxTY2hlbWFGb3JtYXRRTmFtZSh4bWxDaGFyICoqYnVmLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqbmFtZXNwYWNlTmFtZSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSkKewogICAgRlJFRV9BTkRfTlVMTCgqYnVmKQogICAgaWYgKG5hbWVzcGFjZU5hbWUgPT0gTlVMTCkKCXJldHVybihsb2NhbE5hbWUpOwoKICAgICpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsiKTsKICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbmFtZXNwYWNlTmFtZSk7CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJ9Iik7CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsTmFtZSk7CgogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIqICAgCnhtbFNjaGVtYUZvcm1hdFFOYW1lTnMoeG1sQ2hhciAqKmJ1ZiwgeG1sTnNQdHIgbnMsIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSkKewogICAgaWYgKG5zICE9IE5VTEwpCglyZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKGJ1ZiwgbnMtPmhyZWYsIGxvY2FsTmFtZSkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShidWYsIE5VTEwsIGxvY2FsTmFtZSkpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldENvbXBvbmVudE5hbWUoeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSktPm5hbWUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5uYW1lKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSktPm5hbWUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKS0+bmFtZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgaXRlbSktPm5hbWUpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0pLT5uYW1lKTsKCWRlZmF1bHQ6CgkgICAgLyoKCSAgICAqIE90aGVyIGNvbXBvbmVudHMgY2Fubm90IGhhdmUgbmFtZXMuCgkgICAgKi8KCSAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Q29tcG9uZW50VGFyZ2V0TnMoeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSktPnRhcmdldE5hbWVzcGFjZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSktPnRhcmdldE5hbWVzcGFjZSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4gKCgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgoKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJICAgIHJldHVybiAoKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0pLT50YXJnZXROYW1lc3BhY2UpOwoJZGVmYXVsdDoKCSAgICAvKgoJICAgICogT3RoZXIgY29tcG9uZW50cyBjYW5ub3QgaGF2ZSBuYW1lcy4KCSAgICAqLwoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIqCnhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKHhtbENoYXIgKipidWYsCgkJCSAgIHZvaWQgKml0ZW0pCnsKICAgIHJldHVybiAoeG1sU2NoZW1hRm9ybWF0UU5hbWUoYnVmLAoJeG1sU2NoZW1hR2V0Q29tcG9uZW50VGFyZ2V0TnMoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgaXRlbSksCgl4bWxTY2hlbWFHZXRDb21wb25lbnROYW1lKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGl0ZW0pKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmc6CiAqIEBwYzogdGhlIHR5cGUgb2YgcHJvY2Vzc0NvbnRlbnRzCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUgb2YKICogcHJvY2Vzc0NvbnRlbnRzLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmcoaW50IHBjKQp7CiAgICBzd2l0Y2ggKHBjKSB7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9TS0lQOgoJICAgIHJldHVybiAoQkFEX0NBU1QgInNraXAiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX0xBWDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJsYXgiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJzdHJpY3QiKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAiaW52YWxpZCBwcm9jZXNzIGNvbnRlbnRzIik7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDYW5vblZhbHVlV2h0c3BFeHQ6CiAqIEB2YWw6IHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKiBAcmV0VmFsdWU6IHRoZSByZXR1cm5lZCB2YWx1ZQogKiBAd3M6IHRoZSB3aGl0ZXNwYWNlIHR5cGUgb2YgdGhlIHZhbHVlCiAqCiAqIEdldCBhIHRoZSBjb25vbmljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlLgogKiBUaGUgY2FsbGVyIGhhcyB0byBmcmVlIHRoZSByZXR1cm5lZCByZXRWYWx1ZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBjb3VsZCBiZSBidWlsdCBhbmQgLTEgaW4gY2FzZSBvZgogKiAgICAgICAgIEFQSSBlcnJvcnMgb3IgaWYgdGhlIHZhbHVlIHR5cGUgaXMgbm90IHN1cHBvcnRlZCB5ZXQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldENhbm9uVmFsdWVXaHRzcEV4dCh4bWxTY2hlbWFWYWxQdHIgdmFsLAoJCQkgICAgICAgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3cywKCQkJICAgICAgIHhtbENoYXIgKipyZXRWYWx1ZSkKewogICAgaW50IGxpc3Q7CiAgICB4bWxTY2hlbWFWYWxUeXBlIHZhbFR5cGU7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwgKnZhbHVlMiA9IE5VTEw7CiAgICAKCiAgICBpZiAoKHJldFZhbHVlID09IE5VTEwpIHx8ICh2YWwgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIGxpc3QgPSB4bWxTY2hlbWFWYWx1ZUdldE5leHQodmFsKSA/IDEgOiAwOwogICAgKnJldFZhbHVlID0gTlVMTDsKICAgIGRvIHsKCXZhbHVlID0gTlVMTDsJCgl2YWxUeXBlID0geG1sU2NoZW1hR2V0VmFsVHlwZSh2YWwpOyAgICAKCXN3aXRjaCAodmFsVHlwZSkgewkgICAgCgkgICAgY2FzZSBYTUxfU0NIRU1BU19TVFJJTkc6CgkgICAgY2FzZSBYTUxfU0NIRU1BU19OT1JNU1RSSU5HOgoJICAgIGNhc2UgWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRToKCQl2YWx1ZSA9IHhtbFNjaGVtYVZhbHVlR2V0QXNTdHJpbmcodmFsKTsKCQlpZiAodmFsdWUgIT0gTlVMTCkgewoJCSAgICBpZiAod3MgPT0gWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKQoJCQl2YWx1ZTIgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkJICAgIGVsc2UgaWYgKHdzID09IFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFKQoJCQl2YWx1ZTIgPSB4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSk7CgkJICAgIGlmICh2YWx1ZTIgIT0gTlVMTCkKCQkJdmFsdWUgPSB2YWx1ZTI7CgkJfQoJCWJyZWFrOwkgICAKCSAgICBkZWZhdWx0OgoJCWlmICh4bWxTY2hlbWFHZXRDYW5vblZhbHVlKHZhbCwgJnZhbHVlMikgPT0gLTEpIHsKCQkgICAgaWYgKHZhbHVlMiAhPSBOVUxMKQoJCQl4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlMik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXZhbHVlID0gdmFsdWUyOwoJfQoJaWYgKCpyZXRWYWx1ZSA9PSBOVUxMKQoJICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CgkJaWYgKCEgbGlzdCkKCQkgICAgKnJldFZhbHVlID0geG1sU3RyZHVwKEJBRF9DQVNUICIiKTsKCSAgICB9IGVsc2UKCQkqcmV0VmFsdWUgPSB4bWxTdHJkdXAodmFsdWUpOwoJZWxzZSBpZiAodmFsdWUgIT0gTlVMTCkgewoJICAgIC8qIExpc3QuICovCgkgICAgKnJldFZhbHVlID0geG1sU3RyY2F0KCh4bWxDaGFyICopICpyZXRWYWx1ZSwgQkFEX0NBU1QgIiAiKTsKCSAgICAqcmV0VmFsdWUgPSB4bWxTdHJjYXQoKHhtbENoYXIgKikgKnJldFZhbHVlLCB2YWx1ZSk7Cgl9CglGUkVFX0FORF9OVUxMKHZhbHVlMikKCXZhbCA9IHhtbFNjaGVtYVZhbHVlR2V0TmV4dCh2YWwpOwogICAgfSB3aGlsZSAodmFsICE9IE5VTEwpOwoKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKCpyZXRWYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZSgoeG1sQ2hhciAqKSAoKnJldFZhbHVlKSk7CiAgICBpZiAodmFsdWUyICE9IE5VTEwpCgl4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlMik7CiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQ6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGl0ZW0KICogQGl0ZW1OYW1lOiB0aGUgbmFtZSBvZiB0aGUgaXRlbQogKiBAaXRlbTogdGhlIGl0ZW0gYXMgYW4gb2JqZWN0IAogKiBAaXRlbU5vZGU6IHRoZSBub2RlIG9mIHRoZSBpdGVtCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICogQHBhcnNpbmc6IGlmIHRoZSBmdW5jdGlvbiBpcyB1c2VkIGR1cmluZyB0aGUgcGFyc2UKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBpdGVtIHVzZWQKICogZm9yIGVycm9yIHJlcG9ydHMuIAogKgogKiBUaGUgZm9sbG93aW5nIG9yZGVyIGlzIHVzZWQgdG8gYnVpbGQgdGhlIHJlc3VsdGluZyAKICogZGVzaWduYXRpb24gaWYgdGhlIGFyZ3VtZW50cyBhcmUgbm90IE5VTEw6CiAqIDFhLiBJZiBpdGVtRGVzIG5vdCBOVUxMIC0+IGl0ZW1EZXMKICogMWIuIElmIChpdGVtRGVzIG5vdCBOVUxMKSBhbmQgKGl0ZW1OYW1lIG5vdCBOVUxMKQogKiAgICAgLT4gaXRlbURlcyArIGl0ZW1OYW1lCiAqIDIuIElmIHRoZSBwcmVjZWRpbmcgd2FzIE5VTEwgYW5kIChpdGVtIG5vdCBOVUxMKSAtPiBpdGVtCiAqIDMuIElmIHRoZSBwcmVjZWRpbmcgd2FzIE5VTEwgYW5kIChpdGVtTm9kZSBub3QgTlVMTCkgLT4gaXRlbU5vZGUKICogCiAqIElmIHRoZSBpdGVtTm9kZSBpcyBhbiBhdHRyaWJ1dGUgbm9kZSwgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSByZXN1bHQuCiAqCiAqIFJldHVybnMgdGhlIGZvcm1hdHRlZCBzdHJpbmcgYW5kIHNldHMgQGJ1ZiB0byB0aGUgcmVzdWx0aW5nIHZhbHVlLgogKi8gIApzdGF0aWMgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCh4bWxDaGFyICoqYnVmLAkJICAgICAKCQkgICAgIGNvbnN0IHhtbENoYXIgKml0ZW1EZXMsCgkJICAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgICB4bWxOb2RlUHRyIGl0ZW1Ob2RlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgaW50IG5hbWVkID0gMTsKCiAgICBpZiAoKmJ1ZiAhPSBOVUxMKSB7Cgl4bWxGcmVlKCpidWYpOwoJKmJ1ZiA9IE5VTEw7CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKGl0ZW1EZXMgIT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChpdGVtRGVzKTsJCiAgICB9IGVsc2UgaWYgKGl0ZW0gIT0gTlVMTCkgewoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKCSAgICBpZiAoVkFSSUVUWV9BVE9NSUMoaXRlbSkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiYXRvbWljIHR5cGUgJ3hzOiIpOwoJICAgIGVsc2UgaWYgKFZBUklFVFlfTElTVChpdGVtKSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJsaXN0IHR5cGUgJ3hzOiIpOwoJICAgIGVsc2UgaWYgKFZBUklFVFlfVU5JT04oaXRlbSkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAidW5pb24gdHlwZSAneHM6Iik7CgkgICAgZWxzZQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInNpbXBsZSB0eXBlICd4czoiKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QiIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJsb2NhbCAiKTsKCSAgICB9CgkgICAgaWYgKFZBUklFVFlfQVRPTUlDKGl0ZW0pKQoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgImF0b21pYyB0eXBlIik7CgkgICAgZWxzZSBpZiAoVkFSSUVUWV9MSVNUKGl0ZW0pKQoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgImxpc3QgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFZBUklFVFlfVU5JT04oaXRlbSkpCgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJzaW1wbGUgdHlwZSIpOwoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJsb2NhbCAiKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJjb21wbGV4IHR5cGUiKTsKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOiB7CgkJeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHI7CgkgICAgCgkJYXR0ciA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW07CSAgICAKCQlpZiAoKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpIHx8CgkJICAgIChhdHRyLT5yZWYgPT0gTlVMTCkpIHsKCQkgICAgKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCWF0dHItPnRhcmdldE5hbWVzcGFjZSwgYXR0ci0+bmFtZSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCX0gZWxzZSB7CgkJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCWF0dHItPnJlZk5zLCBhdHRyLT5yZWYpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQl9CQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6IHsKCQl4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW07CgoJCWVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbTsJICAgIAoJCWlmICgoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkgfHwgCgkJICAgIChlbGVtLT5yZWYgPT0gTlVMTCkpIHsKCQkgICAgKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCWVsZW0tPnRhcmdldE5hbWVzcGFjZSwgZWxlbS0+bmFtZSkpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkJfQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoJCQoJICAgIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFKQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInVuaXF1ZSAnIik7CgkgICAgZWxzZSBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJrZXkgJyIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJrZXlSZWYgJyIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0pLT5uYW1lKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgoJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKAoJCSAgICAoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBpdGVtKS0+cHJvY2Vzc0NvbnRlbnRzKSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiIHdpbGRjYXJkIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCSAgICAqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJmYWNldCAnIik7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhpdGVtLT50eXBlKSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkgICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAibm90YXRpb24iKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOiB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtTW9kZWxHckRlZik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgICgoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgaXRlbSktPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgKCh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSBpdGVtKS0+bmFtZSkpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFOgoJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyhpdGVtLT50eXBlKSk7CgkgICAgYnJlYWs7CQoJZGVmYXVsdDoKCSAgICBuYW1lZCA9IDA7Cgl9CiAgICB9IGVsc2UgCgluYW1lZCA9IDA7CgogICAgaWYgKChuYW1lZCA9PSAwKSAmJiAoaXRlbU5vZGUgIT0gTlVMTCkpIHsKCXhtbE5vZGVQdHIgZWxlbTsKCglpZiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIGVsZW0gPSBpdGVtTm9kZS0+cGFyZW50OwoJZWxzZSAKCSAgICBlbGVtID0gaXRlbU5vZGU7CgkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCWlmIChlbGVtLT5ucyAhPSBOVUxMKSB7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLAoJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGVsZW0tPm5zLT5ocmVmLCBlbGVtLT5uYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgl9IGVsc2UKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPm5hbWUpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCiAgICB9CiAgICBpZiAoKGl0ZW1Ob2RlICE9IE5VTEwpICYmIChpdGVtTm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpKSB7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsIGF0dHJpYnV0ZSAnIik7CglpZiAoaXRlbU5vZGUtPm5zICE9IE5VTEwpIHsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJaXRlbU5vZGUtPm5zLT5ocmVmLCBpdGVtTm9kZS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJfSBlbHNlCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtTm9kZS0+bmFtZSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CiAgICB9CiAgICBGUkVFX0FORF9OVUxMKHN0cikKICAgIAogICAgcmV0dXJuICgqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQHR5cGU6IHRoZSB0eXBlIGhvbGRpbmcgdGhlIGVudW1lcmF0aW9uIGZhY2V0cwogKgogKiBCdWlsZHMgYSBzdHJpbmcgY29uc2lzdGluZyBvZiBhbGwgZW51bWVyYXRpb24gZWxlbWVudHMuCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgeG1sQ2hhciAqKmJ1ZiwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUgd3M7CiAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CiAgICBpbnQgcmVzOwoKICAgIGlmICgqYnVmICE9IE5VTEwpCgl4bWxGcmVlKCpidWYpOyAgICAKICAgICpidWYgPSBOVUxMOwoKICAgIGRvIHsKCS8qCgkqIFVzZSB0aGUgd2hpdGVzcGFjZSB0eXBlIG9mIHRoZSBiYXNlIHR5cGUuCgkqLwkKCXdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZS0+YmFzZVR5cGUpOwoJZm9yIChmYWNldCA9IHR5cGUtPmZhY2V0czsgZmFjZXQgIT0gTlVMTDsgZmFjZXQgPSBmYWNldC0+bmV4dCkgewoJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKQoJCWNvbnRpbnVlOwoJICAgIHJlcyA9IHhtbFNjaGVtYUdldENhbm9uVmFsdWVXaHRzcEV4dChmYWNldC0+dmFsLAoJCXdzLCAmdmFsdWUpOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFJbnRlcm5hbEVycihhY3R4dCwKCQkgICAgInhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldCIsCgkJICAgICJjb21wdXRlIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiIpOwoJCWlmICgqYnVmICE9IE5VTEwpCgkJICAgIHhtbEZyZWUoKmJ1Zik7CgkJKmJ1ZiA9IE5VTEw7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9CgkgICAgaWYgKCpidWYgPT0gTlVMTCkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInIik7CgkgICAgZWxzZQoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiwgJyIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgdmFsdWUpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICBpZiAodmFsdWUgIT0gTlVMTCkgewoJCXhtbEZyZWUoKHhtbENoYXIgKil2YWx1ZSk7CgkJdmFsdWUgPSBOVUxMOwoJICAgIH0KCX0KCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0gd2hpbGUgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoKICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCUVycm9yIGZ1bmN0aW9ucwkJCQkgICAgICAgICoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWYgMApzdGF0aWMgdm9pZAp4bWxTY2hlbWFFcnJNZW1vcnkoY29uc3QgY2hhciAqbXNnKQp7CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNQLCBYTUxfRVJSX05PX01FTU9SWSwgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgbXNnKTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFQRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyck1lbW9yeSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwoJc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnIyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAbm9kZTogdGhlIGN1cnJlbnQgY2hpbGQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyMih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZCwgaW50IGVycm9yLAogICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgaWYgKGNoaWxkICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjaGlsZCwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7CiAgICBlbHNlCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgbXNnLCBzdHIxLCBzdHIyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFQRXJyRXh0OgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlIAogKiBAc3RyRGF0YTE6IGV4dHJhIGRhdGEKICogQHN0ckRhdGEyOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMzogZXh0cmEgZGF0YQogKiBAbXNnOiB0aGUgbWVzc2FnZQogKiBAc3RyMTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMjogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMzogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNDogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCgkJY29uc3QgeG1sQ2hhciAqIHN0ckRhdGExLCBjb25zdCB4bWxDaGFyICogc3RyRGF0YTIsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMywgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgCgkJY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCBjb25zdCB4bWxDaGFyICogc3RyNCwKCQljb25zdCB4bWxDaGFyICogc3RyNSkKewoKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CglzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTEsIChjb25zdCBjaGFyICopIHN0ckRhdGEyLCAKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgCgkJICAgIHN0cjMsIHN0cjQsIHN0cjUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlBbGxyb3VuZCBlcnJvciBmdW5jdGlvbnMJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYVZUeXBlRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVyck1lbW9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpleHRyYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjdHh0LT5lcnIgPSBYTUxfU0NIRU1BVl9JTlRFUk5BTDsKICAgIH0KICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1YsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFFcnIzOgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIEBzdHIzOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFcnIzKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBjdHh0LCAgCgkgICAgICBpbnQgZXJyb3IsIHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbXNnLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMiwgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CiAgICAKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKCWlmIChjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsKCSAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHh0OwoKCSAgICB2Y3R4dC0+bmJlcnJvcnMrKzsKCSAgICB2Y3R4dC0+ZXJyID0gZXJyb3I7CgkgICAgY2hhbm5lbCA9IHZjdHh0LT5lcnJvcjsKCSAgICBzY2hhbm5lbCA9IHZjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHZjdHh0LT51c2VyRGF0YTsKCSAgICBpZiAoKG5vZGUgPT0gTlVMTCkgJiYgKHZjdHh0LT5kZXB0aCA+PSAwKSAmJgoJCSh2Y3R4dC0+aW5vZGUgIT0gTlVMTCkpCgkJbm9kZSA9IHZjdHh0LT5pbm9kZS0+bm9kZTsKCSAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsCgkJbm9kZSwgWE1MX0ZST01fU0NIRU1BU1YsCgkJZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCgkJKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwKCQkoY29uc3QgY2hhciAqKSBzdHIzLCAwLCAwLCBtc2csIHN0cjEsIHN0cjIsIHN0cjMpOwoKCX0gZWxzZSBpZiAoY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSBjdHh0OwoKCSAgICBwY3R4dC0+bmJlcnJvcnMrKzsKCSAgICBwY3R4dC0+ZXJyID0gZXJyb3I7CgkgICAgY2hhbm5lbCA9IHBjdHh0LT5lcnJvcjsKCSAgICBzY2hhbm5lbCA9IHBjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHBjdHh0LT51c2VyRGF0YTsKCSAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsCgkJbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCgkJZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCgkJKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwKCQkoY29uc3QgY2hhciAqKSBzdHIzLCAwLCAwLCBtc2csIHN0cjEsIHN0cjIsIHN0cjMpOwoJfSBlbHNlIHsKCSAgICBUT0RPCgl9CiAgICB9ICAgICAgIAp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJICAgICBpbnQgZXJyb3IsIHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbXNnLAoJICAgICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxTY2hlbWFFcnIzKGFjdHh0LCBlcnJvciwgbm9kZSwgbXNnLCBzdHIxLCBzdHIyLCBOVUxMKTsKfQoKc3RhdGljIHhtbENoYXIgKgp4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoeG1sQ2hhciAqKiBtc2csCgkJCSAgICB4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCSAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgaWYgKG5vZGUgIT0gTlVMTCkgewoJLyoKCSogV29yayBvbiB0cmVlIG5vZGVzLgoJKi8KCWlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewoJICAgIHhtbE5vZGVQdHIgZWxlbSA9IG5vZGUtPnBhcmVudDsKCSAgICAKCSAgICAqbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCSAgICBpZiAoZWxlbS0+bnMgIT0gTlVMTCkKCQkqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGVsZW0tPm5zLT5ocmVmLCBlbGVtLT5uYW1lKSk7CgkgICAgZWxzZQoJCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgTlVMTCwgZWxlbS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICInLCAiKTsKCSAgICAqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICJhdHRyaWJ1dGUgJyIpOwkgICAgCgl9IGVsc2UgewoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJfQoJaWYgKG5vZGUtPm5zICE9IE5VTEwpCgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJICAgIG5vZGUtPm5zLT5ocmVmLCBub2RlLT5uYW1lKSk7CgllbHNlCgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJICAgIE5VTEwsIG5vZGUtPm5hbWUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKTsKCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIic6ICIpOwogICAgfSBlbHNlIGlmIChhY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SKSB7Cgl4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dDsKCS8qCgkqIFdvcmsgb24gbm9kZSBpbmZvcy4KCSovCQoJaWYgKHZjdHh0LT5pbm9kZS0+bm9kZVR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CgkgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW0gPQoJCXZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKCgkgICAgKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7CgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCWllbGVtLT5uc05hbWUsIGllbGVtLT5sb2NhbE5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJywgIik7CgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiYXR0cmlidXRlICciKTsJICAgIAoJfSBlbHNlIHsKCSAgICAqbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCX0KCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCSAgICB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKTsKCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIic6ICIpOwogICAgfSBlbHNlIHsKCVRPRE8KCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBWQUwgVE9ETzogVGhlIG91dHB1dCBvZiB0aGUgZ2l2ZW4gc2NoZW1hIGNvbXBvbmVudCBpcyBjdXJyZW50bHkKICAgICogZGlzYWJsZWQuCiAgICAqLwojaWYgMCAgICAKICAgIGlmICgodHlwZSAhPSBOVUxMKSAmJiAoeG1sU2NoZW1hSXNHbG9iYWxJdGVtKHR5cGUpKSkgewoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiIFsiKTsKCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKCUZSRUVfQU5EX05VTEwoc3RyKQoJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiXSIpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAoKm1zZyk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUludGVybmFsRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgIGNvbnN0IGNoYXIgKmZ1bmNOYW1lLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkludGVybmFsIGVycm9yOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIGZ1bmNOYW1lKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsICIpOyAgICAKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwoKICAgIGlmIChhY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SKQoJeG1sU2NoZW1hRXJyKGFjdHh0LCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgTlVMTCwKCSAgICAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwoKICAgIGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpCgl4bWxTY2hlbWFFcnIoYWN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBOVUxMLAoJICAgIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CgogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUN1c3RvbUVycih4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgQVRUUklCVVRFX1VOVVNFRCwKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7ICAgCiAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKQoJcmV0dXJuIChub2RlLT50eXBlKTsKICAgIGlmICgoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgJiYKCSgoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpLT5pbm9kZSAhPSBOVUxMKSkKCXJldHVybiAoICgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPmlub2RlLT5ub2RlVHlwZSk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJc0dsb2JhbEl0ZW0oeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgxKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIGlmICggKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJLyogTm90ZSB0aGF0IGF0dHJpYnV0ZSBncm91cHMgYXJlIGFsd2F5cyBnbG9iYWwuICovCglkZWZhdWx0OgoJICAgIHJldHVybigxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgaW50IGRpc3BsYXlWYWx1ZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwoKICAgIGlmIChkaXNwbGF5VmFsdWUgfHwgKHhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKGFjdHh0LCBub2RlKSA9PQoJICAgIFhNTF9BVFRSSUJVVEVfTk9ERSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyVzJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiAiKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGEgdmFsaWQgIgoJICAgICJ2YWx1ZSBvZiAiKTsKCiAgICBpZiAoISB4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSAiKTsKCiAgICBpZiAoVkFSSUVUWV9BVE9NSUModHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiYXRvbWljIHR5cGUiKTsKICAgIGVsc2UgaWYgKFZBUklFVFlfTElTVCh0eXBlKSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJsaXN0IHR5cGUiKTsKICAgIGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoKICAgIGlmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCWlmICh0eXBlLT5idWlsdEluVHlwZSAhPSAwKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInhzOiIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJfSBlbHNlIAoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLCB0eXBlLT5uYW1lKSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKGRpc3BsYXlWYWx1ZSB8fCAoeG1sU2NoZW1hRXZhbEVycm9yTm9kZVR5cGUoYWN0eHQsIG5vZGUpID09CgkgICAgWE1MX0FUVFJJQlVURV9OT0RFKSkKCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwogICAgZWxzZQoJeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKHhtbENoYXIgKiogc3RyLAoJCQkgICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBuaSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgTlVMTCwgbm9kZS0+bmFtZSkpOwogICAgfSBlbHNlIGlmIChuaSAhPSBOVUxMKQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShzdHIsIG5pLT5uc05hbWUsIG5pLT5sb2NhbE5hbWUpKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFBdHRySW5mb1B0ciBuaSwKCQkJeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCXhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKCZzdHIsICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgbmksIG5vZGUpLAoJTlVMTCk7ICAgICAgICAKICAgIEZSRUVfQU5EX05VTEwoc3RyKQogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWludCBuYnZhbCwKCQkJaW50IG5ibmVnLAoJCQl4bWxDaGFyICoqdmFsdWVzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbENoYXIgKmxvY2FsTmFtZSwgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGludCBpOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLiIpOwogICAgLyoKICAgICogTm90ZSB0aGF0IGlzIGRvZXMgbm90IG1ha2Ugc2Vuc2UgdG8gcmVwb3J0IHRoYXQgd2UgaGF2ZSBhCiAgICAqIHdpbGRjYXJkIGhlcmUsIHNpbmNlIHRoZSB3aWxkY2FyZCBtaWdodCBiZSB1bmZvbGRlZCBpbnRvCiAgICAqIG11bHRpcGxlIHRyYW5zaXRpb25zLgogICAgKi8KICAgIGlmIChuYnZhbCArIG5ibmVnID4gMCkgewoJaWYgKG5idmFsICsgbmJuZWcgPiAxKSB7CgkgICAgc3RyID0geG1sU3RyZHVwKEJBRF9DQVNUICIgRXhwZWN0ZWQgaXMgb25lIG9mICggIik7Cgl9IGVsc2UKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiBFeHBlY3RlZCBpcyAoICIpOwoJbnNOYW1lID0gTlVMTDsKICAgIAkgICAgCglmb3IgKGkgPSAwOyBpIDwgbmJ2YWwgKyBuYm5lZzsgaSsrKSB7CgkgICAgY3VyID0gdmFsdWVzW2ldOwoJICAgIC8qCgkgICAgKiBHZXQgdGhlIGxvY2FsIG5hbWUuCgkgICAgKi8KCSAgICBsb2NhbE5hbWUgPSBOVUxMOwoJICAgIAoJICAgIGVuZCA9IGN1cjsKCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQlsb2NhbE5hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIioiKTsKCQllbmQrKzsKCSAgICB9IGVsc2UgewoJCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoKmVuZCAhPSAnfCcpKQoJCSAgICBlbmQrKzsKCQlsb2NhbE5hbWUgPSB4bWxTdHJuY2F0KGxvY2FsTmFtZSwgQkFEX0NBU1QgY3VyLCBlbmQgLSBjdXIpOwoJICAgIH0JCQoJICAgIGlmICgqZW5kICE9IDApIHsJCSAgICAKCQllbmQrKzsKCQkvKgoJCSogU2tpcCAiKnwqIiBpZiB0aGV5IGNvbWUgd2l0aCBuZWdhdGVkIGV4cHJlc3Npb25zLCBzaW5jZQoJCSogdGhleSByZXByZXNlbnQgdGhlIHNhbWUgbmVnYXRlZCB3aWxkY2FyZC4KCQkqLwoJCWlmICgobmJuZWcgPT0gMCkgfHwgKCplbmQgIT0gJyonKSB8fCAoKmxvY2FsTmFtZSAhPSAnKicpKSB7CgkJICAgIC8qCgkJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCQkgICAgKi8KCQkgICAgY3VyID0gZW5kOwoJCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQkJbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Kn0iKTsKCQkgICAgfSBlbHNlIHsKCQkJd2hpbGUgKCplbmQgIT0gMCkKCQkJICAgIGVuZCsrOwoJCQkKCQkJaWYgKGkgPj0gbmJ2YWwpCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsjI290aGVyOiIpOwoJCQllbHNlCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsiKTsKCQkJCgkJCW5zTmFtZSA9IHhtbFN0cm5jYXQobnNOYW1lLCBCQURfQ0FTVCBjdXIsIGVuZCAtIGN1cik7CgkJCW5zTmFtZSA9IHhtbFN0cmNhdChuc05hbWUsIEJBRF9DQVNUICJ9Iik7CgkJICAgIH0KCQkgICAgc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgbnNOYW1lKTsKCQkgICAgRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJfSBlbHNlIHsKCQkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCSAgICBjb250aW51ZTsKCQl9CgkgICAgfQkgICAgICAgIAoJICAgIHN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUIGxvY2FsTmFtZSk7CgkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCQoJICAgIGlmIChpIDwgbmJ2YWwgKyBuYm5lZyAtMSkKCQlzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiLCAiKTsKCX0JCglzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiICkuXG4iKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIHN0cik7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0gZWxzZQogICAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZhY2V0RXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwKCQkgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSBmYWNldFR5cGU7CiAgICBpbnQgbm9kZVR5cGUgPSB4bWxTY2hlbWFFdmFsRXJyb3JOb2RlVHlwZShhY3R4dCwgbm9kZSk7CgogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIGlmIChlcnJvciA9PSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQpIHsKCWZhY2V0VHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CgkvKgoJKiBJZiBlbnVtZXJhdGlvbnMgYXJlIHZhbGlkYXRlZCwgb25lIG11c3Qgbm90IGV4cGVjdCB0aGUKCSogZmFjZXQgdG8gYmUgZ2l2ZW4uCgkqLwkKICAgIH0gZWxzZQkKCWZhY2V0VHlwZSA9IGZhY2V0LT50eXBlOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJmYWNldCAnIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldFR5cGUpKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInXSAiKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBhIGRlZmF1bHQgbWVzc2FnZS4KCSovCglpZiAoKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEgpKSB7CgoJICAgIGNoYXIgbGVuWzI1XSwgYWN0TGVuWzI1XTsKCgkgICAgLyogRklYTUUsIFRPRE86IFdoYXQgaXMgdGhlIG1heCBleHBlY3RlZCBzdHJpbmcgbGVuZ3RoIG9mIHRoZQoJICAgICogdGhpcyB2YWx1ZT8KCSAgICAqLwoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGhhcyBhIGxlbmd0aCBvZiAnJXMnOyAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgoJICAgIHNucHJpbnRmKGxlbiwgMjQsICIlbHUiLCB4bWxTY2hlbWFHZXRGYWNldFZhbHVlQXNVTG9uZyhmYWNldCkpOwoJICAgIHNucHJpbnRmKGFjdExlbiwgMjQsICIlbHUiLCBsZW5ndGgpOwoKCSAgICBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGRpZmZlcnMgZnJvbSB0aGUgYWxsb3dlZCBsZW5ndGggb2YgJyVzJy5cbiIpOyAgICAgCgkgICAgZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbWF4aW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyB1bmRlcnJ1bnMgdGhlIGFsbG93ZWQgbWluaW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIAoJICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJeG1sU2NoZW1hRXJyMyhhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgdmFsdWUsIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCSAgICBlbHNlIAoJCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4pOwoJCgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhbiBlbGVtZW50ICIKCQkib2YgdGhlIHNldCB7JXN9LlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgCgkJeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KGFjdHh0LCAmc3RyLCB0eXBlKSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFjY2VwdGVkICIKCQkiYnkgdGhlIHBhdHRlcm4gJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRSkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBsZXNzIHRoYW4gdGhlICIKCQkibWluaW11bSB2YWx1ZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIGdyZWF0ZXIgdGhhbiB0aGUgIgoJCSJtYXhpbXVtIHZhbHVlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBsZXNzIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgbXVzdCBiZSBtb3JlIHRoYW4gIgoJCSInJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSAiCgkJImRpZ2l0cyB0aGFuIGFyZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUykgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgbW9yZSBmcmFjdGlvbmFsICIKCQkiZGlnaXRzIHRoYW4gYXJlIGFsbG93ZWQgKCclcycpLlxuIik7CgkgICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIqKSBtc2csIHZhbHVlLAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKG5vZGVUeXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewkJCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwkKCX0gZWxzZSB7CSAgICAKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7Cgl4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIpOwogICAgfSAgICAgICAgCiAgICBGUkVFX0FORF9OVUxMKHN0cikKICAgIHhtbEZyZWUobXNnKTsKfQoKI2RlZmluZSBWRVJST1IoZXJyLCB0eXBlLCBtc2cpIFwKICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgZXJyLCBOVUxMLCB0eXBlLCBtc2csIE5VTEwsIE5VTEwpOwoKI2RlZmluZSBWRVJST1JfSU5UKGZ1bmMsIG1zZykgeG1sU2NoZW1hSW50ZXJuYWxFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIGZ1bmMsIG1zZyk7CgojZGVmaW5lIFBFUlJPUl9JTlQoZnVuYywgbXNnKSB4bWxTY2hlbWFJbnRlcm5hbEVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwgZnVuYywgbXNnKTsKCiNkZWZpbmUgQUVSUk9SX0lOVChmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKGFjdHh0LCBmdW5jLCBtc2cpOwoKCi8qKgogKiB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lck5hbWU6IHRoZSBuYW1lIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5vZGU6IHRoZSBwYXJlbnQgZWxlbWVudCBub2RlIG9mIHRoZSBtaXNzaW5nIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtKTsKCiAgICBpZiAobWVzc2FnZSAhPSBOVUxMKQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLCAiJXM6ICVzLlxuIiwgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBtZXNzYWdlKTsKICAgIGVsc2UKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwKCSAgICAiJXM6IFRoZSBhdHRyaWJ1dGUgJyVzJyBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsCgkgICAgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mICB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiB0aGUgb3duZXIgYXMgYW4gZWxlbWVudCBub2RlCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGhvbGRpbmcgdGhlIFFOYW1lCiAqIEByZWZOYW1lOiB0aGUgcmVmZXJlbmNlZCBsb2NhbCBuYW1lCiAqIEByZWZVUkk6IHRoZSByZWZlcmVuY2VkIG5hbWVzcGFjZSBVUkkKICogQG1lc3NhZ2U6IG9wdGlvbmFsIG1lc3NhZ2UKICoKICogVXNlZCB0byByZXBvcnQgUU5hbWUgYXR0cmlidXRlIHZhbHVlcyB0aGF0IGZhaWxlZCB0byByZXNvbHZlCiAqIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgeG1sQ2hhciAqcmVmTmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZlVSSSwKCQkJIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJCSBjb25zdCBjaGFyICpyZWZUeXBlU3RyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSk7CiAgICBpZiAocmVmVHlwZVN0ciA9PSBOVUxMKQoJcmVmVHlwZVN0ciA9IChjb25zdCBjaGFyICopIHhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmcocmVmVHlwZSk7Cgl4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAiJXMsIGF0dHJpYnV0ZSAnJXMnOiBUaGUgUU5hbWUgdmFsdWUgJyVzJyBkb2VzIG5vdCByZXNvbHZlIHRvIGEobikgIgoJICAgICIlcy5cbiIsIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZSwKCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyQSwgcmVmVVJJLCByZWZOYW1lKSwKCSAgICBCQURfQ0FTVCByZWZUeXBlU3RyLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKQogICAgRlJFRV9BTkRfTlVMTChzdHJBKQp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxDaGFyICoqb3duZXJEZXMsCgkJCXhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQl4bWxBdHRyUHRyIGF0dHIsCgkJCWNvbnN0IGNoYXIgKm1zZykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIGF0dHItPm5hbWUsIChjb25zdCB4bWxDaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgYXR0cmlidXRlJ3Mgb3duZXIKICogQG93bmVySXRlbTogdGhlIGF0dHJpYnV0ZSdzIG93bmVyIGl0ZW0KICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbEF0dHJQdHIgYXR0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlCglkZXMgPSAqb3duZXJEZXM7CiAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwKCSIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwgQkFEX0NBU1QgZGVzLAoJeG1sU2NoZW1hRm9ybWF0UU5hbWVOcygmc3RyQSwgYXR0ci0+bnMsIGF0dHItPm5hbWUpKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJBKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBBcXVpcmVEZXM6CiAqIEBkZXM6IHRoZSBmaXJzdCBkZXNpZ25hdGlvbgogKiBAaXRlbURlczogdGhlIHNlY29uZCBkZXNpZ25hdGlvbgogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqCiAqIENyZWF0ZXMgYSBkZXNpZ25hdGlvbiBmb3IgYW4gaXRlbS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBBcXVpcmVEZXMoeG1sQ2hhciAqKmRlcywKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSkKewogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoZGVzLCBOVUxMLCBpdGVtLCBpdGVtRWxlbSk7CiAgICBlbHNlIGlmICgqaXRlbURlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KGl0ZW1EZXMsIE5VTEwsIGl0ZW0sIGl0ZW1FbGVtKTsKCSpkZXMgPSAqaXRlbURlczsKICAgIH0gZWxzZQoJKmRlcyA9ICppdGVtRGVzOwp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIyOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjM6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMiwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtRWxlbSk7CiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKChpdGVtRWxlbSA9PSBOVUxMKSAmJiAoaXRlbSAhPSBOVUxMKSkKCWl0ZW1FbGVtID0gaXRlbS0+bm9kZTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbUVsZW0sIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgIHhtbENoYXIgKippdGVtRGVzLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEpCnsKICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwgZXJyb3IsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtLCBtZXNzYWdlLAoJc3RyMSwgTlVMTCwgTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQXR0clVzZUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbTogdGhlIHNjaGVtYSB0eXBlCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSB0eXBlCiAqIEBhdHRyOiB0aGUgaW52YWxpZCBzY2hlbWEgYXR0cmlidXRlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGF0dHJpYnV0ZSB1c2UgZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQXR0clVzZUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICBjb25zdCB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ciwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIGl0ZW0sIE5VTEwpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiwgIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLAoJQkFEX0NBU1QgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLAoJKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHIsIE5VTEwpKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICI6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGF0dHItPm5vZGUsIGVycm9yLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBOVUxMKTsKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgdHlwZQogKiBAaXRlbTogdGhlIHNjaGVtYSB0eXBlCiAqIEBiYXNlSXRlbTogdGhlIGJhc2UgdHlwZSBvZiB0eXBlCiAqIEBmYWNldDogdGhlIGlsbGVnYWwgZmFjZXQKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGZhY2V0IGZvciBhdG9taWMgc2ltcGxlIHR5cGVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0Vycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgIHhtbENoYXIgKippdGVtRGVzLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VJdGVtLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbS0+bm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXM6IFRoZSBmYWNldCAnJXMnIGlzIG5vdCBhbGxvd2VkIG9uIHR5cGVzIGRlcml2ZWQgZnJvbSB0aGUgIgoJInR5cGUgJXMuXG4iLAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJULCBOVUxMLCBiYXNlSXRlbSwgTlVMTCksCglOVUxMLCBOVUxMKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0clQpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbSBpbnZvbHZlZAogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBmYWNldDogdGhlIGlsbGVnYWwgZmFjZXQKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGZhY2V0IGZvciA8bGlzdD4gYW5kIDx1bmlvbj4uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwgZXJyb3IsCgkiJXM6IFRoZSBmYWNldCAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwKCUJBRF9DQVNUIGRlcywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0clQpOwp9CgovKioKICogeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAZWxlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudCBub2RlCiAqIEBhdHRyOiB0aGUgYmFkIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sQXR0clB0ciBhdHRyLAoJCQkgY29uc3QgY2hhciAqbmFtZTEsCgkJCSBjb25zdCBjaGFyICpuYW1lMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXM6IFRoZSBhdHRyaWJ1dGVzICclcycgYW5kICclcycgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS5cbiIsCglCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUxLCBCQURfQ0FTVCBuYW1lMiwgTlVMTCwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQp9CgovKioKICogeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAdHlwZTogdGhlIHR5cGUgc3BlY2lmaWVyCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBpZiBleGlzdGVudCAKICogQG5vZGU6IHRoZSB2YWxpZGF0ZWQgbm9kZQogKiBAdmFsdWU6IHRoZSB2YWxpZGF0ZWQgdmFsdWUKICoKICogUmVwb3J0cyBhIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqIFRPRE86IFNob3VsZCB0aGlzIHJlcG9ydCB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBhcyB3ZWxsPwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSBBVFRSSUJVVEVfVU5VU0VELAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJY29uc3QgY2hhciAqZXhwZWN0ZWQsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQljb25zdCBjaGFyICptZXNzYWdlLAoJCQljb25zdCB4bWxDaGFyICpzdHIxLAoJCQljb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgY3R4dCwgbm9kZSk7CiAgICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CgkvKgoJKiBVc2UgZGVmYXVsdCBtZXNzYWdlcy4KCSovCQoJaWYgKHR5cGUgIT0gTlVMTCkgewoJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyVzJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgYSAiCgkJInZhbGlkIHZhbHVlIG9mICIpOwkKCSAgICBpZiAoISB4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSBsb2NhbCAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSAiKTsKCSAgICAKCSAgICBpZiAoVkFSSUVUWV9BVE9NSUModHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgImF0b21pYyB0eXBlIik7CgkgICAgZWxzZSBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJsaXN0IHR5cGUiKTsKCSAgICBlbHNlIGlmIChWQVJJRVRZX1VOSU9OKHR5cGUpKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJ1bmlvbiB0eXBlIik7CgkgICAgCgkgICAgaWYgKHhtbFNjaGVtYUlzR2xvYmFsSXRlbSh0eXBlKSkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiAnIik7CgkJaWYgKHR5cGUtPmJ1aWx0SW5UeXBlICE9IDApIHsKCQkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInhzOiIpOwoJCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB0eXBlLT5uYW1lKTsKCQl9IGVsc2UgCgkJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCSAgICB0eXBlLT50YXJnZXROYW1lc3BhY2UsIHR5cGUtPm5hbWUpKTsKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJy4iKTsKCQlGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgfQoJfSBlbHNlIHsKCSAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCB2YWxpZC4iKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgIgoJCSJ2YWxpZC4iKTsKCX0JCglpZiAoZXhwZWN0ZWQpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIEV4cGVjdGVkIGlzICciKTsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBleHBlY3RlZCk7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIicuXG4iKTsKCX0gZWxzZQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJcbiIpOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwoJZWxzZQoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAgIiVzJXMuXG4iLCBtc2csIEJBRF9DQVNUIG1lc3NhZ2UsIHN0cjEsIHN0cjIsIE5VTEwpOwogICAgfQogICAgLyogQ2xlYW51cC4gKi8gICAgCiAgICBGUkVFX0FORF9OVUxMKG1zZykKfQoKLyoqCiAqIHhtbFNjaGVtYVBDb250ZW50RXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvbndlckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGl0ZW0gb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAb3duZXJFbGVtOiB0aGUgbm9kZSBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBjaGlsZDogdGhlIGludmFsaWQgY2hpbGQgbm9kZQogKiBAbWVzc2FnZTogdGhlIG9wdGlvbmFsIGVycm9yIG1lc3NhZ2UKICogQGNvbnRlbnQ6IHRoZSBvcHRpb25hbCBzdHJpbmcgZGVzY3JpYmluZyB0aGUgY29ycmVjdCBjb250ZW50CiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgY29uY2VybmluZyB0aGUgY29udGVudCBvZiBhIHNjaGVtYSBlbGVtZW50LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUENvbnRlbnRFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkgICAgIHhtbE5vZGVQdHIgY2hpbGQsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgY2hhciAqY29udGVudCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkKCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLAoJICAgICIlczogJXMuXG4iLAoJICAgIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBlbHNlIHsKCWlmIChjb250ZW50ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC4gRXhwZWN0ZWQgaXMgJXMuXG4iLAoJCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgY29udGVudCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLAoJCSIlczogVGhlIGNvbnRlbnQgaXMgbm90IHZhbGlkLlxuIiwKCQlCQURfQ0FTVCBkZXMsIE5VTEwpOwoJfQogICAgfQogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVN0cmVhbWFibGUgZXJyb3IgZnVuY3Rpb25zICAgICAgICAgICAgICAgICAgICAgICoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpb24gaGVscGVyIGZ1bmN0aW9ucwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlBbGxvY2F0aW9uIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFOZXdTY2hlbWFGb3JQYXJzZXJDdHh0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBBbGxvY2F0ZSBhIG5ldyBTY2hlbWEgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVB0cgp4bWxTY2hlbWFOZXdTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIHNjaGVtYSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hKSk7CiAgICByZXQtPmRpY3QgPSBjdHh0LT5kaWN0OwogICAgeG1sRGljdFJlZmVyZW5jZShyZXQtPmRpY3QpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1NjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBc3NlbWJsZVB0cgp4bWxTY2hlbWFOZXdBc3NlbWJsZSh2b2lkKQp7CiAgICB4bWxTY2hlbWFBc3NlbWJsZVB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYUFzc2VtYmxlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUFzc2VtYmxlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICAvKiB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGFzc2VtYmxlIGluZm8iLCBOVUxMKTsgKi8KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUFzc2VtYmxlKSk7CiAgICByZXQtPml0ZW1zID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0ZhY2V0OgogKgogKiBBbGxvY2F0ZSBhIG5ldyBGYWNldCBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwp4bWxTY2hlbWFGYWNldFB0cgp4bWxTY2hlbWFOZXdGYWNldCh2b2lkKQp7CiAgICB4bWxTY2hlbWFGYWNldFB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYUZhY2V0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUZhY2V0KSk7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3QW5ub3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBub2RlCiAqCiAqIEFsbG9jYXRlIGEgbmV3IGFubm90YXRpb24gc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUFubm90UHRyCnhtbFNjaGVtYU5ld0Fubm90KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYUFubm90UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUFubm90KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGFubm90YXRpb24iLCBub2RlKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUFubm90KSk7CiAgICByZXQtPmNvbnRlbnQgPSBub2RlOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hSXRlbUxpc3RQdHIKeG1sU2NoZW1hTmV3SXRlbUxpc3Qodm9pZCkKewogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgcmV0OwoKICAgIHJldCA9IHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSXRlbUxpc3QpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJICAgICJhbGxvY2F0aW5nIGFuIGl0ZW0gbGlzdCBzdHJ1Y3R1cmUiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hSXRlbUxpc3QpKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEVsZW1lbnRTdWJzdGl0dXRpb25NZW1iZXI6CiAqIEBwY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBoZWFkOiAgdGhlIGhlYWQgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAogKiBAbWVtYmVyOiB0aGUgbmV3IG1lbWJlciBvZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwCiAqCiAqIEFsbG9jYXRlIGEgbmV3IGFubm90YXRpb24gc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uTWVtYmVyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIG1lbWJlcikKewogICAgeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBzdWJzdEdyb3VwOwoKICAgIGlmIChwY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKHBjdHh0LT5zdWJzdEdyb3VwcyA9PSBOVUxMKSB7CglwY3R4dC0+c3Vic3RHcm91cHMgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgcGN0eHQtPmRpY3QpOwoJaWYgKHBjdHh0LT5zdWJzdEdyb3VwcyA9PSBOVUxMKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgc3Vic3RHcm91cCA9IHhtbEhhc2hMb29rdXAyKHBjdHh0LT5zdWJzdEdyb3VwcywgaGVhZC0+bmFtZSwKCWhlYWQtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBpZiAoc3Vic3RHcm91cCA9PSBOVUxMKSB7CglpbnQgcmVzOwoKCXN1YnN0R3JvdXAgPSAoeG1sU2NoZW1hU3Vic3RHcm91cFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFTdWJzdEdyb3VwKSk7CglpZiAoc3Vic3RHcm91cCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJCSJ4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uLCBhbGxvY2F0aW5nIGEgc3Vic3RpdHV0aW9uICIKCQkiZ3JvdXAgY29udGFpbmVyIiwKCQlOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXN1YnN0R3JvdXAtPm1lbWJlcnMgPSB4bWxTY2hlbWFOZXdJdGVtTGlzdCgpOwoJaWYgKHN1YnN0R3JvdXAtPm1lbWJlcnMgPT0gTlVMTCkgewoJICAgIHhtbEZyZWUoc3Vic3RHcm91cCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglzdWJzdEdyb3VwLT5oZWFkID0gaGVhZDsKCglyZXMgPSB4bWxIYXNoQWRkRW50cnkyKHBjdHh0LT5zdWJzdEdyb3VwcywKCSAgICBoZWFkLT5uYW1lLCBoZWFkLT50YXJnZXROYW1lc3BhY2UsIHN1YnN0R3JvdXApOwoJaWYgKHJlcyAhPSAwKSB7CgkgICAgeG1sRnJlZShzdWJzdEdyb3VwLT5tZW1iZXJzKTsKCSAgICB4bWxGcmVlKHN1YnN0R3JvdXApOwoJICAgIHhtbFNjaGVtYVBFcnIocGN0eHQsIG1lbWJlci0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEVsZW1lbnRTdWJzdGl0dXRpb24sICIKCQkiZmFpbGVkIHRvIGFkZCBhIG5ldyBzdWJzdGl0dXRpb24gZ3JvdXAgY29udGFpbmVyIGZvciAiCgkJIiclcycuXG4iLCBoZWFkLT5uYW1lLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIGlmIChzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtcyA9PSBOVUxMKSB7CglzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoCgkgICAgNSAqIHNpemVvZih4bWxTY2hlbWFFbGVtZW50UHRyKSk7CglpZiAoc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCQkiYWxsb2NhdGluZyBsaXN0IG9mIHN1YnN0aXR1dGlvbiBncm91cCBtZW1iZXJzIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglzdWJzdEdyb3VwLT5tZW1iZXJzLT5zaXplSXRlbXMgPSA1OwogICAgfSBlbHNlIGlmIChzdWJzdEdyb3VwLT5tZW1iZXJzLT5zaXplSXRlbXMgPD0KCSAgICBzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zKSB7CglzdWJzdEdyb3VwLT5tZW1iZXJzLT5zaXplSXRlbXMgKj0gMjsKCXN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MoCgkgICAgc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXMsCgkgICAgc3Vic3RHcm91cC0+bWVtYmVycy0+c2l6ZUl0ZW1zICogc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnRQdHIpKTsKCWlmIChzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJCSJyZS1hbGxvY2F0aW5nIGxpc3Qgb2Ygc3Vic3RpdHV0aW9uIGdyb3VwIG1lbWJlcnMiLCBOVUxMKTsKCSAgICBzdWJzdEdyb3VwLT5tZW1iZXJzLT5zaXplSXRlbXMgPSAwOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgKCh4bWxTY2hlbWFFbGVtZW50UHRyICopIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zKQoJW3N1YnN0R3JvdXAtPm1lbWJlcnMtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBtZW1iZXI7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hR2V0RWxlbWVudFN1YnN0aXR1dGlvbkdyb3VwOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAaGVhZDogIHRoZSBoZWFkIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKICogQG1lbWJlcjogdGhlIG5ldyBtZW1iZXIgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFTdWJzdEdyb3VwUHRyCnhtbFNjaGVtYUdldEVsZW1lbnRTdWJzdGl0dXRpb25Hcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQpCnsKICAgIGlmIChwY3R4dCA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKCiAgICBpZiAocGN0eHQtPnN1YnN0R3JvdXBzID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwoKICAgIHJldHVybiAoKHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIpIHhtbEhhc2hMb29rdXAyKHBjdHh0LT5zdWJzdEdyb3VwcywKCWhlYWQtPm5hbWUsIGhlYWQtPnRhcmdldE5hbWVzcGFjZSkpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUl0ZW1MaXN0OgogKiBAYW5ub3Q6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgYW5ub3RhdGlvbiBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJdGVtTGlzdCh4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0KQp7CiAgICBpZiAobGlzdCA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGxpc3QtPml0ZW1zICE9IE5VTEwpCgl4bWxGcmVlKGxpc3QtPml0ZW1zKTsKICAgIHhtbEZyZWUobGlzdCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQW5ub3Q6CiAqIEBhbm5vdDogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBhbm5vdGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUFubm90KHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICBpZiAoYW5ub3QgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKGFubm90KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbXBvcnQ6CiAqIEBpbXBvcnQ6ICBhIHNjaGVtYSBpbXBvcnQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYW4gaW1wb3J0IHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUltcG9ydCh4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0KQp7CiAgICBpZiAoaW1wb3J0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbFNjaGVtYUZyZWUoaW1wb3J0LT5zY2hlbWEpOwogICAgeG1sRnJlZURvYyhpbXBvcnQtPmRvYyk7CiAgICB4bWxGcmVlKGltcG9ydCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZToKICogQGluY2x1ZGU6ICBhIHNjaGVtYSBpbmNsdWRlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZSh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGUpCnsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbEZyZWVEb2MoaW5jbHVkZS0+ZG9jKTsKICAgIHhtbEZyZWUoaW5jbHVkZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3Q6CiAqIEBpbmNsdWRlczogIGEgc2NoZW1hIGluY2x1ZGUgbGlzdAogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoeG1sU2NoZW1hSW5jbHVkZVB0ciBpbmNsdWRlcykKewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwoKICAgIHdoaWxlIChpbmNsdWRlcyAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IGluY2x1ZGVzLT5uZXh0OwoJeG1sU2NoZW1hRnJlZUluY2x1ZGUoaW5jbHVkZXMpOwoJaW5jbHVkZXMgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZU5vdGF0aW9uOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgbm90YXRpb24gc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgTm90YXRpb24gc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU5vdGF0aW9uKHhtbFNjaGVtYU5vdGF0aW9uUHRyIG5vdGEpCnsKICAgIGlmIChub3RhID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShub3RhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgaWYgKGF0dHItPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGF0dHItPmRlZlZhbCk7CiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQ6CiAqIHNldDogIGEgc2NoZW1hIHdpbGRjYXJkIG5hbWVzcGFjZQogKgogKiBEZWFsbG9jYXRlcyBhIGxpc3Qgb2Ygd2lsZGNhcmQgY29uc3RyYWludCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzZXQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbmV4dDsKCiAgICB3aGlsZSAoc2V0ICE9IE5VTEwpIHsKCW5leHQgPSBzZXQtPm5leHQ7Cgl4bWxGcmVlKHNldCk7CglzZXQgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkOgogKiBAd2lsZGNhcmQ6ICBhIHdpbGRjYXJkIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlcyBhIHdpbGRjYXJkIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjYXJkKQp7CiAgICBpZiAod2lsZGNhcmQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAod2lsZGNhcmQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHdpbGRjYXJkLT5hbm5vdCk7CiAgICBpZiAod2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCh3aWxkY2FyZC0+bnNTZXQpOwogICAgaWYgKHdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sRnJlZSh3aWxkY2FyZC0+bmVnTnNTZXQpOwogICAgeG1sRnJlZSh3aWxkY2FyZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgZ3JvdXAgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIEdyb3VwIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyKQp7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChhdHRyLT5hbm5vdCk7CiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3Q6CiAqIEBhdHRyVXNlOiAgYW4gYXR0cmlidXRlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2Ygc2NoZW1hIGF0dHJpYnV0ZSB1c2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGF0dHJVc2UgIT0gTlVMTCkgewoJbmV4dCA9IGF0dHJVc2UtPm5leHQ7Cgl4bWxGcmVlKGF0dHJVc2UpOwoJYXR0clVzZSA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUU5hbWVSZWY6CiAqIEBpdGVtOiBhIFFOYW1lIHJlZmVyZW5jZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZWEgYSBRTmFtZSByZWZlcmVuY2Ugc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVFOYW1lUmVmKHhtbFNjaGVtYVFOYW1lUmVmUHRyIGl0ZW0pCnsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUU5hbWVSZWY6CiAqIEBpdGVtOiBhIFFOYW1lIHJlZmVyZW5jZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZWEgYSBRTmFtZSByZWZlcmVuY2Ugc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVN1YnN0R3JvdXAoeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBpdGVtKQp7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGl0ZW0tPm1lbWJlcnMgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVJdGVtTGlzdChpdGVtLT5tZW1iZXJzKTsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkVm9sYXRpbGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtKQp7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0OwoKICAgIGlmIChzY2hlbWEtPnZvbGF0aWxlcyA9PSBOVUxMKSB7CglzY2hlbWEtPnZvbGF0aWxlcyA9ICh2b2lkICopIHhtbFNjaGVtYU5ld0l0ZW1MaXN0KCk7CglpZiAoc2NoZW1hLT52b2xhdGlsZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCQkiYWxsb2NhdGluZyBsaXN0IG9mIHZvbGF0aWxlcyIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgbGlzdCA9ICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgc2NoZW1hLT52b2xhdGlsZXM7CiAgICBpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIDIwICogc2l6ZW9mKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkJImFsbG9jYXRpbmcgbmV3IHZvbGF0aWxlIGl0ZW0gYnVmZmVyIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglsaXN0LT5zaXplSXRlbXMgPSAyMDsKICAgIH0gZWxzZSBpZiAobGlzdC0+c2l6ZUl0ZW1zIDw9IGxpc3QtPm5iSXRlbXMpIHsKCWxpc3QtPnNpemVJdGVtcyAqPSAyOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhsaXN0LT5pdGVtcywKCSAgICBsaXN0LT5zaXplSXRlbXMgKiBzaXplb2YoeG1sU2NoZW1hVHlwZVB0cikpOwoJaWYgKGxpc3QtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkJImdyb3dpbmcgdm9sYXRpbGUgaXRlbSBidWZmZXIiLCBOVUxMKTsKCSAgICBsaXN0LT5zaXplSXRlbXMgPSAwOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgKikgbGlzdC0+aXRlbXMpW2xpc3QtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBpdGVtOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3Q6CiAqIEBhbGluazogYSB0eXBlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2YgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmspCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJbmV4dCA9IGxpbmstPm5leHQ7Cgl4bWxGcmVlKGxpbmspOwoJbGluayA9IG5leHQ7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QoeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBuZXh0OwogICAgd2hpbGUgKHN0byAhPSBOVUxMKSB7CgluZXh0ID0gc3RvLT5uZXh0OwoJaWYgKHN0by0+aGlzdG9yeSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoc3RvLT5oaXN0b3J5KTsKCWlmIChzdG8tPnhwYXRoQ3R4dCAhPSBOVUxMKQoJICAgIHhtbEZyZWVTdHJlYW1DdHh0KCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7Cgl4bWxGcmVlKHN0byk7CglzdG8gPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZUlEQzoKICogQGlkYzogYSBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24KICoKICogRGVhbGxvY2F0ZXMgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUlEQyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmKQp7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgY3VyLCBwcmV2OwoKICAgIGlmIChpZGNEZWYgPT0gTlVMTCkKCXJldHVybjsKICAgIGlmIChpZGNEZWYtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGlkY0RlZi0+YW5ub3QpOwogICAgLyogU2VsZWN0b3IgKi8KICAgIGlmIChpZGNEZWYtPnNlbGVjdG9yICE9IE5VTEwpIHsKCWlmIChpZGNEZWYtPnNlbGVjdG9yLT54cGF0aENvbXAgIT0gTlVMTCkKCSAgICB4bWxGcmVlUGF0dGVybigoeG1sUGF0dGVyblB0cikgaWRjRGVmLT5zZWxlY3Rvci0+eHBhdGhDb21wKTsKCXhtbEZyZWUoaWRjRGVmLT5zZWxlY3Rvcik7CiAgICB9CiAgICAvKiBGaWVsZHMgKi8KICAgIGlmIChpZGNEZWYtPmZpZWxkcyAhPSBOVUxMKSB7CgljdXIgPSBpZGNEZWYtPmZpZWxkczsKCWRvIHsKCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCSAgICBpZiAocHJldi0+eHBhdGhDb21wICE9IE5VTEwpCgkJeG1sRnJlZVBhdHRlcm4oKHhtbFBhdHRlcm5QdHIpIHByZXYtPnhwYXRoQ29tcCk7CgkgICAgeG1sRnJlZShwcmV2KTsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIHhtbEZyZWUoaWRjRGVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVFbGVtZW50OgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgZWxlbWVudCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBFbGVtZW50IHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVFbGVtZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoZWxlbS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoZWxlbS0+YW5ub3QpOwogICAgaWYgKGVsZW0tPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZWxlbS0+Y29udE1vZGVsKTsKICAgIGlmIChlbGVtLT5kZWZWYWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShlbGVtLT5kZWZWYWwpOwogICAgeG1sRnJlZShlbGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVGYWNldDoKICogQGZhY2V0OiAgYSBzY2hlbWEgZmFjZXQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRmFjZXQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIGlmIChmYWNldCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChmYWNldC0+dmFsICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGZhY2V0LT52YWwpOwogICAgaWYgKGZhY2V0LT5yZWdleHAgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGZhY2V0LT5yZWdleHApOwogICAgaWYgKGZhY2V0LT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChmYWNldC0+YW5ub3QpOwogICAgeG1sRnJlZShmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZToKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBuZXh0OwoKICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICBuZXh0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgICAgIGZhY2V0ID0gbmV4dDsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodHlwZS0+YXR0cmlidXRlVXNlcyk7CiAgICB9CiAgICBpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3QodHlwZS0+bWVtYmVyVHlwZXMpOwogICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBuZXh0LCBsaW5rOwoKCWxpbmsgPSB0eXBlLT5mYWNldFNldDsKCWRvIHsKCSAgICBuZXh0ID0gbGluay0+bmV4dDsKCSAgICB4bWxGcmVlKGxpbmspOwoJICAgIGxpbmsgPSBuZXh0OwoJfSB3aGlsZSAobGluayAhPSBOVUxMKTsKICAgIH0KICAgIGlmICh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKHR5cGUtPmNvbnRNb2RlbCk7CiAgICB4bWxGcmVlKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXBEZWY6CiAqIEBpdGVtOiAgYSBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgogKgogKiBEZWFsbG9jYXRlcyBhIHNjaGVtYSBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXBEZWYoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtKQp7CiAgICBpZiAoaXRlbS0+YW5ub3QgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBbm5vdChpdGVtLT5hbm5vdCk7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXA6CiAqIEBpdGVtOiAgYSBzY2hlbWEgbW9kZWwgZ3JvdXAKICoKICogRGVhbGxvY2F0ZXMgYSBzY2hlbWEgbW9kZWwgZ3JvdXAgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU1vZGVsR3JvdXAoeG1sU2NoZW1hTW9kZWxHcm91cFB0ciBpdGVtKQp7CiAgICBpZiAoaXRlbS0+YW5ub3QgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBbm5vdChpdGVtLT5hbm5vdCk7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnRpY2xlOgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlUGFydGljbGUoeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbSkKewogICAgaWYgKGl0ZW0tPmFubm90ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQW5ub3QoaXRlbS0+YW5ub3QpOwogICAgeG1sRnJlZShpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVNaXNjQ29tcG9uZW50czoKICogQGl0ZW06ICBhIHNjaGVtYSBjb21wb25lbnQKICoKICogRGVhbGxvY2F0ZXMgbWlzYy4gc2NoZW1hIGNvbXBvbmVudCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU1pc2NDb21wb25lbnRzKHhtbFNjaGVtYVRyZWVJdGVtUHRyIGl0ZW0pCnsKICAgIGlmIChpdGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCSAgICB4bWxTY2hlbWFGcmVlUGFydGljbGUoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBpdGVtKTsKCSAgICByZXR1cm47CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCSAgICB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cCgoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikgaXRlbSk7CgkgICAgcmV0dXJuOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBpdGVtKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgLyogVE9ETzogVGhpcyBzaG91bGQgbmV2ZXIgYmUgaGl0LiAqLwoJICAgIFRPRE8KCSAgICByZXR1cm47CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVWb2xhdGlsZXMoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYS0+dm9sYXRpbGVzID09IE5VTEwpCglyZXR1cm47CiAgICB7Cgl4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0ID0gKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSBzY2hlbWEtPnZvbGF0aWxlczsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGl0ZW07CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgaWYgKGxpc3QtPml0ZW1zW2ldICE9IE5VTEwpIHsKCQlpdGVtID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBsaXN0LT5pdGVtc1tpXTsKCQlzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCQkgICAgY2FzZSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGOgoJCQl4bWxTY2hlbWFGcmVlUU5hbWVSZWYoKHhtbFNjaGVtYVFOYW1lUmVmUHRyKSBpdGVtKTsKCQkJYnJlYWs7CgkJICAgIGRlZmF1bHQ6CgkJCXhtbFNjaGVtYUZyZWVNaXNjQ29tcG9uZW50cyhpdGVtKTsKCQl9CgkgICAgfQoJfQoJeG1sU2NoZW1hRnJlZUl0ZW1MaXN0KGxpc3QpOwogICAgfQp9Ci8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZUxpc3Q6CiAqIEB0eXBlOiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBUeXBlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVUeXBlTGlzdCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbmV4dDsKCiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IHR5cGUtPnJlZGVmOwoJeG1sU2NoZW1hRnJlZVR5cGUodHlwZSk7Cgl0eXBlID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWUoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBpZiAoc2NoZW1hLT52b2xhdGlsZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWb2xhdGlsZXMoc2NoZW1hKTsKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5ub3RhRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlTm90YXRpb24pOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUpOwogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJncnBEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUVsZW1lbnQpOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPnR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVUeXBlTGlzdCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmdyb3VwRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZik7CiAgICBpZiAoc2NoZW1hLT5pZGNEZWYgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmlkY0RlZiwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlSURDKTsKICAgIGlmIChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzICE9IE5VTEwpCgl4bWxIYXNoRnJlZShzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLAoJCSAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlSW1wb3J0KTsKICAgIGlmIChzY2hlbWEtPmluY2x1ZGVzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoKHhtbFNjaGVtYUluY2x1ZGVQdHIpIHNjaGVtYS0+aW5jbHVkZXMpOwogICAgfQogICAgaWYgKHNjaGVtYS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3Qoc2NoZW1hLT5hbm5vdCk7CiAgICBpZiAoc2NoZW1hLT5kb2MgIT0gTlVMTCAmJiAhc2NoZW1hLT5wcmVzZXJ2ZSkKICAgICAgICB4bWxGcmVlRG9jKHNjaGVtYS0+ZG9jKTsKICAgIHhtbERpY3RGcmVlKHNjaGVtYS0+ZGljdCk7CiAgICB4bWxGcmVlKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlEZWJ1ZyBmdW5jdGlvbnMJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmZGVmIExJQlhNTF9PVVRQVVRfRU5BQkxFRAoKLyoqCiAqIHhtbFNjaGVtYUVsZW1lbnREdW1wOgogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKgogKiBEdW1wIHRoZSBlbGVtZW50CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFbGVtZW50RHVtcCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sIEZJTEUgKiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlIEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChlbGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fUkVGKSB7CglmcHJpbnRmKG91dHB1dCwgIlBhcnRpY2xlOiAlcyIsIG5hbWUpOwoJZnByaW50ZihvdXRwdXQsICIsIHRlcm0gZWxlbWVudDogJXMiLCBlbGVtLT5yZWYpOwoJaWYgKGVsZW0tPnJlZk5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICIgbnMgJXMiLCBlbGVtLT5yZWZOcyk7CiAgICB9IGVsc2UgewoJZnByaW50ZihvdXRwdXQsICJFbGVtZW50Iik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIiAoZ2xvYmFsKSIpOwoJZnByaW50ZihvdXRwdXQsICI6ICVzICIsIGVsZW0tPm5hbWUpOwoJaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAibnMgJXMiLCBuYW1lc3BhY2UpOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKChlbGVtLT5taW5PY2N1cnMgIT0gMSkgfHwgKGVsZW0tPm1heE9jY3VycyAhPSAxKSkgewoJZnByaW50ZihvdXRwdXQsICIgIG1pbiAlZCAiLCBlbGVtLT5taW5PY2N1cnMpOwogICAgICAgIGlmIChlbGVtLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogdW5ib3VuZGVkXG4iKTsKICAgICAgICBlbHNlIGlmIChlbGVtLT5tYXhPY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6ICVkXG4iLCBlbGVtLT5tYXhPY2N1cnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgLyoKICAgICogTWlzYyBvdGhlciBwcm9wZXJ0aWVzLgogICAgKi8KICAgIGlmICgoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSB8fAoJKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkgfHwKCShlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpIHx8CgkoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0RFRkFVTFQpIHx8CgkoZWxlbS0+aWQgIT0gTlVMTCkpIHsKCWZwcmludGYob3V0cHV0LCAiICBwcm9wczogIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2ZpeGVkXSAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fREVGQVVMVCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltkZWZhdWx0XSAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpCgkgICAgZnByaW50ZihvdXRwdXQsICJbYWJzdHJhY3RdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltuaWxsYWJsZV0gIik7CglpZiAoZWxlbS0+aWQgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltpZDogJyVzJ10gIiwgZWxlbS0+aWQpOwoJZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgLyoKICAgICogRGVmYXVsdC9maXhlZCB2YWx1ZS4KICAgICovCiAgICBpZiAoZWxlbS0+dmFsdWUgIT0gTlVMTCkKCWZwcmludGYob3V0cHV0LCAiICB2YWx1ZTogJyVzJ1xuIiwgZWxlbS0+dmFsdWUpOwogICAgLyoKICAgICogVHlwZS4KICAgICovCiAgICBpZiAoZWxlbS0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiICB0eXBlOiAlcyAiLCBlbGVtLT5uYW1lZFR5cGUpOwoJaWYgKGVsZW0tPm5hbWVkVHlwZU5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJucyAlc1xuIiwgZWxlbS0+bmFtZWRUeXBlTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIC8qCiAgICAqIFN1YnN0aXR1dGlvbiBncm91cC4KICAgICovCiAgICBpZiAoZWxlbS0+c3Vic3RHcm91cCAhPSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgc3Vic3RpdHV0aW9uR3JvdXA6ICVzICIsIGVsZW0tPnN1YnN0R3JvdXApOwoJaWYgKGVsZW0tPnN1YnN0R3JvdXBOcyAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAibnMgJXNcbiIsIGVsZW0tPnN1YnN0R3JvdXBOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQW5ub3REdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBhbm5vdDogIGEgYW5ub3RhdGlvbgogKgogKiBEdW1wIHRoZSBhbm5vdGF0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBbm5vdER1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIHhtbENoYXIgKmNvbnRlbnQ7CgogICAgaWYgKGFubm90ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGNvbnRlbnQgPSB4bWxOb2RlR2V0Q29udGVudChhbm5vdC0+Y29udGVudCk7CiAgICBpZiAoY29udGVudCAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIEFubm90OiAlc1xuIiwgY29udGVudCk7CiAgICAgICAgeG1sRnJlZShjb250ZW50KTsKICAgIH0gZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogZW1wdHlcbiIpOwp9CgovKioKICogeG1sU2NoZW1hVHlwZUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHR5cGU6ICBhIHR5cGUgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWFUeXBlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcCh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSwgRklMRSAqIG91dHB1dCwgaW50IGRlcHRoKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgdGVybTsKICAgIGNoYXIgc2hpZnRbMTAwXTsKICAgIGludCBpOwoKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJcmV0dXJuOwogICAgZm9yIChpID0gMDsoKGkgPCBkZXB0aCkgJiYgKGkgPCAyNSkpO2krKykKICAgICAgICBzaGlmdFsyICogaV0gPSBzaGlmdFsyICogaSArIDFdID0gJyAnOwogICAgc2hpZnRbMiAqIGldID0gc2hpZnRbMiAqIGkgKyAxXSA9IDA7CiAgICBmcHJpbnRmKG91dHB1dCwgc2hpZnQpOwogICAgaWYgKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIk1JU1NJTkcgcGFydGljbGUgdGVybVxuIik7CglyZXR1cm47CiAgICB9CiAgICB0ZXJtID0gcGFydGljbGUtPmNoaWxkcmVuOwogICAgc3dpdGNoICh0ZXJtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIGZwcmludGYob3V0cHV0LCAiRUxFTSAnJXMnIiwgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkoKHhtbFNjaGVtYUVsZW1lbnRQdHIpdGVybSktPnRhcmdldE5hbWVzcGFjZSwKCQkoKHhtbFNjaGVtYUVsZW1lbnRQdHIpdGVybSktPm5hbWUpKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJICAgIGZwcmludGYob3V0cHV0LCAiU0VRVUVOQ0UiKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICBmcHJpbnRmKG91dHB1dCwgIkNIT0lDRSIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJICAgIGZwcmludGYob3V0cHV0LCAiQUxMIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkgICAgZnByaW50ZihvdXRwdXQsICJBTlkiKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgZnByaW50ZihvdXRwdXQsICJVTktOT1dOXG4iKTsKCSAgICByZXR1cm47CiAgICB9CiAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyAhPSAxKQoJZnByaW50ZihvdXRwdXQsICIgbWluOiAlZCIsIHBhcnRpY2xlLT5taW5PY2N1cnMpOwogICAgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQoJZnByaW50ZihvdXRwdXQsICIgbWF4OiB1bmJvdW5kZWQiKTsKICAgIGVsc2UgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgIT0gMSkKCWZwcmludGYob3V0cHV0LCAiIG1heDogJWQiLCBwYXJ0aWNsZS0+bWF4T2NjdXJzKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgoKHRlcm0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB8fAoJKHRlcm0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgfHwKCSh0ZXJtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpKSAmJgoJKHRlcm0tPmNoaWxkcmVuICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgdGVybS0+Y2hpbGRyZW4sCgkgICAgb3V0cHV0LCBkZXB0aCArMSk7CiAgICB9CiAgICBpZiAocGFydGljbGUtPm5leHQgIT0gTlVMTCkKCXhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXAoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+bmV4dCwKCQlvdXRwdXQsIGRlcHRoKTsKfQovKioKICogeG1sU2NoZW1hVHlwZUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHR5cGU6ICBhIHR5cGUgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWFUeXBlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUR1bXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBGSUxFICogb3V0cHV0KQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlR5cGU6ICIpOwogICAgaWYgKHR5cGUtPm5hbWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzICIsIHR5cGUtPm5hbWUpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gbmFtZSAiKTsKICAgIGlmICh0eXBlLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYob3V0cHV0LCAibnMgJXMgIiwgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltiYXNpY10gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2ltcGxlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbY29tcGxleF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltzZXF1ZW5jZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbY2hvaWNlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlthbGxdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbdXJdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbcmVzdHJpY3Rpb25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2V4dGVuc2lvbl0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Vua25vd24gdHlwZSAlZF0gIiwgdHlwZS0+dHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJjb250ZW50OiAiKTsKICAgIHN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlt1bmtub3duXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2VtcHR5XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2VsZW1lbnRdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbbWl4ZWRdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKCS8qIG5vdCB1c2VkLiAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYmFzaWNdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3NpbXBsZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0FOWToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYW55XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIGJhc2UgdHlwZTogJXMiLCB0eXBlLT5iYXNlKTsKCWlmICh0eXBlLT5iYXNlTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIiBucyAlc1xuIiwgdHlwZS0+YmFzZU5zKTsKCWVsc2UKCSAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFBbm5vdER1bXAob3V0cHV0LCB0eXBlLT5hbm5vdCk7CiNpZmRlZiBEVU1QX0NPTlRFTlRfTU9ERUwKICAgIGlmICgodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCSh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSkgewoJeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzLAoJICAgIG91dHB1dCwgMSk7CiAgICB9CiNlbmRpZgp9CgovKioKICogeG1sU2NoZW1hRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAc2NoZW1hOiAgYSBzY2hlbWEgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWEgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFEdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChvdXRwdXQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoc2NoZW1hID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6IE5VTExcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiU2NoZW1hczogIik7CiAgICBpZiAoc2NoZW1hLT5uYW1lICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcywgIiwgc2NoZW1hLT5uYW1lKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIG5hbWUsICIpOwogICAgaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcyIsIChjb25zdCBjaGFyICopIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIHRhcmdldCBuYW1lc3BhY2UiKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmIChzY2hlbWEtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hQW5ub3REdW1wKG91dHB1dCwgc2NoZW1hLT5hbm5vdCk7CgogICAgeG1sSGFzaFNjYW4oc2NoZW1hLT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFUeXBlRHVtcCwKICAgICAgICAgICAgICAgIG91dHB1dCk7CiAgICB4bWxIYXNoU2NhbkZ1bGwoc2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFFbGVtZW50RHVtcCwgb3V0cHV0KTsKfQoKI2lmZGVmIERFQlVHX0lEQwovKioKICogeG1sU2NoZW1hRGVidWdEdW1wSURDVGFibGU6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRGlzcGxheXMgdGhlIGN1cnJlbnQgSURDIHRhYmxlIGZvciBkZWJ1ZyBwdXJwb3Nlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlKEZJTEUgKiBvdXRwdXQsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSwKCQkJICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKnZhbHVlOwogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgdGFiOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXk7CiAgICBpbnQgaSwgaiwgcmVzOwoKICAgIGZwcmludGYob3V0cHV0LCAiSURDOiBUQUJMRVMgb24gJXNcbiIsCgl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBuYW1lc3BhY2VOYW1lLCBsb2NhbE5hbWUpKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyKQoKICAgIGlmIChiaW5kID09IE5VTEwpCglyZXR1cm47CiAgICBkbyB7CglmcHJpbnRmKG91dHB1dCwgIklEQzogICBCSU5ESU5HICVzXG4iLAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJpbmQtPmRlZmluaXRpb24tPnRhcmdldE5hbWVzcGFjZSwKCSAgICBiaW5kLT5kZWZpbml0aW9uLT5uYW1lKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCWZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCSAgICB0YWIgPSBiaW5kLT5ub2RlVGFibGVbaV07CgkgICAgZnByaW50ZihvdXRwdXQsICIgICAgICAgICAoICIpOwoJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaisrKSB7CgkJa2V5ID0gdGFiLT5rZXlzW2pdOwoJCWlmICgoa2V5ICE9IE5VTEwpICYmIChrZXktPnZhbCAhPSBOVUxMKSkgewoJCSAgICByZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlKGtleS0+dmFsLCAmdmFsdWUpOwoJCSAgICBpZiAocmVzID49IDApCgkJCWZwcmludGYob3V0cHV0LCAiXCIlc1wiICIsIHZhbHVlKTsKCQkgICAgZWxzZQoJCQlmcHJpbnRmKG91dHB1dCwgIkNBTk9OLVZBTFVFLUZBSUxFRCAiKTsKCQkgICAgaWYgKHJlcyA9PSAwKQoJCQlGUkVFX0FORF9OVUxMKHZhbHVlKQoJCX0gZWxzZSBpZiAoa2V5ICE9IE5VTEwpCgkJICAgIGZwcmludGYob3V0cHV0LCAiKG5vIHZhbCksICIpOwoJCWVsc2UKCQkgICAgZnByaW50ZihvdXRwdXQsICIoa2V5IG1pc3NpbmcpLCAiKTsKCSAgICB9CgkgICAgZnByaW50ZihvdXRwdXQsICIpXG4iKTsKCX0KCWJpbmQgPSBiaW5kLT5uZXh0OwogICAgfSB3aGlsZSAoYmluZCAhPSBOVUxMKTsKfQojZW5kaWYgLyogREVCVUdfSURDICovCiNlbmRpZiAvKiBMSUJYTUxfT1VUUFVUX0VOQUJMRUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCVV0aWxpdGllcwkJCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFHZXRQcm9wTm9kZToKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogU2Vla3MgYW4gYXR0cmlidXRlIHdpdGggYSBuYW1lIG9mIEBuYW1lIGluCiAqIG5vIG5hbWVzcGFjZS4KICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIG9yIE5VTEwgaWYgbm90IHByZXNlbnQuCiAqLwpzdGF0aWMgeG1sQXR0clB0cgp4bWxTY2hlbWFHZXRQcm9wTm9kZSh4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbEF0dHJQdHIgcHJvcDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCglyZXR1cm4oTlVMTCk7CiAgICBwcm9wID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChwcm9wICE9IE5VTEwpIHsKICAgICAgICBpZiAoKHByb3AtPm5zID09IE5VTEwpICYmIHhtbFN0ckVxdWFsKHByb3AtPm5hbWUsIEJBRF9DQVNUIG5hbWUpKQoJICAgIHJldHVybihwcm9wKTsKCXByb3AgPSBwcm9wLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3BOb2RlTnM6CiAqIEBub2RlOiB0aGUgZWxlbWVudCBub2RlCiAqIEB1cmk6IHRoZSB1cmkKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogU2Vla3MgYW4gYXR0cmlidXRlIHdpdGggYSBsb2NhbCBuYW1lIG9mIEBuYW1lIGFuZAogKiBhIG5hbWVzcGFjZSBVUkkgb2YgQHVyaS4KICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIG9yIE5VTEwgaWYgbm90IHByZXNlbnQuCiAqLwpzdGF0aWMgeG1sQXR0clB0cgp4bWxTY2hlbWFHZXRQcm9wTm9kZU5zKHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqdXJpLCBjb25zdCBjaGFyICpuYW1lKQp7CiAgICB4bWxBdHRyUHRyIHByb3A7CgogICAgaWYgKChub2RlID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQoJcmV0dXJuKE5VTEwpOwogICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CglpZiAoKHByb3AtPm5zICE9IE5VTEwpICYmCgkgICAgeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgQkFEX0NBU1QgbmFtZSkgJiYKCSAgICB4bWxTdHJFcXVhbChwcm9wLT5ucy0+aHJlZiwgQkFEX0NBU1QgdXJpKSkKCSAgICByZXR1cm4ocHJvcCk7Cglwcm9wID0gcHJvcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKCXZhbCA9IHhtbFN0cmR1cCgoeG1sQ2hhciAqKSIiKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3A6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBub2RlCiAqIEBuYW1lOiB0aGUgcHJvcGVydHkgbmFtZQogKgogKiBSZWFkIGEgYXR0cmlidXRlIHZhbHVlIGFuZCBpbnRlcm5hbGl6ZSB0aGUgc3RyaW5nCiAqCiAqIFJldHVybnMgdGhlIHN0cmluZyBvciBOVUxMIGlmIG5vdCBwcmVzZW50LgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRQcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxHZXRQcm9wKG5vZGUsIEJBRF9DQVNUIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybihOVUxMKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUdldEVsZW06CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGNvbnRleHQKICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCiAqIEBuczogIHRoZSBlbGVtZW50IG5hbWVzcGFjZQogKgogKiBMb29rdXAgYSBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbiBpbiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hR2V0RWxlbSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfSBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICAqIFRoaXMgb25lIHdhcyByZW1vdmVkLCBzaW5jZSB0b3AgbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbnMgaGF2ZQogICAgICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugc3BlY2lmaWVkIGluIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgPHNjaGVtYT4KICAgICAqIGluZm9ybWF0aW9uIGVsZW1lbnQsIGV2ZW4gaWYgZWxlbWVudEZvcm1EZWZhdWx0IGlzICJ1bnF1YWxpZmllZCIuCiAgICAgKi8KCiAgICAvKiBlbHNlIGlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKSA9PSAwKSB7CiAgICAgICAgaWYgKHhtbFN0ckVxdWFsKG5hbWVzcGFjZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpKQoJICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsIE5VTEwpOwoJZWxzZQoJICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICAgICAgaWYgKChyZXQgIT0gTlVMTCkgJiYKCSAgICAoKGxldmVsID09IDApIHx8IChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9UT1BMRVZFTCkpKSB7CiAgICAgICAgICAgIHJldHVybiAocmV0KTsKCX0KICAgICovCgogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0RWxlbShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlLCBsZXZlbCArIDEpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBlbGVtZW50IGRlY2wuICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZWxlbWVudCBkZWNsLiAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRUeXBlOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMgY29udGV4dAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5zOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIHR5cGUgaW4gdGhlIHNjaGVtYXMgb3IgdGhlIHByZWRlZmluZWQgdHlwZXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFR5cGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQ7CgogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hR2V0UHJlZGVmaW5lZFR5cGUobmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmIChyZXQgIT0gTlVMTCkKCXJldHVybiAocmV0KTsKICAgIC8qCiAgICAqIFJlbW92ZWQsIHNpbmNlIHRoZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgZ3JhZnRlZCBvbiB0aGUKICAgICogbWFpbiBzY2hlbWEgb25seS4KICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0VHlwZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlRGVjbDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2woeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKCiAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7CiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCwgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2woaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5hdHRyZ3JwRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7CiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXAoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpKQoJICAgIHJldHVybiAocmV0KTsKCWVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgZ3JvdXAgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0R3JvdXA6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGdyb3VwCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBncm91cAogKgogKiBMb29rdXAgYSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5ncm91cERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICAvKgogICAgKiBSZW1vdmVkIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQoJICAgIHJldHVybiAocmV0KTsKCWVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE5hbWVkQ29tcG9uZW50OgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgZ3JvdXAKICoKICogTG9va3VwIGEgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHJlZUl0ZW1QdHIKeG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgeG1sU2NoZW1hVHlwZVR5cGUgaXRlbVR5cGUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5zKQp7CiAgICBzd2l0Y2ggKGl0ZW1UeXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgeG1sU2NoZW1hR2V0R3JvdXAoc2NoZW1hLAoJCW5hbWUsIHRhcmdldE5zKSk7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybiAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB4bWxTY2hlbWFHZXRFbGVtKHNjaGVtYSwKCQluYW1lLCB0YXJnZXROcykpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gKE5VTEwpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUGFyc2luZyBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIElTX0JMQU5LX05PREUobikJCQkJCQlcCiAgICAoKChuKS0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoeG1sU2NoZW1hSXNCbGFuaygobiktPmNvbnRlbnQsIC0xKSkpCgovKioKICogeG1sU2NoZW1hSXNCbGFuazoKICogQHN0cjogIGEgc3RyaW5nCiAqIEBsZW46IHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBvciAtMQogKgogKiBDaGVjayBpZiBhIHN0cmluZyBpcyBpZ25vcmFibGUKICoKICogUmV0dXJucyAxIGlmIHRoZSBzdHJpbmcgaXMgTlVMTCBvciBtYWRlIG9mIGJsYW5rcyBjaGFycywgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNCbGFuayh4bWxDaGFyICogc3RyLCBpbnQgbGVuKQp7CiAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgxKTsKICAgIGlmIChsZW4gPCAwKSB7Cgl3aGlsZSAoKnN0ciAhPSAwKSB7CgkgICAgaWYgKCEoSVNfQkxBTktfQ0goKnN0cikpKQoJCXJldHVybiAoMCk7CgkgICAgc3RyKys7Cgl9CiAgICB9IGVsc2Ugd2hpbGUgKCgqc3RyICE9IDApICYmIChsZW4gIT0gMCkpIHsKCWlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKCSAgICByZXR1cm4gKDApOwoJc3RyKys7CglsZW4tLTsKICAgIH0KICAgIAogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW06CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQGl0ZW06ICB0aGUgaXRlbQogKgogKiBBZGQgYSBpdGVtIHRvIHRoZSBzY2hlbWEncyBsaXN0IG9mIGN1cnJlbnQgaXRlbXMuCiAqIFRoaXMgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHdhcyBhbHJlYWR5IGNvbnN0cnVjdGVkIGFuZAogKiBuZXcgc2NoZW1hdGEgbmVlZCB0byBiZSBhZGRlZCB0byBpdC4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2VlZHMgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSkKewogICAgc3RhdGljIGludCBncm93U2l6ZSA9IDEwMDsKICAgIHhtbFNjaGVtYUFzc2VtYmxlUHRyIGFzczsKCiAgICBhc3MgPSBjdHh0LT5hc3NlbWJsZTsKICAgIGlmIChhc3MtPnNpemVJdGVtcyA8IDApIHsKCS8qIElmIGRpc2FibGVkLiAqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGlmIChhc3MtPnNpemVJdGVtcyA8PSAwKSB7Cglhc3MtPml0ZW1zID0gKHZvaWQgKiopIHhtbE1hbGxvYyhncm93U2l6ZSAqIHNpemVvZih4bWxTY2hlbWFUeXBlUHRyKSk7CglpZiAoYXNzLT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LAoJCSJhbGxvY2F0aW5nIG5ldyBpdGVtIGJ1ZmZlciIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJYXNzLT5zaXplSXRlbXMgPSBncm93U2l6ZTsKICAgIH0gZWxzZSBpZiAoYXNzLT5zaXplSXRlbXMgPD0gYXNzLT5uYkl0ZW1zKSB7Cglhc3MtPnNpemVJdGVtcyAqPSAyOwoJYXNzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxSZWFsbG9jKGFzcy0+aXRlbXMsCgkgICAgYXNzLT5zaXplSXRlbXMgKiBzaXplb2YoeG1sU2NoZW1hVHlwZVB0cikpOwoJaWYgKGFzcy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCQkiZ3Jvd2luZyBpdGVtIGJ1ZmZlciIsIE5VTEwpOwoJICAgIGFzcy0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIGFzcy0+aXRlbXNbYXNzLT5uYkl0ZW1zKytdID0gKHZvaWQgKikgaXRlbTsgKi8KICAgICgoeG1sU2NoZW1hVHlwZVB0ciAqKSBhc3MtPml0ZW1zKVthc3MtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBpdGVtOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBhbm5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYUFkZE5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sU2NoZW1hTm90YXRpb25QdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+bm90YURlY2wgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGQgYW5ub3RhdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPm5vdGFEZWNsLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJLyoKCSogVE9ETzogVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBzaW5jZSBhIHVuaXF1ZSBuYW1lIHdpbGwgYmUgY29tcHV0ZWQuCgkqIElmIGl0IGZhaWxzLCB0aGVuIGFuIG90aGVyIGludGVybmFsIGVycm9yIG11c3QgaGF2ZSBvY2N1cmVkLgoJKi8KCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9SRURFRklORURfTk9UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAiQW5ub3RhdGlvbiBkZWNsYXJhdGlvbiAnJXMnIGlzIGFscmVhZHkgZGVjbGFyZWQuXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hQWRkQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UsCgkJICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBhdHRyaWJ1dGUgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5hdHRyRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5hbWVzcGFjZTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCWlmICh0b3BMZXZlbCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfQVRUUiwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJBIGdsb2JhbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgIgoJCSJhbHJlYWR5IGV4aXN0IiwgbmFtZSk7CgkgICAgeG1sRnJlZShyZXQpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgewoJICAgIGNoYXIgYnVmWzMwXTsKCSAgICAvKgoJICAgICogVXNpbmcgdGhlIGN0eHQtPmNvbnRhaW5lciBmb3IgeG1sSGFzaEFkZEVudHJ5MyBpcyBhbWJpZ2lvdXMKCSAgICAqIGluIHRoZSBzY2VuYXJpbzoKCSAgICAqIDEuIG11bHRpcGxlIHRvcC1sZXZlbCBjb21wbGV4IHR5cGVzIGhhdmUgZGlmZmVyZW50IHRhcmdldAoJICAgICogICAgbmFtZXNwYWNlcyBidXQgaGF2ZSB0aGUgU0FNRSBOQU1FOyB0aGlzIGNhbiBoYXBwZW4gaWYKCSAgICAqCSBzY2hlbWF0YSBhcmUgIGltcG9ydGVkCgkgICAgKiAyLiB0aG9zZSBjb21wbGV4IHR5cGVzIGNvbnRhaW4gYXR0cmlidXRlcyB3aXRoIGFuIGVxdWFsIG5hbWUKCSAgICAqIDMuIHRob3NlIGF0dHJpYnV0ZXMgYXJlIGluIG5vIG5hbWVzcGFjZQoJICAgICogV2Ugd2lsbCBjb21wdXRlIGEgbmV3IGNvbnRleHQgc3RyaW5nLgoJICAgICovCgkgICAgc25wcmludGYoYnVmLCAyOSwgIiNhQ29udCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgkgICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLAoJCW5hbWVzcGFjZSwgeG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCBidWYsIC0xKSwgcmV0KTsKCgkgICAgaWYgKHZhbCAhPSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUsICIKCQkgICAgImEgZHVibGljYXRlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiB3aXRoIHRoZSBuYW1lICclcycgIgoJCSAgICAiY291bGQgbm90IGJlIGFkZGVkIHRvIHRoZSBoYXNoLiIsIG5hbWUpOwoJCXhtbEZyZWUocmV0KTsKCQlyZXR1cm4gKE5VTEwpOwoJICAgIH0KCX0KICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIEdyb3VwIGRlY2xhcmF0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAoJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmF0dHJncnBEZWNsID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9CiAgICAgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKQogICAgICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cCkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfQVRUUkdST1VQLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkEgZ2xvYmFsIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzIGFscmVhZHkgZXhpc3QiLCBuYW1lKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgdHlwZSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgRWxlbWVudCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUFkZEVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBlbGVtZW50ICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+ZWxlbURlY2wgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCWlmICh0b3BMZXZlbCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfRUxFTUVOVCwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJBIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzICIKCQkiYWxyZWFkeSBleGlzdCIsIG5hbWUpOwogICAgICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgewoJICAgIGNoYXIgYnVmWzMwXTsKCgkgICAgc25wcmludGYoYnVmLCAyOSwgIiNlQ29udCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgkgICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLAoJCW5hbWVzcGFjZSwgKHhtbENoYXIgKikgYnVmLCByZXQpOwoJICAgIGlmICh2YWwgIT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkRWxlbWVudCwgIgoJCSAgICAiYSBkdWJsaWNhdGUgZWxlbWVudCBkZWNsYXJhdGlvbiB3aXRoIHRoZSBuYW1lICclcycgIgoJCSAgICAiY291bGQgbm90IGJlIGFkZGVkIHRvIHRoZSBoYXNoLiIsIG5hbWUpOwoJCXhtbEZyZWUocmV0KTsKCQlyZXR1cm4gKE5VTEwpOwoJICAgIH0KCX0KCiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBpdGVtCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hQWRkVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UsCgkJIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyB0eXBlICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+dHlwZURlY2wgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVR5cGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyB0eXBlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+cmVkZWYgPSBOVUxMOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKICAgICAgICBpZiAoY3R4dC0+aW5jbHVkZXMgPT0gMCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfVFlQRSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJBIGdsb2JhbCB0eXBlIGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIG5hbWUpOwoJICAgIHhtbEZyZWUocmV0KTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIHByZXY7CgoJICAgIHByZXYgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwoJICAgIGlmIChwcmV2ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgIFhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkVHlwZSwgb24gdHlwZSAiCgkJICAgICInJXMnLlxuIiwKCQkgICAgbmFtZSwgTlVMTCk7CgkJeG1sRnJlZShyZXQpOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIHJldC0+cmVkZWYgPSBwcmV2LT5yZWRlZjsKCSAgICBwcmV2LT5yZWRlZiA9IHJldDsKCX0KICAgIH0KICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CiAgICByZXQtPmF0dHJpYnV0ZVVzZXMgPSBOVUxMOwogICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IE5VTEw7CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCxyZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hTmV3UU5hbWVSZWYoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJICAgICBjb25zdCB4bWxDaGFyICpyZWZOYW1lLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqcmVmTnMpCnsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVFOYW1lUmVmKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgUU5hbWUgcmVmZXJlbmNlIGl0ZW0iLAoJICAgIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY7CiAgICByZXQtPm5hbWUgPSByZWZOYW1lOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSByZWZOczsKICAgIHJldC0+aXRlbSA9IE5VTEw7CiAgICByZXQtPml0ZW1UeXBlID0gcmVmVHlwZTsKICAgIC8qCiAgICAqIFN0b3JlIHRoZSByZWZlcmVuY2UgaXRlbSBpbiB0aGUgc2NoZW1hLgogICAgKi8KICAgIHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE1vZGVsR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQHR5cGU6IHRoZSAiY29tcG9zaXRvciIgdHlwZSBvZiB0aGUgbW9kZWwgZ3JvdXAKICogQGNvbnRhaW5lcjogIHRoZSBpbnRlcm5hbCBjb21wb25lbnQgbmFtZQogKiBAbm9kZTogdGhlIG5vZGUgaW4gdGhlIHNjaGVtYSBkb2MKICoKICogQWRkcyBhIHNjaGVtYSBtb2RlbCBncm91cAogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyCnhtbFNjaGVtYUFkZE1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLCBjb25zdCB4bWxDaGFyICoqY29udGFpbmVyLAoJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgcmV0ID0gTlVMTDsKICAgIHhtbENoYXIgYnVmWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBtb2RlbCBncm91cCBjb21wb25lbnRcbiIpOwojZW5kaWYKICAgIHJldCA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgbW9kZWwgZ3JvdXAgY29tcG9uZW50IiwKCSAgICBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5hbm5vdCA9IE5VTEw7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgcmV0LT5jaGlsZHJlbiA9IE5VTEw7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB7CglpZiAoY29udGFpbmVyICE9IE5VTEwpCgkgICAgc25wcmludGYoKGNoYXIgKikgYnVmLCAyOSwgIiNzZXElZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgfSBlbHNlIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWlmIChjb250YWluZXIgIT0gTlVMTCkKCSAgICBzbnByaW50ZigoY2hhciAqKSBidWYsIDI5LCAiI2NobyVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB9IGVsc2UgewoJaWYgKGNvbnRhaW5lciAhPSBOVUxMKQoJICAgIHNucHJpbnRmKChjaGFyICopIGJ1ZiwgMjksICIjYWxsJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIH0KICAgIGlmIChjb250YWluZXIgIT0gTlVMTCkKCSpjb250YWluZXIgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUIGJ1ZiwgLTEpOwogICAgLyoKICAgICogQWRkIHRvIHZvbGF0aWxlIGl0ZW1zLgogICAgKiBUT0RPOiB0aGlzIHNob3VsZCBiZSBjaGFuZ2VkIHNvbWVkYXkuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KSAhPSAwKSB7Cgl4bWxGcmVlKHJldCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUFkZFBhcnRpY2xlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiB0aGUgY29ycmVzcG9uZGluZyBub2RlIGluIHRoZSBzY2hlbWEgZG9jCiAqIEBtaW46IHRoZSBtaW5PY2N1cnMKICogQG1heDogdGhlIG1heE9jY3VycwogKgogKiBBZGRzIGFuIFhNTCBzY2hlbWEgcGFydGljbGUgY29tcG9uZW50LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJ0aWNsZVB0cgp4bWxTY2hlbWFBZGRQYXJ0aWNsZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCBtaW4sIGludCBtYXgpCnsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHJldCA9IE5VTEw7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBwYXJ0aWNsZSBjb21wb25lbnRcbiIpOwojZW5kaWYKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFydGljbGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBwYXJ0aWNsZSBjb21wb25lbnQiLAoJICAgIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRTsKICAgIHJldC0+YW5ub3QgPSBOVUxMOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIHJldC0+bWluT2NjdXJzID0gbWluOwogICAgcmV0LT5tYXhPY2N1cnMgPSBtYXg7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgcmV0LT5jaGlsZHJlbiA9IE5VTEw7CgogICAgaWYgKHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KSAhPSAwKSB7Cgl4bWxGcmVlKHJldCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGdyb3VwIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cgp4bWxTY2hlbWFBZGRHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUsCgkJICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmdyb3VwRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTW9kZWxHcm91cERlZikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5hbWVzcGFjZU5hbWU7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+Z3JvdXBEZWNsLCByZXQtPm5hbWUsIG5hbWVzcGFjZU5hbWUsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfR1JPVVAsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiQSBnbG9iYWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5ICIKCSAgICAiZXhpc3QiLCBuYW1lKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1dpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyCnhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkTnMpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogYSBzY2hlbWEKICoKICogQWRkcyBhIHdpbGRjYXJkLgogKiBJdCBjb3JyZXNwb25kcyB0byBhIHhzZDphbnlBdHRyaWJ1dGUgYW5kIHhzZDphbnkuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFBZGRXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgd2lsZGNhcmQgY29tcG9uZW50XG4iKTsKI2VuZGlmCgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgd2lsZGNhcmQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwoKICAgIGlmICh4bWxTY2hlbWFBZGRWb2xhdGlsZShzY2hlbWEsICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHJldCkgIT0gMCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiRmFpbGVkIHRvIGFkZCBhIHdpbGRjYXJkIGNvbXBvbmVudCB0byB0aGUgbGlzdCIsIE5VTEwpOwoJeG1sRnJlZShyZXQpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqCQlVdGlsaXRpZXMgZm9yIHBhcnNpbmcJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAKLyoqCiAqIHhtbEdldFFOYW1lUHJvcDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHJlc3VsdCBuYW1lc3BhY2UgaWYgYW55CiAqCiAqIEV4dHJhY3QgYSBRTmFtZSBBdHRyaWJ1dGUgdmFsdWUKICoKICogUmV0dXJucyB0aGUgTkNOYW1lIG9yIE5VTEwgaWYgbm90IGZvdW5kLCBhbmQgYWxzbyB1cGRhdGUgQG5hbWVzcGFjZQogKiAgICB3aXRoIHRoZSBuYW1lc3BhY2UgVVJJCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbEdldFFOYW1lUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICB4bWxOc1B0ciBuczsKICAgIGNvbnN0IHhtbENoYXIgKnJldCwgKnByZWZpeDsKICAgIGludCBsZW47CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWwsICc6JykpIHsKCW5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCAwKTsKCWlmIChucykgewoJICAgICpuYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zLT5ocmVmLCAtMSk7CgkgICAgcmV0dXJuICh2YWwpOwoJfQogICAgfQogICAgcmV0ID0geG1sU3BsaXRRTmFtZTModmFsLCAmbGVuKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAodmFsKTsKICAgIH0KICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgcmV0LCAtMSk7CiAgICBwcmVmaXggPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgbGVuKTsKCiAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKICAgIGlmIChucyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIE5VTEwsIHZhbCwKCSAgICAiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlICIKCSAgICAiZGVjbGFyYXRpb24gaW4gc2NvcGUiLCB2YWwsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgcGFyZW50IGFzIGEgc2NoZW1hIG9iamVjdAogKiBAdmFsdWU6ICB0aGUgUU5hbWUgdmFsdWUKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgdGhlIGxvY2FsIG5hbWUgYW5kIHRoZSBVUkkgb2YgYSBRTmFtZSB2YWx1ZSBhbmQgdmFsaWRhdGVzIGl0LgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9uIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdAogKiBzaG91bGQgcmVzb2x2ZSB0byBzY2hlbWEgY29tcG9uZW50cy4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICAgIHhtbENoYXIgKipvd25lckRlcyBBVFRSSUJVVEVfVU5VU0VELAoJCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKipsb2NhbCkKewogICAgY29uc3QgeG1sQ2hhciAqcHJlZjsKICAgIHhtbE5zUHRyIG5zOwogICAgaW50IGxlbiwgcmV0OwoKICAgICp1cmkgPSBOVUxMOwogICAgKmxvY2FsID0gTlVMTDsKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA+IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCSAgICBOVUxMLCB2YWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkqbG9jYWwgPSB2YWx1ZTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSBpZiAocmV0IDwgMCkKCXJldHVybiAoLTEpOwoKICAgIGlmICghc3RyY2hyKChjaGFyICopIHZhbHVlLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCAwKTsKCWlmIChucykKCSAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSB7CgkgICAgLyoKCSAgICAqIFRoaXMgb25lIHRha2VzIGNhcmUgb2YgaW5jbHVkZWQgc2NoZW1hcyB3aXRoIG5vCgkgICAgKiB0YXJnZXQgbmFtZXNwYWNlLgoJICAgICovCgkgICAgKnVyaSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfQoJKmxvY2FsID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWx1ZSwgLTEpOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIEF0IHRoaXMgcG9pbnQgeG1sU3BsaXRRTmFtZTMgaGFzIHRvIHJldHVybiBhIGxvY2FsIG5hbWUuCiAgICAqLwogICAgKmxvY2FsID0geG1sU3BsaXRRTmFtZTModmFsdWUsICZsZW4pOwogICAgKmxvY2FsID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCAqbG9jYWwsIC0xKTsKICAgIHByZWYgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbHVlLCBsZW4pOwogICAgbnMgPSB4bWxTZWFyY2hOcyhhdHRyLT5kb2MsIGF0dHItPnBhcmVudCwgcHJlZik7CiAgICBpZiAobnMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCBOVUxMLCB2YWx1ZSwKCSAgICAiVGhlIHZhbHVlICclcycgb2Ygc2ltcGxlIHR5cGUgJ3hzOlFOYW1lJyBoYXMgbm8gIgoJICAgICJjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiBzY29wZSIsIHZhbHVlLCBOVUxMKTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKnVyaSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyIGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgbm9kZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIHRoZSBRTmFtZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb24gYXR0cmlidXRlIHZhbHVlcyB0aGF0CiAqIHNob3VsZCByZXNvbHZlIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICAgIHhtbENoYXIgKipvd25lckRlcywKCQkJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJCSAgICAgICB4bWxBdHRyUHRyIGF0dHIsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKGN0eHQsIHNjaGVtYSwKCW93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsIHZhbHVlLCB1cmksIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0clFOYW1lOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIFFOYW1lIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0clFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJCSAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkJICAgY29uc3QgY2hhciAqbmFtZSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUob3duZXJFbGVtLCBuYW1lKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCSpsb2NhbCA9IE5VTEw7CgkqdXJpID0gTlVMTDsKCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwKCW93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsIHVyaSwgbG9jYWwpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRySUQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06ICB0aGUgcGFyZW50IG5vZGUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyB0aGUgSUQgb2YgYW4gYXR0cmlidXRlIHZhbHVlLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIElEIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRySUQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxDaGFyICoqb3duZXJEZXMgQVRUUklCVVRFX1VOVVNFRCwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCSAgICBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICBpbnQgcmV0OwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgdmFsdWUgPSB4bWxHZXROb05zUHJvcChvd25lckVsZW0sIG5hbWUpOwogICAgaWYgKHZhbHVlID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIChjb25zdCBjaGFyICopIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoLTEpOwoKICAgIHJldCA9IHhtbFZhbGlkYXRlTkNOYW1lKEJBRF9DQVNUIHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gMCkgewoJLyoKCSogTk9URTogdGhlIElEbmVzcyBtaWdodCBoYXZlIGFscmVhZHkgYmUgZGVjbGFyZWQgaW4gdGhlIERURAoJKi8KCWlmIChhdHRyLT5hdHlwZSAhPSBYTUxfQVRUUklCVVRFX0lEKSB7CgkgICAgeG1sSURQdHIgcmVzOwoJICAgIHhtbENoYXIgKnN0cmlwOwoKCSAgICAvKgoJICAgICogVE9ETzogVXNlIHhtbFNjaGVtYVN0cmlwIGhlcmU7IGl0J3Mgbm90IGV4cG9ydGVkIGF0IHRoaXMKCSAgICAqIG1vbWVudC4KCSAgICAqLwoJICAgIHN0cmlwID0geG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcoQkFEX0NBU1QgdmFsdWUpOwoJICAgIGlmIChzdHJpcCAhPSBOVUxMKQoJCXZhbHVlID0gc3RyaXA7CiAgICAJICAgIHJlcyA9IHhtbEFkZElEKE5VTEwsIG93bmVyRWxlbS0+ZG9jLCBCQURfQ0FTVCB2YWx1ZSwgYXR0cik7CgkgICAgaWYgKHJlcyA9PSBOVUxMKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19JRCksCgkJICAgIE5VTEwsIE5VTEwsICJEdXBsaWNhdGUgdmFsdWUgJyVzJyBvZiBzaW1wbGUgIgoJCSAgICAidHlwZSAneHM6SUQnIiwgQkFEX0NBU1QgdmFsdWUsIE5VTEwpOwoJICAgIH0gZWxzZQoJCWF0dHItPmF0eXBlID0gWE1MX0FUVFJJQlVURV9JRDsKCSAgICBpZiAoc3RyaXAgIT0gTlVMTCkKCQl4bWxGcmVlKHN0cmlwKTsKCX0KICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJcmV0ID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0lEKSwKCSAgICBOVUxMLCBOVUxMLCAiVGhlIHZhbHVlICclcycgb2Ygc2ltcGxlIHR5cGUgJ3hzOklEJyBpcyAiCgkgICAgIm5vdCBhIHZhbGlkICd4czpOQ05hbWUnIiwKCSAgICBCQURfQ0FTVCB2YWx1ZSwgTlVMTCk7CiAgICB9CiAgICB4bWxGcmVlKHZhbHVlKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxHZXRNYXhPY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtYXhPY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNYXhPY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWF4T2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewoJaWYgKG1heCAhPSBVTkJPVU5ERUQpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuIChkZWYpOwoJfSBlbHNlCgkgICAgcmV0dXJuIChVTkJPVU5ERUQpOyAgLyogZW5jb2RpbmcgaXQgd2l0aCAtMSBtaWdodCBiZSBhbm90aGVyIG9wdGlvbiAqLwogICAgfQoKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKGRlZik7CiAgICB9CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICAvKgogICAgKiBUT0RPOiBSZXN0cmljdCB0aGUgbWF4aW1hbCB2YWx1ZSB0byBJbnRlZ2VyLgogICAgKi8KICAgIGlmICgoKmN1ciAhPSAwKSB8fCAocmV0IDwgbWluKSB8fCAoKG1heCAhPSAtMSkgJiYgKHJldCA+IG1heCkpKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0TWluT2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWluT2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWluT2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAoJCWludCBtaW4sIGludCBtYXgsIGludCBkZWYsIGNvbnN0IGNoYXIgKmV4cGVjdGVkKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1pbk9jY3VycyIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoZGVmKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6ICBvd25lciBkZXNpZ25hdGlvbgogKiBAb3duZXJJdGVtOiAgdGhlIG93bmVyIGFzIGEgc2NoZW1hIGl0ZW0KICogQG5vZGU6IHRoZSBub2RlIGhvbGRpbmcgdGhlIHZhbHVlCiAqCiAqIENvbnZlcnRzIGEgYm9vbGVhbiBzdHJpbmcgdmFsdWUgaW50byAxIG9yIDAuCiAqCiAqIFJldHVybnMgMCBvciAxLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbENoYXIgKipvd25lckRlcyBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CiAgICBpbnQgcmVzID0gMDsKCiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwogICAgLyoKICAgICogMy4yLjIuMSBMZXhpY2FsIHJlcHJlc2VudGF0aW9uCiAgICAqIEFuIGluc3RhbmNlIG9mIGEgZGF0YXR5cGUgdGhhdCBpcyBkZWZpbmVkIGFzILdib29sZWFutwogICAgKiBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGxlZ2FsIGxpdGVyYWxzIHt0cnVlLCBmYWxzZSwgMSwgMH0uCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBCQURfQ0FTVCAidHJ1ZSIpKQogICAgICAgIHJlcyA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgImZhbHNlIikpCiAgICAgICAgcmVzID0gMDsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBCQURfQ0FTVCAiMSIpKQoJcmVzID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBCQURfQ0FTVCAiMCIpKQogICAgICAgIHJlcyA9IDA7CiAgICBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckl0ZW0sIG5vZGUsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQk9PTEVBTiksCgkgICAgTlVMTCwgQkFEX0NBU1QgdmFsdWUsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXMpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEV2YWx1YXRlIGlmIGEgYm9vbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqIDEgaWYgZm91bmQgdG8gYmUgdHJ1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRCb29sZWFuUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICB4bWxDaGFyICoqb3duZXJEZXMgQVRUUklCVVRFX1VOVVNFRCwKCQkgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCSAgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBpbnQgZGVmKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CgogICAgdmFsID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKGRlZik7CiAgICAvKgogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63CiAgICAqIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgbGVnYWwgbGl0ZXJhbHMge3RydWUsIGZhbHNlLCAxLCAwfS4KICAgICovCiAgICBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAidHJ1ZSIpKQogICAgICAgIGRlZiA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICJmYWxzZSIpKQogICAgICAgIGRlZiA9IDA7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICIxIikpCglkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMCIpKQogICAgICAgIGRlZiA9IDA7CiAgICBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckl0ZW0sCgkgICAgKHhtbE5vZGVQdHIpIHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsIG5hbWUpLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJICAgIE5VTEwsIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKGRlZik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKgkJU2hlbWEgZXh0cmFjdGlvbiBmcm9tIGFuIEluZm9zZXQJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgIGludCB0b3BMZXZlbCk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSAgeG1sU2NoZW1hVHlwZVR5cGUgcGFyZW50VHlwZSk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSk7CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWU6CiAqCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZSBiZWluZyB2YWxpZGF0ZWQKICogQHZhbHVlOiB0aGUgdmFsdWUKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqCiAqIFZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgIHhtbENoYXIgKipvd25lckRlcyBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJICAgeG1sQXR0clB0ciBhdHRyLAoJCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CgogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICogTk9URTogU2hvdWxkIHdlIG1vdmUgdGhpcyB0byB4bWxzY2hlbWF0eXBlcy5jPyBIbW0sIGJ1dCB0aGlzCiAgICAqIG9uZSBpcyByZWFsbHkgbWVhbnQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5LCBzbyBiZXR0ZXIgbm90LgogICAgKi8KICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkgfHwgKGF0dHIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUiLAoJICAgICJ0aGUgZ2l2ZW4gdHlwZSBpcyBub3QgYSBidWlsdC1pbiB0eXBlIik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHN3aXRjaCAodHlwZS0+YnVpbHRJblR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQVNfTkNOQU1FOgoJY2FzZSBYTUxfU0NIRU1BU19RTkFNRToKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZVVJJOgoJY2FzZSBYTUxfU0NIRU1BU19UT0tFTjoKCWNhc2UgWE1MX1NDSEVNQVNfTEFOR1VBR0U6CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGUodHlwZSwgdmFsdWUsIE5VTEwsCgkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDogewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlIiwKCQkidmFsaWRhdGlvbiB1c2luZyB0aGUgZ2l2ZW4gdHlwZSBpcyBub3Qgc3VwcG9ydGVkIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBUT0RPOiBTaG91bGQgd2UgdXNlIHRoZSBTNFMgZXJyb3IgY29kZXMgaW5zdGVhZD8KICAgICovCiAgICBpZiAocmV0IDwgMCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUiLAoJICAgICJmYWlsZWQgdG8gdmFsaWRhdGUgYSBzY2hlbWEgYXR0cmlidXRlIHZhbHVlIik7CglyZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJaWYgKFZBUklFVFlfTElTVCh0eXBlKSkKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgllbHNlCgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsIAoJICAgIHJldCwgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB0eXBlLCBOVUxMLCB2YWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGU6CiAqCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZSBiZWluZyB2YWxpZGF0ZWQKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqIEB2YWx1ZTogdGhlIHJlc3VsdGluZyB2YWx1ZSBpZiBhbnkKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbENoYXIgKipvd25lckRlcywKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICBjb25zdCB4bWxDaGFyICoqdmFsdWUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkgfHwgKGF0dHIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCSp2YWx1ZSA9IHZhbDsKCiAgICByZXR1cm4gKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIG93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsCgl2YWwsIHR5cGUpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyOgogKgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBub2RlOiB0aGUgZWxlbWVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBlbGVtZW50IG5vZGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdAogKiBAdmFsdWU6IHRoZSByZXN1bHRpbmcgdmFsdWUgaWYgYW55CiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlLgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGludGVybmFsbHkgZm9yIHZhbGlkYXRpb24KICogb2Ygc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZXMgZHVyaW5nIHBhcnNpbmcgb2YgdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0cih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgICAgIHhtbENoYXIgKipvd25lckRlcywKCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICAgICAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCSAgICAgICBjb25zdCBjaGFyICpuYW1lLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKip2YWx1ZSkKewogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgKnZhbHVlID0gTlVMTDsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICAqdmFsdWUgPSBOVUxMOwoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQVmFsQXR0ciwgdGhlIGdpdmVuICIKCSAgICAidHlwZSAnJXMnIGlzIG5vdCBhIGJ1aWx0LWluIHR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUob3duZXJFbGVtLCBuYW1lKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwKCXR5cGUsIHZhbHVlKSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICB4bWxOb2RlUHRyIG5vZGUsCgkJICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUpCnsKICAgIGlmICh4bWxTdHJFcXVhbChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbmFtZXNwYWNlTmFtZSkpCglyZXR1cm4gKDEpOwogICAgaWYgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYU5zLCBuYW1lc3BhY2VOYW1lKSkKCXJldHVybiAoMSk7CiAgICBpZiAocGN0eHQtPmxvY2FsSW1wb3J0cyAhPSBOVUxMKSB7CglpbnQgaTsKCWZvciAoaSA9IDA7IGkgPCBwY3R4dC0+bmJMb2NhbEltcG9ydHM7IGkrKykKCSAgICBpZiAoeG1sU3RyRXF1YWwobmFtZXNwYWNlTmFtZSwgcGN0eHQtPmxvY2FsSW1wb3J0c1tpXSkpCgkJcmV0dXJuICgxKTsKICAgIH0KICAgIGlmIChuYW1lc3BhY2VOYW1lID09IE5VTEwpCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgbm9kZSwKCSAgICAiUmVmZXJlbmNlcyBmcm9tIHRoaXMgc2NoZW1hIHRvIGNvbXBvbmVudHMgaW4gbm8gIgoJICAgICJuYW1lc3BhY2UgYXJlIG5vdCB2YWxpZCwgc2luY2Ugbm90IGluZGljYXRlZCBieSBhbiBpbXBvcnQgIgoJICAgICJzdGF0ZW1lbnQiLCBOVUxMKTsKICAgIGVsc2UKCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBub2RlLAoJICAgICJSZWZlcmVuY2VzIGZyb20gdGhpcyBzY2hlbWEgdG8gY29tcG9uZW50cyBpbiB0aGUgIgoJICAgICJuYW1lc3BhY2UgJyVzJyBhcmUgbm90IHZhbGlkLCBzaW5jZSBub3QgaW5kaWNhdGVkIGJ5IGFuIGltcG9ydCAiCgkgICAgInN0YXRlbWVudCIsIG5hbWVzcGFjZU5hbWUpOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqIEB0eXBlOiAgdGhlIGhvc3RpbmcgdHlwZSB3aGVyZSB0aGUgYXR0cmlidXRlcyB3aWxsIGJlIGFuY2hvcmVkCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBhdHRyRGVjbHMgZGVjbGFyYXRpb24gY29ycmVzcG9uZGluZyB0bwogKiA8IUVOVElUWSAlIGF0dHJEZWNscwogKiAgICAgICAnKCglYXR0cmlidXRlO3wgJWF0dHJpYnV0ZUdyb3VwOykqLCglYW55QXR0cmlidXRlOyk/KSc+CiAqLwpzdGF0aWMgeG1sTm9kZVB0cgp4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGxhc3RhdHRyID0gTlVMTCwgYXR0cjsKCiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSkgewogICAgICAgIGF0dHIgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgewogICAgICAgICAgICBhdHRyID0geG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CiAgICAgICAgICAgIGF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHIgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdGF0dHIgPT0gTlVMTCkgewoJCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkKCQkgICAgKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgdHlwZSktPmF0dHJpYnV0ZXMgPSBhdHRyOwoJCWVsc2UKCQkgICAgdHlwZS0+YXR0cmlidXRlcyA9IGF0dHI7CiAgICAgICAgICAgICAgICBsYXN0YXR0ciA9IGF0dHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0YXR0ci0+bmV4dCA9IGF0dHI7CiAgICAgICAgICAgICAgICBsYXN0YXR0ciA9IGF0dHI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoY2hpbGQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBiYXJrZWQgPSAwOwoKICAgIC8qCiAgICAqIElORk86IFM0UyBjb21wbGV0ZWQuCiAgICAqLwogICAgLyoKICAgICogaWQgPSBJRAogICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CiAgICAqIENvbnRlbnQ6IChhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqCiAgICAqLwogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldCA9IHhtbFNjaGVtYU5ld0Fubm90KGN0eHQsIG5vZGUpOwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJgoJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpKSB8fAoJICAgICgoYXR0ci0+bnMgIT0gTlVMTCkgJiYKCSAgICB4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkgewoKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFwcGluZm8iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJhcHBpbmZvIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJgoJCSAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic291cmNlIikpKSB8fAoJCSAgICAgKChhdHRyLT5ucyAhPSBOVUxMKSAmJgoJCSAgICAgIHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKSB7CgoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIE5VTEwsIGF0dHIpOwoJCX0KCQlhdHRyID0gYXR0ci0+bmV4dDsKCSAgICB9CgkgICAgeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgY2hpbGQsICJzb3VyY2UiLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImRvY3VtZW50YXRpb24iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJkb2N1bWVudGF0aW9uIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzb3VyY2UiKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSB8fAoJCQkoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImxhbmciKSAmJgoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCBYTUxfWE1MX05BTUVTUEFDRSkpKSkgewoKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJCSAgICB9CgkJfQoJCWF0dHIgPSBhdHRyLT5uZXh0OwoJICAgIH0KCSAgICAvKgoJICAgICogQXR0cmlidXRlICJ4bWw6bGFuZyIuCgkgICAgKi8KCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGVOcyhjaGlsZCwgKGNvbnN0IGNoYXIgKikgWE1MX1hNTF9OQU1FU1BBQ0UsICJsYW5nIik7CgkgICAgaWYgKGF0dHIgIT0gTlVMTCkKCQl4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgTlVMTCwgYXR0ciwKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19MQU5HVUFHRSksIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgewoJICAgIGlmICghYmFya2VkKQoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqIik7CgkgICAgYmFya2VkID0gMTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRmFjZXQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEZhY2V0IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUZhY2V0UHRyCnhtbFNjaGVtYVBhcnNlRmFjZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgZmFjZXQgPSB4bWxTY2hlbWFOZXdGYWNldCgpOwogICAgaWYgKGZhY2V0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGZhY2V0Iiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGZhY2V0LT5ub2RlID0gbm9kZTsKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAidmFsdWUiKTsKICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX0ZBQ0VUX05PX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgbm8gdmFsdWVcbiIsIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5FeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4SW5jbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEV4Y2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ0b3RhbERpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImZyYWN0aW9uRGlnaXRzIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAicGF0dGVybiIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk47CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAiZW51bWVyYXRpb24iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ3aGl0ZVNwYWNlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJsZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4TGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkxlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRkFDRVRfVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAiVW5rbm93biBmYWNldCB0eXBlICVzXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsCgkoeG1sU2NoZW1hVHlwZVB0cikgZmFjZXQsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgZmFjZXQtPnZhbHVlID0gdmFsdWU7CiAgICBpZiAoKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgJiYKCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJY29uc3QgeG1sQ2hhciAqZml4ZWQ7CgoJZml4ZWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwoJaWYgKGZpeGVkICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoZml4ZWQsIEJBRF9DQVNUICJ0cnVlIikpCgkJZmFjZXQtPmZpeGVkID0gMTsKCX0KICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIGZhY2V0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9GQUNFVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiRmFjZXQgJXMgaGFzIHVuZXhwZWN0ZWQgY2hpbGQgY29udGVudFxuIiwKICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoZmFjZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB3aWxkYzogIHRoZSB3aWxkY2FyZCwgYWxyZWFkeSBjcmVhdGVkCiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VzIHRoZSBhdHRyaWJ1dGUgInByb2Nlc3NDb250ZW50cyIgYW5kICJuYW1lc3BhY2UiCiAqIG9mIGEgeHNkOmFueUF0dHJpYnV0ZSBhbmQgeHNkOmFueS4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIDAgaWYgZXZlcnl0aGluZyBnb2VzIGZpbmUsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBpZiBzb21ldGhpbmcgaXMgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZGMsCgkJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnBjLCAqbnMsICpkaWN0bnNJdGVtOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxDaGFyICpuc0l0ZW07CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHRtcCwgbGFzdE5zID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBwYyA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInByb2Nlc3NDb250ZW50cyIpOwogICAgaWYgKChwYyA9PSBOVUxMKQogICAgICAgIHx8ICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInN0cmljdCIpKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOwogICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInNraXAiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJsYXgiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfTEFYOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgbm9kZSwKCSAgICBOVUxMLCAiKHN0cmljdCB8IHNraXAgfCBsYXgpIiwgcGMsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgd2lsZGMtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1Q7CglyZXQgPSBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFOwogICAgfQogICAgLyoKICAgICAqIEJ1aWxkIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMuCiAgICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZXNwYWNlIik7CiAgICBucyA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGlmICgoYXR0ciA9PSBOVUxMKSB8fCAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI2FueSIpKSkKCXdpbGRjLT5hbnkgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI290aGVyIikpIHsKCXdpbGRjLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHdpbGRjLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl3aWxkYy0+bmVnTnNTZXQtPnZhbHVlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyOwoKCWN1ciA9IG5zOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgbnNJdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgaWYgKCh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI290aGVyIikpIHx8CgkJICAgICh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI2FueSIpKSkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1dJTERDQVJEX0lOVkFMSURfTlNfTUVNQkVSLAoJCSAgICBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgTlVMTCwKCQkgICAgIigoIyNhbnkgfCAjI290aGVyKSB8IExpc3Qgb2YgKHhzOmFueVVSSSB8ICIKCQkgICAgIigjI3RhcmdldE5hbWVzcGFjZSB8ICMjbG9jYWwpKSkiLAoJCSAgICBuc0l0ZW0sIE5VTEwsIE5VTEwsIE5VTEwpOwoJCXJldCA9IFhNTF9TQ0hFTUFQX1dJTERDQVJEX0lOVkFMSURfTlNfTUVNQkVSOwoJICAgIH0gZWxzZSB7CgkJaWYgKHhtbFN0ckVxdWFsKG5zSXRlbSwgQkFEX0NBU1QgIiMjdGFyZ2V0TmFtZXNwYWNlIikpIHsKCQkgICAgZGljdG5zSXRlbSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNsb2NhbCIpKSB7CgkJICAgIGRpY3Ruc0l0ZW0gPSBOVUxMOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogVmFsaWRhdGUgdGhlIGl0ZW0gKGFueVVSSSkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsCgkJCW5zSXRlbSwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSk7CgkJICAgIGRpY3Ruc0l0ZW0gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zSXRlbSwgLTEpOwoJCX0KCQkvKgoJCSogQXZvaWQgZHVibGljYXRlIG5hbWVzcGFjZXMuCgkJKi8KCQl0bXAgPSB3aWxkYy0+bnNTZXQ7CgkJd2hpbGUgKHRtcCAhPSBOVUxMKSB7CgkJICAgIGlmIChkaWN0bnNJdGVtID09IHRtcC0+dmFsdWUpCgkJCWJyZWFrOwoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJCXhtbEZyZWUobnNJdGVtKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdG1wLT52YWx1ZSA9IGRpY3Ruc0l0ZW07CgkJICAgIHRtcC0+bmV4dCA9IE5VTEw7CgkJICAgIGlmICh3aWxkYy0+bnNTZXQgPT0gTlVMTCkKCQkJd2lsZGMtPm5zU2V0ID0gdG1wOwoJCSAgICBlbHNlCgkJCWxhc3ROcy0+bmV4dCA9IHRtcDsKCQkgICAgbGFzdE5zID0gdG1wOwoJCX0KCgkgICAgfQoJICAgIHhtbEZyZWUobnNJdGVtKTsKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtIEFUVFJJQlVURV9VTlVTRUQsCgkJCQkgeG1sTm9kZVB0ciBub2RlLAoJCQkJIGludCBtaW5PY2N1cnMsCgkJCQkgaW50IG1heE9jY3VycykgewoKICAgIGlmICgobWF4T2NjdXJzID09IDApICYmICggbWluT2NjdXJzID09IDApKQoJcmV0dXJuICgwKTsKICAgIGlmIChtYXhPY2N1cnMgIT0gVU5CT1VOREVEKSB7CgkvKgoJKiBUT0RPOiBNYXliZSB3ZSBzaG91bGQgYmV0dGVyIG5vdCBjcmVhdGUgdGhlIHBhcnRpY2xlLAoJKiBpZiBtaW4vbWF4IGlzIGludmFsaWQsIHNpbmNlIGl0IGNvdWxkIGNvbmZ1c2UgdGhlIGJ1aWxkIG9mIHRoZQoJKiBjb250ZW50IG1vZGVsLgoJKi8KCS8qCgkqIDMuOS42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogUGFydGljbGUgQ29ycmVjdAoJKgoJKi8KCWlmIChtYXhPY2N1cnMgPCAxKSB7CgkgICAgLyoKCSAgICAqIDIuMiB7bWF4IG9jY3Vyc30gbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMiwKCQlOVUxMLCBOVUxMLAoJCXhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtYXhPY2N1cnMiKSwKCQkiVGhlIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEiKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzIpOwoJfSBlbHNlIGlmIChtaW5PY2N1cnMgPiBtYXhPY2N1cnMpIHsKCSAgICAvKgoJICAgICogMi4xIHttaW4gb2NjdXJzfSBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4ge21heCBvY2N1cnN9LgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9QX1BST1BTX0NPUlJFQ1RfMl8xLAoJCU5VTEwsIE5VTEwsCgkJeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1pbk9jY3VycyIpLAoJCSJUaGUgdmFsdWUgbXVzdCBub3QgYmUgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSBvZiAnbWF4T2NjdXJzJyIpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbnk6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VhIGEgWE1MIHNjaGVtYSA8YW55PiBlbGVtZW50LiBBIHBhcnRpY2xlIGFuZCB3aWxkY2FyZAogKiB3aWxsIGJlIGNyZWF0ZWQgKGV4Y2VwdCBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MCwgaW4gdGhpcyBjYXNlCiAqIG5vdGhpbmcgd2lsbCBiZSBjcmVhdGVkKS4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBwYXJ0aWNsZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3Igb3IgaWYgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJ0aWNsZVB0cgp4bWxTY2hlbWFQYXJzZUFueSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQ7CiAgICBpbnQgbWluLCBtYXg7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJwcm9jZXNzQ29udGVudHMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogbWluT2NjdXJzL21heE9jY3Vycy4KICAgICovCiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLAoJIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsCgkieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCBOVUxMLCBub2RlLCBtaW4sIG1heCk7CiAgICAvKgogICAgKiBDcmVhdGUgJiBwYXJzZSB0aGUgd2lsZGNhcmQuCiAgICAqLwogICAgd2lsZCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQsIHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX0FOWSwgbm9kZSk7CiAgICBpZiAod2lsZCA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyhjdHh0LCBzY2hlbWEsIHdpbGQsIG5vZGUpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIC8qCiAgICAqIE5vIGNvbXBvbmVudCBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MC4KICAgICovCiAgICBpZiAoKG1pbiA9PSAwKSAmJiAobWF4ID09IDApKSB7CgkvKiBEb24ndCBmcmVlIHRoZSB3aWxkY2FyZCwgc2luY2UgaXQncyBhbHJlYWR5IG9uIHRoZSBsaXN0LiAqLwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIENyZWF0ZSB0aGUgcGFydGljbGUuCiAgICAqLwogICAgcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShjdHh0LCBzY2hlbWEsIG5vZGUsIG1pbiwgbWF4KTsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBwYXJ0aWNsZS0+YW5ub3QgPSBhbm5vdDsKICAgIHdpbGQtPm1pbk9jY3VycyA9IG1pbjsKICAgIHdpbGQtPm1heE9jY3VycyA9IG1heDsKICAgIHBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgd2lsZDsKCiAgICByZXR1cm4gKHBhcnRpY2xlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIE5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm90YXRpb25QdHIKeG1sU2NoZW1hUGFyc2VOb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgeG1sU2NoZW1hTm90YXRpb25QdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX05PVEFUSU9OX05PX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIk5vdGF0aW9uIGhhcyBubyBuYW1lXG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hQWRkTm90YXRpb24oY3R4dCwgc2NoZW1hLCBuYW1lKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQW55QXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgYSB3aWxkY2FyZCBvciBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQsIHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEUsCglub2RlKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCSAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZXNwYWNlIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicHJvY2Vzc0NvbnRlbnRzIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LAoJbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBQYXJzZSB0aGUgbmFtZXNwYWNlIGxpc3QuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyhjdHh0LCBzY2hlbWEsIHJldCwgbm9kZSkgIT0gMCkKCXJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqYXR0clZhbHVlOwogICAgeG1sQ2hhciAqcmVwTmFtZSA9IE5VTEw7IC8qIFRoZSByZXBvcnRlZCBkZXNpZ25hdGlvbi4gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CiAgICBpbnQgaXNSZWYgPSAwOwoKICAgIC8qCiAgICAgKiBOb3RlIHRoYXQgdGhlIHczYyBzcGVjIGFzc3VtZXMgdGhlIHNjaGVtYSB0byBiZSB2YWxpZGF0ZWQgd2l0aCBzY2hlbWEKICAgICAqIGZvciBzY2hlbWFzIGJlZm9yZWhhbmQuCiAgICAgKgogICAgICogMy4yLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBBdHRyaWJ1dGUgRGVjbGFyYXRpb25zCiAgICAgKi8KCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCiAgICBpZiAoKGF0dHIgPT0gTlVMTCkgJiYgKG5hbWVBdHRyID09IE5VTEwpKSB7CgkvKgoJKiAzLjIuMyA6IDMuMQoJKiBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGgKCSovCgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8zXzEsCgkgICAgTlVMTCwgbm9kZSwgTlVMTCwKCSAgICAiT25lIG9mIHRoZSBhdHRyaWJ1dGVzICdyZWYnIG9yICduYW1lJyBtdXN0IGJlIHByZXNlbnQiKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLCAibmFtZSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9IGVsc2UKCWlzUmVmID0gMTsKCiAgICBpZiAoaXNSZWYpIHsKCWNoYXIgYnVmWzUwXTsKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEw7CgoJLyoKCSogUGFyc2UgYXMgYXR0cmlidXRlIHJlZmVyZW5jZS4KCSovCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYsIE5VTEwsIGF0dHIsICZyZWZOcywKCSAgICAmcmVmKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgICAgICBzbnByaW50ZihidWYsIDQ5LCAiI2FSZWYlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgICAgIG5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlLCAwKTsKCWlmIChyZXQgPT0gTlVMTCkgewoJICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShyZXBOYW1lKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTsKCXJldC0+bm9kZSA9IG5vZGU7CglyZXQtPnJlZk5zID0gcmVmTnM7CglyZXQtPnJlZiA9IHJlZjsKCXhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0LAoJICAgIHJlZk5zKTsKCS8qCgl4bWxTY2hlbWFGb3JtYXRUeXBlUmVwKCZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBOVUxMLCBOVUxMKTsKCSovCglpZiAobmFtZUF0dHIgIT0gTlVMTCkKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8zXzEsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5hbWVBdHRyLAoJCSJyZWYiLCAibmFtZSIpOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmb3JtIikpIHsKCQkgICAgLyoKCQkgICAgKiAzLjIuMyA6IDMuMgoJCSAgICAqIElmIHJlZiBpcyBwcmVzZW50LCB0aGVuIGFsbCBvZiA8c2ltcGxlVHlwZT4sCgkJICAgICogZm9ybSBhbmQgdHlwZSBtdXN0IGJlIGFic2VudC4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18yLCAmcmVwTmFtZSwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CgkJfSBlbHNlIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWYiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidXNlIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQogICAgfSBlbHNlIHsKICAgICAgICBjb25zdCB4bWxDaGFyICpucyA9IE5VTEw7CgoJLyoKCSogUGFyc2UgYXMgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8KCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCSAgICAoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCwgTlVMTCwgbmFtZUF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJLyoKCXhtbFNjaGVtYUZvcm1hdFR5cGVSZXAoJnJlcE5hbWUsIE5VTEwsIHhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCwgbmFtZSk7CgkqLwoJLyoKCSogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4bWxucyBOb3QgQWxsb3dlZAoJKiBUT0RPOiBNb3ZlIHRoaXMgdG8gdGhlIGNvbXBvbmVudCBsYXllci4KCSovCglpZiAoeG1sU3RyRXF1YWwobmFtZSwgQkFEX0NBU1QgInhtbG5zIikpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX05PX1hNTE5TLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBuYW1lQXR0ciwKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCBOVUxMLCBOVUxMLAoJCSJUaGUgdmFsdWUgb2YgdHlwZSAneHM6TkNOYW1lJyBtdXN0IG5vdCBtYXRjaCAneG1sbnMnIiwKCQlOVUxMLCBOVUxMKTsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCX0gZWxzZSB7CgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmb3JtIik7CgkgICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJCWF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCQkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCQl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKQoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9CiAgICAgICAgcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgbmFtZSwgbnMsIG5vZGUsIHRvcExldmVsKTsKCWlmIChyZXQgPT0gTlVMTCkgewoJICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShyZXBOYW1lKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTsKCXJldC0+bm9kZSA9IG5vZGU7CglpZiAodG9wTGV2ZWwpCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTDsKCS8qCgkqIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeHNpOiBOb3QgQWxsb3dlZAoJKiBUT0RPOiBNb3ZlIHRoaXMgdG8gdGhlIGNvbXBvbmVudCBsYXllci4KCSovCglpZiAoeG1sU3RyRXF1YWwocmV0LT50YXJnZXROYW1lc3BhY2UsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX05PX1hTSSwKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgbXVzdCBub3QgbWF0Y2ggJyVzJyIsCgkJeG1sU2NoZW1hSW5zdGFuY2VOcyk7Cgl9CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ0eXBlIikpKSB7CgkJICAgIGlmICgodG9wTGV2ZWwpIHx8CgkJICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSAmJgoJCQkgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidXNlIikpKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJCSAgICB9CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCXhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCSAgICBub2RlLCAidHlwZSIsICZyZXQtPnR5cGVOcywgJnJldC0+dHlwZU5hbWUpOwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LAoJbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImZpeGVkIi4KICAgICovCiAgICByZXQtPmRlZlZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKICAgIGlmIChyZXQtPmRlZlZhbHVlICE9IE5VTEwpCglyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQ7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImRlZmF1bHQiLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJLyoKCSogMy4yLjMgOiAxCgkqIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KCSovCglpZiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpIHsKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8xLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyLCAiZGVmYXVsdCIsICJmaXhlZCIpOwoJfSBlbHNlCgkgICAgcmV0LT5kZWZWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIH0KICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CgkvKgoJKiBBdHRyaWJ1dGUgInVzZSIuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ1c2UiKTsKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgIm9wdGlvbmFsIikpCgkJcmV0LT5vY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTDsKCSAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJwcm9oaWJpdGVkIikpCgkJcmV0LT5vY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEOwoJICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInJlcXVpcmVkIikpCgkJcmV0LT5vY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX1VTRSwKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIiwKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0gZWxzZQoJICAgIHJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CgkvKgoJKiAzLjIuMyA6IDIKCSogSWYgZGVmYXVsdCBhbmQgdXNlIGFyZSBib3RoIHByZXNlbnQsIHVzZSBtdXN0IGhhdmUKCSogdGhlIGFjdHVhbCB2YWx1ZSBvcHRpb25hbC4KCSovCglpZiAoKHJldC0+b2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJICAgIChyZXQtPmRlZlZhbHVlICE9IE5VTEwpICYmCgkgICAgKChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgPT0gMCkpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfMiwKCQkoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAoeG1sTm9kZVB0cikgYXR0ciwKCQlOVUxMLCAiKG9wdGlvbmFsIHwgcHJvaGliaXRlZCB8IHJlcXVpcmVkKSIsIE5VTEwsCgkJIlRoZSB2YWx1ZSBtdXN0IGJlICdvcHRpb25hbCcgaWYgdGhlIGF0dHJpYnV0ZSAiCgkJIidkZWZhdWx0JyBpcyBwcmVzZW50IGFzIHdlbGwiLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGlzUmVmKSB7CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpCgkJLyoKCQkqIDMuMi4zIDogMy4yCgkJKiBJZiByZWYgaXMgcHJlc2VudCwgdGhlbiBhbGwgb2YgPHNpbXBsZVR5cGU+LAoJCSogZm9ybSBhbmQgdHlwZSBtdXN0IGJlIGFic2VudC4KCQkqLwoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18yLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJICAgICIoYW5ub3RhdGlvbj8pIik7CgkgICAgZWxzZQoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJICAgICIoYW5ub3RhdGlvbj8pIik7Cgl9CiAgICB9IGVsc2UgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmIChyZXQtPnR5cGVOYW1lICE9IE5VTEwpIHsKCQkvKgoJCSogMy4yLjMgOiA0CgkJKiB0eXBlIGFuZCA8c2ltcGxlVHlwZT4gbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgoJCSovCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV80LAoJCSAgICAmcmVwTmFtZSwgICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSAgICAiYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZQoJCXJldC0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlPykiKTsKICAgIH0KICAgIC8qCiAgICAqIENsZWFudXAuCiAgICAqLwogICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCXhtbEZyZWUocmVwTmFtZSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBuYW1lQXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZiIpOwogICAgaWYgKCh0b3BMZXZlbCkgfHwgKGF0dHIgPT0gTlVMTCkpIHsKCS8qCgkqIFBhcnNlIGFzIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLgoJKiBOb3RlIHRoYXQgdGhvc2UgYXJlIGFsbG93ZWQgYXQgdG9wIGxldmVsIG9ubHkuCgkqLwoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qIFJFRFVOREFOVDogbmFtZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsCgkqICh4bWxOb2RlUHRyKSBuYW1lQXR0cik7CgkqLwoJLyoKCSogVGhlIG5hbWUgaXMgY3J1Y2lhbCwgZXhpdCBpZiBpbnZhbGlkLgoJKi8KCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCSAgICBOVUxMLCBOVUxMLCBuYW1lQXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIG5vZGUpOwoJaWYgKHJldCA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA7CglyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUw7CglyZXQtPm5vZGUgPSBub2RlOwoJcmV0LT50YXJnZXROYW1lc3BhY2UgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKICAgIH0gZWxzZSB7CgljaGFyIGJ1Zls1MF07Cgljb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMOwoKCS8qCgkqIFBhcnNlIGFzIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHJlZmVyZW5jZS4KCSovCglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLCAicmVmIiwgTlVMTCk7Cgl9Cgl4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkgICAgTlVMTCwgTlVMTCwgYXR0ciwgJnJlZk5zLCZyZWYpOwoKICAgICAgICBzbnByaW50ZihidWYsIDQ5LCAiI2FnUmVmJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCW5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CglpZiAobmFtZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgaW50ZXJuYWwgbmFtZSBmb3IgYW4gIgoJCSJhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UiLCBub2RlKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIG5vZGUpOwoJaWYgKHJldCA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA7CglyZXQtPnJlZiA9IHJlZjsKCXJldC0+cmVmTnMgPSByZWZOczsKCXJldC0+bm9kZSA9IG5vZGU7Cgl4bWxTY2hlbWFDaGVja1JlZmVyZW5jZShjdHh0LCBzY2hlbWEsIG5vZGUsCgkgICAgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0LCByZWZOcyk7CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCgodG9wTGV2ZWwgPT0gMCkgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpKSB8fAoJCSAodG9wTGV2ZWwgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSkpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpCgkgICAgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qIFRPRE86IFZhbGlkYXRlICJpZCIgPyAqLwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHRvcExldmVsKSB7CgljaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdDoKICogQHZhbHVlOiAgdGhlIHZhbHVlCiAqIEBmbGFnczogdGhlIGZsYWdzIHRvIGJlIG1vZGlmaWVkCiAqIEBmbGFnUXVhbGlmaWVkOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInF1YWxpZmllZCIKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQoY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgaW50ICpmbGFncywKCQkJICAgICBpbnQgZmxhZ1F1YWxpZmllZCkKewogICAgaWYgKHhtbFN0ckVxdWFsKHZhbHVlLCBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCWlmICAoKCpmbGFncyAmIGZsYWdRdWFsaWZpZWQpID09IDApCgkgICAgKmZsYWdzIHw9IGZsYWdRdWFsaWZpZWQ7CiAgICB9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpCglyZXR1cm4gKDEpOwoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWw6CiAqIEB2YWx1ZTogIHRoZSB2YWx1ZQogKiBAZmxhZ3M6IHRoZSBmbGFncyB0byBiZSBtb2RpZmllZAogKiBAZmxhZ0FsbDogdGhlIHNwZWNpZmljIGZsYWcgZm9yICIjYWxsIgogKiBAZmxhZ0V4dGVuc2lvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJleHRlbnNpb24iCiAqIEBmbGFnUmVzdHJpY3Rpb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAicmVzdHJpY3Rpb24iCiAqIEBmbGFnU3Vic3RpdHV0aW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInN1YnN0aXR1dGlvbiIKICogQGZsYWdMaXN0OiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgImxpc3QiCiAqIEBmbGFnVW5pb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAidW5pb24iCiAqCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAiZmluYWwiIGFuZCAiYmxvY2siLiBUaGUgdmFsdWUKICogaXMgY29udmVydGVkIGludG8gdGhlIHNwZWNpZmllZCBmbGFnIHZhbHVlcyBhbmQgcmV0dXJuZWQgaW4gQGZsYWdzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCAxIG90aGVyd2lzZS4KICovCgpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgIGludCAqZmxhZ3MsCgkJCSAgICBpbnQgZmxhZ0FsbCwKCQkJICAgIGludCBmbGFnRXh0ZW5zaW9uLAoJCQkgICAgaW50IGZsYWdSZXN0cmljdGlvbiwKCQkJICAgIGludCBmbGFnU3Vic3RpdHV0aW9uLAoJCQkgICAgaW50IGZsYWdMaXN0LAoJCQkgICAgaW50IGZsYWdVbmlvbikKewogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICogVE9ETzogVGhpcyBkb2VzIG5vdCBjaGVjayBmb3IgZHVibGljYXRlIGVudHJpZXMuCiAgICAqLwogICAgaWYgKChmbGFncyA9PSBOVUxMKSB8fCAodmFsdWUgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIGlmICh2YWx1ZVswXSA9PSAwKQoJcmV0dXJuICgwKTsKICAgIGlmICh4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgIiNhbGwiKSkgewoJaWYgKGZsYWdBbGwgIT0gLTEpCgkgICAgKmZsYWdzIHw9IGZsYWdBbGw7CgllbHNlIHsKCSAgICBpZiAoZmxhZ0V4dGVuc2lvbiAhPSAtMSkKCQkqZmxhZ3MgfD0gZmxhZ0V4dGVuc2lvbjsKCSAgICBpZiAoZmxhZ1Jlc3RyaWN0aW9uICE9IC0xKQoJCSpmbGFncyB8PSBmbGFnUmVzdHJpY3Rpb247CgkgICAgaWYgKGZsYWdTdWJzdGl0dXRpb24gIT0gLTEpCgkJKmZsYWdzIHw9IGZsYWdTdWJzdGl0dXRpb247CgkgICAgaWYgKGZsYWdMaXN0ICE9IC0xKQoJCSpmbGFncyB8PSBmbGFnTGlzdDsKCSAgICBpZiAoZmxhZ1VuaW9uICE9IC0xKQoJCSpmbGFncyB8PSBmbGFnVW5pb247Cgl9CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyID0gdmFsdWU7Cgl4bWxDaGFyICppdGVtOwoKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIGl0ZW0gPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImV4dGVuc2lvbiIpKSB7CgkJaWYgKGZsYWdFeHRlbnNpb24gIT0gLTEpIHsKCQkgICAgaWYgKCgqZmxhZ3MgJiBmbGFnRXh0ZW5zaW9uKSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ0V4dGVuc2lvbjsKCQl9IGVsc2UKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJyZXN0cmljdGlvbiIpKSB7CgkJaWYgKGZsYWdSZXN0cmljdGlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdSZXN0cmljdGlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdSZXN0cmljdGlvbjsKCQl9IGVsc2UKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJzdWJzdGl0dXRpb24iKSkgewoJCWlmIChmbGFnU3Vic3RpdHV0aW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1N1YnN0aXR1dGlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdTdWJzdGl0dXRpb247CgkJfSBlbHNlCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAibGlzdCIpKSB7CgkJaWYgKGZsYWdMaXN0ICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ0xpc3QpID09IDApCgkJCSpmbGFncyB8PSBmbGFnTGlzdDsKCQl9IGVsc2UKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJ1bmlvbiIpKSB7CgkJaWYgKGZsYWdVbmlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdVbmlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdVbmlvbjsKCQl9IGVsc2UKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UKCQlyZXQgPSAxOwoJICAgIGlmIChpdGVtICE9IE5VTEwpCgkJeG1sRnJlZShpdGVtKTsKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgocmV0ID09IDApICYmICgqY3VyICE9IDApKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hSURDUHRyIGlkYywKCQkJICAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsZWN0b3IsCgkJCSAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkgICAgIGludCBpc0ZpZWxkKQp7CiAgICB4bWxOb2RlUHRyIG5vZGU7CgogICAgLyoKICAgICogYy1zZWxlY3Rvci14cGF0aDoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTZWxlY3RvciBWYWx1ZSBPSwogICAgKgogICAgKiBUT0RPOiAxIFRoZSB7c2VsZWN0b3J9IG11c3QgYmUgYSB2YWxpZCBYUGF0aCBleHByZXNzaW9uLCBhcyBkZWZpbmVkCiAgICAqIGluIFtYUGF0aF0uCiAgICAqLwogICAgaWYgKHNlbGVjdG9yID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgaWRjLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aCwgIgoJICAgICJ0aGUgc2VsZWN0b3IgaXMgbm90IHNwZWNpZmllZC5cbiIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJbm9kZSA9IGlkYy0+bm9kZTsKICAgIGVsc2UKCW5vZGUgPSAoeG1sTm9kZVB0cikgYXR0cjsKICAgIGlmIChzZWxlY3Rvci0+eHBhdGggPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIC8qIFRPRE86IEFkanVzdCBlcnJvciBjb2RlLiAqLwoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIFhQYXRoIGV4cHJlc3Npb24gb2YgdGhlIHNlbGVjdG9yIGlzIG5vdCB2YWxpZCIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFKTsKICAgIH0gZWxzZSB7Cgljb25zdCB4bWxDaGFyICoqbnNBcnJheSA9IE5VTEw7Cgl4bWxOc1B0ciAqbnNMaXN0ID0gTlVMTDsKCS8qCgkqIENvbXBpbGUgdGhlIFhQYXRoIGV4cHJlc3Npb24uCgkqLwoJLyoKCSogVE9ETzogV2UgbmVlZCB0aGUgYXJyYXkgb2YgaW4tc2NvcGUgbmFtZXNwYWNlcyBmb3IgY29tcGlsYXRpb24uCgkqIFRPRE86IENhbGwgeG1sUGF0dGVybmNvbXBpbGUgd2l0aCBkaWZmZXJlbnQgb3B0aW9ucyBmb3Igc2VsZWN0b3IvCgkqIGZpZWxkLgoJKi8KCW5zTGlzdCA9IHhtbEdldE5zTGlzdChhdHRyLT5kb2MsIGF0dHItPnBhcmVudCk7CgkvKgoJKiBCdWlsZCBhbiBhcnJheSBvZiBwcmVmaXhlcyBhbmQgbmFtZXNwYWNlcy4KCSovCglpZiAobnNMaXN0ICE9IE5VTEwpIHsKCSAgICBpbnQgaSwgY291bnQgPSAwOwoJICAgIHhtbE5zUHRyIG5zOwoKCSAgICBmb3IgKGkgPSAwOyBuc0xpc3RbaV0gIT0gTlVMTDsgaSsrKQoJCWNvdW50Kys7CgoJICAgIG5zQXJyYXkgPSAoY29uc3QgeG1sQ2hhciAqKikgeG1sTWFsbG9jKAoJCShjb3VudCAqIDIgKyAxKSAqIHNpemVvZihjb25zdCB4bWxDaGFyICopKTsKCSAgICBpZiAobnNBcnJheSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIG5hbWVzcGFjZSBhcnJheSIsCgkJICAgIE5VTEwpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCW5zID0gbnNMaXN0W2ldOwoJCW5zQXJyYXlbMiAqIGldID0gbnNMaXN0W2ldLT5ocmVmOwoJCW5zQXJyYXlbMiAqIGkgKyAxXSA9IG5zTGlzdFtpXS0+cHJlZml4OwoJICAgIH0KCSAgICBuc0FycmF5W2NvdW50ICogMl0gPSBOVUxMOwoJICAgIHhtbEZyZWUobnNMaXN0KTsKCX0KCS8qCgkqIFRPRE86IERpZmZlcmVudGlhdGUgYmV0d2VlbiAic2VsZWN0b3IiIGFuZCAiZmllbGQiLgoJKi8KCWlmIChpc0ZpZWxkKQoJICAgIHNlbGVjdG9yLT54cGF0aENvbXAgPSAodm9pZCAqKSB4bWxQYXR0ZXJuY29tcGlsZShzZWxlY3Rvci0+eHBhdGgsCgkJTlVMTCwgWE1MX1BBVFRFUk5fWFNGSUVMRCwgbnNBcnJheSk7CgllbHNlCgkgICAgc2VsZWN0b3ItPnhwYXRoQ29tcCA9ICh2b2lkICopIHhtbFBhdHRlcm5jb21waWxlKHNlbGVjdG9yLT54cGF0aCwKCQlOVUxMLCBYTUxfUEFUVEVSTl9YU1NFTCwgbnNBcnJheSk7CglpZiAobnNBcnJheSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHhtbENoYXIgKiopIG5zQXJyYXkpOwoKCWlmIChzZWxlY3Rvci0+eHBhdGhDb21wID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJLyogVE9ETzogQWRqdXN0IGVycm9yIGNvZGU/ICovCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgWFBhdGggZXhwcmVzc2lvbiAnJXMnIGNvdWxkIG5vdCBiZSAiCgkJImNvbXBpbGVkIiwgc2VsZWN0b3ItPnhwYXRoKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUpOwoJfQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKI2RlZmluZSBBRERfQU5OT1RBVElPTihhbm5vdCkgICBcCiAgICB4bWxTY2hlbWFBbm5vdFB0ciBjdXIgPSBpdGVtLT5hbm5vdDsgXAogICAgaWYgKGl0ZW0tPmFubm90ID09IE5VTEwpIHsgIFwKCWl0ZW0tPmFubm90ID0gYW5ub3Q7ICAgIFwKCXJldHVybiAoYW5ub3QpOyAgICAgICAgIFwKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBjdXIgPSBpdGVtLT5hbm5vdDsgICAgICAgICAgXAogICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7ICAgIFwKCWN1ciA9IGN1ci0+bmV4dDsJXAogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGN1ci0+bmV4dCA9IGFubm90OwoKLyoqCiAqIHhtbFNjaGVtYUFzc2lnbkFubm90YXRpb246CiAqIEBpdGVtOiB0aGUgc2NoZW1hIGNvbXBvbmVudAogKiBAYW5ub3Q6IHRoZSBhbm5vdGF0aW9uCiAqCiAqIEFkZHMgdGhlIGFubm90YXRpb24gdG8gdGhlIGdpdmVuIHNjaGVtYSBjb21wb25lbnQuCiAqCiAqIFJldHVybnMgdGhlIGdpdmVuIGFubm90YWlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKHhtbFNjaGVtYUFubm90SXRlbVB0ciBhbm5JdGVtLAoJCSAgICAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCkKewogICAgaWYgKChhbm5JdGVtID09IE5VTEwpIHx8IChhbm5vdCA9PSBOVUxMKSkKCXJldHVybiAoTlVMTCk7CiAgICBzd2l0Y2ggKGFubkl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6IHsKCQl4bWxTY2hlbWFFbGVtZW50UHRyIGl0ZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6IHsKCQl4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogewoJCXhtbFNjaGVtYVdpbGRjYXJkUHRyIGl0ZW0gPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6IHsKCQl4bWxTY2hlbWFBbm5vdEl0ZW1QdHIgaXRlbSA9ICh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6IHsKCQl4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBpdGVtID0KCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOiB7CgkJeG1sU2NoZW1hTm90YXRpb25QdHIgaXRlbSA9ICh4bWxTY2hlbWFOb3RhdGlvblB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDogewoJCXhtbFNjaGVtYUZhY2V0UHRyIGl0ZW0gPSAoeG1sU2NoZW1hRmFjZXRQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDogewoJCXhtbFNjaGVtYVR5cGVQdHIgaXRlbSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBhbm5JdGVtOwoJCUFERF9BTk5PVEFUSU9OKGFubm90KQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOiB7CgkJeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtID0gKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGFubkl0ZW07CgkJQUREX0FOTk9UQVRJT04oYW5ub3QpCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6IHsKCQl4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW0gPSAoeG1sU2NoZW1hTW9kZWxHcm91cFB0cikgYW5uSXRlbTsKCQlBRERfQU5OT1RBVElPTihhbm5vdCkKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKE5VTEwsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJTlVMTCwgTlVMTCwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEFubm90YXRpb24sICIKCQkiVGhlIGl0ZW0gaXMgbm90IGEgYW5ub3RhdGVkIHNjaGVtYSBjb21wb25lbnQiLCBOVUxMKTsKCSAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKGFubm90KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgU2NoZW1hIGlkZW50aXR5LWNvbnRyYWludCBkZWZpbml0aW9uJ3MKICogPHNlbGVjdG9yPiBhbmQgPGZpZWxkPiBlbGVtZW50cy4KICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFJRENTZWxlY3RQdHIKeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgIHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgeG1sTm9kZVB0ciBub2RlLAoJCQkgIGludCBpc0ZpZWxkKQp7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgaXRlbTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInhwYXRoIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogQ3JlYXRlIHRoZSBpdGVtLgogICAgKi8KICAgIGl0ZW0gPSAoeG1sU2NoZW1hSURDU2VsZWN0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ1NlbGVjdCkpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCSAgICAiYWxsb2NhdGluZyBhICdzZWxlY3Rvcicgb2YgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIiwKCSAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KGl0ZW0sIDAsIHNpemVvZih4bWxTY2hlbWFJRENTZWxlY3QpKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAieHBhdGgiIChtYW5kYXRvcnkpLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAieHBhdGgiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKICAgIAl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgIm5hbWUiLCBOVUxMKTsKICAgIH0gZWxzZSB7CglpdGVtLT54cGF0aCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCS8qCgkqIFVSR0VOVCBUT0RPOiAiZmllbGQicyBoYXZlIGFuIG90aGVyIHN5bnRheCB0aGFuICJzZWxlY3RvciJzLgoJKi8KCglpZiAoeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aChjdHh0LCBpZGMsIGl0ZW0sIGF0dHIsCgkgICAgaXNGaWVsZCkgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsCgkJKHhtbE5vZGVQdHIpIGF0dHIsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZUlEQ1NlbGVjdG9yQW5kRmllbGQsICIKCQkidmFsaWRhdGluZyB0aGUgWFBhdGggZXhwcmVzc2lvbiBvZiBhIElEQyBzZWxlY3Rvci5cbiIsCgkJTlVMTCwgTlVMTCk7Cgl9CgogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIHBhcmVudCBJREMuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSBpZGMsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/KSIpOwogICAgfQoKICAgIHJldHVybiAoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUlEQzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgU2NoZW1hIGlkZW50aXR5LWNvbnRyYWludCBkZWZpbml0aW9uLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZWQgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUlEQ1B0cgp4bWxTY2hlbWFQYXJzZUlEQyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSAgeG1sTm9kZVB0ciBub2RlLAoJCSAgeG1sU2NoZW1hVHlwZVR5cGUgaWRjQ2F0ZWdvcnksCgkJICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpdGVtID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgZmllbGQgPSBOVUxMLCBsYXN0RmllbGQgPSBOVUxMOwogICAgaW50IHJlc0FkZDsKCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJKChpZGNDYXRlZ29yeSAhPSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgfHwKCQkgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmZXIiKSkpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogQXR0cmlidXRlICJuYW1lIiAobWFuZGF0b3J5KS4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAibmFtZSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsCglOVUxMLCBOVUxMLCBhdHRyLAoJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBDcmVhdGUgdGhlIGNvbXBvbmVudC4KICAgICovCiAgICBpZiAoc2NoZW1hLT5pZGNEZWYgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmlkY0RlZiA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmlkY0RlZiA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaXRlbSA9ICh4bWxTY2hlbWFJRENQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDKSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LAoJICAgICJhbGxvY2F0aW5nIGFuIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBBZGQgdGhlIElEQyB0byB0aGUgbGlzdCBvZiBJRENzIG9uIHRoZSBzY2hlbWEgY29tcG9uZW50LgogICAgKi8KICAgIHJlc0FkZCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5pZGNEZWYsIG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgaXRlbSk7CiAgICBpZiAocmVzQWRkICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfVFlQRSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJBbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCSAgICAiYW5kIHRhcmdldE5hbWVzcGFjZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsCgkgICAgbmFtZSwgdGFyZ2V0TmFtZXNwYWNlLCBOVUxMKTsKCXhtbEZyZWUoaXRlbSk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KGl0ZW0sIDAsIHNpemVvZih4bWxTY2hlbWFJREMpKTsKICAgIGl0ZW0tPm5hbWUgPSBuYW1lOwogICAgaXRlbS0+dHlwZSA9IGlkY0NhdGVnb3J5OwogICAgaXRlbS0+bm9kZSA9IG5vZGU7CiAgICAvKgogICAgKiBUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgcGFyZW50IGVsZW1lbnQgZGVjbGFyYXRpb24uCiAgICAqLwogICAgaXRlbS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaWYgKGlkY0NhdGVnb3J5ID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkvKgoJKiBBdHRyaWJ1dGUgInJlZmVyIiAobWFuZGF0b3J5KS4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZmVyIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLAoJCSJyZWZlciIsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogQ3JlYXRlIGEgcmVmZXJlbmNlIGl0ZW0uCgkgICAgKi8KCSAgICBpdGVtLT5yZWYgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihzY2hlbWEsIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZLAoJCU5VTEwsIE5VTEwpOwoJICAgIGlmIChpdGVtLT5yZWYgPT0gTlVMTCkKCQlyZXR1cm4gKE5VTEwpOwoJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwKCQlOVUxMLCBOVUxMLCBhdHRyLAoJCSYoaXRlbS0+cmVmLT50YXJnZXROYW1lc3BhY2UpLAoJCSYoaXRlbS0+cmVmLT5uYW1lKSk7CgkgICAgeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoY3R4dCwgc2NoZW1hLCBub2RlLAoJCSh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGl0ZW0sCgkJaXRlbS0+cmVmLT50YXJnZXROYW1lc3BhY2UpOwoJfQogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkJTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkJIkEgY2hpbGQgZWxlbWVudCBpcyBtaXNzaW5nIiwKCQkiKGFubm90YXRpb24/LCAoc2VsZWN0b3IsIGZpZWxkKykpIik7CiAgICB9CiAgICAvKgogICAgKiBDaGlsZCBlbGVtZW50IDxzZWxlY3Rvcj4uCiAgICAqLwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlbGVjdG9yIikpIHsKCWl0ZW0tPnNlbGVjdG9yID0geG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKGN0eHQsIHNjaGVtYSwKCSAgICBpdGVtLCBjaGlsZCwgMCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwoJLyoKCSogQ2hpbGQgZWxlbWVudHMgPGZpZWxkPi4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZmllbGQiKSkgewoJICAgIGRvIHsKCQlmaWVsZCA9IHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZChjdHh0LCBzY2hlbWEsCgkJICAgIGl0ZW0sIGNoaWxkLCAxKTsKCQlpZiAoZmllbGQgIT0gTlVMTCkgewoJCSAgICBmaWVsZC0+aW5kZXggPSBpdGVtLT5uYkZpZWxkczsKCQkgICAgaXRlbS0+bmJGaWVsZHMrKzsKCQkgICAgaWYgKGxhc3RGaWVsZCAhPSBOVUxMKQoJCQlsYXN0RmllbGQtPm5leHQgPSBmaWVsZDsKCQkgICAgZWxzZQoJCQlpdGVtLT5maWVsZHMgPSBmaWVsZDsKCQkgICAgbGFzdEZpZWxkID0gZmllbGQ7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgfSB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiZmllbGQiKSk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwogICAgfQoKICAgIHJldHVybiAoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHRvcExldmVsOiBpbmRpY2F0ZXMgaWYgdGhpcyBpcyBnbG9iYWwgZGVjbGFyYXRpb24KICoKICogUGFyc2VzIGEgWE1MIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgYSBwYXJ0aWNsZTsgTlVMTCBpbiBjYXNlCiAqIG9mIGFuIGVycm9yIG9yIGlmIHRoZSBwYXJ0aWNsZSBoYXMgbWluT2NjdXJzPT1tYXhPY2N1cnM9PTAuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQmFzaWNJdGVtUHRyCnhtbFNjaGVtYVBhcnNlRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0gTlVMTDsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyLCBuYW1lQXR0cjsKICAgIGludCBtaW4sIG1heCwgaXNSZWYgPSAwOwogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICAvKiAzLjMuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEVsZW1lbnQgRGVjbGFyYXRpb25zICovCiAgICAvKiBUT0RPOiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiAzLjMuNiAqLwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBJZiB3ZSBnZXQgYSAicmVmIiBhdHRyaWJ1dGUgb24gYSBsb2NhbCA8ZWxlbWVudD4gd2Ugd2lsbCBhc3N1bWUgaXQncwogICAgKiBhIHJlZmVyZW5jZSAtIGV2ZW4gaWYgdGhlcmUncyBhICJuYW1lIiBhdHRyaWJ1dGU7IHRoaXMgc2VlbXMgdG8gYmUgbW9yZQogICAgKiByb2J1c3QuCiAgICAqLwogICAgbmFtZUF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIGlmICgodG9wTGV2ZWwpIHx8IChhdHRyID09IE5VTEwpKSB7CglpZiAobmFtZUF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwgIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfSBlbHNlCglpc1JlZiA9IDE7CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7Cglhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBTa2lwIHBhcnRpY2xlIHBhcnQgaWYgYSBnbG9iYWwgZGVjbGFyYXRpb24uCiAgICAqLwogICAgaWYgKHRvcExldmVsKQoJZ290byBkZWNsYXJhdGlvbl9wYXJ0OwogICAgLyoKICAgICogVGhlIHBhcnRpY2xlIHBhcnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgICovCiAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJ4czpub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heCA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsICIoeHM6bm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgTlVMTCwgbm9kZSwgbWluLCBtYXgpOwogICAgcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShjdHh0LCBzY2hlbWEsIG5vZGUsIG1pbiwgbWF4KTsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJZ290byByZXR1cm5fbnVsbDsKCiAgICAvKiByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fUkVGOyAqLwoKICAgIGlmIChpc1JlZikgewoJY29uc3QgeG1sQ2hhciAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTDsKCXhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZmVyID0gTlVMTDsKCS8qCgkqIFRoZSByZWZlcmVuY2UgcGFydCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCSovCgl4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkgICAgTlVMTCwgTlVMTCwgYXR0ciwgJnJlZk5zLCAmcmVmKTsKCXhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgTlVMTCwgcmVmTnMpOwoJLyoKCSogU1BFQyAoMy4zLjMgOiAyLjEpICJPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGgiCgkqLwoJaWYgKG5hbWVBdHRyICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzEsCgkJTlVMTCwgTlVMTCwgbmFtZUF0dHIsICJyZWYiLCAibmFtZSIpOwoJfQoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKQoJCXsKCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qIFNQRUMgKDMuMy4zIDogMi4yKSAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzIsCgkJCU5VTEwsIE5VTEwsIGF0dHIsCgkJCSJPbmx5IHRoZSBhdHRyaWJ1dGVzICdtaW5PY2N1cnMnLCAnbWF4T2NjdXJzJyBhbmQgIgoJCQkiJ2lkJyBhcmUgYWxsb3dlZCBpbiBhZGRpdGlvbiB0byAncmVmJyIpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgkvKgoJKiBObyBjaGlsZHJlbiBleGNlcHQgPGFubm90YXRpb24+IGV4cGVjdGVkLgoJKi8KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7Cgl9CglpZiAoKG1pbiA9PSAwKSAmJiAobWF4ID09IDApKQoJICAgIGdvdG8gcmV0dXJuX251bGw7CgkvKgoJKiBDcmVhdGUgdGhlIHJlZmVyZW5jZSBpdGVtLgoJKi8KCXJlZmVyID0geG1sU2NoZW1hTmV3UU5hbWVSZWYoc2NoZW1hLCBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCwKCSAgICByZWYsIHJlZk5zKTsKCWlmIChyZWZlciA9PSBOVUxMKQoJICAgIGdvdG8gcmV0dXJuX251bGw7CglwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHJlZmVyOwoJcGFydGljbGUtPmFubm90ID0gYW5ub3Q7CgkvKgoJKiBBZGQgdG8gYXNzZW1ibGVkIGl0ZW1zOyB0aGUgcmVmZXJlbmNlIG5lZWQgdG8gYmUgcmVzb2x2ZWQuCgkqLwoJaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcGFydGljbGUpOwoKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcGFydGljbGUpOwogICAgfQogICAgLyoKICAgICogVGhlIGRlY2xhcmF0aW9uIHBhcnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgICovCmRlY2xhcmF0aW9uX3BhcnQ6CiAgICB7Cgljb25zdCB4bWxDaGFyICpucyA9IE5VTEwsICpmaXhlZCwgKm5hbWUsICpvbGRjb250YWluZXIsICphdHRyVmFsdWU7Cgl4bWxTY2hlbWFJRENQdHIgY3VySURDID0gTlVMTCwgbGFzdElEQyA9IE5VTEw7CgoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBuYW1lQXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkKCSAgICBnb3RvIHJldHVybl9udWxsOwoJLyoKCSogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCX0gZWxzZSB7CgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmb3JtIik7CgkgICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJCWF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCQkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCQl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKQoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9CglkZWNsID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBzY2hlbWEsIG5hbWUsIG5zLCBub2RlLCB0b3BMZXZlbCk7CglpZiAoZGVjbCA9PSBOVUxMKSB7CgkgICAgZ290byByZXR1cm5fbnVsbDsKCX0KCWRlY2wtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDsKCWRlY2wtPm5vZGUgPSBub2RlOwoJZGVjbC0+dGFyZ2V0TmFtZXNwYWNlID0gbnM7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJkZWZhdWx0IikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpeGVkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJsb2NrIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5pbGxhYmxlIikpKQoJCXsKCQkgICAgaWYgKHRvcExldmVsID09IDApIHsKCQkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpICYmCgkJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmb3JtIikpKQoJCQl7CgkJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIGF0dHIpOwoJCQl9CgkJICAgIH0gZWxzZSBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkgJiYKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYWJzdHJhY3QiKSkgJiYKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uR3JvdXAiKSkpIHsKCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgYXR0cik7CgkJICAgIH0KCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIEV4dHJhY3QvdmFsaWRhdGUgYXR0cmlidXRlcy4KCSovCglpZiAodG9wTGV2ZWwpIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyB0b3AgYXR0cmlidXRlcyBvZiBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbnMgaGVyZS4KCSAgICAqLwoJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMOwoJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUw7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsCgkJKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIG5vZGUsICJzdWJzdGl0dXRpb25Hcm91cCIsCgkJJihkZWNsLT5zdWJzdEdyb3VwTnMpLCAmKGRlY2wtPnN1YnN0R3JvdXApKTsKCSAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsCgkJbm9kZSwgImFic3RyYWN0IiwgMCkpCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVDsKCSAgICAvKgoJICAgICogQXR0cmlidXRlICJmaW5hbCIuCgkgICAgKi8KCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpbmFsIik7CgkgICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCgkJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfRVhURU5TSU9OOwoJCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikKCQkgICAgZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTjsKCSAgICB9IGVsc2UgewoJCWF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCQlpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihkZWNsLT5mbGFncyksCgkJICAgIC0xLAoJCSAgICBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTiwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTiwgLTEsIC0xLCAtMSkgIT0gMCkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJCU5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0KCSAgICB9Cgl9CgkvKgoJKiBBdHRyaWJ1dGUgImJsb2NrIi4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImJsb2NrIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEFwcGx5IGRlZmF1bHQgImJsb2NrIiB2YWx1ZXMuCgkgICAgKi8KCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTjsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OOwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04pCgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT047Cgl9IGVsc2UgewoJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihkZWNsLT5mbGFncyksCgkJLTEsCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04sCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTiwKCQlYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTiwgLTEsIC0xKSAhPSAwKSB7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsICh4bWxOb2RlUHRyKSBhdHRyLAoJCSAgICBOVUxMLCAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCAiCgkJICAgICJyZXN0cmljdGlvbiB8IHN1YnN0aXR1dGlvbikpIiwgYXR0clZhbHVlLAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CglpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsCgkgICAgbm9kZSwgIm5pbGxhYmxlIiwgMCkpCgkgICAgZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRTsKCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInR5cGUiKTsKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIGF0dHIsCgkJJihkZWNsLT5uYW1lZFR5cGVOcyksICYoZGVjbC0+bmFtZWRUeXBlKSk7CgkgICAgeG1sU2NoZW1hQ2hlY2tSZWZlcmVuY2UoY3R4dCwgc2NoZW1hLCBub2RlLAoJICAgICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGRlY2wsIGRlY2wtPm5hbWVkVHlwZU5zKTsKCX0KCWRlY2wtPnZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZGVmYXVsdCIpOwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaXhlZCIpOwoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIGZpeGVkID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmIChkZWNsLT52YWx1ZSAhPSBOVUxMKSB7CgkJLyoKCQkqIDMuMy4zIDogMQoJCSogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LgoJCSovCgkJeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzEsCgkJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBhdHRyLAoJCSAgICAiZGVmYXVsdCIsICJmaXhlZCIpOwoJICAgIH0gZWxzZSB7CgkJZGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9GSVhFRDsKCQlkZWNsLT52YWx1ZSA9IGZpeGVkOwoJICAgIH0KCX0KCS8qCgkqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgoJKi8KCW9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKCWN0eHQtPmNvbnRhaW5lciA9IGRlY2wtPm5hbWU7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleFR5cGUiKSkgewoJICAgIC8qCgkgICAgKiAzLjMuMyA6IDMKCSAgICAqICJ0eXBlIiBhbmQgZWl0aGVyIDxzaW1wbGVUeXBlPiBvciA8Y29tcGxleFR5cGU+IGFyZSBtdXR1YWxseQoJICAgICogZXhjbHVzaXZlCgkgICAgKi8KCSAgICBpZiAoZGVjbC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8zLAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxjb21wbGV4VHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZQoJCUVMRU1fVFlQRShkZWNsKSA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgLyoKCSAgICAqIDMuMy4zIDogMwoJICAgICogInR5cGUiIGFuZCBlaXRoZXIgPHNpbXBsZVR5cGU+IG9yIDxjb21wbGV4VHlwZT4gYXJlCgkgICAgKiBtdXR1YWxseSBleGNsdXNpdmUKCSAgICAqLwoJICAgIGlmIChkZWNsLT5uYW1lZFR5cGUgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzMsCgkJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBub2RlLCBjaGlsZCwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ3R5cGUnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlFTEVNX1RZUEUoZGVjbCkgPSB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAidW5pcXVlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImtleSIpKSB8fCAoSVNfU0NIRU1BKGNoaWxkLCAia2V5cmVmIikpKSB7CgkgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB7CgkJY3VySURDID0geG1sU2NoZW1hUGFyc2VJREMoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUUsIGRlY2wtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZLCBkZWNsLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAia2V5cmVmIikpIHsKCQljdXJJREMgPSB4bWxTY2hlbWFQYXJzZUlEQyhjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRiwgZGVjbC0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB9CgkgICAgaWYgKGxhc3RJREMgIT0gTlVMTCkKCQlsYXN0SURDLT5uZXh0ID0gY3VySURDOwoJICAgIGVsc2UKCQlkZWNsLT5pZGNzID0gKHZvaWQgKikgY3VySURDOwoJICAgIGxhc3RJREMgPSBjdXJJREM7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgbm9kZSwgY2hpbGQsCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUpPywgIgoJCSIodW5pcXVlIHwga2V5IHwga2V5cmVmKSopKSIpOwoJfQoJY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwoJZGVjbC0+YW5ub3QgPSBhbm5vdDsKICAgIH0KICAgIC8qCiAgICAqIE5PVEU6IEVsZW1lbnQgRGVjbGFyYXRpb24gUmVwcmVzZW50YXRpb24gT0sgNC4gd2lsbCBiZSBjaGVja2VkIGF0IGEKICAgICogZGlmZmVyZW50IGxheWVyLgogICAgKi8KICAgIEZSRUVfQU5EX05VTEwoZGVzKQogICAgaWYgKHRvcExldmVsKQoJcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBkZWNsKTsKICAgIGVsc2UgewoJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBkZWNsOwoJcmV0dXJuICgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBwYXJ0aWNsZSk7CiAgICB9CgpyZXR1cm5fbnVsbDoKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIGlmIChhbm5vdCAhPSBOVUxMKSB7CglpZiAocGFydGljbGUgIT0gTlVMTCkKCSAgICBwYXJ0aWNsZS0+YW5ub3QgPSBOVUxMOwoJaWYgKGRlY2wgIT0gTlVMTCkKCSAgICBkZWNsLT5hbm5vdCA9IE5VTEw7Cgl4bWxTY2hlbWFGcmVlQW5ub3QoYW5ub3QpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlVW5pb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFVuaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgZXJyb3IsIDAgaW4gY2FzZSBvZiBzdWNjZXNzIGFuZCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVVuaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqY3VyID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgLyoKICAgICogTWFyayB0aGUgc2ltcGxlIHR5cGUgYXMgYmVpbmcgb2YgdmFyaWV0eSAidW5pb24iLgogICAgKi8KICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsKICAgIC8qCiAgICAqIFNQRUMgKEJhc2UgdHlwZSkgKDIpICJJZiB0aGUgPGxpc3Q+IG9yIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLAogICAgKiB0aGVuIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuIgogICAgKi8KICAgIHR5cGUtPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtZW1iZXJUeXBlcyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgIm1lbWJlclR5cGVzIi4gVGhpcyBpcyBhIGxpc3Qgb2YgUU5hbWVzLgogICAgKiBUT0RPOiBDaGVjayB0aGUgdmFsdWUgdG8gY29udGFpbiBhbnl0aGluZy4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1lbWJlclR5cGVzIik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgljb25zdCB4bWxDaGFyICplbmQ7Cgl4bWxDaGFyICp0bXA7Cgljb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsICpuc05hbWU7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBsaW5rLCBsYXN0TGluayA9IE5VTEw7Cgl4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWY7CgoJY3VyID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJdHlwZS0+cmVmID0gY3VyOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWUoY3R4dCwgc2NoZW1hLCBOVUxMLAoJCU5VTEwsIGF0dHIsIEJBRF9DQVNUIHRtcCwgJm5zTmFtZSwgJmxvY2FsTmFtZSkgPT0gMCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIG1lbWJlciB0eXBlIGxpbmsuCgkJKi8KCQlsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKQoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CgkJaWYgKGxpbmsgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJ4bWxTY2hlbWFQYXJzZVVuaW9uLCAiCgkJCSJhbGxvY2F0aW5nIGEgdHlwZSBsaW5rIiwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlsaW5rLT50eXBlID0gTlVMTDsKCQlsaW5rLT5uZXh0ID0gTlVMTDsKCQlpZiAobGFzdExpbmsgPT0gTlVMTCkKCQkgICAgdHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rOwoJCWVsc2UKCQkgICAgbGFzdExpbmstPm5leHQgPSBsaW5rOwoJCWxhc3RMaW5rID0gbGluazsKCQkvKgoJCSogQ3JlYXRlIGEgcmVmZXJlbmNlIGl0ZW0uCgkJKi8KCQlyZWYgPSB4bWxTY2hlbWFOZXdRTmFtZVJlZihzY2hlbWEsIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsCgkJICAgIGxvY2FsTmFtZSwgbnNOYW1lKTsKCQlpZiAocmVmID09IE5VTEwpIHsKCQkgICAgRlJFRV9BTkRfTlVMTCh0bXApCgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQkvKgoJCSogQXNzaWduIHRoZSByZWZlcmVuY2UgdG8gdGhlIGxpbmssIGl0IHdpbGwgYmUgcmVzb2x2ZWQKCQkqIGxhdGVyIGR1cmluZyBmaXh1cCBvZiB0aGUgdW5pb24gc2ltcGxlIHR5cGUuCgkJKi8KCQlsaW5rLT50eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpIHJlZjsKCSAgICB9CgkgICAgRlJFRV9BTkRfTlVMTCh0bXApCgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsKCiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBzaW1wbGUgdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlLCBsYXN0ID0gTlVMTDsKCgkvKgoJKiBBbmNob3IgdGhlIG1lbWJlciB0eXBlcyBpbiB0aGUgInN1YnR5cGVzIiBmaWVsZCBvZiB0aGUKCSogc2ltcGxlIHR5cGUuCgkqLwoJd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewoJCWlmIChsYXN0ID09IE5VTEwpIHsKCQkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJCSAgICBsYXN0ID0gc3VidHlwZTsKCQl9IGVsc2UgewoJCSAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKCQkgICAgbGFzdCA9IHN1YnR5cGU7CgkJfQoJCWxhc3QtPm5leHQgPSBOVUxMOwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsICIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGUqKSIpOwogICAgfQogICAgaWYgKChhdHRyID09IE5VTEwpICYmICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSkgewoJIC8qCgkqIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcwoJKiBFaXRoZXIgdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIG9mIHRoZSA8dW5pb24+IGVsZW1lbnQgbXVzdAoJKiBiZSBub24tZW1wdHkgb3IgdGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgc2ltcGxlVHlwZSBbY2hpbGRdLgoJKi8KCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfVU5JT05fTUVNQkVSVFlQRVNfT1JfU0lNUExFVFlQRVMsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ21lbWJlclR5cGVzJyBvciAiCgkgICAgImF0IGxlYXN0IG9uZSA8c2ltcGxlVHlwZT4gY2hpbGQgbXVzdCBiZSBwcmVzZW50IiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMaXN0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBMaXN0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VMaXN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgLyoKICAgICogTWFyayB0aGUgdHlwZSBhcyBiZWluZyBvZiB2YXJpZXR5ICJsaXN0Ii4KICAgICovCiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVDsKICAgIC8qCiAgICAqIFNQRUMgKEJhc2UgdHlwZSkgKDIpICJJZiB0aGUgPGxpc3Q+IG9yIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLAogICAgKiB0aGVuIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuIgogICAgKi8KICAgIHR5cGUtPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpdGVtVHlwZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAiaXRlbVR5cGUiLiBOT1RFIHRoYXQgd2Ugd2lsbCB1c2UgdGhlICJyZWYiIGFuZCAicmVmTnMiCiAgICAqIGZpZWxkcyBmb3IgaG9sZGluZyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBpdGVtVHlwZS4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgTlVMTCwgTlVMTCwKCW5vZGUsICJpdGVtVHlwZSIsICYodHlwZS0+cmVmTnMpLCAmKHR5cGUtPnJlZikpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkvKgoJKiBzcmMtbGlzdC1pdGVtVHlwZS1vci1zaW1wbGVUeXBlCgkqIEVpdGhlciB0aGUgaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb3IgdGhlIDxzaW1wbGVUeXBlPiBbY2hpbGRdIG9mCgkqIHRoZSA8bGlzdD4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4KCSovCglpZiAodHlwZS0+cmVmICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnaXRlbVR5cGUnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCQkiYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCX0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmICh0eXBlLT5yZWYgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdpdGVtVHlwZScgb3IgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgIm11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsICIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGU/KSIpOwogICAgfQogICAgaWYgKCh0eXBlLT5yZWYgPT0gTlVMTCkgJiYKCSh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJgoJKHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJpdGVtVHlwZSIpID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCSAgICAibXVzdCBiZSBwcmVzZW50IiwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTaW1wbGUgVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgb2xkQ3R4dFR5cGUsIG9sZFBhcmVudEl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZSA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAodG9wTGV2ZWwpIHsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwKCQkibmFtZSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgewoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCQlOVUxMLCBOVUxMLCBhdHRyLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZhdHRyVmFsdWUpICE9IDApCgkJcmV0dXJuIChOVUxMKTsKCSAgICAvKgoJICAgICogU2tpcCBidWlsdC1pbiB0eXBlcy4KCSAgICAqLwoJICAgIGlmIChjdHh0LT5pc1M0UykgewoJCXhtbFNjaGVtYVR5cGVQdHIgYmlUeXBlOwoKCQliaVR5cGUgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShhdHRyVmFsdWUsIHhtbFNjaGVtYU5zKTsKCQlpZiAoYmlUeXBlICE9IE5VTEwpCgkJICAgIHJldHVybiAoYmlUeXBlKTsKCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKHRvcExldmVsID09IDApIHsKICAgICAgICBjaGFyIGJ1Zls0MF07CgoJLyoKCSogUGFyc2UgYXMgbG9jYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSovCiAgICAgICAgc25wcmludGYoYnVmLCAzOSwgIiNTVCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7Cgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIChjb25zdCB4bWxDaGFyICopYnVmLCBOVUxMLCBub2RlKTsKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7Cgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIHR5cGUsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQlOVUxMLCB0eXBlLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogUGFyc2UgYXMgZ2xvYmFsIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqCgkqIE5vdGUgdGhhdCBhdHRyVmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgIm5hbWUiIGhlcmUuCgkqLwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBhdHRyVmFsdWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7Cgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIHR5cGUsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIEF0dHJpYnV0ZSAiZmluYWwiLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVCkKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1Q7CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT047Cgl9IGVsc2UgewoJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZpbmFsIik7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYodHlwZS0+ZmxhZ3MpLAoJCS0xLCAtMSwgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTiwgLTEsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNULAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT04pICE9IDApIHsKCgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGxpc3QgfCB1bmlvbiB8IHJlc3RyaWN0aW9uKSIsCgkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQogICAgfQogICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIHR5cGUsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkQ3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIG9sZFBhcmVudEl0ZW0gPSBjdHh0LT5wYXJlbnRJdGVtOwogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IHR5cGU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIpOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZXN0cmljdGlvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImxpc3QiKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlTGlzdChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJ1bmlvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VVbmlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGxpc3QgfCB1bmlvbikpIik7CiAgICB9CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gb2xkUGFyZW50SXRlbTsKICAgIGN0eHQtPmN0eHRUeXBlID0gb2xkQ3R4dFR5cGU7CgogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgc2NoZW1hIHBhcnRpY2xlIChyZWZlcmVuY2UgdG8gYSBtb2RlbCBncm91cCBkZWZpbml0aW9uKS4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpyZWYgPSBOVUxMLCAqcmVmTnMgPSBOVUxMOwogICAgaW50IG1pbiwgbWF4OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAicmVmIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIE5VTEwsCglhdHRyLCAmcmVmTnMsICZyZWYpICE9IDApIHsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJ4czpub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heCA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsCgkiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWYiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICBpdGVtID0geG1sU2NoZW1hQWRkUGFydGljbGUoY3R4dCwgc2NoZW1hLCBub2RlLCBtaW4sIG1heCk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIENyZWF0ZSBhIHJlZmVyZW5jZSBpdGVtIGFzIHRoZSB0ZXJtOyBpdCB3aWxsIGJlIHN1YnN0aXR1dGVkIGZvcgogICAgKiB0aGUgbW9kZWwgZ3JvdXAgYWZ0ZXIgdGhlIHJlZmVyZW5jZSBoYXMgYmVlbiByZXNvbHZlZC4KICAgICovCiAgICBpdGVtLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCXhtbFNjaGVtYU5ld1FOYW1lUmVmKHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX0dST1VQLCByZWYsIHJlZk5zKTsKICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgaXRlbSwgcmVmTnMpOwogICAgeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgaXRlbSwgbm9kZSwgbWluLCBtYXgpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIC8qIFRPRE86IElzIGFubm90YXRpb24gZXZlbiBhbGxvd2VkIGZvciBhIG1vZGVsIGdyb3VwIHJlZmVyZW5jZT8gKi8KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIFRPRE86IFdoYXQgdG8gZG8gZXhhY3RseSB3aXRoIHRoZSBhbm5vdGF0aW9uPwoJKi8KCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICAvKgogICAgKiBDb3JyZXNwb25kcyB0byBubyBjb21wb25lbnQgYXQgYWxsIGlmIG1pbk9jY3Vycz09bWF4T2NjdXJzPT0wLgogICAgKi8KICAgIGlmICgobWluID09IDApICYmIChtYXggPT0gMCkpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtKTsKICAgIHJldHVybiAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZmluaXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VzIGEgWE1MIHNjaGVtYSBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgaXRlbTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCSAgICBOVUxMLCBub2RlLAoJICAgICJuYW1lIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCU5VTEwsIE5VTEwsIGF0dHIsCgl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGl0ZW0gPSB4bWxTY2hlbWFBZGRHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CglpdGVtLT5jaGlsZHJlbiA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKCWl0ZW0tPmNoaWxkcmVuID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgMCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CglpdGVtLT5jaGlsZHJlbiA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgMCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8pIik7CiAgICB9CgogICAgcmV0dXJuIChpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFudXBEb2M6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHJvb3Qgb2YgdGhlIGRvY3VtZW50LgogKgogKiByZW1vdmVzIHVud2FudGVkIG5vZGVzIGluIGEgc2NoZW1hcyBkb2N1bWVudCB0cmVlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhbnVwRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciByb290KQp7CiAgICB4bWxOb2RlUHRyIGRlbGV0ZSwgY3VyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAocm9vdCA9PSBOVUxMKSkgcmV0dXJuOwoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIGRlbGV0ZSA9IE5VTEw7CiAgICBjdXIgPSByb290OwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICAgICAgeG1sRnJlZU5vZGUoZGVsZXRlKTsKICAgICAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB7CiAgICAgICAgICAgIGlmIChJU19CTEFOS19OT0RFKGN1cikpIHsKICAgICAgICAgICAgICAgIGlmICh4bWxOb2RlR2V0U3BhY2VQcmVzZXJ2ZShjdXIpICE9IDEpIHsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgPSBjdXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKChjdXItPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkgJiYKICAgICAgICAgICAgICAgICAgIChjdXItPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICBnb3RvIHNraXBfY2hpbGRyZW47CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFNraXAgdG8gbmV4dCBub2RlCiAgICAgICAgICovCiAgICAgICAgaWYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkgewogICAgICAgICAgICBpZiAoKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9ERUNMKSAmJgogICAgICAgICAgICAgICAgKGN1ci0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfTk9ERSkpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgc2tpcF9jaGlsZHJlbjoKICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGRvIHsKICAgICAgICAgICAgY3VyID0gY3VyLT5wYXJlbnQ7CiAgICAgICAgICAgIGlmIChjdXIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBpZiAoY3VyID09IHJvb3QpIHsKICAgICAgICAgICAgICAgIGN1ciA9IE5VTEw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3VyLT5uZXh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGRlbGV0ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sVW5saW5rTm9kZShkZWxldGUpOwogICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgZGVsZXRlID0gTlVMTDsKICAgIH0KfQoKCi8qKgogKiB4bWxTY2hlbWFJbXBvcnRTY2hlbWEKICoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYUxvY2F0aW9uOiAgYW4gVVJJIGRlZmluaW5nIHdoZXJlIHRvIGZpbmQgdGhlIGltcG9ydGVkIHNjaGVtYQogKgogKiBpbXBvcnQgYSBYTUwgc2NoZW1hCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yIGFuZCAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCiNpZiAwCnN0YXRpYyB4bWxTY2hlbWFJbXBvcnRQdHIKeG1sU2NoZW1hSW1wb3J0U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uKQp7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBuZXdjdHh0OwoKICAgIG5ld2N0eHQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAobmV3Y3R4dCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChuZXdjdHh0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgLyogS2VlcCB0aGUgc2FtZSBkaWN0aW9ubmFyeSBmb3IgcGFyc2luZywgcmVhbGx5ICovCiAgICB4bWxEaWN0UmVmZXJlbmNlKGN0eHQtPmRpY3QpOwogICAgbmV3Y3R4dC0+ZGljdCA9IGN0eHQtPmRpY3Q7CiAgICBuZXdjdHh0LT5pbmNsdWRlcyA9IDA7CiAgICBuZXdjdHh0LT5VUkwgPSB4bWxEaWN0TG9va3VwKG5ld2N0eHQtPmRpY3QsIHNjaGVtYUxvY2F0aW9uLCAtMSk7CgogICAgeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKG5ld2N0eHQsIGN0eHQtPmVycm9yLCBjdHh0LT53YXJuaW5nLAoJICAgICAgICAgICAgICAgICAgICAgY3R4dC0+dXNlckRhdGEpOwoKICAgIGltcG9ydCA9ICh4bWxTY2hlbWFJbXBvcnQqKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaWYgKGltcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBpbXBvcnRlZCBzY2hlbWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChuZXdjdHh0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIG1lbXNldChpbXBvcnQsIDAsIHNpemVvZih4bWxTY2hlbWFJbXBvcnQpKTsKICAgIGltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHNjaGVtYUxvY2F0aW9uLCAtMSk7CiAgICBpbXBvcnQtPnNjaGVtYSA9IHhtbFNjaGVtYVBhcnNlKG5ld2N0eHQpOwoKICAgIGlmIChpbXBvcnQtPnNjaGVtYSA9PSBOVUxMKSB7CiAgICAgICAgLyogRklYTUUgdXNlIGFub3RoZXIgZXJyb3IgZW51bSBoZXJlID8gKi8KICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICAgICAgICAgICAiRmFpbGVkIHRvIGltcG9ydCBzY2hlbWEgZnJvbSBsb2NhdGlvbiBcIiVzXCIuXG4iLAoJCSAgICAgIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChuZXdjdHh0KTsKCS8qIFRoZSBzY2hlbWFMb2NhdGlvbiBpcyBoZWxkIGJ5IHRoZSBkaWN0aW9uYXJ5LgoJaWYgKGltcG9ydC0+c2NoZW1hTG9jYXRpb24gIT0gTlVMTCkKCSAgICB4bWxGcmVlKCh4bWxDaGFyICopaW1wb3J0LT5zY2hlbWFMb2NhdGlvbik7CgkqLwoJeG1sRnJlZShpbXBvcnQpOwoJcmV0dXJuIE5VTEw7CiAgICB9CgogICAgeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQobmV3Y3R4dCk7CiAgICByZXR1cm4gaW1wb3J0Owp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTTsKCiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUjsKCiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNUKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1Q7CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT047CgogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT047CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT047CiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1NVQlNUSVRVVElPTjsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaWYgKHNjaGVtYS0+dmVyc2lvbiA9PSBOVUxMKQoJeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgInZlcnNpb24iLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1RPS0VOKSwgJihzY2hlbWEtPnZlcnNpb24pKTsKICAgIGVsc2UKCXhtbFNjaGVtYVBWYWxBdHRyKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsICJ2ZXJzaW9uIiwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19UT0tFTiksIE5VTEwpOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZWxlbWVudEZvcm1EZWZhdWx0Iik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgl2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CglpZiAoeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdCh2YWwsICZzY2hlbWEtPmZsYWdzLAoJICAgIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKSAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9FTEVNRk9STURFRkFVTFRfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQogICAgfQoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYXR0cmlidXRlRm9ybURlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0KHZhbCwgJnNjaGVtYS0+ZmxhZ3MsCgkgICAgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpICE9IDApIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0FUVFJGT1JNREVGQVVMVF9WQUxVRSwKCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbERlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwodmFsLCAmKHNjaGVtYS0+ZmxhZ3MpLCAtMSwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTiwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OLAoJICAgIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVCwKCSAgICBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OKSAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJibG9ja0RlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwodmFsLCAmKHNjaGVtYS0+ZmxhZ3MpLCAtMSwKCSAgICBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTiwKCSAgICBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1JFU1RSSUNUSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OLCAtMSwgLTEpICE9IDApIHsKCSAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkiLAoJCXZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMKICogQG5vZGVzOiAgdGhlIGxpc3Qgb2YgdG9wIGxldmVsIG5vZGVzCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGVzKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGVzID09IE5VTEwpKQogICAgICAgIHJldHVybjsKCiAgICBjaGlsZCA9IG5vZGVzOwogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJpbmNsdWRlIikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAicmVkZWZpbmUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImltcG9ydCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VJbXBvcnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgewoJICAgIGN0eHQtPmluY2x1ZGVzKys7CgkgICAgeG1sU2NoZW1hUGFyc2VJbmNsdWRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGN0eHQtPmluY2x1ZGVzLS07Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlZGVmaW5lIikpIHsKCSAgICBUT0RPCgl9CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZmluaXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibm90YXRpb24iKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgTlVMTCwgY2hpbGQsCgkJCSAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0NIRU1BU19DSElMRCwKCQkJICAgIlVuZXhwZWN0ZWQgZWxlbWVudCBcIiVzXCIgYXMgY2hpbGQgb2YgPHNjaGVtYT4uXG4iLAoJCQkgICBjaGlsZC0+bmFtZSwgTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJbXBvcnRQdHIKeG1sU2NoZW1hQWRkSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICB4bWxIYXNoVGFibGVQdHIgKmltcG9ydHMsCgkJICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lKQp7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgcmV0OwoKICAgIGlmICgqaW1wb3J0cyA9PSBOVUxMKSB7CgkqaW1wb3J0cyA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKCWlmICgqaW1wb3J0cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkJTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkiSW50ZXJuYWwgZXJyb3I6IGZhaWxlZCB0byBidWlsZCB0aGUgaW1wb3J0IHRhYmxlIiwKCQlOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfQogICAgcmV0ID0gKHhtbFNjaGVtYUltcG9ydCopIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgaW1wb3J0IHN0cnVjdCIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFJbXBvcnQpKTsKICAgIGlmIChuc05hbWUgPT0gTlVMTCkKCW5zTmFtZSA9IFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRTsKICAgIHhtbEhhc2hBZGRFbnRyeSgqaW1wb3J0cywgbnNOYW1lLCByZXQpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoY29uc3QgY2hhciAqVVJMLCB4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwogICAgLyoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoJKi8KCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZGljdCA9IGRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKGRpY3QpOyAgICAKICAgIGlmIChVUkwgIT0gTlVMTCkKCXJldC0+VVJMID0geG1sRGljdExvb2t1cChkaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldC0+aW5jbHVkZXMgPSAwOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGlmICh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgewogICAgICAgIGlmICh2Y3R4dC0+c2NoZW1hICE9IE5VTEwpCgkgICAgdmN0eHQtPnBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoIioiLCB2Y3R4dC0+c2NoZW1hLT5kaWN0KTsKCWVsc2UKCSAgICB2Y3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7CglpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQiLAoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qIFRPRE86IFBhc3MgdXNlciBkYXRhLiAqLwoJeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHZjdHh0LT5wY3R4dCwgdmN0eHQtPmVycm9yLCB2Y3R4dC0+d2FybmluZywgTlVMTCk7CQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgY29uc3QgeG1sQ2hhciAqbG9jYXRpb24sCgkJCSAgeG1sRG9jUHRyICpkb2MsCgkJCSAgY29uc3QgeG1sQ2hhciAqKnRhcmdldE5hbWVzcGFjZSwKCQkJICBpbnQgYWJzb2x1dGUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQ7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwogICAgY29uc3QgeG1sQ2hhciAqbnM7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CgogICAgLyoKICAgICogTk9URTogVGhpcyB3aWxsIGJlIHVzZWQgZm9yIDxpbXBvcnQ+LCA8eHNpOnNjaGVtYUxvY2F0aW9uPiBhbmQKICAgICogPHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uPi4KICAgICovCiAgICAqZG9jID0gTlVMTDsKICAgIC8qCiAgICAqIEdpdmVuIHRoYXQgdGhlIHNjaGVtYUxvY2F0aW9uIFthdHRyaWJ1dGVdIGlzIG9ubHkgYSBoaW50LCBpdCBpcyBvcGVuCiAgICAqIHRvIGFwcGxpY2F0aW9ucyB0byBpZ25vcmUgYWxsIGJ1dCB0aGUgZmlyc3QgPGltcG9ydD4gZm9yIGEgZ2l2ZW4KICAgICogbmFtZXNwYWNlLCByZWdhcmRsZXNzIG9mIHRoZSC3YWN0dWFsIHZhbHVltyBvZiBzY2hlbWFMb2NhdGlvbiwgYnV0CiAgICAqIHN1Y2ggYSBzdHJhdGVneSByaXNrcyBtaXNzaW5nIHVzZWZ1bCBpbmZvcm1hdGlvbiB3aGVuIG5ldwogICAgKiBzY2hlbWFMb2NhdGlvbnMgYXJlIG9mZmVyZWQuCiAgICAqCiAgICAqIFhTViAodmVyIDIuNS0yKSBkb2VzIHVzZSB0aGUgZmlyc3QgPGltcG9ydD4gd2hpY2ggcmVzb2x2ZXMgdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIFhlcmNlcy1KICh2ZXIgMi41LjEpIGlnbm9yZXMgYWxsIGJ1dCB0aGUgZmlyc3QgZ2l2ZW4gPGltcG9ydD4gLSByZWdhcmRsZXNzIGlmCiAgICAqIHZhbGlkIG9yIG5vdC4KICAgICogV2Ugd2lsbCBmb2xsb3cgWFNWIGhlcmUuCiAgICAqLwogICAgaWYgKGxvY2F0aW9uID09IE5VTEwpIHsKCS8qCgkqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneToKCSoKCSogMyBCYXNlZCBvbiB0aGUgbmFtZXNwYWNlIG5hbWUsIGlkZW50aWZ5IGFuIGV4aXN0aW5nIHNjaGVtYSBkb2N1bWVudCwKCSogZWl0aGVyIGFzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gWE1MIGRvY3VtZW50IG9yIGEgPHNjaGVtYT4gZWxlbWVudAoJKiBpbmZvcm1hdGlvbiBpdGVtLCBpbiBzb21lIGxvY2FsIHNjaGVtYSByZXBvc2l0b3J5OwoJKgoJKiA1IEF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgbmFtZXNwYWNlIG5hbWUgdG8gbG9jYXRlIHN1Y2ggYSByZXNvdXJjZS4KCSoKCSogTk9URTogVGhvc2Ugc3RhdGVnaWVzIGFyZSBub3Qgc3VwcG9ydGVkLCBzbyB3ZSB3aWxsIHNraXAuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGlmIChuc05hbWUgPT0gTlVMTCkKCW5zID0gWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFOwogICAgZWxzZQoJbnMgPSBuc05hbWU7CgogICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBucyk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCS8qCgkqIFRoZXJlIHdhcyBhIHZhbGlkIHJlc291cmNlIGZvciB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSBhbHJlYWR5CgkqIGRlZmluZWQsIHNvIHNraXAuCgkqIFRPRE86IFRoaXMgbWlnaHQgYmUgY2hhbmdlZCBzb21lZGF5IHRvIGFsbG93IGltcG9ydCBvZgoJKiBjb21wb25lbnRzIGZyb20gbXVsdGlwbGUgZG9jdW1lbnRzIGZvciBhIHNpbmdsZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikKCXBjdHh0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIGFjdHh0OwogICAgZWxzZSB7Cgl4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpOwoJcGN0eHQgPSAoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpLT5wY3R4dDsKICAgIH0KICAgIC8qCiAgICAqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneToKICAgICoKICAgICogMiBCYXNlZCBvbiB0aGUgbG9jYXRpb24gVVJJLCBpZGVudGlmeSBhbiBleGlzdGluZyBzY2hlbWEgZG9jdW1lbnQsCiAgICAqIGVpdGhlciBhcyBhIHJlc291cmNlIHdoaWNoIGlzIGFuIFhNTCBkb2N1bWVudCBvciBhIDxzY2hlbWE+IGVsZW1lbnQKICAgICogaW5mb3JtYXRpb24gaXRlbSwgaW4gc29tZSBsb2NhbCBzY2hlbWEgcmVwb3NpdG9yeTsKICAgICoKICAgICogNCBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIGxvY2F0aW9uIFVSSSwgdG8gbG9jYXRlIGEgcmVzb3VyY2Ugb24gdGhlCiAgICAqIHdlYiB3aGljaCBpcyBvciBjb250YWlucyBvciByZWZlcmVuY2VzIGEgPHNjaGVtYT4gZWxlbWVudDsKICAgICogVE9ETzogSG1tLCBJIGRvbid0IGtub3cgaWYgdGhlIHJlZmVyZW5jZSBzdHVmZiBpbiA0LiB3aWxsIHdvcmsuCiAgICAqCiAgICAqLwogICAgaWYgKChhYnNvbHV0ZSA9PSAwKSAmJiAobm9kZSAhPSBOVUxMKSkgewoJeG1sQ2hhciAqYmFzZSwgKlVSSTsKCgliYXNlID0geG1sTm9kZUdldEJhc2Uobm9kZS0+ZG9jLCBub2RlKTsKCWlmIChiYXNlID09IE5VTEwpIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgbm9kZS0+ZG9jLT5VUkwpOwoJfSBlbHNlIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmIChVUkkgIT0gTlVMTCkgewoJICAgIGxvY2F0aW9uID0geG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwgVVJJLCAtMSk7CgkgICAgeG1sRnJlZShVUkkpOwoJfQogICAgfQogICAgcGFyc2VyQ3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKICAgIGlmIChwYXJzZXJDdHh0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgInhtbFNjaGVtYVBhcnNlSW1wb3J0OiAiCgkgICAgImFsbG9jYXRpbmcgYSBwYXJzZXIgY29udGV4dCIsIE5VTEwpOwoJcmV0dXJuKC0xKTsKICAgIH0KICAgIGlmICgocGN0eHQtPmRpY3QgIT0gTlVMTCkgJiYgKHBhcnNlckN0eHQtPmRpY3QgIT0gTlVMTCkpIHsKCXhtbERpY3RGcmVlKHBhcnNlckN0eHQtPmRpY3QpOwoJcGFyc2VyQ3R4dC0+ZGljdCA9IHBjdHh0LT5kaWN0OwoJeG1sRGljdFJlZmVyZW5jZShwYXJzZXJDdHh0LT5kaWN0KTsKICAgIH0KICAgICpkb2MgPSB4bWxDdHh0UmVhZEZpbGUocGFyc2VyQ3R4dCwgKGNvbnN0IGNoYXIgKikgbG9jYXRpb24sCgkgICAgTlVMTCwgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgIC8qCiAgICAqIDIuMSBUaGUgcmVmZXJlbnQgaXMgKGEgZnJhZ21lbnQgb2YpIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4KICAgICogWE1MIGRvY3VtZW50IChzZWUgY2xhdXNlIDEuMSksIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8KICAgICogYSA8c2NoZW1hPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaW4gYSB3ZWxsLWZvcm1lZCBpbmZvcm1hdGlvbgogICAgKiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIFRPRE86IFdoYXQgdG8gZG8gd2l0aCB0aGUgImZyYWdtZW50IiBzdHVmZj8KICAgICoKICAgICogMi4yIFRoZSByZWZlcmVudCBpcyBhIDxzY2hlbWE+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpbgogICAgKiBhIHdlbGwtZm9ybWVkIGluZm9ybWF0aW9uIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcwogICAgKiB0byBhIHZhbGlkIHNjaGVtYS4KICAgICogTk9URTogMi4yIHdvbid0IGFwcGx5LCBzaW5jZSBvbmx5IFhNTCBkb2N1bWVudHMgd2lsbCBiZSBwcm9jZXNzZWQKICAgICogaGVyZS4KICAgICovCiAgICBpZiAoKmRvYyA9PSBOVUxMKSB7Cgl4bWxFcnJvclB0ciBsZXJyOwoJLyoKCSogSXQgaXMgKm5vdCogYW4gZXJyb3IgZm9yIHRoZSBhcHBsaWNhdGlvbiBzY2hlbWEgcmVmZXJlbmNlCgkqIHN0cmF0ZWd5IHRvIGZhaWwuCgkqCgkqIElmIHRoZSBkb2MgaXMgTlVMTCBhbmQgdGhlIHBhcnNlciBlcnJvciBpcyBhbiBJTyBlcnJvciB3ZQoJKiB3aWxsIGFzc3VtZSB0aGF0IHRoZSByZXNvdXJjZSBjb3VsZCBub3QgYmUgbG9jYXRlZCBvciBhY2Nlc3NlZC4KCSoKCSogVE9ETzogVHJ5IHRvIGZpbmQgc3BlY2lmaWMgZXJyb3IgY29kZXMgdG8gcmVhY3Qgb25seSBvbgoJKiBsb2NhbGlzYXRpb24gZmFpbHVyZXMuCgkqCgkqIFRPRE8sIEZJWE1FOiBDaGVjayB0aGUgc3BlYzogaXMgYSBuYW1lc3BhY2UgYWRkZWQgdG8gdGhlIGltcG9ydGVkCgkqIG5hbWVzcGFjZXMsIGV2ZW4gaWYgdGhlIHNjaGVtYUxvY2F0aW9uIGRpZCBub3QgcHJvdmlkZQoJKiBhIHJlc291cmNlPyBJIGd1ZXNzIHNvLCBzaW5jZSBvbWl0dGluZyB0aGUgInNjaGVtYUxvY2F0aW9uIgoJKiBhdHRyaWJ1dGUsIGltcG9ydHMgYSBuYW1lc3BhY2UgYXMgd2VsbC4KCSovCglsZXJyID0geG1sR2V0TGFzdEVycm9yKCk7CglpZiAoKGxlcnIgIT0gTlVMTCkgJiYgKGxlcnItPmRvbWFpbiA9PSBYTUxfRlJPTV9JTykpIHsKCSAgICB4bWxGcmVlUGFyc2VyQ3R4dChwYXJzZXJDdHh0KTsKCSAgICByZXR1cm4oMCk7Cgl9Cgl4bWxTY2hlbWFDdXN0b21FcnIoYWN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEsCgkgICAgbm9kZSwgTlVMTCwKCSAgICAiRmFpbGVkIHRvIHBhcnNlIHRoZSByZXNvdXJjZSAnJXMnIGZvciBpbXBvcnQiLAoJICAgIGxvY2F0aW9uLCBOVUxMKTsKCXhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwoJcmV0dXJuKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0KICAgIHhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwoKICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudCgqZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYUN1c3RvbUVycihhY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBub2RlLCBOVUxMLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIGxvY2F0aW9uLCBOVUxMKTsKCXhtbEZyZWVEb2MoKmRvYyk7CgkqZG9jID0gTlVMTDsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEpOwogICAgfQoKICAgIHhtbFNjaGVtYUNsZWFudXBEb2MocGN0eHQsIHJvb3QpOwoKICAgIGlmICghSVNfU0NIRU1BKHJvb3QsICJzY2hlbWEiKSkgewoJeG1sU2NoZW1hQ3VzdG9tRXJyKGFjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xLAoJICAgIG5vZGUsIE5VTEwsCgkgICAgIlRoZSBYTUwgZG9jdW1lbnQgJyVzJyB0byBiZSBpbXBvcnRlZCBpcyBub3QgYSBYTUwgc2NoZW1hIGRvY3VtZW50IiwKCSAgICBsb2NhdGlvbiwgTlVMTCk7Cgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0KICAgICp0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKHBjdHh0LCByb290LCAidGFyZ2V0TmFtZXNwYWNlIik7CiAgICAvKgogICAgKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDogSW1wb3J0IENvbnN0cmFpbnRzIGFuZCBTZW1hbnRpY3MKICAgICovCiAgICBpZiAobnNOYW1lID09IE5VTEwpIHsKCWlmICgqdGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoYWN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIsCgkJbm9kZSwgTlVMTCwKCQkiVGhlIFhNTCBzY2hlbWEgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGV4cGVjdGVkICIKCQkidG8gaGF2ZSBhIHRhcmdldCBuYW1lc3BhY2U7IHRoaXMgZGlmZmVycyBmcm9tICIKCQkiaXRzIHRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJyIsICp0YXJnZXROYW1lc3BhY2UsIE5VTEwpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMik7Cgl9CiAgICB9IGVsc2UgewoJaWYgKCp0YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihhY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQlub2RlLCBOVUxMLAoJCSJUaGUgWE1MIHNjaGVtYSB0byBiZSBpbXBvcnRlZCBpcyBleHBlY3RlZCB0byBoYXZlIGEgdGFyZ2V0ICIKCQkibmFtZXNwYWNlIG9mICclcyciLCBuc05hbWUsIE5VTEwpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSk7Cgl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCgqdGFyZ2V0TmFtZXNwYWNlLCBuc05hbWUpKSB7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKGFjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18xLAoJCW5vZGUsIE5VTEwsCgkJIlRoZSBYTUwgc2NoZW1hIHRvIGJlIGltcG9ydGVkIGlzIGV4cGVjdGVkIHRvIGhhdmUgYSAiCgkJInRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJzsgdGhpcyBkaWZmZXJzIGZyb20gIgoJCSJpdHMgdGFyZ2V0IG5hbWVzcGFjZSBvZiAnJXMnIiwKCQluc05hbWUsICp0YXJnZXROYW1lc3BhY2UpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSk7Cgl9CiAgICB9CiAgICBpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQocGN0eHQsICYoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cyksIG5zTmFtZSk7CiAgICBpZiAoaW1wb3J0ID09IE5VTEwpIHsKCUFFUlJPUl9JTlQoInhtbFNjaGVtYUFjcXVpcmVTY2hlbWFEb2MiLAoJICAgICJmYWlsZWQgdG8gYnVpbGQgaW1wb3J0IHRhYmxlIik7Cgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBsb2NhdGlvbjsKICAgIGltcG9ydC0+ZG9jID0gKmRvYzsKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBhcnNlRm9ySW1wSW5jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCXhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCWNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZSwKCQkJeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpvbGRVUkwsICoqb2xkTG9jSW1wcywgKm9sZFROUzsKICAgIGludCBvbGRGbGFncywgb2xkTnVtTG9jSW1wcywgb2xkU2l6ZUxvY0ltcHMsIG9sZElzUzRTOwoKICAgIC8qCiAgICAqIFNhdmUgYW5kIHJlc2V0IHRoZSBjb250ZXh0ICYgc2NoZW1hLgogICAgKi8KICAgIG9sZFVSTCA9IHBjdHh0LT5VUkw7CiAgICAvKiBUT0RPOiBJcyB1c2luZyB0aGUgZG9jLT5VUkwgaGVyZSBjb3JyZWN0PyAqLwogICAgcGN0eHQtPlVSTCA9IG5vZGUtPmRvYy0+VVJMOwogICAgb2xkTG9jSW1wcyA9IHBjdHh0LT5sb2NhbEltcG9ydHM7CiAgICBwY3R4dC0+bG9jYWxJbXBvcnRzID0gTlVMTDsKICAgIG9sZE51bUxvY0ltcHMgPSBwY3R4dC0+bmJMb2NhbEltcG9ydHM7CiAgICBwY3R4dC0+bmJMb2NhbEltcG9ydHMgPSAwOwogICAgb2xkU2l6ZUxvY0ltcHMgPSBwY3R4dC0+c2l6ZUxvY2FsSW1wb3J0czsKICAgIHBjdHh0LT5zaXplTG9jYWxJbXBvcnRzID0gMDsKICAgIG9sZEZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIG9sZElzUzRTID0gcGN0eHQtPmlzUzRTOwogICAgeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyhzY2hlbWEpOwogICAgb2xkVE5TID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKICAgIGlmICgodGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpICYmCgl4bWxTdHJFcXVhbCh0YXJnZXROYW1lc3BhY2UsIHhtbFNjaGVtYU5zKSkgewoJLyoKCSogV2UgYXJlIHBhcnNpbmcgdGhlIHNjaGVtYSBmb3Igc2NoZW1hIQoJKi8KCXBjdHh0LT5pc1M0UyA9IDE7CiAgICB9CiAgICAvKgogICAgKiBQYXJzZSB0aGUgc2NoZW1hLgogICAgKi8KICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMocGN0eHQsIHNjaGVtYSwgbm9kZSk7CiAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKHBjdHh0LCBzY2hlbWEsIG5vZGUtPmNoaWxkcmVuKTsKICAgIC8qCiAgICAqIFJlc3RvcmUgdGhlIGNvbnRleHQgJiBzY2hlbWEuCiAgICAqLwogICAgc2NoZW1hLT5mbGFncyA9IG9sZEZsYWdzOwogICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBvbGRUTlM7CiAgICBpZiAocGN0eHQtPmxvY2FsSW1wb3J0cyAhPSBOVUxMKQoJeG1sRnJlZSgoeG1sQ2hhciAqKSBwY3R4dC0+bG9jYWxJbXBvcnRzKTsKICAgIHBjdHh0LT5sb2NhbEltcG9ydHMgPSBvbGRMb2NJbXBzOwogICAgcGN0eHQtPm5iTG9jYWxJbXBvcnRzID0gb2xkTnVtTG9jSW1wczsKICAgIHBjdHh0LT5zaXplTG9jYWxJbXBvcnRzID0gb2xkU2l6ZUxvY0ltcHM7CiAgICBwY3R4dC0+VVJMID0gb2xkVVJMOwogICAgcGN0eHQtPmlzUzRTID0gb2xkSXNTNFM7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUltcG9ydDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW1wb3J0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYKICogbm90IHZhbGlkIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24gPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWVzcGFjZSIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwKCSJuYW1lc3BhY2UiLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLAoJJm5hbWVzcGFjZU5hbWUpICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU1QT1JUX05BTUVTUEFDRV9OT1RfVVJJLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICBOVUxMLCBuYW1lc3BhY2VOYW1lLCBOVUxMLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfSU1QT1JUX05BTUVTUEFDRV9OT1RfVVJJKTsKICAgIH0KCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwKCSJzY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksCgkmc2NoZW1hTG9jYXRpb24pICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU1QT1JUX1NDSEVNQV9OT1RfVVJJLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICBOVUxMLCBuYW1lc3BhY2VOYW1lLCBOVUxMLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfSU1QT1JUX1NDSEVNQV9OT1RfVVJJKTsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbiBoZXJlIGlzIHNpbXBseSBkaXNjYXJkZWQgLi4uCgkgKiBUT0RPOiByZWFsbHk/CiAgICAgICAgICovCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fSU1QT1JUX0NISUxELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICAvKgogICAgKiBBcHBseSBhZGRpdGlvbmFsIGNvbnN0cmFpbnRzLgogICAgKi8KICAgIGlmIChuYW1lc3BhY2VOYW1lICE9IE5VTEwpIHsKCS8qCgkqIDEuMSBJZiB0aGUgbmFtZXNwYWNlIFthdHRyaWJ1dGVdIGlzIHByZXNlbnQsIHRoZW4gaXRzILdhY3R1YWwgdmFsdWW3CgkqIG11c3Qgbm90IG1hdGNoIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgZW5jbG9zaW5nIDxzY2hlbWE+J3MKCSogdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmICh4bWxTdHJFcXVhbChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbmFtZXNwYWNlTmFtZSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBub3QgbWF0Y2ggIgoJCSJ0aGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbXBvcnRpbmcgc2NoZW1hIiwKCQlzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzFfMSk7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogMS4yIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgbm90IHByZXNlbnQsIHRoZW4gdGhlIGVuY2xvc2luZwoJKiA8c2NoZW1hPiBtdXN0IGhhdmUgYSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IGJlIGV4aXN0ZW50IGlmICIKCQkidGhlIGltcG9ydGluZyBzY2hlbWEgaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCU5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIpOwoJfQogICAgfQogICAgLyoKICAgICogQWRkIHRoZSBuYW1lc3BhY2UgdG8gdGhlIGxpc3Qgb2YgbG9jYWxseSBpbXBvcnRlZCBuYW1lc3BhY2UuCiAgICAqLwogICAgaWYgKGN0eHQtPmxvY2FsSW1wb3J0cyA9PSBOVUxMKSB7CgljdHh0LT5sb2NhbEltcG9ydHMgPSAoY29uc3QgeG1sQ2hhciAqKikgeG1sTWFsbG9jKDEwICoKCSAgICBzaXplb2YoY29uc3QgeG1sQ2hhciopKTsKCWN0eHQtPnNpemVMb2NhbEltcG9ydHMgPSAxMDsKCWN0eHQtPm5iTG9jYWxJbXBvcnRzID0gMDsKICAgIH0gZWxzZSBpZiAoY3R4dC0+c2l6ZUxvY2FsSW1wb3J0cyA8PSBjdHh0LT5uYkxvY2FsSW1wb3J0cykgewoJY3R4dC0+c2l6ZUxvY2FsSW1wb3J0cyAqPSAyOwoJY3R4dC0+bG9jYWxJbXBvcnRzID0gKGNvbnN0IHhtbENoYXIgKiopIHhtbFJlYWxsb2MoCgkgICAgKHhtbENoYXIgKiopIGN0eHQtPmxvY2FsSW1wb3J0cywKCSAgICBjdHh0LT5zaXplTG9jYWxJbXBvcnRzICogc2l6ZW9mKGNvbnN0IHhtbENoYXIqKSk7CiAgICB9CiAgICBjdHh0LT5sb2NhbEltcG9ydHNbY3R4dC0+bmJMb2NhbEltcG9ydHMrK10gPSBuYW1lc3BhY2VOYW1lOwogICAgLyoKICAgICogTG9jYXRlIGFuZCBhcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIGN0eHQsCglzY2hlbWEsIG5vZGUsIG5hbWVzcGFjZU5hbWUsCglzY2hlbWFMb2NhdGlvbiwgJmRvYywgJnRhcmdldE5hbWVzcGFjZSwgMCk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChkb2MgIT0gTlVMTCkKCSAgICB4bWxGcmVlRG9jKGRvYyk7CglyZXR1cm4gKHJldCk7CiAgICB9IGVsc2UgaWYgKGRvYyAhPSBOVUxMKSB7CiAgICAgICAJeG1sU2NoZW1hUGFyc2VGb3JJbXBJbmMoY3R4dCwgc2NoZW1hLCB0YXJnZXROYW1lc3BhY2UsCgkgICAgeG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKSk7CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSW5jbHVkZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW5jbHVkZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24sICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxEb2NQdHIgZG9jID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgcm9vdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGUgPSBOVUxMOwogICAgaW50IHdhc0NvbnZlcnRpbmdOcyA9IDA7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogUHJlbGltaW5hcnkgc3RlcCwgZXh0cmFjdCB0aGUgVVJJLVJlZmVyZW5jZSBmb3IgdGhlIGluY2x1ZGUgYW5kCiAgICAqIG1ha2UgYW4gVVJJIGZyb20gdGhlIGJhc2UuCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJzY2hlbWFMb2NhdGlvbiIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewogICAgICAgIHhtbENoYXIgKmJhc2UgPSBOVUxMOwogICAgICAgIHhtbENoYXIgKnVyaSA9IE5VTEw7CgoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZzY2hlbWFMb2NhdGlvbikgIT0gMCkKCSAgICBnb3RvIGV4aXRfaW52YWxpZDsKCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBiYXNlKTsKCSAgICB4bWxGcmVlKGJhc2UpOwoJfQoJaWYgKHVyaSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LAoJCW5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZUluY2x1ZGUsICIKCQkiY291bGQgbm90IGJ1aWxkIGFuIFVSSSBmcm9tIHRoZSBzY2hlbWFMb2NhdGlvbi5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgZ290byBleGl0X2ZhaWx1cmU7Cgl9CglzY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdXJpLCAtMSk7Cgl4bWxGcmVlKHVyaSk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9fVVJJLAoJICAgIE5VTEwsIG5vZGUsICJzY2hlbWFMb2NhdGlvbiIsIE5VTEwpOwoJZ290byBleGl0X2ludmFsaWQ7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlIGFubm90YXRpb25zIGhlcmUgYXJlIHNpbXBseSBkaXNjYXJkZWQgLi4uCgkgKiBUT0RPOiByZWFsbHk/CiAgICAgICAgICovCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fSU5DTFVERV9DSElMRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgLyoKICAgICogUmVwb3J0IHNlbGYtaW5jbHVzaW9uLgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbChzY2hlbWFMb2NhdGlvbiwgY3R4dC0+VVJMKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgaW5jbHVkZSBpdHNlbGYuIiwKCSAgICBzY2hlbWFMb2NhdGlvbik7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFKTsKICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGlmIHRoaXMgb25lIHdhcyBhbHJlYWR5IHByb2Nlc3NlZCB0byBhdm9pZCBpbmNvcnJlY3QKICAgICogZHVwbGljYXRlIGNvbXBvbmVudCBlcnJvcnMgYW5kIGluZmluaXRlIGNpcmN1bGFyIGluY2x1c2lvbi4KICAgICovCiAgICBpbmNsdWRlID0gc2NoZW1hLT5pbmNsdWRlczsKICAgIHdoaWxlIChpbmNsdWRlICE9IE5VTEwpIHsKCWlmICh4bWxTdHJFcXVhbChpbmNsdWRlLT5zY2hlbWFMb2NhdGlvbiwgc2NoZW1hTG9jYXRpb24pKSB7CgkgICAgdGFyZ2V0TmFtZXNwYWNlID0gaW5jbHVkZS0+b3JpZ1RhcmdldE5hbWVzcGFjZTsKCSAgICBpZiAodGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCQkvKgoJCSogQ2hhbWVsZW9uIGluY2x1ZGU6IHNraXAgb25seSBpZiBpdCB3YXMgYnVpbGQgZm9yCgkJKiB0aGUgdGFyZ2V0TmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRpbmcgc2NoZW1hLgoJCSovCgkJaWYgKHhtbFN0ckVxdWFsKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICBpbmNsdWRlLT50YXJnZXROYW1lc3BhY2UpKSB7CgkJICAgIGdvdG8gY2hlY2tfdGFyZ2V0TmFtZXNwYWNlOwoJCX0KCSAgICB9IGVsc2UgewoJCWdvdG8gY2hlY2tfdGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0KCX0KCWluY2x1ZGUgPSBpbmNsdWRlLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRmlyc3Qgc3RlcCBpcyB0byBwYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgaW50byBhbiBET00vSW5mb3NldAogICAgKiBUT0RPOiBVc2UgeG1sQ3R4dFJlYWRGaWxlIHRvIHNoYXJlIHRoZSBkaWN0aW9uYXJ5PwogICAgKi8KICAgIHBhcnNlckN0eHQgPSB4bWxOZXdQYXJzZXJDdHh0KCk7CiAgICBpZiAocGFyc2VyQ3R4dCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJ4bWxTY2hlbWFQYXJzZUluY2x1ZGU6ICIKCSAgICAiYWxsb2NhdGluZyBhIHBhcnNlciBjb250ZXh0IiwgTlVMTCk7Cglnb3RvIGV4aXRfZmFpbHVyZTsKICAgIH0KCiAgICBpZiAoKGN0eHQtPmRpY3QgIT0gTlVMTCkgJiYgKHBhcnNlckN0eHQtPmRpY3QgIT0gTlVMTCkpIHsKCXhtbERpY3RGcmVlKHBhcnNlckN0eHQtPmRpY3QpOwoJcGFyc2VyQ3R4dC0+ZGljdCA9IGN0eHQtPmRpY3Q7Cgl4bWxEaWN0UmVmZXJlbmNlKHBhcnNlckN0eHQtPmRpY3QpOwogICAgfQoKICAgIGRvYyA9IHhtbEN0eHRSZWFkRmlsZShwYXJzZXJDdHh0LCAoY29uc3QgY2hhciAqKSBzY2hlbWFMb2NhdGlvbiwKCSAgICBOVUxMLCBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CiAgICBpZiAoZG9jID09IE5VTEwpIHsKCS8qCgkqIFRPRE86IEl0IGlzIG5vdCBhbiBlcnJvciBmb3IgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZQoJKiBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSB0byBmYWlsIHRvIHJlc29sdmUgaXQgYWxsLCBpbiB3aGljaAoJKiBjYXNlIG5vIGNvcnJlc3BvbmRpbmcgaW5jbHVzaW9uIGlzIHBlcmZvcm1lZC4KCSogU28gZG8gd2UgbmVlZCBhIHdhcm5pbmcgcmVwb3J0IGhlcmU/CgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkZhaWxlZCB0byBsb2FkIHRoZSBkb2N1bWVudCAnJXMnIGZvciBpbmNsdXNpb24iLCBzY2hlbWFMb2NhdGlvbik7Cglnb3RvIGV4aXRfaW52YWxpZDsKICAgIH0KCiAgICAvKgogICAgICogVGhlbiBleHRyYWN0IHRoZSByb290IG9mIHRoZSBzY2hlbWEKICAgICAqLwogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfTk9ST09ULAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBpbmNsdWRlZCBkb2N1bWVudCAnJXMnIGhhcyBubyBkb2N1bWVudCAiCgkgICAgImVsZW1lbnQiLCBzY2hlbWFMb2NhdGlvbik7Cglnb3RvIGV4aXRfaW52YWxpZDsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgc2NoZW1hcyB0b3AgbGV2ZWwgZWxlbWVudAogICAgICovCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBkb2N1bWVudCAnJXMnIHRvIGJlIGluY2x1ZGVkIGlzIG5vdCBhIHNjaGVtYSBkb2N1bWVudCIsCgkgICAgc2NoZW1hTG9jYXRpb24pOwoJZ290byBleGl0X2ludmFsaWQ7CiAgICB9CgogICAgdGFyZ2V0TmFtZXNwYWNlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCByb290LCAidGFyZ2V0TmFtZXNwYWNlIik7CiAgICAvKgogICAgKiAyLjEgU0lJIGhhcyBhIHRhcmdldE5hbWVzcGFjZSBbYXR0cmlidXRlXSwgYW5kIGl0cyC3YWN0dWFsCiAgICAqIHZhbHVltyBpcyBpZGVudGljYWwgdG8gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0YXJnZXROYW1lc3BhY2UKICAgICogW2F0dHJpYnV0ZV0gb2YgU0lJkiAod2hpY2ggbXVzdCBoYXZlIHN1Y2ggYW4gW2F0dHJpYnV0ZV0pLgogICAgKi8KY2hlY2tfdGFyZ2V0TmFtZXNwYWNlOgogICAgaWYgKHRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CglpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU5DTFVERSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgaW5jbHVkZWQgc2NoZW1hICIKCQkiJyVzJyBoYXMgdG8gYmUgYWJzZW50LCBzaW5jZSB0aGUgaW5jbHVkaW5nIHNjaGVtYSAiCgkJImhhcyBubyB0YXJnZXQgbmFtZXNwYWNlIiwKCQlzY2hlbWFMb2NhdGlvbik7CgkgICAgZ290byBleGl0X2ludmFsaWQ7Cgl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCh0YXJnZXROYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU5DTFVERSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbmNsdWRlZCBzY2hlbWEgJyVzJyAiCgkJImRpZmZlcnMgZnJvbSAnJXMnIG9mIHRoZSBpbmNsdWRpbmcgc2NoZW1hIiwKCQl0YXJnZXROYW1lc3BhY2UsIHNjaGVtYUxvY2F0aW9uLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgZ290byBleGl0X2ludmFsaWQ7Cgl9CiAgICB9IGVsc2UgaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCWlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSA9PSAwKSB7CgkgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsKCX0gZWxzZQoJICAgIHdhc0NvbnZlcnRpbmdOcyA9IDE7CiAgICB9CgogICAgaWYgKGluY2x1ZGUgIT0gTlVMTCkKCWdvdG8gZXhpdDsKCiAgICAvKgogICAgKiBVUkdFTlQgVE9ETzogSWYgdGhlIHNjaGVtYSBpcyBhIGNoYW1lbGVvbi1pbmNsdWRlIHRoZW4gY29weSB0aGUKICAgICogY29tcG9uZW50cyBpbnRvIHRoZSBpbmNsdWRpbmcgc2NoZW1hIGFuZCBtb2RpZnkgdGhlIHRhcmdldE5hbWVzcGFjZQogICAgKiBvZiB0aG9zZSBjb21wb25lbnRzLCBkbyBub3RoaW5nIG90aGVyd2lzZS4KICAgICogTk9URTogVGhpcyBpcyBjdXJyZW50bHkgd29ya2VkLWFyb3VuZCBieSBjb21waWxpbmcgdGhlIGNoYW1lbGVvbgogICAgKiBmb3IgZXZlcnkgZGVzdGluY3QgaW5jbHVkaW5nIHRhcmdldE5hbWVzcGFjZTsgdGh1cyBub3QgcGVyZm9ybWFudCBhdAogICAgKiB0aGUgbW9tZW50LgogICAgKiBUT0RPOiBDaGVjayB3aGVuIHRoZSBuYW1lc3BhY2UgaW4gd2lsZGNhcmRzIGZvciBjaGFtZWxlb25zIG5lZWRzCiAgICAqIHRvIGJlIGNvbnZlcnRlZDogYmVmb3JlIHdlIGJ1aWx0IHdpbGRjYXJkIGludGVyc2VjdGlvbnMgb3IgYWZ0ZXIuCiAgICAqLwogICAgLyoKICAgICogUmVnaXN0ZXIgdGhlIGluY2x1ZGUuCiAgICAqLwogICAgaW5jbHVkZSA9ICh4bWxTY2hlbWFJbmNsdWRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpKTsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGluY2x1ZGUgZW50cnkiLCBOVUxMKTsKCWdvdG8gZXhpdF9mYWlsdXJlOwogICAgfQogICAgbWVtc2V0KGluY2x1ZGUsIDAsIHNpemVvZih4bWxTY2hlbWFJbmNsdWRlKSk7CiAgICBpbmNsdWRlLT5uZXh0ID0gc2NoZW1hLT5pbmNsdWRlczsKICAgIHNjaGVtYS0+aW5jbHVkZXMgPSBpbmNsdWRlOwogICAgLyoKICAgICogVE9ETzogVXNlIHRoZSByZXNvbHZlZCBVUkkgZm9yIHRoZSB0aGlzIGxvY2F0aW9uLCBzaW5jZSBpdCBtaWdodAogICAgKiBkaWZmZXIgaWYgdXNpbmcgZmlsZW5hbWVzL1VSSXMgc2ltdWx0YW5lb3NseS4KICAgICovCiAgICBpbmNsdWRlLT5zY2hlbWFMb2NhdGlvbiA9IHNjaGVtYUxvY2F0aW9uOwogICAgaW5jbHVkZS0+ZG9jID0gZG9jOwogICAgLyoKICAgICogSW4gY2FzZSBvZiBjaGFtZWxlb25zLCB0aGUgb3JpZ2luYWwgdGFyZ2V0IG5hbWVzcGFjZSB3aWxsIGRpZmZlcgogICAgKiBmcm9tIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlLgogICAgKi8KICAgIGluY2x1ZGUtPm9yaWdUYXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7CiAgICBpbmNsdWRlLT50YXJnZXROYW1lc3BhY2UgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKI2lmZGVmIERFQlVHX0lOQ0xVREVTCiAgICBpZiAodGFyZ2V0TmFtZXNwYWNlICE9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkgICAgIklOQ0xVRElORyBDSEFNRUxFT04gJyVzJ1xuICBvcmlnIFROUyAnJXMnXG4iCgkgICAgIiAgaW50byBUTlMgJyVzJ1xuIiwgc2NoZW1hTG9jYXRpb24sCgkgICAgdGFyZ2V0TmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBlbHNlCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCSAgICAiSU5DTFVESU5HICclcydcbiAgb3JpZy1UTlMgJyVzJ1xuIiwgc2NoZW1hTG9jYXRpb24sCgkgICAgdGFyZ2V0TmFtZXNwYWNlKTsKI2VuZGlmCiAgICAvKgogICAgKiBDb21waWxlIHRoZSBpbmNsdWRlZCBzY2hlbWEuCiAgICAqLwogICAgeG1sU2NoZW1hUGFyc2VGb3JJbXBJbmMoY3R4dCwgc2NoZW1hLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgcm9vdCk7CgpleGl0OgogICAgLyoKICAgICogUmVtb3ZlIHRoZSBjb252ZXJ0aW5nIGZsYWcuCiAgICAqLwogICAgaWYgKCh3YXNDb252ZXJ0aW5nTnMgPT0gMCkgJiYKCShzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsKICAgIHJldHVybiAoMSk7CgpleGl0X2ludmFsaWQ6CiAgICBpZiAoZG9jICE9IE5VTEwpIHsKCWlmIChpbmNsdWRlICE9IE5VTEwpCgkgICAgaW5jbHVkZS0+ZG9jID0gTlVMTDsKCXhtbEZyZWVEb2MoZG9jKTsKICAgIH0KICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKCmV4aXRfZmFpbHVyZToKICAgIGlmIChkb2MgIT0gTlVMTCkgewoJaWYgKGluY2x1ZGUgIT0gTlVMTCkKCSAgICBpbmNsdWRlLT5kb2MgPSBOVUxMOwoJeG1sRnJlZURvYyhkb2MpOwogICAgfQogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHR5cGU6IHRoZSAiY29tcG9zaXRvciIgdHlwZQogKiBAcGFydGljbGVOZWVkZWQ6IGlmIGEgYSBtb2RlbCBncm91cCB3aXRoIGEgcGFydGljbGUKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNlcXVlbmNlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUsCgkJCSBpbnQgd2l0aFBhcnRpY2xlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW07CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lciwgKmNvbnRhaW5lcjsKICAgIGludCBtaW4gPSAwLCBtYXggPSAwOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBDcmVhdGUgYSBtb2RlbCBncm91cCB3aXRoIHRoZSBnaXZlbiBjb21wb3NpdG9yLgogICAgKi8KICAgIGl0ZW0gPSB4bWxTY2hlbWFBZGRNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgdHlwZSwgJmNvbnRhaW5lciwgbm9kZSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKCiAgICBpZiAod2l0aFBhcnRpY2xlKSB7CglpZiAodHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB7CgkgICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIDEsIDEsICIoMCB8IDEpIik7CgkgICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDEsIDEsIDEsICIxIik7Cgl9IGVsc2UgewoJICAgIC8qIGNob2ljZSArIHNlcXVlbmNlICovCgkgICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CgkgICAgbWF4ID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwKCQkiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKCX0KCXhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIE5VTEwsIG5vZGUsIG1pbiwgbWF4KTsKCS8qCgkqIENyZWF0ZSBhIHBhcnRpY2xlCgkqLwoJcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShjdHh0LCBzY2hlbWEsIG5vZGUsIG1pbiwgbWF4KTsKCWlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGl0ZW07CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQlOVUxMLCBOVUxMLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQlOVUxMLCBOVUxMLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgogICAgfQoKICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKICAgIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpIHsKCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnQsIGxhc3QgPSBOVUxMOwoKCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKCSAgICBwYXJ0ID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwKCQlzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBpZiAocGFydCAhPSBOVUxMKSB7CgkJaWYgKHBhcnQtPm1pbk9jY3VycyA+IDEpCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsCgkJCU5VTEwsIE5VTEwsIGNoaWxkLAoJCQkiSW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzIChtdXN0IGJlIDAgb3IgMSkiLCBOVUxMKTsKCQlpZiAocGFydC0+bWF4T2NjdXJzID4gMSkKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKCQkJTlVMTCwgTlVMTCwgY2hpbGQsCgkJCSJJbnZhbGlkIHZhbHVlIGZvciBtYXhPY2N1cnMgKG11c3QgYmUgMCBvciAxKSIsCgkJCU5VTEwpOwoJCWlmIChsYXN0ID09IE5VTEwpCgkJICAgIGl0ZW0tPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0OwoJCWVsc2UKCQkgICAgbGFzdC0+bmV4dCA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcGFydDsKCQlsYXN0ID0gcGFydDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoYW5ub3RhdGlvbj8sIGVsZW1lbnQqKSIpOwoJfQogICAgfSBlbHNlIHsKCS8qIGNob2ljZSArIHNlcXVlbmNlICovCgl4bWxTY2hlbWFUcmVlSXRlbVB0ciBwYXJ0ID0gTlVMTCwgbGFzdCA9IE5VTEw7CgoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKCgkgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewoJCXBhcnQgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCQlwYXJ0ID0KCQkgICAgeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmUmVmKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHsKCQlwYXJ0ID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKQoJCSAgICB4bWxTY2hlbWFQYXJzZUFueShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkJcGFydCA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCQlwYXJ0ID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgMSk7CgkgICAgfQoJICAgIGlmIChwYXJ0ICE9IE5VTEwpIHsKCQlpZiAobGFzdCA9PSBOVUxMKQoJCSAgICBpdGVtLT5jaGlsZHJlbiA9IHBhcnQ7CgkJZWxzZQoJCSAgICBsYXN0LT5uZXh0ID0gcGFydDsKCQlsYXN0ID0gcGFydDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoZWxlbWVudCB8IGdyb3VwIHwgY2hvaWNlIHwgc2VxdWVuY2UgfCBhbnkpKikiKTsKCX0KICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIGlmICh3aXRoUGFydGljbGUpIHsKCWlmICgobWluID09IDApICYmIChtYXggPT0gMCkpCgkgICAgcmV0dXJuIChOVUxMKTsKCWVsc2UKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgcGFydGljbGUpOwogICAgfSBlbHNlCglyZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBSZXN0cmljdGlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCB4bWxTY2hlbWFUeXBlVHlwZSBwYXJlbnRUeXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNoYXIgYnVmWzMwXTsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lciwgKmNvbnRhaW5lcjsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoKICAgIC8qCiAgICAqIFRPRE86IElzIHRoZSBjb250YWluZXIgbmVlZGVkIGF0IGFsbD8gdGhlIGFub255bW91cwogICAgKiBpdGVtcyBpbnNpZGUgc2hvdWxkIGdlbmVyYXRlIHVuaXF1ZSBuYW1lcyBhbHJlYWR5LgogICAgKi8KICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjcmVzdHIlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgY29udGFpbmVyID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCBidWYsIC0xKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJhc2UiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImJhc2UiIC0gbWFuZGF0b3J5IGlmIGluc2lkZSBhIGNvbXBsZXggdHlwZS4KICAgICovCiAgICAvKgogICAgKiBTUEVDICgxLjIpICJvdGhlcndpc2UgKDxyZXN0cmljdGlvbj4gaGFzIG5vIDxzaW1wbGVUeXBlPiAiCiAgICAqIGFtb25nIGl0cyBbY2hpbGRyZW5dKSwgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gd2hpY2ggaXMKICAgICogdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieQogICAgKiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0iCiAgICAqLwogICAgaWYgKCh4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwKCU5VTEwsIE5VTEwsIG5vZGUsICJiYXNlIiwKCSYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSkgPT0gMCkgJiYKCSh0eXBlLT5iYXNlID09IE5VTEwpICYmCgkodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgdHlwZSwgbm9kZSwgImJhc2UiLCBOVUxMKTsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIHNpbXBsZSB0eXBlIGFuY2VzdG9yLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBjdHh0LT5jb250YWluZXIgPSBjb250YWluZXI7CiAgICBpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8c2ltcGxlVHlwZT48cmVzdHJpY3Rpb24+PHNpbXBsZVR5cGU+LgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CgkJLyoKCQkqIHNyYy1yZXN0cmljdGlvbi1iYXNlLW9yLXNpbXBsZVR5cGUKCQkqIEVpdGhlciB0aGUgYmFzZSBbYXR0cmlidXRlXSBvciB0aGUgc2ltcGxlVHlwZSBbY2hpbGRdIG9mIHRoZQoJCSogPHJlc3RyaWN0aW9uPiBlbGVtZW50IG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLgoJCSovCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU1RSSUNUSU9OX0JBU0VfT1JfU0lNUExFVFlQRSwKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICdiYXNlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQl0eXBlLT5iYXNlVHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU1RSSUNUSU9OX0JBU0VfT1JfU0lNUExFVFlQRSwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwKCQkiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2Jhc2UnIG9yIGEgPHNpbXBsZVR5cGU+IGNoaWxkICIKCQkibXVzdCBiZSBwcmVzZW50IiwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxjb21wbGV4Q29udGVudD48cmVzdHJpY3Rpb24+Li4uCgkqIGZvbGxvd2VkIGJ5OgoJKgoJKiBNb2RlbCBncm91cHMgPGFsbD4sIDxjaG9pY2U+IGFuZCA8c2VxdWVuY2U+LgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwKCQkgICAgc2NoZW1hLCBjaGlsZCwgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCS8qCgkqIE1vZGVsIGdyb3VwIHJlZmVyZW5jZSA8Z3JvdXA+LgoJKi8KCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmUmVmKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8Y29tcGxleFR5cGU+PHNpbXBsZUNvbnRlbnQ+PHJlc3RyaWN0aW9uPi4uLgoJKgoJKiAiMS4xIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPgoJKiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8cmVzdHJpY3Rpb24+IGlmIHRoZXJlIGlzIG9uZTsiCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIC8qCgkgICAgKiBXZSB3aWxsIHN0b3JlIHRoZSB0by1iZS1yZXN0cmljdGVkIHNpbXBsZSB0eXBlIGluCgkgICAgKiB0eXBlLT5jb250ZW50VHlwZURlZiAqdGVtcG9yYXJpbHkqLgoJICAgICovCgkgICAgdHlwZS0+Y29udGVudFR5cGVEZWYgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgaWYgKCB0eXBlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKQoJCXJldHVybiAoTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KCiAgICBpZiAoKHBhcmVudFR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwKCShwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBsYXN0ZmFjZXQgPSBOVUxMOwoJLyoKCSogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50PjxyZXN0cmljdGlvbj4uLi4KCSogPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uPi4uLgoJKi8KCgkvKgoJKiBBZGQgdGhlIGZhY2V0cyB0byB0aGUgc2ltcGxlIHR5cGUgYW5jZXN0b3IuCgkqLwoJLyoKCSogVE9ETzogRGF0YXR5cGVzOiA0LjEuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb24gb2YKCSogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKCSogKlNpbmdsZSBGYWNldCBWYWx1ZSoKCSovCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgIm1pbkluY2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5FeGNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4SW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heEV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJ0b3RhbERpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJmcmFjdGlvbkRpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJwYXR0ZXJuIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImVudW1lcmF0aW9uIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIndoaXRlU3BhY2UiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heExlbmd0aCIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5MZW5ndGgiKSkpIHsKCSAgICBmYWNldCA9IHhtbFNjaGVtYVBhcnNlRmFjZXQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKGZhY2V0ICE9IE5VTEwpIHsKCQlpZiAobGFzdGZhY2V0ID09IE5VTEwpCgkJICAgIHR5cGUtPmZhY2V0cyA9IGZhY2V0OwoJCWVsc2UKCQkgICAgbGFzdGZhY2V0LT5uZXh0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCS8qCgkqIENyZWF0ZSBsaW5rcyBmb3IgZGVyaXZhdGlvbiBhbmQgdmFsaWRhdGlvbi4KCSovCglpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rLCBsYXN0RmFjZXRMaW5rID0gTlVMTDsKCgkgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkgICAgZG8gewoJCWZhY2V0TGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkJaWYgKGZhY2V0TGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJICAgIHhtbEZyZWUoZmFjZXRMaW5rKTsKCQkgICAgcmV0dXJuIChOVUxMKTsKCQl9CgkJZmFjZXRMaW5rLT5mYWNldCA9IGZhY2V0OwoJCWZhY2V0TGluay0+bmV4dCA9IE5VTEw7CgkJaWYgKGxhc3RGYWNldExpbmsgPT0gTlVMTCkKCQkgICAgdHlwZS0+ZmFjZXRTZXQgPSBmYWNldExpbms7CgkJZWxzZQoJCSAgICBsYXN0RmFjZXRMaW5rLT5uZXh0ID0gZmFjZXRMaW5rOwoJCWxhc3RGYWNldExpbmsgPSBmYWNldExpbms7CgkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCX0KICAgIH0KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7CgkvKgoJKiBBdHRyaWJ1dGUgdXNlcy9kZWNsYXJhdGlvbnMuCgkqLwoJY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCS8qCgkqIEF0dHJpYnV0ZSB3aWxkY2FyZC4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9CgkJeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CglpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiYW5ub3RhdGlvbj8sIChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKCX0gZWxzZSBpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpIHsKCSAgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8sIChtaW5FeGNsdXNpdmUgfCBtaW5JbmNsdXNpdmUgfCAiCgkJIm1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCAiCgkJImxlbmd0aCB8IG1pbkxlbmd0aCB8IG1heExlbmd0aCB8IGVudW1lcmF0aW9uIHwgd2hpdGVTcGFjZSB8ICIKCQkicGF0dGVybikqKT8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpIik7Cgl9IGVsc2UgewoJICAgIC8qIFNpbXBsZSB0eXBlICovCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8sIChtaW5FeGNsdXNpdmUgfCBtaW5JbmNsdXNpdmUgfCAiCgkJIm1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCAiCgkJImxlbmd0aCB8IG1pbkxlbmd0aCB8IG1heExlbmd0aCB8IGVudW1lcmF0aW9uIHwgd2hpdGVTcGFjZSB8ICIKCQkicGF0dGVybikqKSkiKTsKCX0KICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYW4gPGV4dGVuc2lvbj4sIHdoaWNoIGlzIGZvdW5kIGluc2lkZSBhCiAqIDxzaW1wbGVDb250ZW50PiBvciA8Y29tcGxleENvbnRlbnQ+LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlLgogKgogKiBUT0RPOiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgeG1sU2NoZW1hVHlwZVR5cGUgcGFyZW50VHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjaGFyIGJ1ZlszMF07CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXIsICpjb250YWluZXI7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT047CgogICAgc25wcmludGYoYnVmLCAyOSwgIiNleHQlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgY29udGFpbmVyID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCBidWYsIC0xKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJhc2UiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImJhc2UiIC0gbWFuZGF0b3J5LgogICAgKi8KICAgIGlmICgoeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsCglOVUxMLCBOVUxMLCBub2RlLCAiYmFzZSIsICYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSkgPT0gMCkgJiYKCSh0eXBlLT5iYXNlID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsICJiYXNlIiwgTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSB0eXBlIGFuY2VzdG9yLgoJKi8KCXhtbFNjaGVtYUFkZEFubm90YXRpb24oKHhtbFNjaGVtYUFubm90SXRlbVB0cikgdHlwZSwKCSAgICB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCkpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBjdHh0LT5jb250YWluZXIgPSBjb250YWluZXI7CiAgICBpZiAocGFyZW50VHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CgkvKgoJKiBDb3JyZXNwb25kcyB0byA8Y29tcGxleFR5cGU+PGNvbXBsZXhDb250ZW50PjxleHRlbnNpb24+Li4uIGFuZDoKCSoKCSogTW9kZWwgZ3JvdXBzIDxhbGw+LCA8Y2hvaWNlPiwgPHNlcXVlbmNlPiBhbmQgPGdyb3VwPi4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsCgkJICAgIGNoaWxkLCBYTUxfU0NIRU1BX1RZUEVfQUxMLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwKCQkgICAgY2hpbGQsIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsCgkJY2hpbGQsIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmUmVmKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyoKCSogQXR0cmlidXRlIHVzZXMvZGVjbGFyYXRpb25zLgoJKi8KCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CgkvKgoJKiBBdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgY3R4dC0+Y3R4dFR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0KCQl4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChwYXJlbnRUeXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCSAgICAvKiBDb21wbGV4IGNvbnRlbnQgZXh0ZW5zaW9uLiAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpIik7Cgl9IGVsc2UgewoJICAgIC8qIFNpbXBsZSBjb250ZW50IGV4dGVuc2lvbi4gKi8KCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sICgoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgIgoJCSJhbnlBdHRyaWJ1dGU/KSkiKTsKCX0KICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZUNvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIGNvbXBsZXggdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4Q29udGVudCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaXhlZCIpKSkKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogU2V0IHRoZSAnbWl4ZWQnIG9uIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCiAgICAqLwogICAgaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsICJtaXhlZCIsIDApKSAgewoJaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpID09IDApCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIGNvbXBsZXggdHlwZSBhbmNlc3Rvci4KCSovCgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZXh0ZW5zaW9uIikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbihjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENvbXBsZXggVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lciwgKm5hbWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlOwogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsgLyogVGhlIHJlcG9ydGVkIGRlc2lnbmF0aW9uLiAqLwogICAgY2hhciBidWZbNDBdOwogICAgaW50IGZpbmFsID0gMCwgYmxvY2sgPSAwOwoKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CgogICAgaWYgKHRvcExldmVsKSB7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCBOVUxMLCBub2RlLCAibmFtZSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0NULCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KCiAgICBpZiAodG9wTGV2ZWwgPT0gMCkgewoJLyoKCSogUGFyc2UgYXMgbG9jYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjQ1QlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CgluYW1lID0gdHlwZS0+bmFtZTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOwoJLyoKCSogVE9ETzogV2UgbmVlZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCiAgICB9IGVsc2UgewoJLyoKCSogUGFyc2UgYXMgZ2xvYmFsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgoJKi8KCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKICAgIH0KICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgImlkIi4KCQkqLwoJCXhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgdHlwZSwgbm9kZSwKCQkgICAgQkFEX0NBU1QgImlkIik7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgIm1peGVkIi4KCQkqLwoJCWlmICh4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZShjdHh0LCAmZGVzLCB0eXBlLAoJCSAgICAoeG1sTm9kZVB0cikgYXR0cikpCgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CgkgICAgfSBlbHNlIGlmICh0b3BMZXZlbCkgewoJCS8qCgkJKiBBdHRyaWJ1dGVzIG9mIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbnMuCgkJKi8KCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgewoJCSAgICAvKiBQYXNzLiAqLwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImFic3RyYWN0Ii4KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsICZkZXMsIHR5cGUsCgkJCSh4bWxOb2RlUHRyKSBhdHRyKSkKCQkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9BQlNUUkFDVDsKCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJmaW5hbCIuCgkJICAgICovCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsCgkJCSh4bWxOb2RlUHRyKSBhdHRyKTsKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsCgkJCSYodHlwZS0+ZmxhZ3MpLAoJCQktMSwKCQkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04sCgkJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04sCgkJCS0xLCAtMSwgLTEpICE9IDApCgkJICAgIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkJICAgICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLAoJCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkgICAgfSBlbHNlIAoJCQlmaW5hbCA9IDE7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmxvY2siKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiYmxvY2siLgoJCSAgICAqLwoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CgkJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwKCQkJLTEsCgkJCVhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OLAoJCQktMSwgLTEsIC0xKSAhPSAwKSB7CgkJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkgICAgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpICIsCgkJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCSAgICB9IGVsc2UgCgkJCWJsb2NrID0gMTsKCQl9IGVsc2UgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgJmRlcywgdHlwZSwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICAmZGVzLCB0eXBlLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkmZGVzLCB0eXBlLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgaWYgKCEgYmxvY2spIHsKCS8qCgkqIEFwcGx5IGRlZmF1bHQgImJsb2NrIiB2YWx1ZXMuCgkqLwoJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1JFU1RSSUNUSU9OKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT047CglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwogICAgfQogICAgaWYgKCEgZmluYWwpIHsKCS8qCgkqIEFwcGx5IGRlZmF1bHQgImJsb2NrIiB2YWx1ZXMuCgkqLwoJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT047CglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVDb250ZW50IikpIHsKCS8qCgkqIDMuNC4zIDogMi4yCgkqIFNwZWNpZnlpbmcgbWl4ZWQ9J3RydWUnIHdoZW4gdGhlIDxzaW1wbGVDb250ZW50PgoJKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4gaGFzIG5vIGVmZmVjdAoJKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgICAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleENvbnRlbnQiKSkgewoJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMKCSogIi4uLnRoZSB0aGlyZCBhbHRlcm5hdGl2ZSAobmVpdGhlciA8c2ltcGxlQ29udGVudD4gbm9yCgkqIDxjb21wbGV4Q29udGVudD4pIGlzIGNob3Nlbi4gVGhpcyBjYXNlIGlzIHVuZGVyc3Rvb2QgYXMgc2hvcnRoYW5kCgkqIGZvciBjb21wbGV4IGNvbnRlbnQgcmVzdHJpY3RpbmcgdGhlILd1ci10eXBlIGRlZmluaXRpb263LCBhbmQgdGhlCgkqIGRldGFpbHMgb2YgdGhlIG1hcHBpbmdzIHNob3VsZCBiZSBtb2RpZmllZCBhcyBuZWNlc3NhcnkuCgkqLwoJdHlwZS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgkvKgoJKiBQYXJzZSBtb2RlbCBncm91cHMuCgkqLwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDEpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDEpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZlJlZihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgZGVjbHMvcmVmcy4KCSovCiAgICAgICAgY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCS8qCgkqIFBhcnNlIGF0dHJpYnV0ZSB3aWxkY2FyZC4KCSovCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICAmZGVzLCB0eXBlLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAoc2ltcGxlQ29udGVudCB8IGNvbXBsZXhDb250ZW50IHwgIgoJICAgICIoKGdyb3VwIHwgYWxsIHwgY2hvaWNlIHwgc2VxdWVuY2UpPywgKChhdHRyaWJ1dGUgfCAiCgkgICAgImF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSkpIik7CiAgICB9CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICBjdHh0LT5jdHh0VHlwZSA9IGN0eHRUeXBlOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2NoZW1hOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBkZWZpbml0aW9uIGZyb20gYSBub2RlIHNldAogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hUHRyCnhtbFNjaGVtYVBhcnNlU2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKICAgIGludCBuYmVycm9yczsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICAvKgogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hUGFyc2Ugb25seSBhbmQgaXMgdXNlZCBpZgogICAgKiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYSB0aGUgQVBJOyBpLmUuIG5vdAogICAgKiBhdXRvbWF0aWNhbGx5IGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgZG9jdW1lbnQuCiAgICAqLwogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBuYmVycm9ycyA9IGN0eHQtPm5iZXJyb3JzOwogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgY3R4dC0+aXNTNFMgPSAwOwogICAgaWYgKElTX1NDSEVNQShub2RlLCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7CgogICAgICAgIHNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0KTsKICAgICAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInRhcmdldE5hbWVzcGFjZSIpOwoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZ2YWwpOwoJICAgIC8qCgkgICAgKiBUT0RPOiBTaG91bGQgd2UgcHJvY2VlZCB3aXRoIGFuIGludmFsaWQgdGFyZ2V0IG5hbWVzcGFjZT8KCSAgICAqLwoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCSAgICBpZiAoeG1sU3RyRXF1YWwoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIHhtbFNjaGVtYU5zKSkgewoJCS8qCgkJKiBXZSBhcmUgcGFyc2luZyB0aGUgc2NoZW1hIGZvciBzY2hlbWEhCgkJKi8KCQljdHh0LT5pc1M0UyA9IDE7CgkgICAgfQoJfSBlbHNlIHsKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IE5VTEw7Cgl9CgkvKgoJKiBBZGQgdGhlIGN1cnJlbnQgbnMgbmFtZSBhbmQgbG9jYXRpb24gdG8gdGhlIGltcG9ydCB0YWJsZTsKCSogdGhpcyBpcyBuZWVkZWQgdG8gaGF2ZSBhIGNvbnNpc3RlbnQgbWVjaGFuaXNtLCByZWdhcmRsZXNzCgkqIGlmIGFsbCBzY2hlbWF0YSBhcmUgY29uc3RydWN0ZWQgZHluYW1pY2FsbHkgZmlyZWQgYnkgdGhlCgkqIGluc3RhbmNlIG9yIGlmIHRoZSBzY2hlbWEgdG8gYmUgdXNlZCB3YXMgc3BlY2lmaWVkIHZpYQoJKiB0aGUgQVBJLgoJKi8KCWltcG9ydCA9IHhtbFNjaGVtYUFkZEltcG9ydChjdHh0LCAmKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMpLAoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWlmIChpbXBvcnQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfRkFJTEVEX0JVSUxEX0lNUE9SVCwKCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VTY2hlbWEsICIKCQkiZmFpbGVkIHRvIGFkZCBhbiBpbXBvcnQgZW50cnkiLCBOVUxMKTsKCSAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CgkgICAgc2NoZW1hID0gTlVMTDsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiA9IGN0eHQtPlVSTDsKCS8qCgkqIE5PVEU6IFdlIHdvbid0IHNldCB0aGUgZG9jIGhlcmUsIG90aGVyd2lzZSBpdCB3aWxsIGJlIGZyZWVkCgkqIGlmIHRoZSBpbXBvcnQgc3RydWN0IGlzIGZyZWVkLgoJKiBpbXBvcnQtPmRvYyA9IGN0eHQtPmRvYzsKCSovCgl4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKGN0eHQsIHNjaGVtYSwgbm9kZSk7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChjdHh0LCBzY2hlbWEsIG5vZGUtPmNoaWxkcmVuKTsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sRG9jUHRyIGRvYzsKCglkb2MgPSBub2RlLT5kb2M7CgogICAgICAgIGlmICgoZG9jICE9IE5VTEwpICYmIChkb2MtPlVSTCAhPSBOVUxMKSkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJCSAgICAgICJUaGUgZmlsZSBcIiVzXCIgaXMgbm90IGEgWE1MIHNjaGVtYS5cbiIsIGRvYy0+VVJMLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIlRoZSBmaWxlIGlzIG5vdCBhIFhNTCBzY2hlbWEuXG4iLCBOVUxMLCBOVUxMKTsKCX0KCXJldHVybihOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CiAgICAgICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWUoc2NoZW1hKTsKICAgICAgICAgICAgc2NoZW1hID0gTlVMTDsKICAgICAgICB9CiAgICB9CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpCglzY2hlbWEtPmNvdW50ZXIgPSBjdHh0LT5jb3VudGVyOwogICAgY3R4dC0+bmJlcnJvcnMgPSBuYmVycm9yczsKI2lmZGVmIERFQlVHCiAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZSgpIGZhaWxlZFxuIik7CiNlbmRpZgogICAgcmV0dXJuIChzY2hlbWEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJVmFsaWRhdGluZyB1c2luZyBTY2hlbWFzCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUmVhZGluZy9Xcml0aW5nIFNjaGVtYXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWYgMCAvKiBXaWxsIGJlIGVuYWJsZWQgaWYgaXQgaXMgY2xlYXIgd2hhdCBvcHRpb25zIGFyZSBuZWVkZWQuICovCi8qKgogKiB4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBvcHRpb25zOiBhIGNvbWJpbmF0aW9uIG9mIHhtbFNjaGVtYVBhcnNlck9wdGlvbgogKgogKiBTZXRzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSBwYXJzZS4KICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBhbgogKiBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlckN0eHRTZXRPcHRpb25zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICAgaW50IG9wdGlvbnMpCgp7CiAgICBpbnQgaTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBXQVJOSU5HOiBDaGFuZ2UgdGhlIHN0YXJ0IHZhbHVlIGlmIGFkZGluZyB0byB0aGUKICAgICogeG1sU2NoZW1hUGFyc2VPcHRpb24uCiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfQogICAgfQogICAgY3R4dC0+b3B0aW9ucyA9IG9wdGlvbnM7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9uczoKICogQGN0eHQ6IGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIFJldHVybnMgdGhlIG9wdGlvbiBjb21iaW5hdGlvbiBvZiB0aGUgcGFyc2VyIGNvbnRleHQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlckN0eHRHZXRPcHRpb25zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dChjb25zdCBjaGFyICpVUkwpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUjsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIHJldC0+VVJMID0geG1sRGljdExvb2t1cChyZXQtPmRpY3QsIChjb25zdCB4bWxDaGFyICopIFVSTCwgLTEpOwogICAgcmV0LT5pbmNsdWRlcyA9IDA7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0OgogKiBAYnVmZmVyOiAgYSBwb2ludGVyIHRvIGEgY2hhciBhcnJheSBjb250YWluaW5nIHRoZSBzY2hlbWFzCiAqIEBzaXplOiAgdGhlIHNpemUgb2YgdGhlIGFycmF5CiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IG1lbW9yeSBidWZmZXIgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3TWVtUGFyc2VyQ3R4dChjb25zdCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoKGJ1ZmZlciA9PSBOVUxMKSB8fCAoc2l6ZSA8PSAwKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5idWZmZXIgPSBidWZmZXI7CiAgICByZXQtPnNpemUgPSBzaXplOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dDoKICogQGRvYzogIGEgcHJlcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZG9jdW1lbnQuCiAqIE5CLiBUaGUgZG9jdW1lbnQgbWF5IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgcGFyc2luZyBwcm9jZXNzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dCh4bWxEb2NQdHIgZG9jKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoZG9jID09IE5VTEwpCiAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKCQkJICBOVUxMKTsKICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIC8qIFRoZSBhcHBsaWNhdGlvbiBoYXMgcmVzcG9uc2liaWxpdHkgZm9yIHRoZSBkb2N1bWVudCAqLwogICAgcmV0LT5wcmVzZXJ2ZSA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+ZG9jICE9IE5VTEwgJiYgIWN0eHQtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2MoY3R4dC0+ZG9jKTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKSB7Cgl4bWxGcmVlKCh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtcyk7Cgl4bWxGcmVlKGN0eHQtPmFzc2VtYmxlKTsKICAgIH0KICAgIGlmIChjdHh0LT52Y3R4dCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KGN0eHQtPnZjdHh0KTsKICAgIH0KICAgIGlmIChjdHh0LT5sb2NhbEltcG9ydHMgIT0gTlVMTCkKCXhtbEZyZWUoKHhtbENoYXIgKikgY3R4dC0+bG9jYWxJbXBvcnRzKTsKICAgIGlmIChjdHh0LT5zdWJzdEdyb3VwcyAhPSBOVUxMKQoJeG1sSGFzaEZyZWUoY3R4dC0+c3Vic3RHcm91cHMsCgkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZVN1YnN0R3JvdXApOwogICAgeG1sRGljdEZyZWUoY3R4dC0+ZGljdCk7CiAgICB4bWxGcmVlKGN0eHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKgkJCUJ1aWxkaW5nIHRoZSBjb250ZW50IG1vZGVscwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCQl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsIG1lbWJlcjsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgZW5kOwogICAgeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBzdWJzdEdyb3VwOwogICAgaW50IGk7CgogICAgZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwogICAgLyoKICAgICogV3JhcCB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwIHdpdGggYSBDSE9JQ0UuCiAgICAqLwogICAgc3RhcnQgPSBwY3R4dC0+c3RhdGU7CiAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CiAgICBzdWJzdEdyb3VwID0geG1sU2NoZW1hR2V0RWxlbWVudFN1YnN0aXR1dGlvbkdyb3VwKHBjdHh0LCBlbGVtRGVjbCk7CiAgICBpZiAoc3Vic3RHcm91cCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBHRVRfTk9ERShwYXJ0aWNsZSksCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAsICIKCSAgICAiZGVjbGFyYXRpb24gaXMgbWFya2VkIGhhdmluZyBhIHN1YnN0LiBncm91cCBidXQgbm9uZSAiCgkgICAgImF2YWlsYWJsZS5cbiIsIGVsZW1EZWNsLT5uYW1lLCBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCS8qCgkqIE5PVEUgdGhhdCB3ZSBwdXQgdGhlIGRlY2xhcmF0aW9uIGluLCBldmVuIGlmIGl0J3MgYWJzdHJhY3QsCgkqLwoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCSAgICBzdGFydCwgTlVMTCwKCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpLCBlbmQpOwoJLyoKCSogQWRkIHN1YnN0LiBncm91cCBtZW1iZXJzLgoJKi8KCWZvciAoaSA9IDA7IGkgPCBzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zOyBpKyspIHsKCSAgICBtZW1iZXIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXNbaV07CgkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQlzdGFydCwgTlVMTCwKCQltZW1iZXItPm5hbWUsIG1lbWJlci0+dGFyZ2V0TmFtZXNwYWNlLCBtZW1iZXIpLAoJCWVuZCk7Cgl9CiAgICB9IGVsc2UgewoJaW50IGNvdW50ZXI7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKCWludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CgkgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CglpbnQgbWluT2NjdXJzID0gcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJY291bnRlciA9CgkgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwgbWluT2NjdXJzLAoJICAgIG1heE9jY3Vycyk7Cglob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCSAgICBzdGFydCwgTlVMTCwKCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpLAoJICAgIGhvcCk7CgkvKgoJKiBBZGQgc3Vic3QuIGdyb3VwIG1lbWJlcnMuCgkqLwoJZm9yIChpID0gMDsgaSA8IHN1YnN0R3JvdXAtPm1lbWJlcnMtPm5iSXRlbXM7IGkrKykgewoJICAgIG1lbWJlciA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtc1tpXTsKCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCXN0YXJ0LCBOVUxMLAoJCW1lbWJlci0+bmFtZSwgbWVtYmVyLT50YXJnZXROYW1lc3BhY2UsIG1lbWJlciksCgkJaG9wKTsKCX0KCXhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwgaG9wLCBzdGFydCwgY291bnRlcik7Cgl4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIGhvcCwgZW5kLCBjb3VudGVyKTsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApCgl4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBzdGFydCwgZW5kKTsKICAgIHBjdHh0LT5zdGF0ZSA9IGVuZDsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWxGb3JFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmICgoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbiktPmZsYWdzICYKCVhNTF9TQ0hFTUFTX0VMRU1fU1VCU1RfR1JPVVBfSEVBRCkgewoJLyoKCSogU3Vic3RpdHV0aW9uIGdyb3Vwcy4KCSovCgl4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAoY3R4dCwgcGFydGljbGUpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoKCWVsZW1EZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbjsKCglpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKCSAgICByZXR1cm47CglpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCWVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCk7Cgl9IGVsc2UgaWYgKChwYXJ0aWNsZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkgJiYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPCAyKSkgewoJICAgIC8qIFNwZWNpYWwgY2FzZS4gKi8KCSAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwgc3RhcnQsIE5VTEwsCgkJZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsKCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBzdGFydCk7Cgl9IGVsc2UgewoJICAgIGludCBjb3VudGVyOwoJICAgIGludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CgkJCSAgICBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKCSAgICBpbnQgbWluT2NjdXJzID0gcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPwoJCQkgICAgMCA6IHBhcnRpY2xlLT5taW5PY2N1cnMgLSAxOwoKCSAgICBzdGFydCA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIE5VTEwpOwoJICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCWVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCk7CgkgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBzdGFydCwgY291bnRlcik7CgkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCgkJTlVMTCwgY291bnRlcik7Cgl9CglpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKQoJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGN0eHQtPnN0YXRlKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBwYXJ0aWNsZTogIHRoZSBwYXJ0aWNsZSBjb21wb25lbnQKICogQG5hbWU6ICB0aGUgY29tcGxleCB0eXBlJ3MgbmFtZSB3aG9zZSBjb250ZW50IGlzIGJlaW5nIGJ1aWx0CiAqCiAqIEdlbmVyYXRlIHRoZSBhdXRvbWF0YSBzZXF1ZW5jZSBuZWVkZWQgZm9yIHRoYXQgdHlwZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChwYXJ0aWNsZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwsICIKCSAgICAicGFydGljbGUgaXMgTlVMTC5cbiIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuOwogICAgfQogICAgaWYgKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIEdFVF9OT0RFKHBhcnRpY2xlKSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCwgIgoJICAgICJubyB0ZXJtIG9uIHBhcnRpY2xlLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm47CiAgICB9CgogICAgc3dpdGNoIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogewoJICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkOwoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbnM7CgoJICAgIHdpbGQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbjsKCgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKCSAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCgkgICAgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgPT0gMSkgewoJCWlmICh3aWxkLT5hbnkgPT0gMSkgewoJCSAgICAvKgoJCSAgICAqIFdlIG5lZWQgdG8gYWRkIGJvdGggdHJhbnNpdGlvbnM6CgkJICAgICoKCQkgICAgKiAxLiB0aGUgeyIqIiwgIioifSBmb3IgZWxlbWVudHMgaW4gYSBuYW1lc3BhY2UuCgkJICAgICovCgkJICAgIGN0eHQtPnN0YXRlID0KCQkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkgICAgLyoKCQkgICAgKiAyLiB0aGUgeyIqIn0gZm9yIGVsZW1lbnRzIGluIG5vIG5hbWVzcGFjZS4KCQkgICAgKi8KCQkgICAgY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIG5zID0gd2lsZC0+bnNTZXQ7CgkJICAgIGRvIHsKCQkJY3R4dC0+c3RhdGUgPSBzdGFydDsKCQkJY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkgICAgY3R4dC0+c3RhdGUsIE5VTEwsIEJBRF9DQVNUICIqIiwgbnMtPnZhbHVlLCB3aWxkKTsKCQkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoKCQkgICAgLyoKCQkgICAgKiBMZWFkIG5vZGVzIHdpdGggdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIHRvIHRoZSBzaW5rLXN0YXRlCgkJICAgICogeyIqIiwgIiMjb3RoZXIifS4KCQkgICAgKi8KCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLCBzdGFydCwgTlVMTCwKCQkJQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsIHdpbGQpOwoJCSAgICAvKgoJCSAgICAqIE9wZW4gYSBkb29yIGZvciBub2RlcyB3aXRoIGFueSBvdGhlciBuYW1lc3BhY2UKCQkgICAgKiB7IioiLCAiKiJ9CgkJICAgICovCgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQl9CgkgICAgfSBlbHNlIHsKCQlpbnQgY291bnRlcjsKCQl4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKCQlpbnQgbWF4T2NjdXJzID0KCQkgICAgcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPyBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKCQlpbnQgbWluT2NjdXJzID0KCQkgICAgcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJCWNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCQlob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCQlpZiAod2lsZC0+YW55ID09IDEpIHsKCQkgICAgY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHdpbGQpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCSAgICBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIE5VTEwsIHdpbGQpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCWN0eHQtPnN0YXRlID0KCQkJICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBucy0+dmFsdWUsIHdpbGQpOwoJCQl4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCQlucyA9IG5zLT5uZXh0OwoJCSAgICB9IHdoaWxlIChucyAhPSBOVUxMKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgZGVhZEVuZDsKCgkJICAgIGRlYWRFbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgZGVhZEVuZCwgQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsIHdpbGQpOwoJCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIEJBRF9DQVNUICIqIiwgd2lsZCk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CgkJfQoJCXhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBob3AsIHN0YXJ0LCBjb3VudGVyKTsKCQl4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwoJICAgIH0KCSAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CgkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBzdGFydCwgZW5kKTsKCSAgICB9CgkgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWxGb3JFbGVtZW50KGN0eHQsIHBhcnRpY2xlKTsKCSAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBzdWI7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIG1heCBhbmQgbWluIG9jY3VyYW5jZXMgYXJlIGRlZmF1bHQgKDEpIHRoZW4KICAgICAgICAgICAgICAgICAqIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlIHBhcnRpY2xlcyBvZiB0aGUgPHNlcXVlbmNlPi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDEpICYmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKGN0eHQsCgkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKCQkJCW9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKCQkJCXBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLCBVTkJPVU5ERUQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoY3R4dCwKCQkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewoJCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChjdHh0LAoJCQkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCgkJCQkgICAgb2xkc3RhdGUsIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHBhcnRpY2xlLT5tYXhPY2N1cnMgPiAxKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHBhcnRpY2xlLT5taW5PY2N1cnMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKCQkJICAgIG9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCgkJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwKCQkJICAgIHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKGN0eHQsCgkJCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLAoJCQkgICAgdG1wLCBvbGRzdGF0ZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKGN0eHQsCgkJCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBzdWI7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCBlbmQ7CgogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIGVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzIGFuZCByZW1lcmdlIHRoZSBlbmQgd2l0aCBhbgogICAgICAgICAgICAgICAgICogZXBzaWxvbiB0cmFuc2l0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKGN0eHQsCgkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CiAgICAgICAgICAgICAgICAgICAgICAgIFVOQk9VTkRFRCA6IHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxOwogICAgICAgICAgICAgICAgICAgIGludCBtaW5PY2N1cnMgPQogICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMSA/IDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiB1c2UgYSBjb3VudGVyIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB0cmFuc3Rpb25zCiAgICAgICAgICAgICAgICAgICAgICogd2hpY2ggd2VudCB0aHJvdWdoIHRoZSBjaG9pY2UuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY291bnRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwgbWluT2NjdXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4T2NjdXJzKTsKICAgICAgICAgICAgICAgICAgICBob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCgkJICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChjdHh0LAoJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBob3AsIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDp7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoJCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHN1YjsKCQl4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOwogICAgICAgICAgICAgICAgaW50IGxheDsKCgkJc3ViID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgaWYgKHN1YiA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CgoJCSAgICBlbGVtRGVjbCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBzdWItPmNoaWxkcmVuOwoJCSAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsLCAiCgkJCSAgICAiPGVsZW1lbnQ+IHBhcnRpY2xlIGEgTlVMTCB0ZXJtLlxuIiwgTlVMTCwgTlVMTCk7CgkJCXJldHVybjsKCQkgICAgfTsKCQkgICAgLyoKCQkgICAgKiBOT1RFOiBUaGUge21heCBvY2N1cnN9IG9mIGFsbCB0aGUgcGFydGljbGVzIGluIHRoZQoJCSAgICAqIHtwYXJ0aWNsZXN9IG9mIHRoZSBncm91cCBtdXN0IGJlIDAgb3IgMTsgdGhpcyBpcwoJCSAgICAqIGFscmVhZHkgZW5zdXJlZCBkdXJpbmcgdGhlIHBhcnNlIG9mIHRoZSBjb250ZW50IG9mCgkJICAgICogPGFsbD4uCgkJICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKChzdWItPm1pbk9jY3VycyA9PSAxKSAmJgoJCQkoc3ViLT5tYXhPY2N1cnMgPT0gMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsCgkJCQkJCWVsZW1EZWNsLT5uYW1lLAoJCQkJCQllbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkJCQkxLCAxLCBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoc3ViLT5taW5PY2N1cnMgPT0gMCkgJiYKCQkJKHN1Yi0+bWF4T2NjdXJzID09IDEpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50VHJhbnMyKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLAoJCQkJCQkgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHN1YiA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGF4ID0gcGFydGljbGUtPm1pbk9jY3VycyA9PSAwOwogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3QWxsVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMLCBsYXgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCwgZm91bmQgIgoJCSJ1bmV4cGVjdGVkIHRlcm0gb2YgdHlwZSAlZCBpbiBjb250ZW50IG1vZGVsIG9mIGNvbXBsZXggIgoJCSJ0eXBlICclcycuXG4iLAoJCXBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSwgbmFtZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lCiAqCiAqIEJ1aWxkcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgY29tcGxleCB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoKICAgIGlmICgodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwKCSh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkgfHwKCSgodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSAmJgoJKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkpKQoJcmV0dXJuOwoKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICJCdWlsZGluZyBjb250ZW50IG1vZGVsIGZvciAlc1xuIiwgbmFtZSk7CiNlbmRpZgoKICAgIGN0eHQtPmFtID0geG1sTmV3QXV0b21hdGEoKTsKICAgIGlmIChjdHh0LT5hbSA9PSBOVUxMKSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkgICAgIkNhbm5vdCBjcmVhdGUgYXV0b21hdGEgZm9yIGNvbXBsZXggdHlwZSAlc1xuIiwgbmFtZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3RhcnQgPSBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhR2V0SW5pdFN0YXRlKGN0eHQtPmFtKTsKICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChjdHh0LCAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzLCBuYW1lKTsKICAgIHhtbEF1dG9tYXRhU2V0RmluYWxTdGF0ZShjdHh0LT5hbSwgY3R4dC0+c3RhdGUpOwogICAgdHlwZS0+Y29udE1vZGVsID0geG1sQXV0b21hdGFDb21waWxlKGN0eHQtPmFtKTsKICAgIGlmICh0eXBlLT5jb250TW9kZWwgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLAoJICAgICJGYWlsZWQgdG8gY29tcGlsZSB0aGUgY29udGVudCBtb2RlbCIsIE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxSZWdleHBJc0RldGVybWluaXN0KHR5cGUtPmNvbnRNb2RlbCkgIT0gMSkgewogICAgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1RfREVURVJNSU5JU1RJQywKCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfTk9UREVURVJNSU5JU1QsICovCgkgICAgTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwKCSAgICAiVGhlIGNvbnRlbnQgbW9kZWwgaXMgbm90IGRldGVybWluaXN0IiwgTlVMTCk7CiAgICB9IGVsc2UgewojaWZkZWYgREVCVUdfQ09OVEVOVF9SRUdFWFAKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQgbW9kZWwgb2YgJXM6XG4iLCB0eXBlLT5uYW1lKTsKICAgICAgICB4bWxSZWdleHBQcmludChzdGRlcnIsIHR5cGUtPmNvbnRNb2RlbCk7CiNlbmRpZgogICAgfQogICAgY3R4dC0+c3RhdGUgPSBOVUxMOwogICAgeG1sRnJlZUF1dG9tYXRhKGN0eHQtPmFtKTsKICAgIGN0eHQtPmFtID0gTlVMTDsKfQoKLyoqCiAqIHhtbFNjaGVtYUVsZW1lbnRGaXh1cDoKICogQGVsZW06ICB0aGUgc2NoZW1hIGVsZW1lbnQgY29udGV4dAogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgdGhlIHJlZmVyZW5jZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgogKiBvciBwYXJ0aWNsZSwgd2hpY2ggaGFzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gYXMgaXQncwogKiB0ZXJtLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRWxlbWVudEZpeHVwKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIGNvbnRleHQgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZWxlbURlY2wgPT0gTlVMTCkgfHwKCSgoZWxlbURlY2wgIT0gTlVMTCkgJiYKCShlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX1JFU09MVkVEKSkpCiAgICAgICAgcmV0dXJuOwogICAgZWxlbURlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfUkVTT0xWRUQ7CgogICAgaWYgKChlbGVtRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgJiYgKGVsZW1EZWNsLT5uYW1lZFR5cGUgIT0gTlVMTCkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCgkvKiAodHlwZSBkZWZpbml0aW9uKSAuLi4gb3RoZXJ3aXNlIHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktwoJKiB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIHR5cGUgW2F0dHJpYnV0ZV0gLi4uCgkqLwoJdHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBlbGVtRGVjbC0+bmFtZWRUeXBlLAoJICAgIGVsZW1EZWNsLT5uYW1lZFR5cGVOcyk7CglpZiAodHlwZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCBlbGVtRGVjbC0+bm9kZSwKCQkidHlwZSIsIGVsZW1EZWNsLT5uYW1lZFR5cGUsIGVsZW1EZWNsLT5uYW1lZFR5cGVOcywKCQlYTUxfU0NIRU1BX1RZUEVfQkFTSUMsICJ0eXBlIGRlZmluaXRpb24iKTsKCX0gZWxzZQoJICAgIGVsZW1EZWNsLT5zdWJ0eXBlcyA9IHR5cGU7CiAgICB9CiAgICBpZiAoZWxlbURlY2wtPnN1YnN0R3JvdXAgIT0gTlVMTCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBzdWJzdEhlYWQ7CgoJLyoKCSogRklYTUUgVE9ETzogRG8gd2UgbmVlZCBhIG5ldyBmaWVsZCBpbiBfeG1sU2NoZW1hRWxlbWVudCBmb3IKCSogc3Vic3RpdHV0aW9uR3JvdXA/CgkqLwoJc3Vic3RIZWFkID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGVsZW1EZWNsLT5zdWJzdEdyb3VwLAoJICAgIGVsZW1EZWNsLT5zdWJzdEdyb3VwTnMpOwoJaWYgKHN1YnN0SGVhZCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCBOVUxMLAoJCSJzdWJzdGl0dXRpb25Hcm91cCIsIGVsZW1EZWNsLT5zdWJzdEdyb3VwLAoJCWVsZW1EZWNsLT5zdWJzdEdyb3VwTnMsIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hRWxlbWVudEZpeHVwKHN1YnN0SGVhZCwgY3R4dCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgLyoKCSAgICAqIFNldCB0aGUgInN1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbiIuCgkgICAgKiBOT1RFIHRoYXQgbm93IHdlIHVzZSB0aGUgInJlZkRlY2wiIGZpZWxkIGZvciB0aGlzLgoJICAgICovCgkgICAgZWxlbURlY2wtPnJlZkRlY2wgPSBzdWJzdEhlYWQ7CgkgICAgLyoKCSAgICAqICh0eXBlIGRlZmluaXRpb24pLi4ub3RoZXJ3aXNlIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvZiB0aGUKCSAgICAqIGVsZW1lbnQgZGVjbGFyYXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YKCSAgICAqIHRoZSBzdWJzdGl0dXRpb25Hcm91cCBbYXR0cmlidXRlXSwgaWYgcHJlc2VudAoJICAgICovCgkgICAgaWYgKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCWVsZW1EZWNsLT5zdWJ0eXBlcyA9IHN1YnN0SGVhZC0+c3VidHlwZXM7Cgl9CiAgICB9CiAgICBpZiAoKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAoZWxlbURlY2wtPm5hbWVkVHlwZSA9PSBOVUxMKSAmJgoJKGVsZW1EZWNsLT5zdWJzdEdyb3VwID09IE5VTEwpKQoJZWxlbURlY2wtPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlVW5pb25NZW1iZXJUeXBlczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNjaGVtYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBhbmQgYnVpbGRzIHRoZSAibWVtYmVyIHR5cGUgZGVmaW5pdGlvbnMiIHByb3BlcnR5IG9mIHRoZSB1bmlvbgogKiBzaW1wbGUgdHlwZS4gVGhpcyBoYW5kbGVzIHBhcnQgKDEpLCBwYXJ0ICgyKSBpcyBkb25lIGluCiAqIHhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KCkKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVzb2x2ZVVuaW9uTWVtYmVyVHlwZXMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewoKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rLCBuZXdMaW5rOwogICAgeG1sU2NoZW1hVHlwZVB0ciBtZW1iZXJUeXBlOwoKICAgIC8qCiAgICAqIFNQRUMgKDEpICJJZiB0aGUgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gW0RlZmluaXRpb246XQogICAgKiBkZWZpbmUgdGhlIGV4cGxpY2l0IG1lbWJlcnMgYXMgdGhlIHR5cGUgZGVmaW5pdGlvbnMgt3Jlc29sdmVktwogICAgKiB0byBieSB0aGUgaXRlbXMgaW4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSwKICAgICogaWYgYW55LCBmb2xsb3dlZCBieSB0aGUgdHlwZSBkZWZpbml0aW9ucyBjb3JyZXNwb25kaW5nIHRvIHRoZQogICAgKiA8c2ltcGxlVHlwZT5zIGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDx1bmlvbj4sIGlmIGFueS4iCiAgICAqLwogICAgLyoKICAgICogUmVzb2x2ZSByZWZlcmVuY2VzLgogICAgKi8KICAgIGxpbmsgPSB0eXBlLT5tZW1iZXJUeXBlczsKICAgIGxhc3RMaW5rID0gTlVMTDsKICAgIHdoaWxlIChsaW5rICE9IE5VTEwpIHsKCWNvbnN0IHhtbENoYXIgKm5hbWUsICpuc05hbWU7CgoJbmFtZSA9ICgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGxpbmstPnR5cGUpLT5uYW1lOwoJbnNOYW1lID0gKCh4bWxTY2hlbWFRTmFtZVJlZlB0cikgbGluay0+dHlwZSktPnRhcmdldE5hbWVzcGFjZTsKCgltZW1iZXJUeXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIG5hbWUsIG5zTmFtZSk7CglpZiAoKG1lbWJlclR5cGUgPT0gTlVMTCkgfHwgKCEgSVNfU0lNUExFX1RZUEUobWVtYmVyVHlwZSkpKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCXR5cGUsIHR5cGUtPm5vZGUsICJtZW1iZXJUeXBlcyIsCgkJbmFtZSwgbnNOYW1lLCBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCSAgICAvKgoJICAgICogUmVtb3ZlIHRoZSBtZW1iZXIgdHlwZSBsaW5rLgoJICAgICovCgkgICAgaWYgKGxhc3RMaW5rID09IE5VTEwpCgkJdHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rLT5uZXh0OwoJICAgIGVsc2UKCQlsYXN0TGluay0+bmV4dCA9IGxpbmstPm5leHQ7CgkgICAgbmV3TGluayA9IGxpbms7CgkgICAgbGluayA9IGxpbmstPm5leHQ7CgkgICAgeG1sRnJlZShuZXdMaW5rKTsKCX0gZWxzZSB7CgkgICAgbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CgkgICAgbGFzdExpbmsgPSBsaW5rOwoJICAgIGxpbmsgPSBsaW5rLT5uZXh0OwoJfQogICAgfQogICAgLyoKICAgICogQWRkIGxvY2FsIHNpbXBsZSB0eXBlcywKICAgICovCiAgICBtZW1iZXJUeXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICB3aGlsZSAobWVtYmVyVHlwZSAhPSBOVUxMKSB7CglsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CglsaW5rLT5uZXh0ID0gTlVMTDsKCWlmIChsYXN0TGluayA9PSBOVUxMKQoJICAgIHR5cGUtPm1lbWJlclR5cGVzID0gbGluazsKCWVsc2UKCSAgICBsYXN0TGluay0+bmV4dCA9IGxpbms7CglsYXN0TGluayA9IGxpbms7CgltZW1iZXJUeXBlID0gbWVtYmVyVHlwZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBoYXMgdGhlIGdpdmVuIHZhbHVlIHR5cGUsIG9yCiAqIGlzIGRlcml2ZWQgZnJvbSBzdWNoIGEgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgaW50IHZhbFR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgaWYgKElTX0NPTVBMRVhfVFlQRSh0eXBlKSkKCXJldHVybiAoMCk7CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5idWlsdEluVHlwZSA9PSB2YWxUeXBlKQoJICAgIHJldHVybigxKTsKCWlmICgodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkgfHwKCSAgICAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCgkgICAgcmV0dXJuICgwKTsKCXJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUodHlwZS0+c3VidHlwZXMsIHZhbFR5cGUpKTsKICAgIH0gZWxzZQoJcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcywgdmFsVHlwZSkpOwoKICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBoYXMgdGhlIGdpdmVuIHZhbHVlIHR5cGUsIG9yCiAqIGlzIGRlcml2ZWQgZnJvbSBzdWNoIGEgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNVc2VyRGVyaXZlZEZyb21CdWlsdEluVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCB2YWxUeXBlKQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGlmIChJU19DT01QTEVYX1RZUEUodHlwZSkpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gdmFsVHlwZSkKCSAgICByZXR1cm4oMSk7CglyZXR1cm4gKDApOwogICAgfSBlbHNlCglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzLCB2YWxUeXBlKSk7CgogICAgcmV0dXJuICgwKTsKfQojZW5kaWYKCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVF1ZXJ5QnVpbHRJblR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmIChJU19DT01QTEVYX1RZUEUodHlwZSkpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKQoJICAgIHJldHVybih0eXBlKTsKICAgIGVsc2UKCXJldHVybih4bWxTY2hlbWFRdWVyeUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzKSk7CgogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZVR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZ2l2ZW4gdHlwZSBvcgogKiBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewoKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCS8qCgkqIE5vdGUgdGhhdCBhbnlTaW1wbGVUeXBlIGlzIGFjdHVhbGx5IG5vdCBhIHByaW1pdGl2ZSB0eXBlCgkqIGJ1dCB3ZSBuZWVkIHRoYXQgaGVyZS4KCSovCglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHx8CgkgICAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0JVSUxUSU5fUFJJTUlUSVZFKSkKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZUFuY2VzdG9yOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3Rvcih4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmIChWQVJJRVRZX0xJU1QodHlwZSkgfHwgVkFSSUVUWV9VTklPTih0eXBlKSkKCXJldHVybiAoMCk7CiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CglpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCgkgICAgcmV0dXJuICh0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogQGN1cjogdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBsaXN0CiAqIEBsYXN0VXNlOiB0aGUgdG9wIG9mIHRoZSBhdHRyaWJ1dGUgdXNlIGxpc3QKICoKICogQnVpbGRzIHRoZSBhdHRyaWJ1dGUgdXNlcyBsaXN0IG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFRoaXMgb25lIGlzIHN1cHBvc2VkIHRvIGJlIGNhbGxlZCBieQogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24gb25seS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBjdXIsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqdXNlcywKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyICpsYXN0VXNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIHRtcDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJaWYgKGN1ci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICAvKgoJICAgICAqIFczQzogIjIgVGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGF0dHJpYnV0ZSBncm91cHMgt3Jlc29sdmVktwoJICAgICAqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVlt3Mgb2YgdGhlIHJlZiBbYXR0cmlidXRlXSBvZiB0aGUKCSAgICAgKiA8YXR0cmlidXRlR3JvdXA+IFtjaGlsZHJlbl0sIGlmIGFueS4iCgkgICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKGN0eHQsCgkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgY3VyKS0+YXR0cmlidXRlcywgdXNlcywKCQlsYXN0VXNlKSA9PSAtMSkgewoJCXJldHVybiAoLTEpOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgLyogVzNDOiAiMSBUaGUgc2V0IG9mIGF0dHJpYnV0ZSB1c2VzIGNvcnJlc3BvbmRpbmcgdG8gdGhlCgkgICAgICogPGF0dHJpYnV0ZT4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8KCSAgICB0bXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0cikKCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCSAgICBpZiAodG1wID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyIsIE5VTEwpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICB0bXAtPmF0dHIgPSBjdXI7CgkgICAgdG1wLT5uZXh0ID0gTlVMTDsKCSAgICBpZiAoKnVzZXMgPT0gTlVMTCkKCQkqdXNlcyA9IHRtcDsKCSAgICBlbHNlCgkJKCpsYXN0VXNlKS0+bmV4dCA9IHRtcDsKCSAgICAqbGFzdFVzZSA9IHRtcDsKCX0KCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50czoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBkZXN0OiAgdGhlIGRlc3RpbmF0aW9uIHdpbGRjYXJkCiAqIEBzb3VyY2U6IHRoZSBzb3VyY2Ugd2lsZGNhcmQKICoKICogQ2xvbmVzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2Ygc291cmNlCiAqIGFuZCBhc3NpZ25lcyB0aGVtIHRvIGRlc3QuCiAqIFJldHVybnMgLTEgb24gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmRlc3QsCgkJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgc291cmNlKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgdG1wLCBsYXN0OwoKICAgIGlmICgoc291cmNlID09IE5VTEwpIHx8ICgqZGVzdCA9PSBOVUxMKSkKCXJldHVybigtMSk7CiAgICAoKmRlc3QpLT5hbnkgPSBzb3VyY2UtPmFueTsKICAgIGN1ciA9IHNvdXJjZS0+bnNTZXQ7CiAgICBsYXN0ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAodG1wID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICAoKmRlc3QpLT5uc1NldCA9IHRtcDsKCWVsc2UKCSAgICBsYXN0LT5uZXh0ID0gdG1wOwoJbGFzdCA9IHRtcDsKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIGlmICgoKmRlc3QpLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoKCpkZXN0KS0+bmVnTnNTZXQpOwogICAgaWYgKHNvdXJjZS0+bmVnTnNTZXQgIT0gTlVMTCkgewoJKCpkZXN0KS0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICgoKmRlc3QpLT5uZWdOc1NldCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7CgkoKmRlc3QpLT5uZWdOc1NldC0+dmFsdWUgPSBzb3VyY2UtPm5lZ05zU2V0LT52YWx1ZTsKICAgIH0gZWxzZQoJKCpkZXN0KS0+bmVnTnNTZXQgPSBOVUxMOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hVW5pb25XaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkCiAqCiAqIFVuaW9ucyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgdW5pb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgoJCS8qCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLgoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUKICAgICovCiAgICBpZiAoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSB7CglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLAogICAgKiB0aGVuIHRoZSB1bmlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsKCWludCBmb3VuZDsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc3RhcnQ7CgoJY3VyID0gY3VyV2lsZC0+bnNTZXQ7CglzdGFydCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IHN0YXJ0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmICh0bXAgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CgkJdG1wLT5uZXh0ID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gdG1wOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CgoJcmV0dXJuKDApOwogICAgfQogICAgLyoKICAgICogNCBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IHZhbHVlcyAobmFtZXNwYWNlIG5hbWVzCiAgICAqIG9yILdhYnNlbnS3KSwgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgICogNS4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpbnQgbnNGb3VuZCwgYWJzZW50Rm91bmQgPSAwOwoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uZWdOc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQ7Cgl9Cgluc0ZvdW5kID0gMDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpCgkJYWJzZW50Rm91bmQgPSAxOwoJICAgIGVsc2UgaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpCgkJbnNGb3VuZCA9IDE7CgkgICAgaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpCgkJYnJlYWs7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoKCWlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgYm90aCB0aGUgbmVnYXRlZCBuYW1lc3BhY2UKCSAgICAqIG5hbWUgYW5kILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0gZWxzZSBpZiAobnNGb3VuZCAmJiAoIWFic2VudEZvdW5kKSkgewoJICAgIC8qCgkgICAgKiA1LjIgSWYgdGhlIHNldCBTIGluY2x1ZGVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lCgkgICAgKiBidXQgbm90ILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QKCSAgICAqIGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMyBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcgYnV0IG5vdCB0aGUgbmVnYXRlZAoJICAgICogbmFtZXNwYWNlIG5hbWUsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSwKCQkiVGhlIHVuaW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZS5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSk7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKgoJICAgICogNS40IElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlIGVpdGhlciB0aGUgbmVnYXRlZCBuYW1lc3BhY2UKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QKCSAgICAqIGFuZCBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAgKiA2LgogICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCX0KCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIHsKCQkvKgoJCSogNi4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90CgkgICAgKiBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKDApOwoKfQoKLyoqCiAqIHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQKICoKICogSW50ZXJzZWN0cyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgaW50ZXJzZWN0aW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCBwcmV2LCAgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgoJCS8qCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLgoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsKCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwoJcmV0dXJuKDApOwogICAgfQogICAgLyoKICAgICogMyBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSB2YWx1ZSAoYSBuYW1lc3BhY2UKICAgICogbmFtZSBvciC3YWJzZW50tykgYW5kIHRoZSBvdGhlciBpcyBhIHNldCBvZiAobmFtZXNwYWNlIG5hbWVzIG9yCiAgICAqILdhYnNlbnS3KSwgdGhlbiB0aGF0IHNldCwgbWludXMgdGhlIG5lZ2F0ZWQgdmFsdWUgaWYgaXQgd2FzIGluCiAgICAqIHRoZSBzZXQsIG1pbnVzILdhYnNlbnS3IGlmIGl0IHdhcyBpbiB0aGUgc2V0LCBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7Cgljb25zdCB4bWxDaGFyICpuZWc7CgoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgewoJICAgIG5lZyA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJfSBlbHNlCgkgICAgbmVnID0gY3VyV2lsZC0+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+dmFsdWUpCgkJICAgIHJldHVybiAoMSk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCSAgICByZXR1cm4gKDApOwoJfQogICAgfQogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBhdHRyczogdGhlIGF0dHJpYnV0ZSBsaXN0CiAqIEBjb21wbGV0ZVdpbGQ6IHRoZSByZXN1bHRpbmcgY29tcGxldGUgd2lsZGNhcmQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRycywKCQkJCSAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpjb21wbGV0ZVdpbGQpCnsKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CglpZiAoYXR0cnMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3JvdXA7CgoJICAgIGdyb3VwID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhdHRyczsKCSAgICAvKgoJICAgICogSGFuZGxlIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzLgoJICAgICovCgkgICAgaWYgKGdyb3VwLT5yZWYgIT0gTlVMTCkgewoJCWlmIChncm91cC0+cmVmSXRlbSA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogVE9ETzogU2hvdWxkIHdlIHJhaXNlIGEgd2FybmluZyBoZXJlPwoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRoZSByZWZlcmVuY2VkIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIGNvdWxkIG5vdAoJCSAgICAqIGJlIHJlc29sdmVkIGJlZm9yZWhhbmQsIHNvIHNraXAuCgkJICAgICovCgkJICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZQoJCSAgICBncm91cCA9IGdyb3VwLT5yZWZJdGVtOwoJICAgIH0KCSAgICAvKgoJICAgICogRm9yIGV2ZXJ5IGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLCBhbiBpbnRlcnNlY3RlZCB3aWxkY2FyZAoJICAgICogd2lsbCBiZSBjcmVhdGVkIChhc3N1bWVkIHRoYXQgYSB3aWxkY2FyZCBleGlzdHMgb24gdGhlCgkgICAgKiBwYXJ0aWN1bGFyIGF0dHIuIGdyLiBkZWYuIG9yIG9uIGFueSBjb250YWluZWQgYXR0ci4gZ3IuIGRlZgoJICAgICogYXQgYWxsKS4KCSAgICAqIFRoZSBmbGFnIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEIGVuc3VyZXMKCSAgICAqIHRoYXQgdGhlIGludGVyc2VjdGlvbiB3aWxsIGJlIHBlcmZvcm1lZCBvbmx5IG9uY2UuCgkgICAgKi8KCSAgICBpZiAoKGdyb3VwLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEKSA9PSAwKSB7CgkJaWYgKGdyb3VwLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LAoJCQlncm91cC0+YXR0cmlidXRlcywgJmdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCX0KCQlncm91cC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQ7CgkgICAgfQoJICAgIGlmIChncm91cC0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJCWlmICgqY29tcGxldGVXaWxkID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBDb3B5IHRoZSBmaXJzdCBlbmNvdW50ZXJlZCB3aWxkY2FyZCBhcyBjb250ZXh0LCBleGNlcHQgZm9yIHRoZSBhbm5vdGF0aW9uLgoJCSAgICAqCgkJICAgICogQWx0aG91Z2ggdGhlIGNvbXBsZXRlIHdpbGRjYXJkIG1pZ2h0IG5vdCBjb3JyZXNwb25kIHRvIGFueQoJCSAgICAqIG5vZGUgaW4gdGhlIHNjaGVtYSwgd2Ugd2lsbCBzYXZlIHRoaXMgY29udGV4dCBub2RlLgoJCSAgICAqLwoJCSAgICAqY29tcGxldGVXaWxkID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCwgY3R4dC0+c2NoZW1hLAoJCQlYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURSwKCQkJZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5ub2RlKTsKCQkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsCgkJCWNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkJcmV0dXJuICgtMSk7CgkJICAgICgqY29tcGxldGVXaWxkKS0+cHJvY2Vzc0NvbnRlbnRzID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHM7CgkJICAgICgqY29tcGxldGVXaWxkKS0+bm9kZSA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bm9kZTsKCQl9IGVsc2UgaWYgKHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyhjdHh0LCAqY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCSAgICByZXR1cm4gKC0xKTsKCSAgICB9Cgl9CglhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAoJCQkJICAgICBpbnQgKmZpeGVkLAoJCQkJICAgICBjb25zdCB4bWxDaGFyICoqdmFsdWUsCgkJCQkgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsKQp7CiAgICAqZml4ZWQgPSAwOwogICAgKnZhbHVlID0gTlVMTDsKICAgIGlmICh2YWwgIT0gMCkKCSp2YWwgPSBOVUxMOwoKICAgIGlmIChpdGVtLT5kZWZWYWx1ZSA9PSBOVUxMKQoJaXRlbSA9IGl0ZW0tPnJlZkRlY2w7CgogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybiAoMCk7CgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpIHsKCSp2YWx1ZSA9IGl0ZW0tPmRlZlZhbHVlOwoJaWYgKHZhbCAhPSAwKQoJICAgICp2YWwgPSBpdGVtLT5kZWZWYWw7CglpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKQoJICAgICpmaXhlZCA9IDE7CglyZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQovKioKICogeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZToKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKgogKiBWYWxpZGF0aW9uIFJ1bGU6IFdpbGRjYXJkIGFsbG93cyBOYW1lc3BhY2UgTmFtZQogKiAoY3ZjLXdpbGRjYXJkLW5hbWVzcGFjZSkKICoKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsCgkJCQkgICBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigtMSk7CgogICAgaWYgKHdpbGQtPmFueSkKCXJldHVybigxKTsKICAgIGVsc2UgaWYgKHdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoKCWN1ciA9IHdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGN1ci0+dmFsdWUsIG5zKSkKCQlyZXR1cm4oMSk7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfSBlbHNlIGlmICgod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKG5zICE9IE5VTEwpICYmCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsKCiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgY3VyLCBiYXNlLCB0bXAsIGlkID0gTlVMTCwKCXByZXYgPSBOVUxMLCB1c2VzID0gTlVMTCwgbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW55VHlwZTsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgZXJyID0gMDsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKgogICAgICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gd2l0aCBjb21wbGV4IGNvbnRlbnQgU2NoZW1hIENvbXBvbmVudC4KICAgICAqCiAgICAgKiBBdHRyaWJ1dGUgdXNlcy4KICAgICAqIFRPRE86IEFkZCBjaGVja3MgZm9yIGFic2VudCByZWZlcmVuY2VkIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgYW5kCiAgICAgKiBzaW1wbGUgdHlwZXMuCiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbiIsCgkgICAgImF0dHJpYnV0ZSB1c2VzIGFscmVhZHkgYnVpbGRlZCIpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbiIsCgkgICAgIm5vIGJhc2UgdHlwZSIpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIC8qCiAgICAgKiBJbmhlcml0IHRoZSBhdHRyaWJ1dGUgdXNlcyBvZiB0aGUgYmFzZSB0eXBlLgogICAgICovCiAgICAvKgogICAgICogTk9URTogSXQgaXMgYWxsb3dlZCB0byAiZXh0ZW5kIiB0aGUgYW55VHlwZSBjb21wbGV4IHR5cGUuCiAgICAgKi8KICAgIGlmICghIElTX0FOWVRZUEUoYmFzZVR5cGUpKSB7CglpZiAoYmFzZVR5cGUgIT0gTlVMTCkgewoJICAgIGZvciAoY3VyID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVVzZXM7IGN1ciAhPSBOVUxMOwoJCWN1ciA9IGN1ci0+bmV4dCkgewoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyKQoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCQkJImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIG9mIGNvbXBsZXhUeXBlIiwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQl0bXAtPmF0dHIgPSBjdXItPmF0dHI7CgkJdG1wLT5uZXh0ID0gTlVMTDsKCQlpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJfSBlbHNlCgkJICAgIGxhc3RCYXNlVXNlLT5uZXh0ID0gdG1wOwoJCWxhc3RCYXNlVXNlID0gdG1wOwoJICAgIH0KCX0KICAgIH0KICAgIGF0dHJzID0gdHlwZS0+YXR0cmlidXRlczsgICAgCiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlIHdpbGRjYXJkcy4KICAgICovCiAgICBlcnIgPSB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQocGN0eHQsCglhdHRycywgJnR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKTsKICAgIC8qCiAgICAqIE5PVEU6IER1cmluZyB0aGUgcGFyc2UgdGltZSwgdGhlIHdpbGRjYXJkIGlzIGNyZWF0ZWQgb24gdGhlIGNvbXBsZXhUeXBlCiAgICAqIGRpcmVjdGx5LCBpZiBlbmNvdW50ZXJlZCBpbiBhIDxyZXN0cmljdGlvbj4gb3IgPGV4dGVuc2lvbj4gZWxlbWVudC4KICAgICovCiAgICBpZiAoZXJyID09IC0xKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24iLAoJICAgICJmYWlsZWQgdG8gYnVpbGQgYW4gaW50ZXJzZWN0ZWQgYXR0cmlidXRlIHdpbGRjYXJkIik7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmCgkoKElTX0FOWVRZUEUoYmFzZVR5cGUpKSB8fAoJICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYKCSAgKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgoJICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSkpIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFVuaW9uIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCB3aXRoIHRoZSBiYXNlIHdpbGRjYXJkLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKHBjdHh0LCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCXJldHVybiAoLTEpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogSnVzdCBpbmhlcml0IHRoZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGlzIGlzIHRoZSBvbmx5IGNhc2Ugd2hlcmUgYW4gYXR0cmlidXRlCiAgICAgICAgICAgICogd2lsZGNhcmQgaXMgc2hhcmVkLgogICAgICAgICAgICAqLwoJICAgIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJfQogICAgfQoKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIERlcml2YXRpb24gVmFsaWQgKFJlc3RyaWN0aW9uLCBDb21wbGV4KQoJICAgICogNC4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYWxzbyBoYXZlIG9uZS4KCSAgICAqLwoJICAgIGlmIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIHR5cGUgaGFzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCwgIgoJCSAgICAiYnV0IHRoZSBiYXNlIHR5cGUgJXMgZG9lcyBub3QgaGF2ZSBvbmUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuICgxKTsKCSAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYUNoZWNrQ09TTlNTdWJzZXQoCgkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkpIHsKCQkvKiA0LjIgKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIgoJCSAgICAic3Vic2V0IG9mIHRoZSB3aWxkY2FyZCBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIC8qIDQuMyBVbmxlc3MgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILd1ci10eXBlCgkgICAgKiBkZWZpbml0aW9utywgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZQoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9IG11c3QgYmUgaWRlbnRpY2FsIHRvIG9yCgkgICAgKiBzdHJvbmdlciB0aGFuIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2F0dHJpYnV0ZQoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9LCB3aGVyZSBzdHJpY3QgaXMgc3Ryb25nZXIKCSAgICAqIHRoYW4gbGF4IGlzIHN0cm9uZ2VyIHRoYW4gc2tpcC4KCSAgICAqLwoJICAgIGlmICgoISBJU19BTllUWVBFKGJhc2VUeXBlKSkgJiYKCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA8CgkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzMsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgJ3Byb2Nlc3MgY29udGVudHMnIG9mIHRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgIgoJCSAgICAid2Vha2VyIHRoYW4gdGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkvKgoJKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCgkqIEF0IHRoaXMgcG9pbnQgdGhlIHR5cGUgYW5kIHRoZSBiYXNlIGhhdmUgYm90aCwgZWl0aGVyCgkqIG5vIHdpbGRjYXJkIG9yIGEgd2lsZGNhcmQuCgkqLwoJaWYgKChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCSAgICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSkgewoJICAgIC8qIDEuMyAqLwoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU05TU3Vic2V0KAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8zLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyBub3QgYSB2YWxpZCAiCgkJICAgICJzdXBlcnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuICgxKTsKCSAgICB9Cgl9CiAgICB9CgogICAgLyoKICAgICAqIEdhdGhlciBhdHRyaWJ1dGUgdXNlcyBkZWZpbmVkIGJ5IHRoaXMgdHlwZS4KICAgICAqLwogICAgaWYgKGF0dHJzICE9IE5VTEwpIHsKCWlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChwY3R4dCwgYXR0cnMsCgkgICAgJnVzZXMsICZsYXN0VXNlKSA9PSAtMSkgewoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgLyogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0IDQuCiAgICAgKiAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdAogICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuIgogICAgICoKICAgICAqIEZvciAiZXh0ZW5zaW9uIiB0aGlzIGlzIGRvbmUgZnVydGhlciBkb3duLgogICAgICovCiAgICBpZiAoKHVzZXMgIT0gTlVMTCkgJiYgKCh0eXBlLT5mbGFncyAmCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgljdXIgPSB1c2VzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgdG1wID0gY3VyLT5uZXh0OwoJICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgewoJCWlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwKCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJICAgICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyKSwKCQkgICAgeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0cikpKSkgewoKCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwKCQkJdHlwZSwgY3VyLT5hdHRyLAoJCQkiRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2UgJXMgc3BlY2lmaWVkIiwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpLAoJCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgYnJlYWs7CgkJfQoJCXRtcCA9IHRtcC0+bmV4dDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfQogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewoJLyoKCSAqIERlcml2ZSBieSByZXN0cmljdGlvbi4KCSAqLwoJaWYgKElTX0FOWVRZUEUoYmFzZVR5cGUpKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7Cgl9IGVsc2UgewoJICAgIGludCBmb3VuZCwgdmFsaWQ7CgkgICAgY29uc3QgeG1sQ2hhciAqYkVmZlZhbHVlOwoJICAgIGludCBlZmZGaXhlZDsKCgkgICAgY3VyID0gdXNlczsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJdmFsaWQgPSAxOwoJCWJhc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoJCXdoaWxlIChiYXNlICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksCgkJCXhtbFNjaGVtYUdldEF0dHJOYW1lKGJhc2UtPmF0dHIpKSAmJgoJCQl4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyKSwKCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGJhc2UtPmF0dHIpKSkgewoKCQkJZm91bmQgPSAxOwoJCQkKCQkJaWYgKChjdXItPmF0dHItPm9jY3VycyA9PQoJCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0KCQkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSkgewoJCQkgICAgLyoKCQkJICAgICogTk9PUC4KCQkJICAgICovCgkJCX0gZWxzZSBpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09CgkJCSAgICBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0KCQkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAyLjEuMQoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMSwKCQkJCXR5cGUsIGN1ci0+YXR0ciwKCQkJCSJUaGUgJ29wdGlvbmFsJyB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggYSAiCgkJCQkibWF0Y2hpbmcgJ3JlcXVpcmVkJyB1c2Ugb2YgdGhlIGJhc2UgdHlwZSIsCgkJCQlOVUxMKTsKCQkJfSBlbHNlIGlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0KCQkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09CgkJCSAgICBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMwoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzMsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkJIkEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBmb3IgdGhlICdyZXF1aXJlZCcgIgoJCQkJImF0dHJpYnV0ZSB1c2UgJyVzJyBvZiB0aGUgYmFzZSB0eXBlIGlzICIKCQkJCSJtaXNzaW5nIiwKCQkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0ciksCgkJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkpOwoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCX0gZWxzZSBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSygKCQkJICAgIGN1ci0+YXR0ci0+c3VidHlwZXMsIGJhc2UtPmF0dHItPnN1YnR5cGVzLCAwKSAhPSAwKSB7CgkJCSAgICAJCQkgICAgCgkJCSAgICAvKgoJCQkgICAgKiBTUEVDICgyLjEuMikgIlIncyB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzCgkJCSAgICAqIHt0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20KCQkJICAgICogQidzIHt0eXBlIGRlZmluaXRpb259IGdpdmVuIHRoZSBlbXB0eSBzZXQgYXMKCQkJICAgICogZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLiIKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihwY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzIsCgkJCQl0eXBlLCBjdXItPmF0dHIsCgkJCQkiVGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbidzIHR5cGUgIgoJCQkJImRlZmluaXRpb24gaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tICIKCQkJCSJ0aGUgY29ycmVzcG9uZGluZyBkZWZpbml0aW9uIGluIHRoZSAiCgkJCQkiYmFzZSB0eXBlIiwgTlVMTCk7CQkJICAgIAoJCQl9IGVsc2UgewoJCQkgICAgLyoKCQkJICAgICogMi4xLjMgW0RlZmluaXRpb246XSAgTGV0IHRoZSBlZmZlY3RpdmUgdmFsdWUKCQkJICAgICogY29uc3RyYWludCBvZiBhbiBhdHRyaWJ1dGUgdXNlIGJlIGl0cyB7dmFsdWUKCQkJICAgICogY29uc3RyYWludH0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSBpdHMge2F0dHJpYnV0ZQoJCQkgICAgKiBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0gLgoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiYXNlLT5hdHRyLAoJCQkJJmVmZkZpeGVkLCAmYkVmZlZhbHVlLCAwKTsKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zIC4uLiBvbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWUKCQkJICAgICoKCQkJICAgICogMi4xLjMuMSBCJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcwoJCQkgICAgKiC3YWJzZW50tyBvciBkZWZhdWx0LgoJCQkgICAgKi8KCQkJICAgIGlmICgoYkVmZlZhbHVlICE9IE5VTEwpICYmCgkJCQkoZWZmRml4ZWQgPT0gMSkpIHsKCQkJCWNvbnN0IHhtbENoYXIgKnJFZmZWYWx1ZSA9IE5VTEw7CgkJCQkKCQkJCXhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiYXNlLT5hdHRyLAoJCQkJICAgICZlZmZGaXhlZCwgJnJFZmZWYWx1ZSwgMCk7CgkJCQkgICAgLyoKCQkJCSAgICAqIDIuMS4zLjIgUidzILdlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludLcgaXMKCQkJCSAgICAqIGZpeGVkIHdpdGggdGhlIHNhbWUgc3RyaW5nIGFzIEIncy4KCQkJCSAgICAqIFRPRE86IENvbXBhcmUgdGhlIGNvbXB1dGVkIHZhbHVlcy4KCQkJCSovCgkJCQlpZiAoKGVmZkZpeGVkID09IDApIHx8CgkJCQkgICAgKCEgeG1sU3RyRXF1YWwockVmZlZhbHVlLCBiRWZmVmFsdWUpKSkgewoJCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKHBjdHh0LAoJCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzMsCgkJCQkJdHlwZSwgY3VyLT5hdHRyLAoJCQkJCSJUaGUgZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnQgb2YgdGhlICIKCQkJCQkiYXR0cmlidXRlIHVzZSBpcyBpbmNvbnNpc3RlbnQgd2l0aCAiCgkJCQkJIml0cyBjb3JyZXNwb25kZW50IG9mIHRoZSBiYXNlIHR5cGUiLAoJCQkJCU5VTEwpOwoJCQkJfSBlbHNlIHsKCQkJCSAgICAvKgoJCQkJICAgICogT3ZlcnJpZGUgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCQkgICAgKi8KCQkJCSAgICBiYXNlLT5hdHRyID0gY3VyLT5hdHRyOwoJCQkJfQoJCQkgICAgfSBlbHNlCQkJCQoJCQkJYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJfQoKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgYmFzZSA9IGJhc2UtPm5leHQ7CgkJfQoKCQlpZiAoKCFmb3VuZCkgJiYgKGN1ci0+YXR0ci0+b2NjdXJzICE9CgkJCVhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpKSB7CgkJICAgIC8qCgkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4yCgkJICAgICovCgkJICAgIGlmICgoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpIHx8CgkJCSh4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKAoJCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJCWN1ci0+YXR0ci0+dGFyZ2V0TmFtZXNwYWNlKSAhPSAxKSkgewoJCQl4bWxTY2hlbWFQQXR0clVzZUVycihwY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8yLAoJCQkgICAgdHlwZSwgY3VyLT5hdHRyLAoJCQkgICAgIk5laXRoZXIgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlLCAiCgkJCSAgICAibm9yIGEgbWF0Y2hpbmcgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZSBkb2VzIGV4aXN0IiwKCQkJICAgIE5VTEwpOwoJCSAgICB9IGVsc2UgewoJCQkvKgoJCQkqIEFkZCB0aGUgYXR0cmlidXRlIHVzZS4KCQkJKgoJCQkqIE5vdGUgdGhhdCB0aGlzIG1heSBsZWFkIHRvIGZ1bm55IGRlcml2YXRpb24gZXJyb3IgcmVwb3J0cywgaWYKCQkJKiBtdWx0aXBsZSBlcXVhbCBhdHRyaWJ1dGUgdXNlcyBleGlzdDsgYnV0IHRoaXMgaXMgbm90CgkJCSogYWxsb3dlZCBhbnl3YXksIGFuZCBpdCB3aWxsIGJlIHJlcG9ydGVkIGJlZm9yZWhhbmQuCgkJCSovCgkJCXRtcCA9IGN1cjsKCQkJaWYgKHByZXYgIT0gTlVMTCkKCQkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJCWVsc2UKCQkJICAgIHVzZXMgPSBjdXItPm5leHQ7CgkJCWN1ciA9IGN1ci0+bmV4dDsKCQkJdG1wLT5uZXh0ID0gTlVMTDsKCQkJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHRtcDsKCQkJfSBlbHNlCgkJCSAgICBsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQkJbGFzdEJhc2VVc2UgPSB0bXA7CgkJCQoJCQljb250aW51ZTsKCQkgICAgfQoJCX0KCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHVzZXMgIT0gTlVMTCkKCQl4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdCh1c2VzKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJLyoKCSAqIFRoZSBzcGVjIGFsbG93cyBvbmx5IGFwcGVuZGluZywgYW5kIG5vdCBvdGhlciBraW5kcyBvZiBleHRlbnNpb25zLgoJICoKCSAqIFRoaXMgZW5zdXJlczogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pIDogMS4yCgkgKi8KCWlmICh1c2VzICE9IE5VTEwpIHsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CgkgICAgfSBlbHNlCgkJbGFzdEJhc2VVc2UtPm5leHQgPSB1c2VzOwoJfQogICAgfSBlbHNlIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbiIsCgkgICAgIm5vIGRlcml2YXRpb24gbWV0aG9kIik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAgKiAzLjQuNiAtPiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkgewoJY3VyID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDQuIFR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QKCSAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLgoJICAgICoKCSAgICAqIE5vdGUgdGhhdCB0aGlzIHdhcyBhbHJlYWR5IGRvbmUgZm9yICJyZXN0cmljdGlvbiIgYW5kIHR5cGVzIGRlcml2ZWQgZnJvbQoJICAgICogdGhlIHVyLXR5cGUuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJCXRtcCA9IGN1ci0+bmV4dDsKCQl3aGlsZSAodG1wICE9IE5VTEwpIHsKCQkgICAgaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkJKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShjdXItPmF0dHIgKSwKCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0cikpKSkgewoKCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnIocGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsCgkJCSAgICB0eXBlLCB0bXAtPmF0dHIsCgkJCSAgICAiRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2Ugc3BlY2lmaWVkIiwgTlVMTCk7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIHRtcCA9IHRtcC0+bmV4dDsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiA1LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0CgkgICAgKiBub3QgaGF2ZSB7dHlwZSBkZWZpbml0aW9ufXMgd2hpY2ggYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuCgkgICAgKi8KCSAgICBpZiAoKGN1ci0+YXR0ci0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCQkoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN1ci0+YXR0ci0+c3VidHlwZXMsCgkJICAgIFhNTF9TQ0hFTUFTX0lEKSkpIHsKCQlpZiAoaWQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF81LAoJCQl0eXBlLCBjdXItPmF0dHIsCgkJCSJUaGVyZSBtdXN0IG5vdCBleGlzdCBtb3JlIHRoYW4gb25lIGF0dHJpYnV0ZSB1c2UsICIKCQkJImRlY2xhcmVkIG9mIHR5cGUgJ0lEJyBvciBkZXJpdmVkIGZyb20gaXQiLAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJfQoJCWlkID0gY3VyOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVtb3ZlICJwcm9oaWJpdGVkIiBhdHRyaWJ1dGUgdXNlcy4gVGhlIHJlYXNvbiB0aGlzIGlzIGRvbmUgYXQgdGhpcyBsYXRlCgkgICAgKiBzdGFnZSBpcyB0byBiZSBhYmxlIHRvIGNhdGNoIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgdXNlcy4gU28gd2UgaGFkIHRvIGtlZXAKCSAgICAqIHByb2hpYml0ZWQgdXNlcyBpbiB0aGUgbGlzdCBhcyB3ZWxsLgoJICAgICovCgkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQl0bXAgPSBjdXI7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IGN1ci0+bmV4dDsKCQllbHNlCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJY3VyID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUodG1wKTsKCSAgICB9IGVsc2UgewoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAgKiBUT0RPOiBUaGlzIGNoZWNrIHNob3VsZCBiZSByZW1vdmVkIGlmIHdlIGFyZSAxMDAlIHN1cmUgb2YKICAgICAqIHRoZSBiYXNlIHR5cGUgYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBiZWluZyBidWlsdC4KICAgICAqLwogICAgaWYgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoISBJU19BTllUWVBFKGJhc2VUeXBlKSkgJiYKCShiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCShJU19OT1RfVFlQRUZJWEVEKGJhc2VUeXBlKSkpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbiIsCgkgICAgImF0dHJpYnV0ZSB1c2VzIG5vdCBidWlsZGVkIG9uIGJhc2UgdHlwZSIpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYQogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQGZpbmFsOiB0aGUgZmluYWwKICoKICogRXZhbHVhdGVzIGlmIGEgdHlwZSBkZWZpbml0aW9uIGNvbnRhaW5zIHRoZSBnaXZlbiAiZmluYWwiLgogKiBUaGlzIGRvZXMgdGFrZSAiZmluYWxEZWZhdWx0IiBpbnRvIGFjY291bnQgYXMgd2VsbC4KICoKICogUmV0dXJucyAxIGlmIHRoZSB0eXBlIGRvZXMgY29udGFpbnQgdGhlIGdpdmVuICJmaW5hbCIsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCBmaW5hbCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBmaW5hbCkKCXJldHVybiAoMSk7CiAgICBlbHNlCglyZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXM6CiAqIEB0eXBlOiAgdGhlIFVuaW9uIFNpbXBsZSBUeXBlCiAqCiAqIFJldHVybnMgYSBsaXN0IG9mIG1lbWJlciB0eXBlcyBvZiBAdHlwZSBpZiBleGlzdGluZywKICogcmV0dXJucyBOVUxMIG90aGVyd2lzZS4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlTGlua1B0cgp4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkgewoJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgkgICAgcmV0dXJuICh0eXBlLT5tZW1iZXJUeXBlcyk7CgllbHNlCgkgICAgdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbjoKICogQHBhcnRpY2xlOiB0aGUgcGFydGljbGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFZmZlY3RpdmUgVG90YWwgUmFuZ2UKICogKGFsbCBhbmQgc2VxdWVuY2UpICsgKGNob2ljZSkKICoKICogUmV0dXJucyB0aGUgbWluaW11biBFZmZlY3RpdmUgVG90YWwgUmFuZ2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbih4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApKQoJcmV0dXJuICgwKTsKICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgewoJaW50IG1pbiA9IC0xLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJaWYgKHBhcnQgPT0gTlVMTCkKCSAgICByZXR1cm4gKDApOwoJd2hpbGUgKHBhcnQgIT0gTlVMTCkgewoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1pbk9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHBhcnQpOwoJICAgIGlmIChjdXIgPT0gMCkKCQlyZXR1cm4gKDApOwoJICAgIGlmICgobWluID4gY3VyKSB8fCAobWluID09IC0xKSkKCQltaW4gPSBjdXI7CgkgICAgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dDsKCX0KCXJldHVybiAocGFydGljbGUtPm1pbk9jY3VycyAqIG1pbik7CiAgICB9IGVsc2UgewoJLyogPGFsbD4gYW5kIDxzZXF1ZW5jZT4gKi8KCWludCBzdW0gPSAwOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWlmIChwYXJ0ID09IE5VTEwpCgkgICAgcmV0dXJuICgwKTsKCWRvIHsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQlzdW0gKz0gcGFydC0+bWluT2NjdXJzOwoJICAgIGVsc2UKCQlzdW0gKz0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWluKHBhcnQpOwoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQ7Cgl9IHdoaWxlIChwYXJ0ICE9IE5VTEwpOwoJcmV0dXJuIChwYXJ0aWNsZS0+bWluT2NjdXJzICogc3VtKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heDoKICogQHBhcnRpY2xlOiB0aGUgcGFydGljbGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFZmZlY3RpdmUgVG90YWwgUmFuZ2UKICogKGFsbCBhbmQgc2VxdWVuY2UpICsgKGNob2ljZSkKICoKICogUmV0dXJucyB0aGUgbWF4aW11bSBFZmZlY3RpdmUgVG90YWwgUmFuZ2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heCh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuICgwKTsKICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgewoJaW50IG1heCA9IC0xLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJZm9yICg7IHBhcnQgIT0gTlVMTDsgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dCkgewoJICAgIGlmIChwYXJ0LT5jaGlsZHJlbiA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1heE9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWF4KHBhcnQpOwoJICAgIGlmIChjdXIgPT0gVU5CT1VOREVEKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBpZiAoKG1heCA8IGN1cikgfHwgKG1heCA9PSAtMSkpCgkJbWF4ID0gY3VyOwoJfQoJLyogVE9ETzogSGFuZGxlIG92ZXJmbG93cz8gKi8KCXJldHVybiAocGFydGljbGUtPm1heE9jY3VycyAqIG1heCk7CiAgICB9IGVsc2UgewoJLyogPGFsbD4gYW5kIDxzZXF1ZW5jZT4gKi8KCWludCBzdW0gPSAwLCBjdXI7Cgl4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0ID0KCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgoJZm9yICg7IHBhcnQgIT0gTlVMTDsgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dCkgewoJICAgIGlmIChwYXJ0LT5jaGlsZHJlbiA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmICgocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHx8CgkJKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpKQoJCWN1ciA9IHBhcnQtPm1heE9jY3VyczsKCSAgICBlbHNlCgkJY3VyID0geG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWF4KHBhcnQpOwoJICAgIGlmIChjdXIgPT0gVU5CT1VOREVEKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBpZiAoKGN1ciA+IDApICYmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCkpCgkJcmV0dXJuIChVTkJPVU5ERUQpOwoJICAgIHN1bSArPSBjdXI7Cgl9CgkvKiBUT0RPOiBIYW5kbGUgb3ZlcmZsb3dzPyAqLwoJcmV0dXJuIChwYXJ0aWNsZS0+bWF4T2NjdXJzICogc3VtKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGU6CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogUGFydGljbGUgRW1wdGlhYmxlCiAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBwYXJ0aWNsZSBpcyBlbXB0aWFibGUuCiAqCiAqIFJldHVybnMgMSBpZiBlbXB0aWFibGUsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlKHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlKQp7CiAgICAvKgogICAgKiBTUEVDICgxKSAiSXRzIHttaW4gb2NjdXJzfSBpcyAwLiIKICAgICovCiAgICBpZiAoKHBhcnRpY2xlID09IE5VTEwpIHx8IChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHx8CgkocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDIpICJJdHMge3Rlcm19IGlzIGEgZ3JvdXAgYW5kIHRoZSBtaW5pbXVtIHBhcnQgb2YgdGhlCiAgICAqIGVmZmVjdGl2ZSB0b3RhbCByYW5nZSBvZiB0aGF0IGdyb3VwLCBbLi4uXSBpcyAwLiIKICAgICovCiAgICBpZiAoSVNfTU9ERUxfR1JPVVAocGFydGljbGUtPmNoaWxkcmVuKSkgewoJaWYgKHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihwYXJ0aWNsZSkgPT0gMCkKCSAgICByZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0s6CiAqIEB0eXBlOiAgdGhlIGRlcml2ZWQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKGNvcy1zdC1kZXJpdmVkLU9LKQogKgogKiBDaGVja3Mgd2hldGVyIEB0eXBlIGNhbiBiZSB2YWxpZGx5CiAqIGRlcml2ZWQgZnJvbSBAYmFzZVR5cGUuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhbiBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSwKCQkJICAgICBpbnQgc3Vic2V0KQp7CiAgICAvKgogICAgKiAxIFRoZXkgYXJlIHRoZSBzYW1lIHR5cGUgZGVmaW5pdGlvbi4KICAgICogVE9ETzogVGhlIGlkZW50eSBjaGVjayBtaWdodCBoYXZlIHRvIGJlIG1vcmUgY29tcGxleCB0aGFuIHRoaXMuCiAgICAqLwogICAgaWYgKHR5cGUgPT0gYmFzZVR5cGUpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogMi4xIHJlc3RyaWN0aW9uIGlzIG5vdCBpbiB0aGUgc3Vic2V0LCBvciBpbiB0aGUge2ZpbmFsfQogICAgKiBvZiBpdHMgb3duIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn07CiAgICAqLwogICAgaWYgKChzdWJzZXQgJiBTVUJTRVRfUkVTVFJJQ1RJT04pIHx8CgkoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnModHlwZS0+YmFzZVR5cGUsCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpKSB7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9ERVJJVkVEX09LXzJfMSk7CiAgICB9CiAgICAvKiAyLjIgKi8KICAgIGlmICh0eXBlLT5iYXNlVHlwZSA9PSBiYXNlVHlwZSkgewoJLyoKCSogMi4yLjEgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgQi4KCSovCglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogMi4yLjIgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgbm90IHRoZSC3dXItdHlwZSBkZWZpbml0aW9utwogICAgKiBhbmQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0LCBhcyBkZWZpbmVkIGJ5IHRoaXMKICAgICogY29uc3RyYWludC4KICAgICovCiAgICBpZiAoKCEgSVNfQU5ZVFlQRSh0eXBlLT5iYXNlVHlwZSkpICYmCgkoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh0eXBlLT5iYXNlVHlwZSwKCSAgICBiYXNlVHlwZSwgc3Vic2V0KSA9PSAwKSkgewoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDIuMi4zIEQncyB7dmFyaWV0eX0gaXMgbGlzdCBvciB1bmlvbiBhbmQgQiBpcyB0aGUgt3NpbXBsZSB1ci10eXBlCiAgICAqIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmIChJU19BTllfU0lNUExFX1RZUEUoYmFzZVR5cGUpICYmCgkoVkFSSUVUWV9MSVNUKHR5cGUpIHx8IFZBUklFVFlfVU5JT04odHlwZSkpKSB7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogMi4yLjQgQidzIHt2YXJpZXR5fSBpcyB1bmlvbiBhbmQgRCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhIHR5cGUKICAgICogZGVmaW5pdGlvbiBpbiBCJ3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgc3Vic2V0LCBhcwogICAgKiBkZWZpbmVkIGJ5IHRoaXMgY29uc3RyYWludC4KICAgICoKICAgICogTk9URTogVGhpcyBzZWVtcyBub3QgdG8gaW52b2x2ZSBidWlsdC1pbiB0eXBlcywgc2luY2UgdGhlcmUgaXMgbm8KICAgICogYnVpbHQtaW4gVW5pb24gU2ltcGxlIFR5cGUuCiAgICAqLwogICAgaWYgKFZBUklFVFlfVU5JT04oYmFzZVR5cGUpKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBjdXI7CgoJY3VyID0gYmFzZVR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0sodHlwZSwgY3VyLT50eXBlLCBzdWJzZXQpID09IDApCgkJcmV0dXJuICgwKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9CgogICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzIpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXJJbnRlcm5hbDoKICogQHBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY3R4dFR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBhbmNlc3RvcjogYW4gYW5jZXN0b3Igb2YgQGN0eHRUeXBlCiAqCiAqIENoZWNrcyBzdC1wcm9wcy1jb3JyZWN0ICgyKSArIGN0LXByb3BzLWNvcnJlY3QgKDMpLgogKiBDaXJjdWxhciB0eXBlIGRlZmluaXRpb25zIGFyZSBub3QgYWxsb3dlZC4KICoKICogUmV0dXJucyBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIgaWYgdGhlIGdpdmVuIHR5cGUgaXMKICogY2lyY3VsYXIsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGUsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgYW5jZXN0b3IpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChhbmNlc3RvciA9PSBOVUxMKSB8fCAoYW5jZXN0b3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkKCXJldHVybiAoMCk7CgogICAgaWYgKGN0eHRUeXBlID09IGFuY2VzdG9yKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiwKCSAgICBOVUxMLCBjdHh0VHlwZSwgR0VUX05PREUoY3R4dFR5cGUpLAoJICAgICJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIpOwogICAgfQogICAgaWYgKGFuY2VzdG9yLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEKSB7CgkvKgoJKiBBdm9pZCBpbmlmaW5pdGUgcmVjdXJzaW9uIG9uIGNpcmN1bGFyIHR5cGVzIG5vdCB5ZXQgY2hlY2tlZC4KCSovCglyZXR1cm4gKDApOwogICAgfQogICAgYW5jZXN0b3ItPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwogICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXJJbnRlcm5hbChwY3R4dCwgY3R4dFR5cGUsCglhbmNlc3Rvci0+YmFzZVR5cGUpOwogICAgYW5jZXN0b3ItPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXI6CiAqIEBpdGVtOiAgdGhlIGNvbXBsZXgvc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lCiAqCiAqIENoZWNrcyBmb3IgY2lyY3VsYXIgdHlwZSBkZWZpbml0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyKHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkJICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoKGl0ZW0gPT0gTlVMTCkgfHwKCSgoaXRlbS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCShpdGVtLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpKSkKCXJldHVybjsKICAgIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWwoY3R4dCwgaXRlbSwgaXRlbS0+YmFzZVR5cGUpOwoKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVUeXBlRGVmczoKICogQGl0ZW06ICB0aGUgY29tcGxleC9zaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciB0eXBlIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZVR5cGVEZWZzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZiwKCQkJIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmICh0eXBlRGVmID09IE5VTEwpCglyZXR1cm47CgogICAgLyoKICAgICogUmVzb2x2ZSB0aGUgYmFzZSB0eXBlLgogICAgKi8KICAgIGlmICh0eXBlRGVmLT5iYXNlVHlwZSA9PSBOVUxMKSB7Cgl0eXBlRGVmLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLAoJICAgIHR5cGVEZWYtPmJhc2UsIHR5cGVEZWYtPmJhc2VOcyk7CglpZiAodHlwZURlZi0+YmFzZVR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCXR5cGVEZWYsIHR5cGVEZWYtPm5vZGUsCgkJImJhc2UiLCB0eXBlRGVmLT5iYXNlLCB0eXBlRGVmLT5iYXNlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQogICAgfQogICAgaWYgKElTX1NJTVBMRV9UWVBFKHR5cGVEZWYpKSB7CglpZiAoVkFSSUVUWV9VTklPTih0eXBlRGVmKSkgewoJICAgIC8qCgkgICAgKiBSZXNvbHZlIHRoZSBtZW1iZXJUeXBlcy4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVJlc29sdmVVbmlvbk1lbWJlclR5cGVzKGN0eHQsIHR5cGVEZWYpOwoJICAgIHJldHVybjsKCX0gZWxzZSBpZiAoVkFSSUVUWV9MSVNUKHR5cGVEZWYpKSB7CgkgICAgLyoKCSAgICAqIFJlc29sdmUgdGhlIGl0ZW1UeXBlLgoJICAgICovCgkgICAgaWYgKCh0eXBlRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAodHlwZURlZi0+cmVmICE9IE5VTEwpKSB7CgkJdHlwZURlZi0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwKCQkgICAgdHlwZURlZi0+cmVmLCB0eXBlRGVmLT5yZWZOcyk7CgkJaWYgKCh0eXBlRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSB8fAoJCSAgICAoISBJU19TSU1QTEVfVFlQRSh0eXBlRGVmLT5zdWJ0eXBlcykpKSB7CgkJICAgIHR5cGVEZWYtPnN1YnR5cGVzID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCQl0eXBlRGVmLCB0eXBlRGVmLT5ub2RlLAoJCQkiaXRlbVR5cGUiLCB0eXBlRGVmLT5yZWYsIHR5cGVEZWYtPnJlZk5zLAoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCQl9CgkgICAgfQoJICAgIHJldHVybjsKCX0KICAgIH0KfQoKCgovKioKICogeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHN0LXByb3BzLWNvcnJlY3QuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgcHJvcGVydGllcyBhcmUgY29ycmVjdCwKICogaWYgbm90LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGUsIGFueVNpbXBsZVR5cGUsCglhbnlUeXBlOwogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCiAgICAvKiBTVEFURTogZXJyb3IgZnVuY3MgY29udmVydGVkLiAqLwogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIHNvbWVob3cgcmVkdW5kYW50LCBzaW5jZSB3ZSBhY3R1YWxseSBidWlsdCBhIHNpbXBsZSB0eXBlCiAgICAqIHRvIGhhdmUgYWxsIHRoZSBuZWVkZWQgaW5mb3JtYXRpb247IHRoaXMgYWN0cyBhcyBhbiBzZWxmIHRlc3QuCiAgICAqLwogICAgYW55U2ltcGxlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgLyogQmFzZSB0eXBlOiBJZiB0aGUgZGF0YXR5cGUgaGFzIGJlZW4gt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcKICAgICogdGhlbiB0aGUgU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBjb21wb25lbnQgZnJvbSB3aGljaCBpdCBpcyC3ZGVyaXZlZLcsCiAgICAqIG90aGVyd2lzZSB0aGUgU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBmb3IgYW55U2ltcGxlVHlwZSAopzQuMS42KS4KICAgICovCiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJLyoKCSogVE9ETzogVGhpbmsgYWJvdXQ6ICJtb2R1bG8gdGhlIGltcGFjdCBvZiBNaXNzaW5nCgkqIFN1Yi1jb21wb25lbnRzICinNS4zKS4iCgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJObyBiYXNlIHR5cGUgZXhpc3RlbnQiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKCiAgICB9CiAgICBpZiAoISBJU19TSU1QTEVfVFlQRShiYXNlVHlwZSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiVGhlIGJhc2UgdHlwZSAnJXMnIGlzIG5vdCBhIHNpbXBsZSB0eXBlIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlVHlwZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoIChWQVJJRVRZX0xJU1QodHlwZSkgfHwgVkFSSUVUWV9VTklPTih0eXBlKSkgJiYKCSAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgPT0gMCkgJiYKCSAoISBJU19BTllfU0lNUExFX1RZUEUoYmFzZVR5cGUpKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJBIHR5cGUsIGRlcml2ZWQgYnkgbGlzdCBvciB1bmlvbiwgbXVzdCBoYXZlIgoJICAgICJ0aGUgc2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbiBhcyBiYXNlIHR5cGUsIG5vdCAnJXMnIiwKCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBiYXNlVHlwZSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKgogICAgKiBWYXJpZXR5OiBPbmUgb2Yge2F0b21pYywgbGlzdCwgdW5pb259LgogICAgKi8KICAgIGlmICgoISBWQVJJRVRZX0FUT01JQyh0eXBlKSkgJiYgKCEgVkFSSUVUWV9VTklPTih0eXBlKSkgJiYKCSghIFZBUklFVFlfTElTVCh0eXBlKSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiVGhlIHZhcmlldHkgaXMgYWJzZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKiBUT0RPOiBGaW5pc2ggdGhpcy4gSG1tLCBpcyB0aGlzIGZpbmlzaGVkPyAqLwoKICAgIC8qCiAgICAqIDMgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoYmFzZVR5cGUsCglYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMywKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJUaGUgJ2ZpbmFsJyBvZiBpdHMgYmFzZSB0eXBlICclcycgbXVzdCBub3QgY29udGFpbiAiCgkgICAgIidyZXN0cmljdGlvbiciLAoJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGJhc2VUeXBlKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8zKTsKICAgIH0KCiAgICAvKgogICAgKiAyIEFsbCBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucyBtdXN0IGJlIGRlcml2ZWQgdWx0aW1hdGVseSBmcm9tIHRoZSC3c2ltcGxlCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbiAoc2+3IGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS4gVGhhdCBpcywgaXQKICAgICogbXVzdCBiZSBwb3NzaWJsZSB0byByZWFjaCBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZSBvciB0aGUgt3NpbXBsZQogICAgKiB1ci10eXBlIGRlZmluaXRpb263IGJ5IHJlcGVhdGVkbHkgZm9sbG93aW5nIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgogICAgKgogICAgKiBOT1RFOiB0aGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXIoKS4KICAgICovCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0czoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgU2ltcGxlKSAoY29zLXN0LXJlc3RyaWN0cykKCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gQHR5cGUgKHNpbXBsZVR5cGUpIGlzIGRlcml2ZWQgdmFsaWRseSBieSByZXN0cmljdGlvbi4KICogU1RBVFVTOgogKgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9ycywgMCBpZiB0aGUgdHlwZSBpcyB2YWxpZGx5IGRlcml2ZWQsCiAqIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkgICAgImdpdmVuIHR5cGUgaXMgbm90IGEgdXNlci1kZXJpdmVkIHNpbXBsZVR5cGUiKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChWQVJJRVRZX0FUT01JQyh0eXBlKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBwcmltaXRpdmU7CgkvKgoJKiAxLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhbiBhdG9taWMgc2ltcGxlCgkqIHR5cGUgZGVmaW5pdGlvbiBvciBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZS4KCSovCglpZiAoISBWQVJJRVRZX0FUT01JQyh0eXBlLT5iYXNlVHlwZSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSBiYXNlIHR5cGUgJyVzJyBpcyBub3QgYW4gYXRvbWljIHNpbXBsZSB0eXBlIiwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzEpOwoJfQoJLyogMS4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4KCSogcmVzdHJpY3Rpb24uCgkqLwoJLyogT1BUSU1JWkUgVE9ETyA6IFRoaXMgaXMgYWxyZWFkeSBkb25lIGluIHhtbFNjaGVtYUNoZWNrU3RQcm9wc0NvcnJlY3QgKi8KCWlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh0eXBlLT5iYXNlVHlwZSwKCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzIsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiVGhlIGZpbmFsIG9mIGl0cyBiYXNlIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMik7Cgl9CgoJLyoKCSogMS4zLjEgREYgbXVzdCBiZSBhbiBhbGxvd2VkIGNvbnN0cmFpbmluZyBmYWNldCBmb3IgdGhlIHtwcmltaXRpdmUKCSogdHlwZSBkZWZpbml0aW9ufSwgYXMgc3BlY2lmaWVkIGluIHRoZSBhcHByb3ByaWF0ZSBzdWJzZWN0aW9uIG9mIDMuMgoJKiBQcmltaXRpdmUgZGF0YXR5cGVzLgoJKi8KCWlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIGludCBvayA9IDE7CgoJICAgIHByaW1pdGl2ZSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHlwZSk7CgkgICAgaWYgKHByaW1pdGl2ZSA9PSBOVUxMKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkJICAgICJmYWlsZWQgdG8gZ2V0IHByaW1pdGl2ZSB0eXBlIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJICAgIGRvIHsKCQlpZiAoeG1sU2NoZW1hSXNCdWlsdEluVHlwZUZhY2V0KHByaW1pdGl2ZSwgZmFjZXQtPnR5cGUpID09IDApIHsKCQkgICAgb2sgPSAwOwoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfM18xLAoJCQlOVUxMLCB0eXBlLCBwcmltaXRpdmUsIGZhY2V0KTsKCQl9CgkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCSAgICBpZiAob2sgPT0gMCkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEpOwoJfQoJLyoKCSogU1BFQyAoMS4zLjIpICJJZiB0aGVyZSBpcyBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgaW4gdGhlIHtmYWNldHN9CgkqIG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IChjYWxsIHRoaXMgQkYpLHRoZW4gdGhlIERGJ3Mge3ZhbHVlfQoJKiBtdXN0IGJlIGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgQkYncyB7dmFsdWV9IGFzIGRlZmluZWQgaW4KCSogW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLiIKCSoKCSogTk9URSAoMS4zLjIpIEZhY2V0IGRlcml2YXRpb24gY29uc3RyYWludHMgYXJlIGN1cnJlbnRseSBoYW5kbGVkIGluCgkqIHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKCkKCSovCiAgICB9IGVsc2UgaWYgKFZBUklFVFlfTElTVCh0eXBlKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBpdGVtVHlwZSA9IE5VTEw7CgoJaXRlbVR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKCWlmICgoaXRlbVR5cGUgPT0gTlVMTCkgfHwgKCEgSVNfU0lNUExFX1RZUEUoaXRlbVR5cGUpKSkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMiLAoJCSJmYWlsZWQgdG8gZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJaWYgKElTX05PVF9UWVBFRklYRUQoaXRlbVR5cGUpKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtVHlwZSwgcGN0eHQsIE5VTEwpOwoJLyoKCSogMi4xIFRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiBhdG9taWMgb3IKCSogdW5pb24gKGluIHdoaWNoIGNhc2UgYWxsIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9CgkqIG11c3QgYmUgYXRvbWljKS4KCSovCglpZiAoKCEgVkFSSUVUWV9BVE9NSUMoaXRlbVR5cGUpKSAmJgoJICAgICghIFZBUklFVFlfVU5JT04oaXRlbVR5cGUpKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiVGhlIGl0ZW0gdHlwZSAnJXMnIGRvZXMgbm90IGhhdmUgYSB2YXJpZXR5IG9mIGF0b21pYyBvciB1bmlvbiIsCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgaXRlbVR5cGUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCX0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTihpdGVtVHlwZSkpIHsKCSAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7CgoJICAgIG1lbWJlciA9IGl0ZW1UeXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoISBWQVJJRVRZX0FUT01JQyhtZW1iZXItPnR5cGUpKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlIGl0ZW0gdHlwZSBpcyBhIHVuaW9uIHR5cGUsIGJ1dCB0aGUgIgoJCQkibWVtYmVyIHR5cGUgJyVzJyBvZiB0aGlzIGl0ZW0gdHlwZSBpcyBub3QgYXRvbWljIiwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgbWVtYmVyLT50eXBlKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCX0KCglpZiAoSVNfQU5ZX1NJTVBMRV9UWVBFKHR5cGUtPmJhc2VUeXBlKSkgewoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxsaXN0IC4uCgkgICAgKi8KCSAgICAvKgoJICAgICogMi4zLjEKCSAgICAqIDIuMy4xLjEgVGhlIHtmaW5hbH0gb2YgdGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QKCSAgICAqIGNvbnRhaW4gbGlzdC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhpdGVtVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBpdGVtIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdsaXN0JyIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIGl0ZW1UeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBvbmx5IGNvbnRhaW4gdGhlIHdoaXRlU3BhY2UKCSAgICAqIGZhY2V0IGNvbXBvbmVudC4KCSAgICAqIE9QVElNSVpFIFRPRE86IHRoZSBTNFMgYWxyZWFkeSBkaXNhbGxvd3MgYW55IGZhY2V0CgkgICAgKiB0byBiZSBzcGVjaWZpZWQuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihwY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMiwKCQkJICAgIE5VTEwsIHR5cGUsIGZhY2V0KTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIpOwoJCSAgICB9CgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBNQVlCRSBUT0RPOiAoSG1tLCBub3QgcmVhbGx5KSBEYXRhdHlwZXMgc3RhdGVzOgoJICAgICogQSC3bGlzdLcgZGF0YXR5cGUgY2FuIGJlILdkZXJpdmVktyBmcm9tIGFuILdhdG9taWO3IGRhdGF0eXBlCgkgICAgKiB3aG9zZSC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlIChzdWNoIGFzIHN0cmluZyBvciBhbnlVUkkpb3IKCSAgICAqIGEgt3VuaW9utyBkYXRhdHlwZSBhbnkgb2Ygd2hvc2Uge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSdzCgkgICAgKiC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlLgoJICAgICovCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbiAuLi4KCSAgICAqIEkuZS4gdGhlIHZhcmlldHkgb2YgImxpc3QiIGlzIGluaGVyaXRlZC4KCSAgICAqLwoJICAgIC8qCgkgICAgKiAyLjMuMgoJICAgICogMi4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgbGlzdC4KCSAgICAqLwoJICAgIGlmICghIFZBUklFVFlfTElTVCh0eXBlLT5iYXNlVHlwZSkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYmFzZSB0eXBlICclcycgbXVzdCBiZSBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIHR5cGUtPmJhc2VUeXBlKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJICAgICogY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh0eXBlLT5iYXNlVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4yLjMgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQKCSAgICAqIGZyb20gdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0ncyB7aXRlbSB0eXBlIGRlZmluaXRpb259IGdpdmVuCgkgICAgKiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuCgkgICAgKi8KCSAgICB7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlSXRlbVR5cGU7CgoJCWJhc2VJdGVtVHlwZSA9IHR5cGUtPmJhc2VUeXBlLT5zdWJ0eXBlczsKCQlpZiAoKGJhc2VJdGVtVHlwZSA9PSBOVUxMKSB8fCAoISBJU19TSU1QTEVfVFlQRShiYXNlSXRlbVR5cGUpKSkgewoJCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzIiwKCQkJImZhaWxlZCB0byBldmFsIHRoZSBpdGVtIHR5cGUgb2YgYSBiYXNlIHR5cGUiKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCWlmICgoaXRlbVR5cGUgIT0gYmFzZUl0ZW1UeXBlKSAmJgoJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhpdGVtVHlwZSwKCQkJYmFzZUl0ZW1UeXBlLCAwKSAhPSAwKSkgewoJCSAgICB4bWxDaGFyICpzdHJCSVQgPSBOVUxMLCAqc3RyQlQgPSBOVUxMOwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzMsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgaXRlbSB0eXBlICclcycgaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tICIKCQkJInRoZSBpdGVtIHR5cGUgJyVzJyBvZiB0aGUgYmFzZSB0eXBlICclcyciLAoJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBpdGVtVHlwZSksCgkJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCSVQsIGJhc2VJdGVtVHlwZSksCgkJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCVCwgdHlwZS0+YmFzZVR5cGUpKTsKCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJJVCkKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCVCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzMpOwoJCX0KCSAgICB9CgoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgkJLyoKCQkqIDIuMy4yLjQgT25seSBsZW5ndGgsIG1pbkxlbmd0aCwgbWF4TGVuZ3RoLCB3aGl0ZVNwYWNlLCBwYXR0ZXJuCgkJKiBhbmQgZW51bWVyYXRpb24gZmFjZXQgY29tcG9uZW50cyBhcmUgYWxsb3dlZCBhbW9uZyB0aGUge2ZhY2V0c30uCgkJKi8KCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJCSAgICAvKgoJCQkgICAgKiBUT0RPOiAyLjUuMS4yIExpc3QgZGF0YXR5cGVzCgkJCSAgICAqIFRoZSB2YWx1ZSBvZiC3d2hpdGVTcGFjZbcgaXMgZml4ZWQgdG8gdGhlIHZhbHVlIGNvbGxhcHNlLgoJCQkgICAgKi8KCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQkJICAgIGJyZWFrOwoJCQlkZWZhdWx0OiB7CgkJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80LAoJCQkJTlVMTCwgdHlwZSwgZmFjZXQpOwoJCQkgICAgLyoKCQkJICAgICogV2UgY291bGQgcmV0dXJuLCBidXQgaXQncyBuaWNlciB0byByZXBvcnQgYWxsCgkJCSAgICAqIGludmFsaWQgZmFjZXRzLgoJCQkgICAgKi8KCQkJICAgIG9rID0gMDsKCQkJfQoJCSAgICB9CgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80KTsKCQkvKgoJCSogU1BFQyAoMi4zLjIuNSkgKHNhbWUgYXMgMS4zLjIpCgkJKgoJCSogTk9URSAoMi4zLjIuNSkgVGhpcyBpcyBjdXJyZW50bHkgZG9uZSBpbgoJCSogeG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMoKQoJCSovCgkgICAgfQoJfQogICAgfSBlbHNlIGlmIChWQVJJRVRZX1VOSU9OKHR5cGUpKSB7CgkvKgoJKiAzLjEgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBhbGwgaGF2ZSB7dmFyaWV0eX0gb2YKCSogYXRvbWljIG9yIGxpc3QuCgkqLwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgaWYgKElTX05PVF9UWVBFRklYRUQobWVtYmVyLT50eXBlKSkKCQl4bWxTY2hlbWFUeXBlRml4dXAobWVtYmVyLT50eXBlLCBwY3R4dCwgTlVMTCk7CgoJICAgIGlmICgoISBWQVJJRVRZX0FUT01JQyhtZW1iZXItPnR5cGUpKSAmJgoJCSghIFZBUklFVFlfTElTVChtZW1iZXItPnR5cGUpKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIG1lbWJlciB0eXBlICclcycgaXMgbmVpdGhlciBhbiBhdG9taWMsIG5vciBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHIsIG1lbWJlci0+dHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEpOwoJICAgIH0KCSAgICBtZW1iZXIgPSBtZW1iZXItPm5leHQ7Cgl9CgkvKgoJKiAzLjMuMSBJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyB0aGUgt3NpbXBsZSB1ci10eXBlCgkqIGRlZmluaXRpb263CgkqLwoJaWYgKHR5cGUtPmJhc2VUeXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSB7CgkgICAgLyoKCSAgICAqIDMuMy4xLjEgQWxsIG9mIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgaGF2ZSBhCgkgICAgKiB7ZmluYWx9IHdoaWNoIGRvZXMgbm90IGNvbnRhaW4gdW5pb24uCgkgICAgKi8KCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMobWVtYmVyLT50eXBlLAoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlICdmaW5hbCcgb2YgbWVtYmVyIHR5cGUgJyVzJyBjb250YWlucyAndW5pb24nIiwKCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ciwgbWVtYmVyLT50eXBlKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMS4yIFRoZSB7ZmFjZXRzfSBtdXN0IGJlIGVtcHR5LgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJObyBmYWNldHMgYWxsb3dlZCIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMV8yKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAzLjMuMi4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiB1bmlvbi4KCSAgICAqIEkuZS4gdGhlIHZhcmlldHkgb2YgImxpc3QiIGlzIGluaGVyaXRlZC4KCSAgICAqLwoJICAgIGlmICghIFZBUklFVFlfVU5JT04odHlwZS0+YmFzZVR5cGUpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGJhc2UgdHlwZSAnJXMnIGlzIG5vdCBhIHVuaW9uIHR5cGUiLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh0eXBlLT5iYXNlVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSAnZmluYWwnIG9mIGl0cyBiYXNlIHR5cGUgJyVzJyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCB0eXBlLT5iYXNlVHlwZSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjMgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLCBtdXN0IGJlIHZhbGlkbHkKCSAgICAqIGRlcml2ZWQgZnJvbSB0aGUgY29ycmVzcG9uZGluZyB0eXBlIGRlZmluaXRpb25zIGluIHRoZSB7YmFzZQoJICAgICogdHlwZSBkZWZpbml0aW9ufSdzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIGVtcHR5IHNldCwKCSAgICAqIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlTGlua1B0ciBiYXNlTWVtYmVyOwoKCQkvKgoJCSogT1BUSU1JWkU6IGlmIHRoZSB0eXBlIGlzIHJlc3RyaWN0aW5nLCBpdCBoYXMgbm8gbG9jYWwgZGVmaW5lZAoJCSogbWVtYmVyIHR5cGVzIGFuZCBpbmhlcml0cyB0aGUgbWVtYmVyIHR5cGVzIG9mIHRoZSBiYXNlIHR5cGU7CgkJKiB0aHVzIGEgY2hlY2sgZm9yIGVxdWFsaXR5IGNhbiBiZSBza2lwcGVkLgoJCSovCgkJLyoKCQkqIEV2ZW4gd29yc2U6IEkgY2Fubm90IHNlZSBhIHNjZW5hcmlvIHdoZXJlIGEgcmVzdHJpY3RpbmcKCQkqIHVuaW9uIHNpbXBsZSB0eXBlIGNhbiBoYXZlIG90aGVyIG1lbWJlciB0eXBlcyBhcyB0aGUgbWVtYmVyCgkJKiB0eXBlcyBvZiBpdCdzIGJhc2UgdHlwZS4gVGhpcyBjaGVjayBzZWVtcyBub3QgbmVjZXNzYXJ5IHdpdGgKCQkqIHJlc3BlY3QgdG8gdGhlIGRlcml2YXRpb24gcHJvY2VzcyBpbiBsaWJ4bWwyLgoJCSogQnV0IG5lY2Vzc2FyeSBpZiBjb25zdHJ1Y3RpbmcgdHlwZXMgd2l0aCBhbiBBUEkuCgkJKi8KCQlpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkgewoJCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCQkgICAgYmFzZU1lbWJlciA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHR5cGUtPmJhc2VUeXBlKTsKCQkgICAgaWYgKChtZW1iZXIgPT0gTlVMTCkgJiYgKGJhc2VNZW1iZXIgIT0gTlVMTCkpIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyIsCgkJCSAgICAiZGlmZmVyZW50IG51bWJlciBvZiBtZW1iZXIgdHlwZXMgaW4gYmFzZSIpOwoJCSAgICB9CgkJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCQlpZiAoYmFzZU1lbWJlciA9PSBOVUxMKSB7CgkJCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzIiwKCQkJICAgICJkaWZmZXJlbnQgbnVtYmVyIG9mIG1lbWJlciB0eXBlcyBpbiBiYXNlIik7CgkJCX0KCQkJaWYgKChtZW1iZXItPnR5cGUgIT0gYmFzZU1lbWJlci0+dHlwZSkgJiYKCQkJICAgICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKAoJCQkJbWVtYmVyLT50eXBlLCBiYXNlTWVtYmVyLT50eXBlLCAwKSAhPSAwKSkgewoJCQkgICAgeG1sQ2hhciAqc3RyQk1UID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJCSJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgIgoJCQkJImRlcml2ZWQgZnJvbSBpdHMgY29ycmVzcG9uZGluZyBtZW1iZXIgIgoJCQkJInR5cGUgJXMgb2YgdGhlIGJhc2UgdHlwZSAlcyIsCgkJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyLCBtZW1iZXItPnR5cGUpLAoJCQkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckJNVCwgYmFzZU1lbWJlci0+dHlwZSksCgkJCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQlQsIHR5cGUtPmJhc2VUeXBlKSk7CgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyQk1UKQoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCVCkKCQkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zKTsKCQkJfQoJCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkJCWJhc2VNZW1iZXIgPSBiYXNlTWVtYmVyLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuNCBPbmx5IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlCgkgICAgKiBhbGxvd2VkIGFtb25nIHRoZSB7ZmFjZXRzfS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80LAoJCQkJTlVMTCwgdHlwZSwgZmFjZXQpOwoJCQlvayA9IDA7CgkJICAgIH0KCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQpOwoKCSAgICB9CgkgICAgLyoKCSAgICAqIFNQRUMgKDMuMy4yLjUpIChzYW1lIGFzIDEuMy4yKQoJICAgICoKCSAgICAqIE5PVEUgKDMuMy4yLjUpIFRoaXMgaXMgY3VycmVudGx5IGRvbmUgaW4KCSAgICAqIHhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKCkKCSAgICAqLwoJfQogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1NSQ1NpbXBsZVR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBjcmMtc2ltcGxlLXR5cGUgY29uc3RyYWludHMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwKICogaWYgbm90IGEgcG9zaXRpdmUgZXJyb3IgY29kZSBhbmQgLTEgb24gaW50ZXJuYWwKICogZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NSQ1NpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICAvKgogICAgKiBzcmMtc2ltcGxlLXR5cGUuMSBUaGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCBpZiBhbnksCiAgICAqIG11c3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9ucyBzZXQgb3V0IGluIENvbnN0cmFpbnRzIG9uIFNpbXBsZSBUeXBlCiAgICAqIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjE0LjYpLgogICAgKi8KICAgIGlmICgoeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdChjdHh0LCB0eXBlKSAhPSAwKSB8fAoJKHhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoY3R4dCwgdHlwZSkgIT0gMCkpIHsKCS8qCgkqIFRPRE86IFJlbW92ZWQgdGhpcywgc2luY2UgaXQgZ290IGFubm95aW5nIHRvIGdldCBhbgoJKiBleHRyYSBlcnJvciByZXBvcnQsIGlmIGFueXRoaW5nIGZhaWxlZCB1bnRpbCBub3cuCgkqIEVuYWJsZSB0aGlzIGlmIG5lZWRlZC4KCSovCgkvKgoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgICJTaW1wbGUgdHlwZSAnJXMnIGRvZXMgbm90IHNhdGlzZnkgdGhlIGNvbnN0cmFpbnRzICIKCSAgICAib24gc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJKi8KCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEpOwogICAgfQoKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCS8qCgkqIHNyYy1zaW1wbGUtdHlwZS4yIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKCSogZWl0aGVyIGl0IG11c3QgaGF2ZSBhIGJhc2UgW2F0dHJpYnV0ZV0gb3IgYSA8c2ltcGxlVHlwZT4gYW1vbmcgaXRzCgkqIFtjaGlsZHJlbl0sIGJ1dCBub3QgYm90aC4KCSovCgkvKgoJKiBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMgoJKiBOT1RFOiBUaGlzIGlzIGNoZWNrZWQgaW4gdGhlIHBhcnNlIGZ1bmN0aW9uIG9mIDxyZXN0cmljdGlvbj4uCgkqLwogICAgfSBlbHNlIGlmIChWQVJJRVRZX0xJU1QodHlwZSkpIHsKCS8qIHNyYy1zaW1wbGUtdHlwZS4zIElmIHRoZSA8bGlzdD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCBlaXRoZXIgaXQgbXVzdCBoYXZlCgkqIGFuIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyBbY2hpbGRyZW5dLAoJKiBidXQgbm90IGJvdGguCgkqCgkqIFJFTU9WRUQ6IFRoaXMgaXMgY2hlY2tlZCBpbiB0aGUgcGFyc2UgZnVuY3Rpb24gb2YgPGxpc3Q+LgoJKi8KICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTih0eXBlKSkgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoJeG1sU2NoZW1hVHlwZVB0ciBhbmNlc3RvciwgYW55U2ltcGxlVHlwZTsKCglhbnlTaW1wbGVUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CgoJLyogc3JjLXNpbXBsZS10eXBlLjQgQ2lyY3VsYXIgdW5pb24gdHlwZSBkZWZpbml0aW9uIGlzIGRpc2FsbG93ZWQuIFRoYXQgaXMsIGlmCgkqIHRoZSA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlcmUgbXVzdCBub3QgYmUgYW55IGVudHJpZXMKCSogaW4gdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIGF0IGFueSBkZXB0aCB3aGljaCByZXNvbHZlIHRvIHRoZQoJKiBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+LgoJKi8KCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgYW5jZXN0b3IgPSBtZW1iZXItPnR5cGU7CgkgICAgd2hpbGUgKChhbmNlc3RvciAhPSBOVUxMKSAmJiAoYW5jZXN0b3ItPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkgewoJCWlmIChhbmNlc3RvciA9PSB0eXBlKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzQsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCQl9CgkJaWYgKElTX05PVF9UWVBFRklYRUQoYW5jZXN0b3IpKQoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYW5jZXN0b3IsIGN0eHQsICBOVUxMKTsKCQlpZiAoVkFSSUVUWV9MSVNUKGFuY2VzdG9yKSkgewoJCSAgICAvKgoJCSAgICAqIFRPRE8sIEZJWE1FOiBBbHRob3VnaCBhIGxpc3Qgc2ltcGxlIHR5cGUgbXVzdCBub3QgaGF2ZSBhIHVuaW9uIFNUCgkJICAgICogdHlwZSBhcyBpdGVtIHR5cGUsIHdoaWNoIGluIHR1cm4gaGFzIGEgbGlzdCBTVCBhcyBtZW1iZXIKCQkgICAgKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGlzIGhlcmUgYXMgd2VsbCwgc2luY2UgdGhpcyBjaGVjawoJCSAgICAqIHdhcyBub3QgeWV0IHBlcmZvcm1lZC4KCQkgICAgKi8KCQl9CgoJCWFuY2VzdG9yID0gYW5jZXN0b3ItPmJhc2VUeXBlOwoJICAgIH0KCSAgICBtZW1iZXIgPSBtZW1iZXItPm5leHQ7Cgl9CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgIGlmIChjdHh0LT52Y3R4dCA9PSBOVUxMKSB7CgljdHh0LT52Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKCWlmIChjdHh0LT52Y3R4dCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0LCAiCgkJImZhaWxlZCB0byBjcmVhdGUgYSB0ZW1wLiB2YWxpZGF0aW9uIGNvbnRleHQuXG4iLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyogVE9ETzogUGFzcyB1c2VyIGRhdGEuICovCgl4bWxTY2hlbWFTZXRWYWxpZEVycm9ycyhjdHh0LT52Y3R4dCwgY3R4dC0+ZXJyb3IsIGN0eHQtPndhcm5pbmcsIE5VTEwpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgIHhtbFNjaGVtYVZhbFB0ciAqcmV0VmFsLAoJCQkgICAgIGludCBmaXJlRXJyb3JzLAoJCQkgICAgIGludCBub3JtYWxpemUsCgkJCSAgICAgaW50IGlzTm9ybWFsaXplZCk7CgovKioKICogeG1sU2NoZW1hUGFyc2VDaGVja0NPU1ZhbGlkRGVmYXVsdDoKICogQHBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWx1ZTogdGhlIGRlZmF1bHQgdmFsdWUKICogQG5vZGU6IGFuIG9wdGlvbmFsIG5vZGUgKHRoZSBob2xkZXIgb2YgdGhlIHZhbHVlKQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogKiAoY29zLXZhbGlkLWRlZmF1bHQpCiAqIFRoaXMgd2lsbCBiZSB1c2VkIGJ5IHRoZSBwYXJzZXIgb25seS4gRm9yIHRoZSB2YWxpZGF0b3IgdGhlcmUncwogKiBhbiBvdGhlciB2ZXJzaW9uLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlQ2hlY2tDT1NWYWxpZERlZmF1bHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkJICAgeG1sU2NoZW1hVmFsUHRyICp2YWwpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIGNvcy12YWxpZC1kZWZhdWx0OgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogICAgKiBGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0IHdpdGggcmVzcGVjdCB0byBhIHR5cGUKICAgICogZGVmaW5pdGlvbiB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBpZiBJU19DT01QTEVYX1RZUEUodHlwZSkgewoJLyoKCSogQ29tcGxleCB0eXBlLgoJKgoJKiBTUEVDICgyLjEpICJpdHMge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KCSogb3IgbWl4ZWQuIgoJKiBTUEVDICgyLjIuMikgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBtaXhlZCwgdGhlbiB0aGUge2NvbnRlbnQKCSogdHlwZX0ncyBwYXJ0aWNsZSBtdXN0IGJlILdlbXB0aWFibGW3IGFzIGRlZmluZWQgYnkKCSogUGFydGljbGUgRW1wdGlhYmxlICinMy45LjYpLiIKCSovCglpZiAoKCEgSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKSAmJgoJICAgICgoISBIQVNfTUlYRURfQ09OVEVOVCh0eXBlKSkgfHwgKCEgSVNfUEFSVElDTEVfRU1QVElBQkxFKHR5cGUpKSkpIHsKCSAgICAvKiBOT1RFIHRoYXQgdGhpcyBjb3ZlcnMgKDIuMi4yKSBhcyB3ZWxsLiAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xLAoJCU5VTEwsIHR5cGUsIHR5cGUtPm5vZGUsCgkJIkZvciBhIHN0cmluZyB0byBiZSBhIHZhbGlkIGRlZmF1bHQsIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSJtdXN0IGJlIGEgc2ltcGxlIHR5cGUgb3IgYSBjb21wbGV4IHR5cGUgd2l0aCBtaXhlZCBjb250ZW50ICIKCQkiYW5kIGEgcGFydGljbGUgZW1wdGlhYmxlIiwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiAxIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBzdHJpbmcKICAgICogbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcKICAgICogVmFsaWQgKKczLjE0LjQpLgogICAgKgogICAgKiBBTkQKICAgICoKICAgICogMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUKICAgICogc3RyaW5nIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAgICAqIGFzIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KICAgICovCiAgICBpZiAoSVNfU0lNUExFX1RZUEUodHlwZSkpCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LCBub2RlLAoJICAgIHR5cGUsIHZhbHVlLCB2YWwsIDEsIDEsIDApOwogICAgZWxzZSBpZiAoSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKQoJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwgbm9kZSwKCSAgICB0eXBlLT5jb250ZW50VHlwZURlZiwgdmFsdWUsIHZhbCwgMSwgMSwgMCk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7CgogICAgaWYgKHJldCA8IDApIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlQ2hlY2tDT1NWYWxpZERlZmF1bHQiLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ1RQcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKi4oNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCAoY3QtcHJvcHMtY29ycmVjdCkKICogU1RBVFVTOiAoc2VlbXMpIGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgLyoKICAgICogVE9ETzogQ29ycmVjdCB0aGUgZXJyb3IgY29kZTsgWE1MX1NDSEVNQVBfU1JDX0NUXzEgaXMgdXNlZCB0ZW1wb3JhcmlseS4KICAgICoKICAgICogU1BFQyAoMSkgIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBtdXN0CiAgICAqIGJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgQ29tcGxleCBUeXBlIERlZmluaXRpb24KICAgICogU2NoZW1hIENvbXBvbmVudCAopzMuNC4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZwogICAgKiBTdWItY29tcG9uZW50cyAopzUuMykuIgogICAgKi8KICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgJiYKCShJU19TSU1QTEVfVFlQRSh0eXBlLT5iYXNlVHlwZSkpICYmCgkoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgkvKgoJKiBTUEVDICgyKSAiSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLAoJKiB0aGUge2Rlcml2YXRpb24gbWV0aG9kfSBtdXN0IGJlIGV4dGVuc2lvbi4iCgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJZiB0aGUgYmFzZSB0eXBlIGlzIGEgc2ltcGxlIHR5cGUsIHRoZSBkZXJpdmF0aW9uIG1ldGhvZCBtdXN0IGJlICIKCSAgICAiJ2V4dGVuc2lvbiciLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwogICAgfQogICAgLyoKICAgICogU1BFQyAoMykgIkNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkLCBleGNlcHQgZm9yIHRoZSC3dXItdHlwZQogICAgKiBkZWZpbml0aW9uty4gVGhhdCBpcywgaXQgbXVzdCBiZSBwb3NzaWJsZSB0byByZWFjaCB0aGUgt3VyLXR5cGUKICAgICogZGVmaW5pdGlvbiBieSByZXBlYXRlZGx5IGZvbGxvd2luZyB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4iCiAgICAqCiAgICAqIE5PVEUgKDMpIGlzIGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXIoKS4KICAgICoKICAgICogU1BFQyAoNCkgIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9CiAgICAqIG11c3Qgbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuIgogICAgKiBTUEVDICg1KSAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30KICAgICogbXVzdCBub3QgaGF2ZSB7dHlwZSBkZWZpbml0aW9ufXMgd2hpY2ggYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuIgogICAgKgogICAgKiBOT1RFICg0KSBhbmQgKDUpIGFyZSBkb25lIGluIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbigpLgogICAgKi8KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXJlRXF1YWxUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVBLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVCKQp7CiAgICAvKgogICAgKiBUT0RPOiBUaGlzIHNob3VsZCBpbXBsZW1lbnQgY29tcG9uZW50LWlkZW50aXR5CiAgICAqIGluIHRoZSBmdXR1cmUuCiAgICAqLwogICAgaWYgKCh0eXBlQSA9PSBOVUxMKSB8fCAodHlwZUIgPT0gTlVMTCkpCglyZXR1cm4gKDApOwogICAgcmV0dXJuICh0eXBlQSA9PSB0eXBlQik7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU0NURGVyaXZlZE9LOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdG8tYmUgZGVyaXZlZCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAc2V0OiB0aGUgZ2l2ZW4gc2V0CiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAoY29zLWN0LWRlcml2ZWQtb2spCiAqCiAqIFNUQVRVUzogY29tcGxldGVkCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgb3IgMQogKiBpZiBub3QuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TQ1REZXJpdmVkT0soeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCSAgICAgaW50IHNldCkKewogICAgaW50IGVxdWFsID0geG1sU2NoZW1hQXJlRXF1YWxUeXBlcyh0eXBlLCBiYXNlVHlwZSk7CiAgICAvKiBUT0RPOiBFcnJvciBjb2Rlcy4gKi8KICAgIC8qCiAgICAqIFNQRUMgIkZvciBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIChjYWxsIGl0IEQsIGZvciBkZXJpdmVkKQogICAgKiB0byBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhIHR5cGUgZGVmaW5pdGlvbiAoY2FsbCB0aGlzCiAgICAqIEIsIGZvciBiYXNlKSBnaXZlbiBhIHN1YnNldCBvZiB7ZXh0ZW5zaW9uLCByZXN0cmljdGlvbn0KICAgICogYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICovCiAgICBpZiAoISBlcXVhbCkgewoJLyoKCSogU1BFQyAoMSkgIklmIEIgYW5kIEQgYXJlIG5vdCB0aGUgc2FtZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlCgkqIHtkZXJpdmF0aW9uIG1ldGhvZH0gb2YgRCBtdXN0IG5vdCBiZSBpbiB0aGUgc3Vic2V0LiIKCSovCglpZiAoKChzZXQgJiBTVUJTRVRfRVhURU5TSU9OKSAmJgoJICAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSkgfHwKCSAgICAoKHNldCAmIFNVQlNFVF9SRVNUUklDVElPTikgJiYKCSAgICAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSkpCgkgICAgcmV0dXJuICgxKTsKICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDICgyLjEpICJCIGFuZCBEIG11c3QgYmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLiIKCSovCglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogU1BFQyAoMi4yKSAiQiBtdXN0IGJlIEQncyB7YmFzZSB0eXBlIGRlZmluaXRpb259LiIKICAgICovCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gYmFzZVR5cGUpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogU1BFQyAoMi4zLjEpICJEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBiZSB0aGUgt3VyLXR5cGUKICAgICogZGVmaW5pdGlvbrcuIgogICAgKi8KICAgIGlmIChJU19BTllUWVBFKHR5cGUtPmJhc2VUeXBlKSkKCXJldHVybiAoMSk7CgogICAgaWYgKElTX0NPTVBMRVhfVFlQRSh0eXBlLT5iYXNlVHlwZSkpIHsKCS8qCgkqIFNQRUMgKDIuMy4yLjEpICJJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4LCB0aGVuIGl0CgkqIG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0IGFzIGRlZmluZWQgYnkgdGhpcwoJKiBjb25zdHJhaW50LiIKCSovCglyZXR1cm4gKHhtbFNjaGVtYUNoZWNrQ09TQ1REZXJpdmVkT0sodHlwZS0+YmFzZVR5cGUsCgkgICAgYmFzZVR5cGUsIHNldCkpOwogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMgKDIuMy4yLjIpICJJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBzaW1wbGUsIHRoZW4gaXQKCSogbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQgYXMgZGVmaW5lZCBpbiBUeXBlCgkqIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJKi8KCXJldHVybiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh0eXBlLT5iYXNlVHlwZSwgYmFzZVR5cGUsIHNldCkpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0s6CiAqIEB0eXBlOiAgdGhlIGRlcml2ZWQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2FsbHM6CiAqIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSBBTkQgVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KQogKgogKiBDaGVja3Mgd2hldGVyIEB0eXBlIGNhbiBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBAYmFzZVR5cGUuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhbiBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0soeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICBpbnQgc2V0KQp7CiAgICBpZiAoSVNfU0lNUExFX1RZUEUodHlwZSkpCglyZXR1cm4gKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0sodHlwZSwgYmFzZVR5cGUsIHNldCkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFDaGVja0NPU0NURGVyaXZlZE9LKHR5cGUsIGJhc2VUeXBlLCBzZXQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgKGNvcy1jdC1leHRlbmRzKQogKgogKiBTVEFUVVM6CiAqICAgbWlzc2luZzoKICogICAgICgxLjUpCiAqICAgICAoMS40LjMuMi4yLjIpICJQYXJ0aWNsZSBWYWxpZCAoRXh0ZW5zaW9uKSIsIHdoaWNoIGlzIG5vdCByZWFsbHkgbmVlZGVkLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIC8qCiAgICAqIFRPRE86IENvcnJlY3QgdGhlIGVycm9yIGNvZGU7IFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSBpcyB1c2VkCiAgICAqIHRlbXBvcmFyaWx5IG9ubHkuCiAgICAqLwogICAgLyoKICAgICogU1BFQyAoMSkgIklmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24sCiAgICAqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICovCiAgICBpZiAoYmFzZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJLyoKCSogU1BFQyAoMS4xKSAiVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QKCSogY29udGFpbiBleHRlbnNpb24uIgoJKi8KCWlmIChiYXNlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJUaGUgJ2ZpbmFsJyBvZiB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gIgoJCSJjb250YWlucyAnZXh0ZW5zaW9uJyIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KCS8qCgkqIFNQRUMgKDEuMikgIkl0cyB7YXR0cmlidXRlIHVzZXN9IG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlIHthdHRyaWJ1dGUKCSogdXNlc30KCSogb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZiwgdGhhdCBpcywgZm9yIGV2ZXJ5IGF0dHJpYnV0ZQoJKiB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0sIHRoZXJlCgkqIG11c3QgYmUgYW4gYXR0cmlidXRlIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUgY29tcGxleAoJKiB0eXBlIGRlZmluaXRpb24gaXRzZWxmIHdob3NlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyB0aGUgc2FtZQoJKiB7bmFtZX0sIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge3R5cGUgZGVmaW5pdGlvbn0gYXMgaXRzIGF0dHJpYnV0ZQoJKiBkZWNsYXJhdGlvbiIKCSoKCSogTk9URSAoMS4yKTogVGhpcyB3aWxsIGJlIGFscmVhZHkgc2F0aXNmaWVkIGJ5IHRoZSB3YXkgdGhlIGF0dHJpYnV0ZQoJKiB1c2VzIGFyZSBleHRlbmRlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oKTsgdGh1cyB0aGlzCgkqIGNoZWNrIGlzIG5vdCBuZWVkZWQuCgkqLwoKCS8qCgkqIFNQRUMgKDEuMykgIklmIGl0IGhhcyBhbiB7YXR0cmlidXRlIHdpbGRjYXJkfSwgdGhlIGNvbXBsZXggdHlwZQoJKiBkZWZpbml0aW9uIG11c3QgYWxzbyBoYXZlIG9uZSwgYW5kIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbidzCgkqIHthdHRyaWJ1dGUgIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldAoJKiBvZiB0aGUgY29tcGxleCAgdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlCgkqIGNvbnN0cmFpbnR9LCBhcyBkZWZpbmVkIGJ5IFdpbGRjYXJkIFN1YnNldCAopzMuMTAuNikuIgoJKgoJKiBOT1RFICgxLjMpIFRoaXMgaXMgYWxyZWFkeSBjaGVja2VkIGluCgkqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjsgdGh1cyB0aGlzIGNoZWNrIGlzIG5vdCBuZWVkZWQuCgkqCgkqIFNQRUMgKDEuNCkgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkqLwoJaWYgKCh0eXBlLT5jb250ZW50VHlwZURlZiAhPSBOVUxMKSAmJgoJICAgICh0eXBlLT5jb250ZW50VHlwZURlZiA9PSBiYXNlLT5jb250ZW50VHlwZURlZikpIHsKCSAgICAvKgoJICAgICogU1BFQyAoMS40LjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0KCSAgICAqIGFuZCB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZgoJICAgICogbXVzdCBiZSB0aGUgc2FtZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpICYmCgkgICAgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDEuNC4yKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIGJvdGggdGhlIHtiYXNlIHR5cGUKCSAgICAqIGRlZmluaXRpb259IGFuZCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmIG11c3QKCSAgICAqIGJlIGVtcHR5LiIKCSAgICAqIFBBU1MKCSAgICAqLwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogU1BFQyAoMS40LjMpICJBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJICAgICovCgkgICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCQkvKgoJCSogU1BFQyAxLjQuMy4xIFRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlCgkJKiBkZWZpbml0aW9uIGl0c2VsZiBtdXN0IHNwZWNpZnkgYSBwYXJ0aWNsZS4KCQkqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGNvbnRlbnQgdHlwZSBtdXN0IHNwZWNpZnkgYSBwYXJ0aWNsZSIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFNQRUMgKDEuNC4zLjIpICJPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJICAgICovCgkgICAgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCS8qCgkJKiBTUEVDICgxLjQuMy4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUKCQkqIGRlZmluaXRpb259IG11c3QgYmUgZW1wdHkuCgkJKiBQQVNTCgkJKi8KCSAgICB9IGVsc2UgewoJCS8qCgkJKiBTUEVDICgxLjQuMy4yLjIpICJBbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJCSovCgkJaWYgKCh0eXBlLT5jb250ZW50VHlwZSAhPSBiYXNlLT5jb250ZW50VHlwZSkgfHwKCQkgICAgKCh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkJICAgICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKSkgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDEuNC4zLjIuMi4xKSAiQm90aCB7Y29udGVudCB0eXBlfXMgbXVzdCBiZSBtaXhlZAoJCSAgICAqIG9yIGJvdGggbXVzdCBiZSBlbGVtZW50LW9ubHkuIgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIlRoZSBjb250ZW50IHR5cGUgb2YgYm90aCwgdGhlIHR5cGUgYW5kIGl0cyBiYXNlICIKCQkJInR5cGUsIG11c3QgZWl0aGVyICdtaXhlZCcgb3IgJ2VsZW1lbnQtb25seSciLCBOVUxMKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJCX0KCQkvKgoJCSogRlVUVVJFIFRPRE8gU1BFQyAoMS40LjMuMi4yLjIpICJUaGUgcGFydGljbGUgb2YgdGhlCgkJKiBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBtdXN0IGJlIGEgt3ZhbGlkIGV4dGVuc2lvbrcKCQkqIG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3MgcGFydGljbGUsIGFzIGRlZmluZWQKCQkqIGluIFBhcnRpY2xlIFZhbGlkIChFeHRlbnNpb24pICinMy45LjYpLiIKCQkqCgkJKiBOT1RFIHRoYXQgd2Ugd29uJ3QgY2hlY2sgIlBhcnRpY2xlIFZhbGlkIChFeHRlbnNpb24pIiwKCQkqIHNpbmNlIGl0IGlzIGVuc3VyZWQgYnkgdGhlIGRlcml2YXRpb24gcHJvY2VzcyBpbgoJCSogeG1sU2NoZW1hVHlwZUZpeHVwKCkuIFdlIG5lZWQgdG8gaW1wbGVtZW50IHRoaXMgd2hlbiBoZWFkaW5nCgkJKiBmb3IgYSBjb25zdHJ1Y3Rpb24gQVBJCgkJKi8KCSAgICB9CgkgICAgLyoKCSAgICAqIFRPRE8gKDEuNSkKCSAgICAqLwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMgKDIpICJJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sCgkqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKCSovCglpZiAodHlwZS0+Y29udGVudFR5cGVEZWYgIT0gYmFzZSkgewoJICAgIC8qCgkgICAgKiBTUEVDICgyLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSB0aGUgc2FtZSBzaW1wbGUgdHlwZQoJICAgICogZGVmaW5pdGlvbi4iCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSBjb250ZW50IHR5cGUgbXVzdCBiZSB0aGUgc2ltcGxlIGJhc2UgdHlwZSIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KCWlmIChiYXNlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDIuMikgIlRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkgICAgKiBjb250YWluIGV4dGVuc2lvbiIKCSAgICAqIE5PVEUgdGhhdCB0aGlzIGlzIHRoZSBzYW1lIGFzICgxLjEpLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJUaGUgJ2ZpbmFsJyBvZiB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gIgoJCSJjb250YWlucyAnZXh0ZW5zaW9uJyIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25PS1Jlc3RyaWN0aW9uOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIERlcml2YXRpb24gVmFsaWQgKFJlc3RyaWN0aW9uLCBDb21wbGV4KSAoZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbikKICoKICogU1RBVFVTOgogKiAgIG1pc3Npbmc6CiAqICAgICAoNS40LjIpLCAoNS4yLjIuMSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25PS1Jlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKICAgIC8qCiAgICAqIFRPRE86IENvcnJlY3QgdGhlIGVycm9yIGNvZGU7IFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSBpcyB1c2VkCiAgICAqIHRlbXBvcmFyaWx5IG9ubHkuCiAgICAqLwogICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikgewoJLyoKCSogU1BFQyAoMSkgIlRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgYSBjb21wbGV4IHR5cGUKCSogZGVmaW5pdGlvbiB3aG9zZSB7ZmluYWx9IGRvZXMgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uIgoJKi8KCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiVGhlICdmaW5hbCcgb2YgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uICIKCSAgICAiY29udGFpbnMgJ3Jlc3RyaWN0aW9uJyIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwogICAgfQogICAgLyoKICAgICogTk9URSAoMykgYW5kICg0KSBhcmUgZG9uZSBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oKS4KICAgICoKICAgICogU1BFQyAoNSkgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCiAgICAqLwogICAgaWYgKGJhc2UtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpIHsKCS8qCgkqIFNQRUMgKDUuMSkgIlRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdGhlCgkqILd1ci10eXBlIGRlZmluaXRpb263LiIKCSogUEFTUwoJKi8KICAgIH0gZWxzZSBpZiAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8CgkgICAgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpIHsKCS8qCgkqIFNQRUMgKDUuMi4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgoJKiBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIKCSoKCSogU1BFQyAoNS4yLjIpICJPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJKi8KCWlmICgoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwKCSAgICAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgewoJICAgIC8qCgkgICAgKiBTUEVDICg1LjIuMi4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB7YmFzZSB0eXBlCgkgICAgKiBkZWZpbml0aW9ufSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBmcm9tIHdoaWNoCgkgICAgKiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgdmFsaWRseSBkZXJpdmVkIGdpdmVuIHRoZSBlbXB0eQoJICAgICogc2V0IGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4iCgkgICAgKiBVUkdFTlQgVE9ETwoJICAgICovCgl9IGVsc2UgaWYgKChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkgICAgKHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoCgkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlLT5zdWJ0eXBlcykpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuMi4yLjIpICJUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIG1peGVkCgkgICAgKiBhbmQgaGF2ZSBhIHBhcnRpY2xlIHdoaWNoIGlzILdlbXB0aWFibGW3IGFzIGRlZmluZWQgaW4KCSAgICAqIFBhcnRpY2xlIEVtcHRpYWJsZSAopzMuOS42KS4iCgkgICAgKiBQQVNTCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJUaGUgY29udGVudCB0eXBlIG9mIHRoZSBiYXNlIHR5cGUgbXVzdCBiZSBlaXRoZXIgIgoJCSJhIHNpbXBsZSB0eXBlIG9yICdtaXhlZCcgYW5kIGFuIGVtcHRpYWJsZSBwYXJ0aWNsZSIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkvKgoJKiBTUEVDICg1LjMuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGl0c2VsZiBtdXN0CgkqIGJlIGVtcHR5IgoJKi8KCWlmIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCSAgICAvKgoJICAgICogU1BFQyAoNS4zLjIuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZQoJICAgICogZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGJlIGVtcHR5LiIKCSAgICAqIFBBU1MKCSAgICAqLwoJfSBlbHNlIGlmICgoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgfHwKCSAgICAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSkgJiYKCSAgICB4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlKAoJCSh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgYmFzZS0+c3VidHlwZXMpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuMy4yLjIpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUKCSAgICAqIGRlZmluaXRpb259IG11c3QgYmUgZWxlbWVudE9ubHkgb3IgbWl4ZWQgYW5kIGhhdmUgYSBwYXJ0aWNsZQoJICAgICogd2hpY2ggaXMgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBpbiBQYXJ0aWNsZSBFbXB0aWFibGUgKKczLjkuNikuIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiVGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgYmFzZSB0eXBlIG11c3QgYmUgZWl0aGVyICIKCQkiZW1wdHkgb3IgJ21peGVkJyAob3IgJ2VsZW1lbnRzLW9ubHknKSBhbmQgYW4gZW1wdGlhYmxlICIKCQkicGFydGljbGUiLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CiAgICB9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpIHx8CglIQVNfTUlYRURfQ09OVEVOVCh0eXBlKSkgewoJLyoKCSogU1BFQyAoNS40LjEuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KCSogaXRzZWxmIG11c3QgYmUgZWxlbWVudC1vbmx5IgoJKi8JIAoJaWYgKEhBU19NSVhFRF9DT05URU5UKHR5cGUpICYmICghIEhBU19NSVhFRF9DT05URU5UKGJhc2UpKSkgewoJICAgIC8qCgkgICAgKiBTUEVDICg1LjQuMS4yKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUKCSAgICAqIGRlZmluaXRpb24gaXRzZWxmIGFuZCBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlCgkgICAgKiBtaXhlZCIKCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiSWYgdGhlIGNvbnRlbnQgdHlwZSBpcyAnbWl4ZWQnLCB0aGVuIHRoZSBjb250ZW50IHR5cGUgb2YgdGhlICIKCQkiYmFzZSB0eXBlIG11c3QgYWxzbyBiZSAnbWl4ZWQnIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQoJLyoKCSogU1BFQyAoNS40LjIpICJUaGUgcGFydGljbGUgb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZgoJKiBtdXN0IGJlIGEgt3ZhbGlkIHJlc3RyaWN0aW9utyBvZiB0aGUgcGFydGljbGUgb2YgdGhlIHtjb250ZW50CgkqIHR5cGV9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gUGFydGljbGUgVmFsaWQKCSogKFJlc3RyaWN0aW9uKSAopzMuOS42KS4KCSoKCSogVVJHRU5UIFRPRE86ICg1LjQuMikKCSovCiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJUaGUgdHlwZSBpcyBub3QgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBpdHMgYmFzZSB0eXBlIiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDVENvbXBvbmVudDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqICgzLjQuNikgQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NUQ29tcG9uZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGludCByZXQ7CiAgICAvKgogICAgKiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFDaGVja0NUUHJvcHNDb3JyZWN0KGN0eHQsIHR5cGUpOwogICAgaWYgKHJldCAhPSAwKQoJcmV0dXJuIChyZXQpOwogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pCglyZXQgPSB4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kcyhjdHh0LCB0eXBlKTsKICAgIGVsc2UKCXJldCA9IHhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvbk9LUmVzdHJpY3Rpb24oY3R4dCwgdHlwZSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1NSQ0NUOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC4zKSBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIENvbXBsZXggVHlwZSBEZWZpbml0aW9uczoKICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6CiAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFJlcHJlc2VudGF0aW9uIE9LIChzcmMtY3QpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNDVCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICogVE9ETzogQWRqdXN0IHRoZSBlcnJvciBjb2RlcyBoZXJlLCBhcyBJIHVzZWQKICAgICogWE1MX1NDSEVNQVBfU1JDX0NUXzEgb25seSB5ZXQuCiAgICAqLwogICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKCEgSEFTX1NJTVBMRV9DT05URU5UKHR5cGUpKSB7CgkvKgoJKiAxIElmIHRoZSA8Y29tcGxleENvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlIHR5cGUgZGVmaW5pdGlvbgoJKiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXQoJKiBtdXN0IGJlIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb247CgkqLwoJaWYgKCEgSVNfQ09NUExFWF9UWVBFKGJhc2UpKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwKCQkiSWYgdXNpbmcgPGNvbXBsZXhDb250ZW50PiwgdGhlIGJhc2UgdHlwZSBpcyBleHBlY3RlZCB0byBiZSAiCgkJImEgY29tcGxleCB0eXBlLiBUaGUgYmFzZSB0eXBlICclcycgaXMgYSBzaW1wbGUgdHlwZSIsCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCWJhc2UtPm5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBTUEVDCgkqIDIgSWYgdGhlIDxzaW1wbGVDb250ZW50PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIGFsbCBvZiB0aGUKCSogZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSogMi4xIFRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlCgkqIGJhc2UgW2F0dHJpYnV0ZV0gbXVzdCBiZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoKCSovCglpZiAoSVNfU0lNUExFX1RZUEUoYmFzZSkpIHsKCSAgICBpZiAoKHR5cGUtPmZsYWdzICYKCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgPT0gMCkgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJLyoKCQkqIDIuMS4zIG9ubHkgaWYgdGhlIDxleHRlbnNpb24+IGFsdGVybmF0aXZlIGlzIGFsc28KCQkqIGNob3NlbiwgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJCSovCgkJLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzFfMy4gKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiSWYgdXNpbmcgPHNpbXBsZUNvbnRlbnQ+IGFuZCA8cmVzdHJpY3Rpb24+LCB0aGUgYmFzZSAiCgkJICAgICJ0eXBlIG11c3QgYmUgYSBjb21wbGV4IHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyBpcyAiCgkJICAgICJhIHNpbXBsZSB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCQliYXNlLT5uYW1lKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKiBCYXNlIHR5cGUgaXMgYSBjb21wbGV4IHR5cGUuICovCgkgICAgaWYgKChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fAoJCShiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJLyoKCQkqIDIuMS4xIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0gaXMgYQoJCSogc2ltcGxlIHR5cGUgZGVmaW5pdGlvbjsKCQkqIFBBU1MKCQkqLwoJCWlmIChiYXNlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkiJyVzJywgYmFzZSB0eXBlIGhhcyBubyBjb250ZW50IHR5cGUiLAoJCQl0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJICAgIH0gZWxzZSBpZiAoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCQkodHlwZS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSkgewoKCQkvKgoJCSogMi4xLjIgb25seSBpZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBhbHNvCgkJKiBjaG9zZW4sIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0KCQkqIGlzIG1peGVkIGFuZCBhIHBhcnRpY2xlIGVtcHRpYWJsZS4KCQkqLwoJCWlmICghIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoCgkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgYmFzZS0+c3VidHlwZXMpKSB7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX1NSQ19DVF8xOwoJCX0gZWxzZSAKCQkgICAgLyoKCQkgICAgKiBBdHRlbnRpb246IGF0IHRoaXMgcG9pbnQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBpcyBpbgoJCSAgICAqIC0+Y29udGVudFR5cGVEZWYgKHB1dCB0aGVyZSBkdXJpbmcgcGFyc2luZykuCgkJICAgICovCQkgICAgCgkJICAgIGlmICh0eXBlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogMi4yIElmIGNsYXVzZSAyLjEuMiBhYm92ZSBpcyBzYXRpc2ZpZWQsIHRoZW4gdGhlcmUKCQkgICAgKiBtdXN0IGJlIGEgPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mCgkJICAgICogPHJlc3RyaWN0aW9uPi4KCQkgICAgKi8KCQkgICAgLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzIuICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJBIDxzaW1wbGVUeXBlPiBpcyBleHBlY3RlZCBhbW9uZyB0aGUgY2hpbGRyZW4gIgoJCQkib2YgPHJlc3RyaWN0aW9uPiwgaWYgPHNpbXBsZUNvbnRlbnQ+IGlzIHVzZWQgYW5kICIKCQkJInRoZSBiYXNlIHR5cGUgJyVzJyBpcyBhIGNvbXBsZXggdHlwZSIsCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkJYmFzZS0+bmFtZSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJfQoJICAgIH0gZWxzZSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfU1JDX0NUXzE7CgkgICAgfQoJfQoJaWYgKHJldCA+IDApIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiSWYgPHNpbXBsZUNvbnRlbnQ+IGFuZCA8cmVzdHJpY3Rpb24+IGlzIHVzZWQsIHRoZSAiCgkJICAgICJiYXNlIHR5cGUgbXVzdCBiZSBhIHNpbXBsZSB0eXBlIG9yIGEgY29tcGxleCB0eXBlIHdpdGggIgoJCSAgICAibWl4ZWQgY29udGVudCBhbmQgcGFydGljbGUgZW1wdGlhYmxlLiBUaGUgYmFzZSB0eXBlICIKCQkgICAgIiclcycgaXMgbm9uZSBvZiB0aG9zZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgYmFzZS0+bmFtZSkpOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIklmIDxzaW1wbGVDb250ZW50PiBhbmQgPGV4dGVuc2lvbj4gaXMgdXNlZCwgdGhlICIKCQkgICAgImJhc2UgdHlwZSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyAiCgkJICAgICJpcyBhIGNvbXBsZXggdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIGJhc2UtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgYmFzZS0+bmFtZSkpOwoJICAgIH0KCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCX0KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDMpICJUaGUgY29ycmVzcG9uZGluZyBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBjb21wb25lbnQgbXVzdAogICAgKiBzYXRpc2Z5IHRoZSBjb25kaXRpb25zIHNldCBvdXQgaW4gQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlCiAgICAqIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjQuNik7IgogICAgKiBOT1RFICgzKSB3aWxsIGJlIGRvbmUgaW4geG1sU2NoZW1hVHlwZUZpeHVwKCkuCiAgICAqLwogICAgLyoKICAgICogU1BFQyAoNCkgSWYgY2xhdXNlIDIuMi4xIG9yIGNsYXVzZSAyLjIuMiBpbiB0aGUgY29ycmVzcG9uZGVuY2Ugc3BlY2lmaWNhdGlvbgogICAgKiBhYm92ZSBmb3Ige2F0dHJpYnV0ZSB3aWxkY2FyZH0gaXMgc2F0aXNmaWVkLCB0aGUgaW50ZW5zaW9uYWwKICAgICogaW50ZXJzZWN0aW9uIG11c3QgYmUgZXhwcmVzc2libGUsIGFzIGRlZmluZWQgaW4gQXR0cmlidXRlIFdpbGRjYXJkCiAgICAqIEludGVyc2VjdGlvbiAopzMuMTAuNikuCiAgICAqIE5PVEUgKDQpIGlzIGRvbmUgaW4geG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKCkuCiAgICAqLwogICAgcmV0dXJuIChyZXQpOwp9CgojaWZkZWYgRU5BQkxFX1BBUlRJQ0xFX1JFU1RSSUNUSU9OCi8qKgogKiB4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSzoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBPY2N1cnJlbmNlIFJhbmdlIE9LIChyYW5nZS1vaykKICoKICogU1RBVFVTOiBjb21wbGV0ZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKGludCBybWluLCBpbnQgcm1heCwKCQkJICAgICAgaW50IGJtaW4sIGludCBibWF4KQp7CiAgICBpZiAocm1pbiA8IGJtaW4pCglyZXR1cm4gKDEpOwogICAgaWYgKChibWF4ICE9IFVOQk9VTkRFRCkgJiYKCShybWF4ID4gYm1heCkpCglyZXR1cm4gKDEpOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VOYW1lQW5kVHlwZU9LOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSByZXN0cmljdGluZyBlbGVtZW50IGRlY2xhcmF0aW9uIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSBlbGVtZW50IGRlY2xhcmF0aW9uIHBhcnRpY2xlCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBSZXN0cmljdGlvbiBPSyAoRWx0OkVsdCAtLSBOYW1lQW5kVHlwZU9LKQogKiAocmNhc2UtTmFtZUFuZFR5cGVPSykKICoKICogU1RBVFVTOgogKiAgIE1JU1NJTkcgKDMuMi4zKQogKiAgIENMQVJJRlk6ICgzLjIuMikKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1JDYXNlTmFtZUFuZFR5cGVPSyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgeG1sU2NoZW1hUGFydGljbGVQdHIgciwKCQkJCSB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1SLCBlbGVtQjsKCiAgICAvKiBUT0RPOiBFcnJvciBjb2RlcyAocmNhc2UtTmFtZUFuZFR5cGVPSykuICovCiAgICBlbGVtUiA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSByLT5jaGlsZHJlbjsKICAgIGVsZW1CID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGItPmNoaWxkcmVuOwogICAgLyoKICAgICogU1BFQyAoMSkgIlRoZSBkZWNsYXJhdGlvbnMnIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMgYXJlCiAgICAqIHRoZSBzYW1lLiIKICAgICovCiAgICBpZiAoKGVsZW1SICE9IGVsZW1CKSAmJgoJKCghIHhtbFN0ckVxdWFsKGVsZW1SLT5uYW1lLCBlbGVtQi0+bmFtZSkpIHx8CgkoISB4bWxTdHJFcXVhbChlbGVtUi0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtQi0+dGFyZ2V0TmFtZXNwYWNlKSkpKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDIpICJSJ3Mgb2NjdXJyZW5jZSByYW5nZSBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEIncwogICAgKiBvY2N1cnJlbmNlIHJhbmdlIGFzIGRlZmluZWQgYnkgT2NjdXJyZW5jZSBSYW5nZSBPSyAopzMuOS42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKHItPm1pbk9jY3Vycywgci0+bWF4T2NjdXJzLAoJICAgIGItPm1pbk9jY3VycywgYi0+bWF4T2NjdXJzKSAhPSAwKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDMuMSkgIkJvdGggQidzIGRlY2xhcmF0aW9uJ3Mge3Njb3BlfSBhbmQgUidzIGRlY2xhcmF0aW9uJ3MKICAgICoge3Njb3BlfSBhcmUgZ2xvYmFsLiIKICAgICovCiAgICBpZiAoZWxlbVIgPT0gZWxlbUIpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogU1BFQyAoMy4yLjEpICJFaXRoZXIgQidzIHtuaWxsYWJsZX0gaXMgdHJ1ZSBvciBSJ3Mge25pbGxhYmxlfSBpcyBmYWxzZS4iCiAgICAqLwogICAgaWYgKCgoZWxlbUItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgPT0gMCkgJiYKCShlbGVtUi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSkKCSByZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMy4yLjIpICJlaXRoZXIgQidzIGRlY2xhcmF0aW9uJ3Mge3ZhbHVlIGNvbnN0cmFpbnR9IGlzIGFic2VudCwKICAgICogb3IgaXMgbm90IGZpeGVkLCBvciBSJ3MgZGVjbGFyYXRpb24ncyB7dmFsdWUgY29uc3RyYWludH0gaXMgZml4ZWQKICAgICogd2l0aCB0aGUgc2FtZSB2YWx1ZS4iCiAgICAqLwogICAgaWYgKChlbGVtQi0+dmFsdWUgIT0gTlVMTCkgJiYgKGVsZW1CLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCgkoKGVsZW1SLT52YWx1ZSA9PSBOVUxMKSB8fAoJICgoZWxlbVItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgPT0gMCkgfHwKCSAvKiBUT0RPOiBFcXVhbGl0eSBvZiB0aGUgaW5pdGlhbCB2YWx1ZSBvciBub3JtYWxpemVkIG9yIGNhbm9uaWNhbD8gKi8KCSAoISB4bWxTdHJFcXVhbChlbGVtUi0+dmFsdWUsIGVsZW1CLT52YWx1ZSkpKSkKCSByZXR1cm4gKDEpOwogICAgLyoKICAgICogVE9ETzogU1BFQyAoMy4yLjMpICJSJ3MgZGVjbGFyYXRpb24ncyB7aWRlbnRpdHktY29uc3RyYWludAogICAgKiBkZWZpbml0aW9uc30gaXMgYSBzdWJzZXQgb2YgQidzIGRlY2xhcmF0aW9uJ3Mge2lkZW50aXR5LWNvbnN0cmFpbnQKICAgICogZGVmaW5pdGlvbnN9LCBpZiBhbnkuIgogICAgKi8KICAgIGlmIChlbGVtQi0+aWRjcyAhPSBOVUxMKSB7CgkvKiBUT0RPICovCiAgICB9CiAgICAvKgogICAgKiBTUEVDICgzLjIuNCkgIlIncyBkZWNsYXJhdGlvbidzIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9IGlzIGEKICAgICogc3VwZXJzZXQgb2YgQidzIGRlY2xhcmF0aW9uJ3Mge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30uIgogICAgKi8KICAgIGlmICgoKGVsZW1CLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OKSAmJgoJICgoZWxlbVItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pID09IDApKSB8fAoJKChlbGVtQi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OKSAmJgoJICgoZWxlbVItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTikgPT0gMCkpIHx8CgkoKGVsZW1CLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OKSAmJgoJICgoZWxlbVItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT04pID09IDApKSkKCSByZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMy4yLjUpICJSJ3Mge3R5cGUgZGVmaW5pdGlvbn0gaXMgdmFsaWRseSBkZXJpdmVkIGdpdmVuCiAgICAqIHtleHRlbnNpb24sIGxpc3QsIHVuaW9ufSBmcm9tIEIncyB7dHlwZSBkZWZpbml0aW9ufSIKICAgICoKICAgICogQkFEU1BFQyBUT0RPOiBXaGF0J3MgdGhlIHBvaW50IG9mIGFkZGluZyAibGlzdCIgYW5kICJ1bmlvbiIgdG8gdGhlCiAgICAqIHNldCwgaWYgdGhlIGNvcnJlc3BvbmRpbmcgY29uc3RyYWludHMgaGFuZGxlICJyZXN0cmljdGlvbiIgYW5kCiAgICAqICJleHRlbnNpb24iIG9ubHk/CiAgICAqCiAgICAqLwogICAgewoJaW50IHNldCA9IDA7CgoJc2V0IHw9IFNVQlNFVF9FWFRFTlNJT047CglzZXQgfD0gU1VCU0VUX0xJU1Q7CglzZXQgfD0gU1VCU0VUX1VOSU9OOwoJaWYgKHhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LKGVsZW1SLT5zdWJ0eXBlcywKCSAgICBlbGVtQi0+c3VidHlwZXMsIHNldCkgIT0gMCkKCSAgICByZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VOU0NvbXBhdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgcmVzdHJpY3RpbmcgZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZQogKiBAYjogdGhlIGJhc2Ugd2lsZGNhcmQgcGFydGljbGUKICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFBhcnRpY2xlIERlcml2YXRpb24gT0sgKEVsdDpBbnkgLS0gTlNDb21wYXQpCiAqIChyY2FzZS1OU0NvbXBhdCkKICoKICogU1RBVFVTOiBjb21wbGV0ZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VOU0NvbXBhdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgLyogVE9ETzpFcnJvciBjb2RlcyAocmNhc2UtTlNDb21wYXQpLiAqLwogICAgLyoKICAgICogU1BFQyAiRm9yIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGUgdG8gYmUgYSC3dmFsaWQgcmVzdHJpY3Rpb263CiAgICAqIG9mIGEgd2lsZGNhcmQgcGFydGljbGUgYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICoKICAgICogU1BFQyAoMSkgIlRoZSBlbGVtZW50IGRlY2xhcmF0aW9uJ3Mge3RhcmdldCBuYW1lc3BhY2V9IGlzILd2YWxpZLcKICAgICogd2l0aCByZXNwZWN0IHRvIHRoZSB3aWxkY2FyZCdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gYXMgZGVmaW5lZCBieQogICAgKiBXaWxkY2FyZCBhbGxvd3MgTmFtZXNwYWNlIE5hbWUgKKczLjEwLjQpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZSgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGItPmNoaWxkcmVuLAoJKCh4bWxTY2hlbWFFbGVtZW50UHRyKSByLT5jaGlsZHJlbiktPnRhcmdldE5hbWVzcGFjZSkgIT0gMCkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykgIT0gMCkKCXJldHVybiAoMSk7CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlQXNJZkdyb3VwOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSByZXN0cmljdGluZyBlbGVtZW50IGRlY2xhcmF0aW9uIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSBtb2RlbCBncm91cCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoRWx0OkFsbC9DaG9pY2UvU2VxdWVuY2UgLS0gUmVjdXJzZUFzSWZHcm91cCkKICogKHJjYXNlLVJlY3Vyc2VBc0lmR3JvdXApCiAqCiAqIFNUQVRVUzogVE9ETwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlQXNJZkdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1SZWN1cnNlQXNJZkdyb3VwKS4gKi8KICAgIFRPRE8KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1JDYXNlTlNTdWJzZXQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIHJlc3RyaWN0aW5nIHdpbGRjYXJkIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSB3aWxkY2FyZCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoQW55OkFueSAtLSBOU1N1YnNldCkKICogKHJjYXNlLU5TU3Vic2V0KQogKgogKiBTVEFUVVM6IGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TU3Vic2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIsCgkJCQkgICAgaW50IGlzQW55VHlwZUJhc2UpCnsKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1OU1N1YnNldCkuICovCiAgICAvKgogICAgKiBTUEVDICgxKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMikgIlIncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IG11c3QgYmUgYW4gaW50ZW5zaW9uYWwgc3Vic2V0CiAgICAqIG9mIEIncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IGFzIGRlZmluZWQgYnkgV2lsZGNhcmQgU3Vic2V0ICinMy4xMC42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TTlNTdWJzZXQoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSByLT5jaGlsZHJlbiwKCSh4bWxTY2hlbWFXaWxkY2FyZFB0cikgYi0+Y2hpbGRyZW4pKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDMpICJVbmxlc3MgQiBpcyB0aGUgY29udGVudCBtb2RlbCB3aWxkY2FyZCBvZiB0aGUgt3VyLXR5cGUKICAgICogZGVmaW5pdGlvbrcsIFIncyB7cHJvY2VzcyBjb250ZW50c30gbXVzdCBiZSBpZGVudGljYWwgdG8gb3Igc3Ryb25nZXIKICAgICogdGhhbiBCJ3Mge3Byb2Nlc3MgY29udGVudHN9LCB3aGVyZSBzdHJpY3QgaXMgc3Ryb25nZXIgdGhhbiBsYXggaXMKICAgICogc3Ryb25nZXIgdGhhbiBza2lwLiIKICAgICovCiAgICBpZiAoISBpc0FueVR5cGVCYXNlKSB7CglpZiAoICgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHItPmNoaWxkcmVuKS0+cHJvY2Vzc0NvbnRlbnRzIDwKCSAgICAoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBiLT5jaGlsZHJlbiktPnByb2Nlc3NDb250ZW50cykKCSAgICByZXR1cm4gKDEpOwogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU1BhcnRpY2xlUmVzdHJpY3Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgVmFsaWQgKFJlc3RyaWN0aW9uKSAoY29zLXBhcnRpY2xlLXJlc3RyaWN0KQogKgogKiBTVEFUVVM6IFRPRE8KICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1BhcnRpY2xlUmVzdHJpY3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKnBhcnQgPSBHRVRfUEFSVElDTEUodHlwZSk7CiAgICBiYXNlUGFydCA9IEdFVF9QQVJUSUNMRShiYXNlKTsKICAgICovCgogICAgVE9ETwoKICAgIC8qCiAgICAqIFNQRUMgKDEpICJUaGV5IGFyZSB0aGUgc2FtZSBwYXJ0aWNsZS4iCiAgICAqLwogICAgaWYgKHIgPT0gYikKCXJldHVybiAoMCk7CgoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1JDYXNlTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgbW9kZWwgZ3JvdXAgcGFydGljbGUKICogQGI6IHRoZSBiYXNlIHdpbGRjYXJkIHBhcnRpY2xlCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBEZXJpdmF0aW9uIE9LIChBbGwvQ2hvaWNlL1NlcXVlbmNlOkFueSAtLQogKiAgICAgICAgICAgICAgICAgICAgICAgICBOU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5KQogKiAocmNhc2UtTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eSkKICoKICogU1RBVFVTOiBUT0RPOiBzdWJzdC1ncm91cHMKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1JDYXNlTlNSZWN1cnNlQ2hlY2tDYXJkaW5hbGl0eSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJICAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJCSAgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydDsKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5KS4gKi8KICAgIGlmICgoci0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwgKHItPmNoaWxkcmVuLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogU1BFQyAiRm9yIGEgZ3JvdXAgcGFydGljbGUgdG8gYmUgYSC3dmFsaWQgcmVzdHJpY3Rpb263IG9mIGEKICAgICogd2lsZGNhcmQgcGFydGljbGUuLi4iCiAgICAqCiAgICAqIFNQRUMgKDEpICJFdmVyeSBtZW1iZXIgb2YgdGhlIHtwYXJ0aWNsZXN9IG9mIHRoZSBncm91cCBpcyBhILd2YWxpZAogICAgKiByZXN0cmljdGlvbrcgb2YgdGhlIHdpbGRjYXJkIGFzIGRlZmluZWQgYnkKICAgICogUGFydGljbGUgVmFsaWQgKFJlc3RyaWN0aW9uKSAopzMuOS42KS4iCiAgICAqLwogICAgcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgci0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgZG8gewoJaWYgKHhtbFNjaGVtYUNoZWNrQ09TUGFydGljbGVSZXN0cmljdChjdHh0LCBwYXJ0LCBiKSkKCSAgICByZXR1cm4gKDEpOwoJcGFydCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydC0+bmV4dDsKICAgIH0gd2hpbGUgKHBhcnQgIT0gTlVMTCk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiVGhlIGVmZmVjdGl2ZSB0b3RhbCByYW5nZSBvZiB0aGUgZ3JvdXAgWy4uLl0gaXMgYQogICAgKiB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3Mgb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5CiAgICAqIE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSygKCSAgICB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW4ociksCgkgICAgeG1sU2NoZW1hR2V0UGFydGljbGVUb3RhbFJhbmdlTWF4KHIpLAoJICAgIGItPm1pbk9jY3VycywgYi0+bWF4T2NjdXJzKSAhPSAwKQoJcmV0dXJuICgxKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja1JDYXNlUmVjdXJzZToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgPGFsbD4gb3IgPHNlcXVlbmNlPiBtb2RlbCBncm91cCBwYXJ0aWNsZQogKiBAYjogdGhlIGJhc2UgPGFsbD4gb3IgPHNlcXVlbmNlPiBtb2RlbCBncm91cCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoQWxsOkFsbCxTZXF1ZW5jZTpTZXF1ZW5jZSAtLQogICAgICAgICAgICAgICAgICAgICAgICAgICBSZWN1cnNlKQogKiAocmNhc2UtUmVjdXJzZSkKICoKICogU1RBVFVTOiAgPwogKiBUT0RPOiBzdWJzdC1ncm91cHMKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1JDYXNlUmVjdXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCSAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIC8qIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnQ7ICovCiAgICAvKiBUT0RPOiBFcnJvciBjb2RlcyAocmNhc2UtUmVjdXJzZSkuICovCiAgICBpZiAoKHItPmNoaWxkcmVuID09IE5VTEwpIHx8IChiLT5jaGlsZHJlbiA9PSBOVUxMKSB8fAoJKHItPmNoaWxkcmVuLT50eXBlICE9IGItPmNoaWxkcmVuLT50eXBlKSkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogU1BFQyAiRm9yIGFuIGFsbCBvciBzZXF1ZW5jZSBncm91cCBwYXJ0aWNsZSB0byBiZSBhILd2YWxpZAogICAgKiByZXN0cmljdGlvbrcgb2YgYW5vdGhlciBncm91cCBwYXJ0aWNsZSB3aXRoIHRoZSBzYW1lIHtjb21wb3NpdG9yfS4uLiIKICAgICoKICAgICogU1BFQyAoMSkgIlIncyBvY2N1cnJlbmNlIHJhbmdlIGlzIGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgQidzCiAgICAqIG9jY3VycmVuY2UgcmFuZ2UgYXMgZGVmaW5lZCBieSBPY2N1cnJlbmNlIFJhbmdlIE9LICinMy45LjYpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tQYXJ0aWNsZVJhbmdlT0soci0+bWluT2NjdXJzLCByLT5tYXhPY2N1cnMsCgkgICAgYi0+bWluT2NjdXJzLCBiLT5tYXhPY2N1cnMpKQoJcmV0dXJuICgxKTsKCgogICAgcmV0dXJuICgwKTsKfQoKI2VuZGlmCgojZGVmaW5lIEZBQ0VUX1JFU1RSX01VVFVBTF9FUlIoZmFjMSwgZmFjMikgXAogICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwgICAgICBcCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLCBcCglOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZmFjMSwgZmFjMS0+bm9kZSwgXAoJIkl0IGlzIGFuIGVycm9yIGZvciBib3RoICclcycgYW5kICclcycgdG8gYmUgc3BlY2lmaWVkIG9uIHRoZSAiXAoJInNhbWUgdHlwZSBkZWZpbml0aW9uIiwgXAoJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjMS0+dHlwZSksIFwKCUJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhYzItPnR5cGUpLCBOVUxMKTsKCiNkZWZpbmUgRkFDRVRfUkVTVFJfRVJSKGZhYzEsIG1zZykgXAogICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwgICAgICBcCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLCBcCglOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZmFjMSwgZmFjMS0+bm9kZSwgXAoJbXNnLCBOVUxMKTsKCiNkZWZpbmUgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZhYykgXAogICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwgXAoJWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRSwgXAoJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGZhYywgZmFjLT5ub2RlLCBcCgkiVGhlIGJhc2UgdHlwZSdzIGZhY2V0IGlzICdmaXhlZCcsIHRodXMgdGhlIHZhbHVlIG11c3Qgbm90ICIgXAoJImRpZmZlciIsIE5VTEwpOwoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQxLAoJCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDIsCgkJCWludCBsZXNzR3JlYXRlciwKCQkJaW50IG9yRXF1YWwsCgkJCWludCBvZkJhc2UpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEw7CgogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICInIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldDEtPnR5cGUpKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInIGhhcyB0byBiZSIpOwogICAgaWYgKGxlc3NHcmVhdGVyID09IDApCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIGVxdWFsIHRvIik7CiAgICBpZiAobGVzc0dyZWF0ZXIgPT0gMSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgZ3JlYXRlciB0aGFuIik7CiAgICBlbHNlCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIGxlc3MgdGhhbiIpOwoKICAgIGlmIChvckVxdWFsKQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBvciBlcXVhbCB0byIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiAnIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldDItPnR5cGUpKTsKICAgIGlmIChvZkJhc2UpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyBvZiB0aGUgYmFzZSB0eXBlIik7CiAgICBlbHNlCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwoKICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLAoJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGZhY2V0MSwgZmFjZXQxLT5ub2RlLAoJKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMKTsKCiAgICBpZiAobXNnICE9IE5VTEwpCgl4bWxGcmVlKG1zZyk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbmssIGN1ciwgbGFzdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgYmZhY2V0LAoJZmxlbmd0aCA9IE5VTEwsIGZ0b3RkaWcgPSBOVUxMLCBmZnJhY2RpZyA9IE5VTEwsCglmbWF4bGVuID0gTlVMTCwgZm1pbmxlbiA9IE5VTEwsIC8qIGZhY2V0cyBvZiB0aGUgY3VycmVudCB0eXBlICovCglmbWluaW5jID0gTlVMTCwgZm1heGluYyA9IE5VTEwsCglmbWluZXhjID0gTlVMTCwgZm1heGV4YyA9IE5VTEwsCgliZmxlbmd0aCA9IE5VTEwsIGJmdG90ZGlnID0gTlVMTCwgYmZmcmFjZGlnID0gTlVMTCwKCWJmbWF4bGVuID0gTlVMTCwgYmZtaW5sZW4gPSBOVUxMLCAvKiBmYWNldHMgb2YgdGhlIGJhc2UgdHlwZSAqLwoJYmZtaW5pbmMgPSBOVUxMLCBiZm1heGluYyA9IE5VTEwsCgliZm1pbmV4YyA9IE5VTEwsIGJmbWF4ZXhjID0gTlVMTDsKICAgIGludCByZXMsIGVyciA9IDAsIGZpeGVkRXJyOwogICAgLyoKICAgICogMyBUaGUge2ZhY2V0c30gb2YgUiBhcmUgdGhlIHVuaW9uIG9mIFMgYW5kIHRoZSB7ZmFjZXRzfQogICAgKiBvZiBCLCBlbGltaW5hdGluZyBkdXBsaWNhdGVzLiBUbyBlbGltaW5hdGUgZHVwbGljYXRlcywKICAgICogd2hlbiBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgb2NjdXJzIGluIGJvdGggUyBhbmQgdGhlCiAgICAqIHtmYWNldHN9IG9mIEIsIHRoZSBvbmUgaW4gdGhlIHtmYWNldHN9IG9mIEIgaXMgbm90CiAgICAqIGluY2x1ZGVkLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgZW51bWVyYXRpb24gYW5kIHBhdHRlcm4KICAgICogZmFjZXRzLCBmb3Igd2hpY2ggbXVsdGlwbGUgb2NjdXJyZW5jZXMgd2l0aCBkaXN0aW5jdCB2YWx1ZXMKICAgICogYXJlIGFsbG93ZWQuCiAgICAqLwoKICAgIGlmICgodHlwZS0+ZmFjZXRTZXQgPT0gTlVMTCkgJiYgKGJhc2UtPmZhY2V0U2V0ID09IE5VTEwpKQoJcmV0dXJuICgwKTsKCiAgICBsYXN0ID0gdHlwZS0+ZmFjZXRTZXQ7CiAgICBpZiAobGFzdCAhPSBOVUxMKQoJd2hpbGUgKGxhc3QtPm5leHQgIT0gTlVMTCkKCSAgICBsYXN0ID0gbGFzdC0+bmV4dDsKCiAgICBmb3IgKGN1ciA9IHR5cGUtPmZhY2V0U2V0OyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CglmYWNldCA9IGN1ci0+ZmFjZXQ7Cglzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQlmbGVuZ3RoID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJZm1pbmxlbiA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJCWZtaW5pbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCQlmbWluZXhjID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJZm1heGxlbiA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgoJCWZtYXhpbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCQlmbWF4ZXhjID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKCQlmdG90ZGlnID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKCQlmZnJhY2RpZyA9IGZhY2V0OyBicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgZm9yIChjdXIgPSBiYXNlLT5mYWNldFNldDsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJZmFjZXQgPSBjdXItPmZhY2V0OwoJc3dpdGNoIChmYWNldC0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkJYmZsZW5ndGggPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQliZm1pbmxlbiA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJCWJmbWluaW5jID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CgkJYmZtaW5leGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQliZm1heGxlbiA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgoJCWJmbWF4aW5jID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgkJYmZtYXhleGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJCWJmdG90ZGlnID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKCQliZmZyYWNkaWcgPSBmYWNldDsgYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGVyciA9IDA7CiAgICAvKgogICAgKiBsZW5ndGggYW5kIG1pbkxlbmd0aCBvciBtYXhMZW5ndGggKDIuMikgKyAoMy4yKQogICAgKi8KICAgIGlmIChmbGVuZ3RoICYmIChmbWlubGVuIHx8IGZtYXhsZW4pKSB7CglGQUNFVF9SRVNUUl9FUlIoZmxlbmd0aCwgIkl0IGlzIGFuIGVycm9yIGZvciBib3RoICdsZW5ndGgnIGFuZCAiCgkgICAgImVpdGhlciBvZiAnbWluTGVuZ3RoJyBvciAnbWF4TGVuZ3RoJyB0byBiZSBzcGVjaWZpZWQgb24gIgoJICAgICJ0aGUgc2FtZSB0eXBlIGRlZmluaXRpb24iKQogICAgfQogICAgLyoKICAgICogTXV0dWFsIGV4Y2x1c2lvbnMgaW4gdGhlIHNhbWUgZGVyaXZhdGlvbiBzdGVwLgogICAgKi8KICAgIGlmICgoZm1heGluYykgJiYgKGZtYXhleGMpKSB7CgkvKgoJKiBTQ0MgIm1heEluY2x1c2l2ZSBhbmQgbWF4RXhjbHVzaXZlIgoJKi8KCUZBQ0VUX1JFU1RSX01VVFVBTF9FUlIoZm1heGluYywgZm1heGV4YykKICAgIH0KICAgIGlmICgoZm1pbmluYykgJiYgKGZtaW5leGMpKSB7CgkvKgoJKiBTQ0MgIm1pbkluY2x1c2l2ZSBhbmQgbWluRXhjbHVzaXZlIgoJKi8KCUZBQ0VUX1JFU1RSX01VVFVBTF9FUlIoZm1pbmluYywgZm1pbmV4YykKICAgIH0KCiAgICBpZiAoZmxlbmd0aCAmJiBiZmxlbmd0aCkgewoJLyoKCSogU0NDICJsZW5ndGggdmFsaWQgcmVzdHJpY3Rpb24iCgkqIFRoZSB2YWx1ZXMgaGF2ZSB0byBiZSBlcXVhbC4KCSovCglyZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZsZW5ndGgtPnZhbCwgYmZsZW5ndGgtPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzICE9IDApCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZsZW5ndGgsIGJmbGVuZ3RoLCAwLCAwLCAxKTsKCWlmICgocmVzICE9IDApICYmIChiZmxlbmd0aC0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZsZW5ndGgpCgl9CgogICAgfQogICAgaWYgKGZtaW5sZW4gJiYgYmZtaW5sZW4pIHsKCS8qCgkqIFNDQyAibWluTGVuZ3RoIHZhbGlkIHJlc3RyaWN0aW9uIgoJKiBtaW5MZW5ndGggPj0gQkFTRSBtaW5MZW5ndGgKCSovCglyZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5sZW4tPnZhbCwgYmZtaW5sZW4tPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzID09IC0xKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWlubGVuLCBiZm1pbmxlbiwgMSwgMSwgMSk7CglpZiAoKHJlcyAhPSAwKSAmJiAoYmZtaW5sZW4tPmZpeGVkKSkgewoJICAgIEZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWlubGVuKQoJfQogICAgfQogICAgaWYgKGZtYXhsZW4gJiYgYmZtYXhsZW4pIHsKCS8qCgkqIFNDQyAibWF4TGVuZ3RoIHZhbGlkIHJlc3RyaWN0aW9uIgoJKiBtYXhMZW5ndGggPD0gQkFTRSBtaW5MZW5ndGgKCSovCglyZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhsZW4tPnZhbCwgYmZtYXhsZW4tPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzID09IDEpCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhsZW4sIGJmbWF4bGVuLCAtMSwgMSwgMSk7CglpZiAoKHJlcyAhPSAwKSAmJiAoYmZtYXhsZW4tPmZpeGVkKSkgewoJICAgIEZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWF4bGVuKQoJfQogICAgfQogICAgLyoKICAgICogU0NDICJsZW5ndGggYW5kIG1pbkxlbmd0aCBvciBtYXhMZW5ndGgiCiAgICAqLwogICAgaWYgKCEgZmxlbmd0aCkKCWZsZW5ndGggPSBiZmxlbmd0aDsKICAgIGlmIChmbGVuZ3RoKSB7CglpZiAoISBmbWlubGVuKQoJICAgIGZsZW5ndGggPSBiZmxlbmd0aDsKCWlmIChmbWlubGVuKSB7CgkgICAgLyogKDEuMSkgbGVuZ3RoID49IG1pbkxlbmd0aCAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZmxlbmd0aC0+dmFsLCBmbWlubGVuLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKQoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbGVuZ3RoLCBmbWlubGVuLCAxLCAxLCAwKTsKCX0KCWlmICghIGZtYXhsZW4pCgkgICAgZm1heGxlbiA9IGJmbWF4bGVuOwoJaWYgKGZtYXhsZW4pIHsKCSAgICAvKiAoMi4xKSBsZW5ndGggPD0gbWF4TGVuZ3RoICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbGVuZ3RoLT52YWwsIGZtYXhsZW4tPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZmxlbmd0aCwgZm1heGxlbiwgLTEsIDEsIDApOwoJfQogICAgfQogICAgaWYgKGZtYXhpbmMpIHsKCS8qCgkqICJtYXhJbmNsdXNpdmUiCgkqLwoJaWYgKGZtaW5pbmMpIHsKCSAgICAvKiBTQ0MgIm1heEluY2x1c2l2ZSA+PSBtaW5JbmNsdXNpdmUiICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4aW5jLT52YWwsIGZtaW5pbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGluYywgZm1pbmluYywgMSwgMSwgMCk7CgkgICAgfQoJfQoJLyoKCSogU0NDICJtYXhJbmNsdXNpdmUgdmFsaWQgcmVzdHJpY3Rpb24iCgkqLwoJaWYgKGJmbWF4aW5jKSB7CgkgICAgLyogbWF4SW5jbHVzaXZlIDw9IEJBU0UgbWF4SW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4aW5jLT52YWwsIGJmbWF4aW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpCgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhpbmMsIGJmbWF4aW5jLCAtMSwgMSwgMSk7CgkgICAgaWYgKChyZXMgIT0gMCkgJiYgKGJmbWF4aW5jLT5maXhlZCkpIHsKCQlGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1heGluYykKCSAgICB9Cgl9CglpZiAoYmZtYXhleGMpIHsKCSAgICAvKiBtYXhJbmNsdXNpdmUgPCBCQVNFIG1heEV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGluYy0+dmFsLCBiZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4aW5jLCBiZm1heGV4YywgLTEsIDAsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1pbmluYykgewoJICAgIC8qIG1heEluY2x1c2l2ZSA+PSBCQVNFIG1pbkluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGluYy0+dmFsLCBiZm1pbmluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4aW5jLCBiZm1pbmluYywgMSwgMSwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluZXhjKSB7CgkgICAgLyogbWF4SW5jbHVzaXZlID4gQkFTRSBtaW5FeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhpbmMtPnZhbCwgYmZtaW5leGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4aW5jLCBiZm1pbmV4YywgMSwgMCwgMSk7CgkgICAgfQoJfQogICAgfQogICAgaWYgKGZtYXhleGMpIHsKCS8qCgkqICJtYXhFeGNsdXNpdmUgPj0gbWluRXhjbHVzaXZlIgoJKi8KCWlmIChmbWluZXhjKSB7CgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4ZXhjLT52YWwsIGZtaW5leGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGV4YywgZm1pbmV4YywgMSwgMSwgMCk7CgkgICAgfQoJfQoJLyoKCSogIm1heEV4Y2x1c2l2ZSB2YWxpZCByZXN0cmljdGlvbiIKCSovCglpZiAoYmZtYXhleGMpIHsKCSAgICAvKiBtYXhFeGNsdXNpdmUgPD0gQkFTRSBtYXhFeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhleGMtPnZhbCwgYmZtYXhleGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4ZXhjLCBiZm1heGV4YywgLTEsIDEsIDEpOwoJICAgIH0KCSAgICBpZiAoKHJlcyAhPSAwKSAmJiAoYmZtYXhleGMtPmZpeGVkKSkgewoJCUZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWF4ZXhjKQoJICAgIH0KCX0KCWlmIChiZm1heGluYykgewoJICAgIC8qIG1heEV4Y2x1c2l2ZSA8PSBCQVNFIG1heEluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGV4Yy0+dmFsLCBiZm1heGluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhleGMsIGJmbWF4aW5jLCAtMSwgMSwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluaW5jKSB7CgkgICAgLyogbWF4RXhjbHVzaXZlID4gQkFTRSBtaW5JbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhleGMtPnZhbCwgYmZtaW5pbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4ZXhjLCBiZm1pbmluYywgMSwgMCwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluZXhjKSB7CgkgICAgLyogbWF4RXhjbHVzaXZlID4gQkFTRSBtaW5FeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhleGMtPnZhbCwgYmZtaW5leGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4ZXhjLCBiZm1pbmV4YywgMSwgMCwgMSk7CgkgICAgfQoJfQogICAgfQogICAgaWYgKGZtaW5leGMpIHsKCS8qCgkqICJtaW5FeGNsdXNpdmUgPCBtYXhJbmNsdXNpdmUiCgkqLwoJaWYgKGZtYXhpbmMpIHsKCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5leGMtPnZhbCwgZm1heGluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluZXhjLCBmbWF4aW5jLCAtMSwgMCwgMCk7CgkgICAgfQoJfQoJLyoKCSogIm1pbkV4Y2x1c2l2ZSB2YWxpZCByZXN0cmljdGlvbiIKCSovCglpZiAoYmZtaW5leGMpIHsKCSAgICAvKiBtaW5FeGNsdXNpdmUgPj0gQkFTRSBtaW5FeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5leGMtPnZhbCwgYmZtaW5leGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmV4YywgYmZtaW5leGMsIDEsIDEsIDEpOwoJICAgIH0KCSAgICBpZiAoKHJlcyAhPSAwKSAmJiAoYmZtaW5leGMtPmZpeGVkKSkgewoJCUZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWluZXhjKQoJICAgIH0KCX0KCWlmIChiZm1heGluYykgewoJICAgIC8qIG1pbkV4Y2x1c2l2ZSA8PSBCQVNFIG1heEluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmV4Yy0+dmFsLCBiZm1heGluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5leGMsIGJmbWF4aW5jLCAtMSwgMSwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluaW5jKSB7CgkgICAgLyogbWluRXhjbHVzaXZlID49IEJBU0UgbWluSW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluZXhjLT52YWwsIGJmbWluaW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5leGMsIGJmbWluaW5jLCAxLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtYXhleGMpIHsKCSAgICAvKiBtaW5FeGNsdXNpdmUgPCBCQVNFIG1heEV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmV4Yy0+dmFsLCBiZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluZXhjLCBiZm1heGV4YywgLTEsIDAsIDEpOwoJICAgIH0KCX0KICAgIH0KICAgIGlmIChmbWluaW5jKSB7CgkvKgoJKiAibWluSW5jbHVzaXZlIDwgbWF4RXhjbHVzaXZlIgoJKi8KCWlmIChmbWF4ZXhjKSB7CgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluaW5jLT52YWwsIGZtYXhleGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgZm1heGV4YywgLTEsIDAsIDApOwoJICAgIH0KCX0KCS8qCgkqICJtaW5FeGNsdXNpdmUgdmFsaWQgcmVzdHJpY3Rpb24iCgkqLwoJaWYgKGJmbWluaW5jKSB7CgkgICAgLyogbWluSW5jbHVzaXZlID49IEJBU0UgbWluSW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluaW5jLT52YWwsIGJmbWluaW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5pbmMsIGJmbWluaW5jLCAxLCAxLCAxKTsKCSAgICB9CgkgICAgaWYgKChyZXMgIT0gMCkgJiYgKGJmbWluaW5jLT5maXhlZCkpIHsKCQlGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZm1pbmluYykKCSAgICB9Cgl9CglpZiAoYmZtYXhpbmMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPD0gQkFTRSBtYXhJbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5pbmMtPnZhbCwgYmZtYXhpbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtYXhpbmMsIC0xLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5leGMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPiBCQVNFIG1pbkV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAxKQoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluaW5jLCBiZm1pbmV4YywgMSwgMCwgMSk7Cgl9CglpZiAoYmZtYXhleGMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPCBCQVNFIG1heEV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtYXhleGMsIC0xLCAwLCAxKTsKCX0KICAgIH0KICAgIGlmIChmdG90ZGlnICYmIGJmdG90ZGlnKSB7CgkvKgoJKiBTQ0MgIiB0b3RhbERpZ2l0cyB2YWxpZCByZXN0cmljdGlvbiIKCSogdG90YWxEaWdpdHMgPD0gQkFTRSB0b3RhbERpZ2l0cwoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZnRvdGRpZy0+dmFsLCBiZnRvdGRpZy0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgPT0gMSkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZnRvdGRpZywgYmZ0b3RkaWcsCgkgICAgLTEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmdG90ZGlnLT5maXhlZCkpIHsKCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZnRvdGRpZykKCX0KICAgIH0KICAgIGlmIChmZnJhY2RpZyAmJiBiZmZyYWNkaWcpIHsKCS8qCgkqIFNDQyAgImZyYWN0aW9uRGlnaXRzIHZhbGlkIHJlc3RyaWN0aW9uIgoJKiBmcmFjdGlvbkRpZ2l0cyA8PSBCQVNFIGZyYWN0aW9uRGlnaXRzCgkqLwoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmZnJhY2RpZy0+dmFsLCBiZmZyYWNkaWctPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzID09IDEpCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZmcmFjZGlnLCBiZmZyYWNkaWcsCgkgICAgLTEsIDEsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmZnJhY2RpZy0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZmcmFjZGlnKQoJfQogICAgfQogICAgLyoKICAgICogU0NDICJmcmFjdGlvbkRpZ2l0cyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdG90YWxEaWdpdHMiCiAgICAqLwogICAgaWYgKCEgZnRvdGRpZykKCWZ0b3RkaWcgPSBiZnRvdGRpZzsKICAgIGlmICghIGZmcmFjZGlnKQoJZmZyYWNkaWcgPSBiZmZyYWNkaWc7CiAgICBpZiAoZnRvdGRpZyAmJiBmZnJhY2RpZykgewoJcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmZnJhY2RpZy0+dmFsLCBmdG90ZGlnLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyA9PSAxKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmZnJhY2RpZywgZnRvdGRpZywKCQktMSwgMSwgMCk7CiAgICB9CiAgICAvKgogICAgKiAqRW51bWVyYXRpb25zKiB3b24nIGJlIGFkZGVkIGhlcmUsIHNpbmNlIG9ubHkgdGhlIGZpcnN0IHNldAogICAgKiBvZiBlbnVtZXJhdGlvbnMgaW4gdGhlIGFuY2VzdG9yLW9yLXNlbGYgYXhpcyBpcyB1c2VkCiAgICAqIGZvciB2YWxpZGF0aW9uLCBwbHVzIHdlIG5lZWQgdG8gdXNlIHRoZSBiYXNlIHR5cGUgb2YgdGhvc2UKICAgICogZW51bWVyYXRpb25zIGZvciB3aGl0ZXNwYWNlLgogICAgKgogICAgKiAqUGF0dGVybnMqOiB3b24ndCBiZSBhZGQgaGVyZSwgc2luY2UgdGhleSBhcmUgT1JlZCBhdAogICAgKiB0eXBlIGxldmVsIGFuZCBBTkRlZCBhdCBhbmNlc3RvciBsZXZlbC4gVGhpcyB3aWxsCiAgICAqIGhhcHBlZCBkdXJpbmcgdmFsaWRhdGlvbiBieSB3YWxraW5nIHRoZSBiYXNlIGF4aXMKICAgICogb2YgdGhlIHR5cGUuCiAgICAqLwogICAgZm9yIChjdXIgPSBiYXNlLT5mYWNldFNldDsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJYmZhY2V0ID0gY3VyLT5mYWNldDsKCS8qCgkqIFNwZWNpYWwgaGFuZGxpbmcgb2YgZW51bWVyYXRpb25zIGFuZCBwYXR0ZXJucy4KCSogVE9ETzogaG1tLCB0aGV5IHNob3VsZCBub3QgYXBwZWFyIGluIHRoZSBzZXQsIHNvIHJlbW92ZSB0aGlzLgoJKi8KCWlmICgoYmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgfHwKCSAgICAoYmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pKQoJICAgIGNvbnRpbnVlOwoJLyoKCSogU2VhcmNoIGZvciBhIGR1cGxpY2F0ZSBmYWNldCBpbiB0aGUgY3VycmVudCB0eXBlLgoJKi8KCWxpbmsgPSB0eXBlLT5mYWNldFNldDsKCWVyciA9IDA7CglmaXhlZEVyciA9IDA7Cgl3aGlsZSAobGluayAhPSBOVUxMKSB7CgkgICAgZmFjZXQgPSBsaW5rLT5mYWNldDsKCSAgICBpZiAoZmFjZXQtPnR5cGUgPT0gYmZhY2V0LT50eXBlKSB7CgkJc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkJLyoKCQkJKiBUaGUgd2hpdGVzcGFjZSBtdXN0IGJlIHN0cm9uZ2VyLgoJCQkqLwoJCQlpZiAoZmFjZXQtPndoaXRlc3BhY2UgPCBiZmFjZXQtPndoaXRlc3BhY2UpIHsKCQkJICAgIEZBQ0VUX1JFU1RSX0VSUihmbGVuZ3RoLAoJCQkJIlRoZSAnd2hpdGVzcGFjZScgdmFsdWUgaGFzIHRvIGJlIGVxdWFsIHRvICIKCQkJCSJvciBzdHJvbmdlciB0aGFuIHRoZSAnd2hpdGVzcGFjZScgdmFsdWUgb2YgIgoJCQkJInRoZSBiYXNlIHR5cGUiKQoJCQl9CgkJCWlmICgoYmZhY2V0LT5maXhlZCkgJiYKCQkJICAgIChmYWNldC0+d2hpdGVzcGFjZSAhPSBiZmFjZXQtPndoaXRlc3BhY2UpKSB7CgkJCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZmFjZXQpCgkJCX0KCQkJYnJlYWs7CgkJICAgIGRlZmF1bHQ6CgkJCWJyZWFrOwoJCX0KCQkvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJYnJlYWs7CgkgICAgfQoJICAgIGxpbmsgPSBsaW5rLT5uZXh0OwoJfQoJLyoKCSogSWYgbm8gZHVwbGljYXRlIHdhcyBmb3VuZDogYWRkIHRoZSBiYXNlIHR5cGVzJ3MgZmFjZXQKCSogdG8gdGhlIHNldC4KCSovCglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgbGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpCgkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldExpbmspKTsKCSAgICBpZiAobGluayA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwKCQkgICAgImRlcml2aW5nIGZhY2V0cywgY3JlYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGxpbmstPmZhY2V0ID0gY3VyLT5mYWNldDsKCSAgICBsaW5rLT5uZXh0ID0gTlVMTDsKCSAgICBpZiAobGFzdCA9PSBOVUxMKQoJCXR5cGUtPmZhY2V0U2V0ID0gbGluazsKCSAgICBlbHNlCgkJbGFzdC0+bmV4dCA9IGxpbms7CgkgICAgbGFzdCA9IGxpbms7Cgl9CgogICAgfQoKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCVhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsCglOVUxMLCB0eXBlLCBOVUxMLAoJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFEZXJpdmVBbmRWYWxpZGF0ZUZhY2V0cyIsIE5VTEwpOwogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hRmluaXNoTWVtYmVyVHlwZURlZmluaXRpb25zUHJvcGVydHkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaywgbGFzdExpbmssIHByZXZMaW5rLCBzdWJMaW5rLCBuZXdMaW5rOwogICAgLyoKICAgICogVGhlIGFjdHVhbCB2YWx1ZSBpcyB0aGVuIGZvcm1lZCBieSByZXBsYWNpbmcgYW55IHVuaW9uIHR5cGUKICAgICogZGVmaW5pdGlvbiBpbiB0aGUgt2V4cGxpY2l0IG1lbWJlcnO3IHdpdGggdGhlIG1lbWJlcnMgb2YgdGhlaXIKICAgICoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIuCiAgICAqLwogICAgbGluayA9IHR5cGUtPm1lbWJlclR5cGVzOwogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoKCWlmIChJU19OT1RfVFlQRUZJWEVEKGxpbmstPnR5cGUpKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChsaW5rLT50eXBlLCBwY3R4dCwgTlVMTCk7CgoJaWYgKFZBUklFVFlfVU5JT04obGluay0+dHlwZSkpIHsKCSAgICBzdWJMaW5rID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMobGluay0+dHlwZSk7CgkgICAgaWYgKHN1YkxpbmsgIT0gTlVMTCkgewoJCWxpbmstPnR5cGUgPSBzdWJMaW5rLT50eXBlOwoJCWlmIChzdWJMaW5rLT5uZXh0ICE9IE5VTEwpIHsKCQkgICAgbGFzdExpbmsgPSBsaW5rLT5uZXh0OwoJCSAgICBzdWJMaW5rID0gc3ViTGluay0+bmV4dDsKCQkgICAgcHJldkxpbmsgPSBsaW5rOwoJCSAgICB3aGlsZSAoc3ViTGluayAhPSBOVUxMKSB7CgkJCW5ld0xpbmsgPSAoeG1sU2NoZW1hVHlwZUxpbmtQdHIpCgkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CgkJCWlmIChuZXdMaW5rID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkocGN0eHQsICJhbGxvY2F0aW5nIGEgdHlwZSBsaW5rIiwKCQkJCU5VTEwpOwoJCQkgICAgcmV0dXJuICgtMSk7CgkJCX0KCQkJbmV3TGluay0+dHlwZSA9IHN1YkxpbmstPnR5cGU7CgkJCXByZXZMaW5rLT5uZXh0ID0gbmV3TGluazsKCQkJcHJldkxpbmsgPSBuZXdMaW5rOwoJCQluZXdMaW5rLT5uZXh0ID0gbGFzdExpbms7CgoJCQlzdWJMaW5rID0gc3ViTGluay0+bmV4dDsKCQkgICAgfQoJCX0KCSAgICB9Cgl9CglsaW5rID0gbGluay0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cE9wdGltRmFjZXRzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAgICAKICAgIGludCBoYXMgPSAwLCBuZWVkVmFsID0gMCwgbm9ybVZhbCA9IDA7CgogICAgaGFzCT0gKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUykgPyAxIDogMDsKICAgIGlmIChoYXMpIHsKCW5lZWRWYWwgPSAodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYKCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZBQ0VUU05FRURWQUxVRSkgPyAxIDogMDsKCW5vcm1WYWwgPSAodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYKCSAgICBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRCkgPyAxIDogMDsKICAgIH0KICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRQdHIgZmFjOwoJCglmb3IgKGZhYyA9IHR5cGUtPmZhY2V0czsgZmFjICE9IE5VTEw7IGZhYyA9IGZhYy0+bmV4dCkgewoJICAgIHN3aXRjaCAoZmFjLT50eXBlKSB7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJCSAgICBub3JtVmFsID0gMTsKCQkgICAgaGFzID0gMTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCSAgICBuZWVkVmFsID0gMTsKCQkgICAgbm9ybVZhbCA9IDE7CgkJICAgIGhhcyA9IDE7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIGhhcyA9IDE7CgkJICAgIGJyZWFrOwoJICAgIH0KCX0JCiAgICB9CiAgICBpZiAobm9ybVZhbCkKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEOwogICAgaWYgKG5lZWRWYWwpCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZBQ0VUU05FRURWQUxVRTsKICAgIGlmIChoYXMpCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFM7CgogICAgaWYgKGhhcyAmJiAoISBuZWVkVmFsKSAmJiBWQVJJRVRZX0FUT01JQyh0eXBlKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBwcmltID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eXBlKTsKCS8qCgkqIE9QVElNSVpFIFZBTCBUT0RPOiBTb21lIGZhY2V0cyBuZWVkIGEgY29tcHV0ZWQgdmFsdWUuCgkqLwoJaWYgKChwcmltLT5idWlsdEluVHlwZSAhPSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSAmJgoJICAgIChwcmltLT5idWlsdEluVHlwZSAhPSBYTUxfU0NIRU1BU19TVFJJTkcpKSB7CgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7Cgl9IAkKICAgIH0gICAgICAgCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpeHVwV2hpdGVzcGFjZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIAogICAgCiAgICAvKgogICAgKiBFdmFsdWF0ZSB0aGUgd2hpdGVzcGFjZS1mYWNldCB2YWx1ZS4KICAgICovICAgIAogICAgaWYgKFZBUklFVFlfTElTVCh0eXBlKSkgewoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX0NPTExBUFNFOwoJcmV0dXJuICgwKTsKICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTih0eXBlKSkKCXJldHVybiAoMCk7CiAgICAKICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldExpbmtQdHIgbGluOwoKCWZvciAobGluID0gdHlwZS0+ZmFjZXRTZXQ7IGxpbiAhPSBOVUxMOyBsaW4gPSBsaW4tPm5leHQpIHsKCSAgICBpZiAobGluLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQlzd2l0Y2ggKGxpbi0+ZmFjZXQtPndoaXRlc3BhY2UpIHsKCQljYXNlIFhNTF9TQ0hFTUFTX0ZBQ0VUX1BSRVNFUlZFOgoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUFJFU0VSVkU7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQVNfRkFDRVRfUkVQTEFDRToKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1JFUExBQ0U7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0U6CgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9DT0xMQVBTRTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCXJldHVybiAoMCk7CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogRm9yIGFsbCC3YXRvbWljtyBkYXRhdHlwZXMgb3RoZXIgdGhhbiBzdHJpbmcgKGFuZCB0eXBlcyC3ZGVyaXZlZLcgCiAgICAqIGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBpdCkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2UgaXMgZml4ZWQgdG8gCiAgICAqIGNvbGxhcHNlCiAgICAqLwogICAgewoJeG1sU2NoZW1hVHlwZVB0ciBhbmM7CgoJZm9yIChhbmMgPSB0eXBlLT5iYXNlVHlwZTsgYW5jICE9IE5VTEwgJiYgCgkJYW5jLT5idWlsdEluVHlwZSAhPSBYTUxfU0NIRU1BU19BTllUWVBFOwoJCWFuYyA9IGFuYy0+YmFzZVR5cGUpIHsKCgkgICAgaWYgKGFuYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCQlpZiAoYW5jLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19OT1JNU1RSSU5HKSB7CSAgICAKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1JFUExBQ0U7CgoJCX0gZWxzZSBpZiAoKGFuYy0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSB8fAoJCSAgICAoYW5jLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkgewkJICAgIAoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfUFJFU0VSVkU7CgoJCX0gZWxzZQoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfQ09MTEFQU0U7CgkJYnJlYWs7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkKCXJldHVybjsKICAgIGlmICghIElTX05PVF9UWVBFRklYRUQodHlwZSkpCglyZXR1cm47CiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0lOVEVSTkFMX1JFU09MVkVEOwogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gdHlwZS0+bmFtZTsKCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVHlwZUZpeHVwLCAiCgkgICAgImJhc2VUeXBlIGlzIG1pc3Npbmcgb24gJyVzJyIsIHR5cGUtPm5hbWUpOwoJcmV0dXJuOwogICAgfQoKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CgoJLyoKCSogVHlwZS1maXggdGhlIGJhc2UgdHlwZS4KCSovCglpZiAoSVNfTk9UX1RZUEVGSVhFRChiYXNlVHlwZSkpCgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBwY3R4dCwgTlVMTCk7CglpZiAoYmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9JTlZBTElEKSB7CgkgICAgLyoKCSAgICAqIFNraXAgZml4dXAgaWYgdGhlIGJhc2UgdHlwZSBpcyBpbnZhbGlkLgoJICAgICogVE9ETzogR2VuZXJhdGUgYSB3YXJuaW5nIQoJICAgICovCgkgICAgcmV0dXJuOwoJfQkKCS8qCgkqIFRoaXMgYmFzaWNhbGx5IGNoZWNrcyBpZiB0aGUgYmFzZSB0eXBlIGNhbiBiZSBkZXJpdmVkLgoJKi8KCWlmICh4bWxTY2hlbWFDaGVja1NSQ0NUKHBjdHh0LCB0eXBlKSAhPSAwKSB7CgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9JTlZBTElEOwoJICAgIHJldHVybjsKCX0KCS8qCgkqIEZpeHVwIHRoZSBjb250ZW50IHR5cGUuCgkqLwoJaWYgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHsKCSAgICAvKgoJICAgICogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50Pi4uLgoJICAgICovCgkgICAgaWYgKChJU19DT01QTEVYX1RZUEUoYmFzZVR5cGUpKSAmJgoJCShiYXNlVHlwZS0+Y29udGVudFR5cGVEZWYgIT0gTlVMTCkgJiYKCQkodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVR5cGVQdHIgY29udGVudEJhc2UsIGNvbnRlbnQ7CgkJY2hhciBidWZbMzBdOwoJCWNvbnN0IHhtbENoYXIgKnRtcG5hbWU7CgkJLyoKCQkqIFNQRUMgKDEpIElmIDxyZXN0cmljdGlvbj4gKyBiYXNlIHR5cGUgaXMgPGNvbXBsZXhUeXBlPiwKCQkqICJ3aG9zZSBvd24ge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZS4uLiIKCQkqLwoJCWlmICh0eXBlLT5jb250ZW50VHlwZURlZiAhPSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogU1BFQyAoMS4xKSAidGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUKCQkgICAgKiA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPHJlc3RyaWN0aW9uPiBpZiB0aGVyZQoJCSAgICAqIGlzIG9uZTsiCgkJICAgICogTm90ZSB0aGF0IHRoaXMgIjxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSIgd2FzIHB1dAoJCSAgICAqIGludG8gLT5jb250ZW50VHlwZURlZiBkdXJpbmcgcGFyc2luZy4KCQkgICAgKi8KCQkgICAgY29udGVudEJhc2UgPSB0eXBlLT5jb250ZW50VHlwZURlZjsKCQkgICAgdHlwZS0+Y29udGVudFR5cGVEZWYgPSBOVUxMOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogKDEuMikgIi4uLm90aGVyd2lzZSAoPHJlc3RyaWN0aW9uPiBoYXMgbm8gPHNpbXBsZVR5cGU+CgkJICAgICogYW1vbmcgaXRzIFtjaGlsZHJlbl0pLCB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiB3aGljaAoJCSAgICAqIGlzIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgLi4uIGJhc2UgdHlwZS4iCgkJICAgICovCgkJICAgIGNvbnRlbnRCYXNlID0gYmFzZVR5cGUtPmNvbnRlbnRUeXBlRGVmOwoJCX0KCQkvKgoJCSogU1BFQwoJCSogIi4uLiBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gd2hpY2ggcmVzdHJpY3RzIHRoZSBzaW1wbGUKCQkqIHR5cGUgZGVmaW5pdGlvbiBpZGVudGlmaWVkIGluIGNsYXVzZSAxLjEgb3IgY2xhdXNlIDEuMgoJCSogd2l0aCBhIHNldCBvZiBmYWNldCBjb21wb25lbnRzIgoJCSoKCQkqIENyZWF0ZSB0aGUgYW5vbnltb3VzIHNpbXBsZSB0eXBlLCB3aGljaCB3aWxsIGJlIHRoZSBjb250ZW50CgkJKiB0eXBlIG9mIHRoZSBjb21wbGV4IHR5cGUuCgkJKi8JCQoJCXNucHJpbnRmKGJ1ZiwgMjksICIjc2NTVCVkIiwgKysocGN0eHQtPmNvdW50ZXIpKTsKCQl0bXBuYW1lID0geG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwgQkFEX0NBU1QgYnVmLCAtMSk7CgkJY29udGVudCA9IHhtbFNjaGVtYUFkZFR5cGUocGN0eHQsCgkJICAgIHBjdHh0LT5zY2hlbWEsIHRtcG5hbWUsIHRtcG5hbWUsIHR5cGUtPm5vZGUpOwoJCWlmIChjb250ZW50ID09IE5VTEwpCgkJICAgIHJldHVybjsKCQkvKgoJCSogV2Ugd2lsbCB1c2UgdGhlIHNhbWUgbm9kZSBhcyBmb3IgdGhlIDxjb21wbGV4VHlwZT4KCQkqIHRvIGhhdmUgaXQgc29tZWhvdyBhbmNob3JlZCBpbiB0aGUgc2NoZW1hIGRvYy4KCQkqLwoJCWNvbnRlbnQtPm5vZGUgPSB0eXBlLT5ub2RlOwoJCWNvbnRlbnQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJCWNvbnRlbnQtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQljb250ZW50LT5iYXNlVHlwZSA9IGNvbnRlbnRCYXNlOwoJCS8qCgkJKiBNb3ZlIHRoZSBmYWNldHMsIHByZXZpb3VzbHkgYW5jaG9yZWQgb24gdGhlIGNvbXBsZXhUeXBlLgoJCSovCgkJY29udGVudC0+ZmFjZXRzID0gdHlwZS0+ZmFjZXRzOwoJCXR5cGUtPmZhY2V0cyA9IE5VTEw7CgkJY29udGVudC0+ZmFjZXRTZXQgPSB0eXBlLT5mYWNldFNldDsKCQl0eXBlLT5mYWNldFNldCA9IE5VTEw7CgoJCXR5cGUtPmNvbnRlbnRUeXBlRGVmID0gY29udGVudDsKCQlpZiAoSVNfTk9UX1RZUEVGSVhFRChjb250ZW50QmFzZSkpCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChjb250ZW50QmFzZSwgcGN0eHQsIE5VTEwpOwoJCXhtbFNjaGVtYVR5cGVGaXh1cChjb250ZW50LCBwY3R4dCwgTlVMTCk7CgoJICAgIH0gZWxzZSBpZiAoKElTX0NPTVBMRVhfVFlQRShiYXNlVHlwZSkpICYmCgkJKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkJKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikpIHsKCQkvKgoJCSogU1BFQyAoMikgSWYgPHJlc3RyaWN0aW9uPiArIGJhc2UgaXMgYSBtaXhlZCA8Y29tcGxleFR5cGU+IHdpdGgKCQkqIGFuIGVtcHRpYWJsZSBwYXJ0aWNsZSwgdGhlbiBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gd2hpY2gKCQkqIHJlc3RyaWN0cyB0aGUgPHJlc3RyaWN0aW9uPidzIDxzaW1wbGVUeXBlPiBjaGlsZC4KCQkqLwoJCWlmICgodHlwZS0+Y29udGVudFR5cGVEZWYgPT0gTlVMTCkgfHwKCQkgICAgKHR5cGUtPmNvbnRlbnRUeXBlRGVmLT5iYXNlVHlwZSA9PSBOVUxMKSkgewoJCSAgICAvKgoJCSAgICAqIFRPRE86IENoZWNrIGlmIHRoaXMgZXZlciBoYXBwZW5zLgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFUeXBlRml4dXAsICIKCQkJImNvbXBsZXggdHlwZSAnJXMnOiB0aGUgPHNpbXBsZUNvbnRlbnQ+PHJlc3RyaWN0aW9uPiAiCgkJCSJpcyBtaXNzaW5nIGEgPHNpbXBsZVR5cGU+IGNoaWxkLCBidXQgd2FzIG5vdCBjYXRjaGVkICIKCQkJImJ5IHhtbFNjaGVtYUNoZWNrU1JDQ1QoKSIsIHR5cGUtPm5hbWUpOwoJCX0KCSAgICB9IGVsc2UgaWYgKChJU19DT01QTEVYX1RZUEUoYmFzZVR5cGUpKSAmJgoJCSh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSkgewoJCS8qCgkJKiBTUEVDICgzKSBJZiA8ZXh0ZW5zaW9uPiArIGJhc2UgaXMgPGNvbXBsZXhUeXBlPiB3aXRoCgkJKiA8c2ltcGxlVHlwZT4gY29udGVudCwgIi4uLnRoZW4gdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoYXQKCQkqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIgoJCSovCgkJaWYgKGJhc2VUeXBlLT5jb250ZW50VHlwZURlZiA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogVE9ETzogQ2hlY2sgaWYgdGhpcyBldmVyIGhhcHBlbnMuIHhtbFNjaGVtYUNoZWNrU1JDQ1QKCQkgICAgKiBzaG91bGQgaGF2ZSBjYXRjaGVkIHRoaXMgYWxyZWFkeS4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVHlwZUZpeHVwLCAiCgkJCSJjb21wbGV4IHR5cGUgJyVzJzogdGhlIDxleHRlbnNpb24+ZWQgYmFzZSB0eXBlIGlzICIKCQkJImEgY29tcGxleCB0eXBlIHdpdGggbm8gc2ltcGxlIGNvbnRlbnQgdHlwZSIsCgkJCXR5cGUtPm5hbWUpOwoJCX0KCQl0eXBlLT5jb250ZW50VHlwZURlZiA9IGJhc2VUeXBlLT5jb250ZW50VHlwZURlZjsKCSAgICB9IGVsc2UgaWYgKChJU19TSU1QTEVfVFlQRShiYXNlVHlwZSkpICYmCgkJKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pKSB7CgkJLyoKCQkqIFNQRUMgKDQpIDxleHRlbnNpb24+ICsgYmFzZSBpcyA8c2ltcGxlVHlwZT4KCQkqICIuLi4gdGhlbiB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24iCgkJKi8KCQl0eXBlLT5jb250ZW50VHlwZURlZiA9IGJhc2VUeXBlOwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIFRPRE86IENoZWNrIGlmIHRoaXMgZXZlciBoYXBwZW5zLgoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVHlwZUZpeHVwLCAiCgkJICAgICJjb21wbGV4IHR5cGUgJyVzJyB3aXRoIDxzaW1wbGVDb250ZW50PjogdW5oYW5kbGVkICIKCQkgICAgImRlcml2YXRpb24gY2FzZSIsIHR5cGUtPm5hbWUpOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgaW50IGR1bW15U2VxdWVuY2UgPSAwOwoJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0KCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzOwoJICAgIC8qCgkgICAgKiBDb3JyZXNwb25kcyB0byA8Y29tcGxleFR5cGU+PGNvbXBsZXhDb250ZW50Pi4uLgoJICAgICoKCSAgICAqIE5PVEUgdGhhdCB0aGUgZWZmZWN0aXZlIG1peGVkIHdhcyBhbHJlYWR5IHNldCBkdXJpbmcgcGFyc2luZyBvZgoJICAgICogPGNvbXBsZXhUeXBlPiBhbmQgPGNvbXBsZXhDb250ZW50PjsgaXRzIGZsYWcgdmFsdWUgaXMKCSAgICAqIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQuCgkgICAgKgoJICAgICogQ29tcHV0ZSB0aGUgImVmZmVjdGl2ZSBjb250ZW50IjoKCSAgICAqICgyLjEuMSkgKyAoMi4xLjIpICsgKDIuMS4zKQoJICAgICovCgkgICAgaWYgKChwYXJ0aWNsZSA9PSBOVUxMKSB8fAoJCSgocGFydGljbGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFKSAmJgoJCSAoKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQUxMKSB8fAoJCSAgKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8CgkJICAoKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSAmJgoJCSAgIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApKSkgJiYKCQkgICAoICgoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHBhcnRpY2xlLT5jaGlsZHJlbiktPmNoaWxkcmVuID09IE5VTEwpKSkgewoJCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpIHsKCQkgICAgLyoKCQkgICAgKiBTUEVDICgyLjEuNCkgIklmIHRoZSC3ZWZmZWN0aXZlIG1peGVktyBpcyB0cnVlLCB0aGVuCgkJICAgICogYSBwYXJ0aWNsZSB3aG9zZSBwcm9wZXJ0aWVzIGFyZSBhcyBmb2xsb3dzOi4uLiIKCQkgICAgKgoJCSAgICAqIEVtcHR5IHNlcXVlbmNlIG1vZGVsIGdyb3VwIHdpdGgKCQkgICAgKiBtaW5PY2N1cnMvbWF4T2NjdXJzID0gMSAoaS5lLiBhICJwYXJ0aWNsZSBlbXB0aWFibGUiKS4KCQkgICAgKiBOT1RFIHRoYXQgd2Ugc2lsbCBhc3NpZ24gaXQgdGhlIDxjb21wbGV4VHlwZT4gbm9kZSB0bwoJCSAgICAqIHNvbWVob3cgYW5jaG9yIGl0IGluIHRoZSBkb2MuCgkJICAgICovCgkJICAgIGlmICgocGFydGljbGUgPT0gTlVMTCkgfHwKCQkJKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpKSB7CgkJCS8qCgkJCSogQ3JlYXRlIHRoZSBwYXJ0aWNsZS4KCQkJKi8KCQkJcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJICAgIHR5cGUtPm5vZGUsIDEsIDEpOwoJCQlpZiAocGFydGljbGUgPT0gTlVMTCkKCQkJICAgIHJldHVybjsKCQkJLyoKCQkJKiBDcmVhdGUgdGhlIG1vZGVsIGdyb3VwLgoJCQkqLwoJCQlwYXJ0aWNsZS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgkJCSAgICB4bWxTY2hlbWFBZGRNb2RlbEdyb3VwKHBjdHh0LCBwY3R4dC0+c2NoZW1hLAoJCQkJWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCBOVUxMLCB0eXBlLT5ub2RlKTsKCQkJaWYgKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKQoJCQkgICAgcmV0dXJuOwoKCQkJdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikgcGFydGljbGU7CgkJICAgIH0KCQkgICAgZHVtbXlTZXF1ZW5jZSA9IDE7CgkJICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogU1BFQyAoMi4xLjUpICJvdGhlcndpc2UgZW1wdHkiCgkJICAgICovCgkJICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCX0KCSAgICB9IGVsc2UgewoJCS8qCgkgCSogU1BFQyAoMi4yKSAib3RoZXJ3aXNlIHRoZSBwYXJ0aWNsZSBjb3JyZXNwb25kaW5nIHRvIHRoZQoJCSogPGFsbD4sIDxjaG9pY2U+LCA8Z3JvdXA+IG9yIDxzZXF1ZW5jZT4gYW1vbmcgdGhlCgkJKiBbY2hpbGRyZW5dLiIKCQkqLwoJCXR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJICAgIH0KCSAgICAvKgoJICAgICogQ29tcHV0ZSB0aGUgImNvbnRlbnQgdHlwZSIuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CgkJLyoKCQkqIFNQRUMgKDMuMSkgIklmIDxyZXN0cmljdGlvbj4uLi4iCgkJKiAoMy4xLjEpICsgKDMuMS4yKSAqLwoJCWlmICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCQkJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CgkJfQoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIFNQRUMgKDMuMikgIklmIDxleHRlbnNpb24+Li4uIgoJCSovCgkJaWYgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDMuMi4xKQoJCSAgICAqLwoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IGJhc2VUeXBlLT5jb250ZW50VHlwZTsKCQkgICAgdHlwZS0+c3VidHlwZXMgPSBiYXNlVHlwZS0+c3VidHlwZXM7CgkJICAgIC8qCgkJICAgICogTk9URSB0aGF0IHRoZSBlZmZlY3RpdmUgbWl4ZWQgaXMgaWdub3JlZCBoZXJlLgoJCSAgICAqLwoJCX0gZWxzZSBpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDMuMi4yKQoJCSAgICAqLwoJCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCQl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDMuMi4zKQoJCSAgICAqLwoJCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJCQl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCQkgICAgLyoKCQkgICAgKiAiQSBtb2RlbCBncm91cCB3aG9zZSB7Y29tcG9zaXRvcn0gaXMgc2VxdWVuY2UgYW5kIHdob3NlCgkJICAgICoge3BhcnRpY2xlc30gYXJlLi4uIgoJCSAgICAqLwoJCSAgICBpZiAoISBkdW1teVNlcXVlbmNlKSB7CgkJCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGVmZmVjdGl2ZUNvbnRlbnQgPQoJCQkgICAgKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB0eXBlLT5zdWJ0eXBlczsKCQkJLyoKCQkJKiBDcmVhdGUgdGhlIHBhcnRpY2xlLgoJCQkqLwoJCQlwYXJ0aWNsZSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKHBjdHh0LCBwY3R4dC0+c2NoZW1hLAoJCQkgICAgdHlwZS0+bm9kZSwgMSwgMSk7CgkJCWlmIChwYXJ0aWNsZSA9PSBOVUxMKQoJCQkgICAgcmV0dXJuOwoJCQkvKgoJCQkqIENyZWF0ZSB0aGUgInNlcXVlbmNlIiBtb2RlbCBncm91cC4KCQkJKi8KCQkJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKQoJCQkgICAgeG1sU2NoZW1hQWRkTW9kZWxHcm91cChwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJCVhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgTlVMTCwgdHlwZS0+bm9kZSk7CgkJCWlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkJICAgIHJldHVybjsKCQkJdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikgcGFydGljbGU7CgkJCS8qCgkJCSogU1BFQyAidGhlIHBhcnRpY2xlIG9mIHRoZSB7Y29udGVudCB0eXBlfSBvZgoJCQkqIHRoZSAuLi4gYmFzZSAuLi4iCgkJCSogQ3JlYXRlIGEgZHVwbGljYXRlIG9mIHRoZSBiYXNlIHR5cGUncyBwYXJ0aWNsZQoJCQkqIGFuZCBhc3NpZ24gaXRzICJ0ZXJtIiB0byBpdC4KCQkJKi8KCQkJcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbiA9CgkJCSAgICAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHhtbFNjaGVtYUFkZFBhcnRpY2xlKHBjdHh0LAoJCQkJcGN0eHQtPnNjaGVtYSwgdHlwZS0+bm9kZSwKCQkJCSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzKS0+bWluT2NjdXJzLAoJCQkJKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgdHlwZS0+c3VidHlwZXMpLT5tYXhPY2N1cnMpOwoJCQlpZiAocGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbiA9PSBOVUxMKQoJCQkgICAgcmV0dXJuOwoJCQlwYXJ0aWNsZSA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCQkJICAgIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CgkJCXBhcnRpY2xlLT5jaGlsZHJlbiA9CgkJCQkoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlVHlwZS0+c3VidHlwZXMpLT5jaGlsZHJlbjsKCQkJLyoKCQkJKiBTUEVDICJmb2xsb3dlZCBieSB0aGUgt2VmZmVjdGl2ZSBjb250ZW50ty4iCgkJCSovCgkJCXBhcnRpY2xlLT5uZXh0ID0gZWZmZWN0aXZlQ29udGVudDsKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBUaGlzIGlzIHRoZSBjYXNlIHdoZW4gdGhlcmUgaXMgYWxyZWFkeSBhbiBlbXB0eQoJCQkqIDxzZXF1ZW5jZT4gd2l0aCBtaW5PY2N1cnM9PW1heE9jY3Vycz09MS4KCQkJKiBKdXN0IGFkZCB0aGUgYmFzZSB0eXBlcydzIGNvbnRlbnQgdHlwZS4KCQkJKiBOT1RFIHRoYXQsIGFsdGhvdWdoIHdlIG1pc3MgdG8gYWRkIGFuIGludGVybWVkaWF0ZQoJCQkqIDxzZXF1ZW5jZT4sIHRoaXMgc2hvdWxkIHByb2R1Y2Ugbm8gZGlmZmVyZW5jZSB0bwoJCQkqIG5laXRoZXIgdGhlIHJlZ2V4IGNvbXBpbGF0aW9uIG9mIHRoZSBjb250ZW50IG1vZGVsLAoJCQkqIG5vciB0byB0aGUgY29tcGxleCB0eXBlIGNvbnRyYWludHMuCgkJCSovCgkJCXBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPQoJCQkgICAgKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBiYXNlVHlwZS0+c3VidHlwZXM7CgkJICAgIH0KCQl9CgkgICAgfQoJfQoJLyoKCSogQXBwbHkgdGhlIGNvbXBsZXggdHlwZSBjb21wb25lbnQgY29uc3RyYWludHM7IHRoaXMgd2lsbCBub3QKCSogY2hlY2sgYXR0cmlidXRlcywgc2luY2UgdGhpcyBpcyBkb25lIGluCgkqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbigpLgoJKi8KCWlmICh4bWxTY2hlbWFDaGVja0NUQ29tcG9uZW50KHBjdHh0LCB0eXBlKSAhPSAwKQoJICAgIHJldHVybjsKCS8qCgkqIEluaGVyaXQgJiBjaGVjayBjb25zdHJhaW50cyBmb3IgYXR0cmlidXRlcy4KCSovCgl4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24ocGN0eHQsIHR5cGUpOwogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCS8qCgkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudAoJKi8KCXR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCWlmIChWQVJJRVRZX0xJU1QodHlwZSkpIHsKCSAgICAvKgoJICAgICogQ29ycmVzcG9uZHMgdG8gPHNpbXBsZVR5cGU+PGxpc3Q+Li4uCgkgICAgKi8KCSAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJCS8qCgkJKiBUaGlzIG9uZSBpcyByZWFsbHkgbmVlZGVkLCBzbyBnZXQgb3V0LgoJCSovCgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hVHlwZUZpeHVwIiwKCQkibGlzdCB0eXBlIGhhcyBubyBpdGVtLXR5cGUgYXNzaWduZWQiKTsKCQlyZXR1cm47CgkgICAgfQoJICAgIGlmIChJU19OT1RfVFlQRUZJWEVEKHR5cGUtPnN1YnR5cGVzKSkKCQl4bWxTY2hlbWFUeXBlRml4dXAodHlwZS0+c3VidHlwZXMsIHBjdHh0LCBOVUxMKTsKCX0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTih0eXBlKSkgewoJICAgIC8qCgkgICAgKiBDb3JyZXNwb25kcyB0byA8c2ltcGxlVHlwZT48dW5pb24+Li4uCgkgICAgKi8KCSAgICBpZiAodHlwZS0+bWVtYmVyVHlwZXMgPT0gTlVMTCkgewoJCS8qCgkJKiBUaGlzIG9uZSBpcyByZWFsbHkgbmVlZGVkLCBzbyBnZXQgb3V0LgoJCSovCgkJcmV0dXJuOwoJICAgIH0KCSAgICBpZiAoeG1sU2NoZW1hRmluaXNoTWVtYmVyVHlwZURlZmluaXRpb25zUHJvcGVydHkocGN0eHQsIHR5cGUpID09IC0xKQoJCXJldHVybjsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIC8qCgkgICAgKiBDb3JyZXNwb25kcyB0byA8c2ltcGxlVHlwZT48cmVzdHJpY3Rpb24+Li4uCgkgICAgKi8KCSAgICBpZiAoSVNfTk9UX1RZUEVGSVhFRChiYXNlVHlwZSkpCgkJeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBwY3R4dCwgTlVMTCk7CgkgICAgLyoKCSAgICAqIFZhcmlldHkKCSAgICAqIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUKCSAgICAqIHt2YXJpZXR5fSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KCSAgICAqLwoJICAgIGlmIChWQVJJRVRZX0FUT01JQyhiYXNlVHlwZSkpCgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQzsKCSAgICBlbHNlIGlmIChWQVJJRVRZX0xJU1QoYmFzZVR5cGUpKSB7CgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CgkJLyoKCQkqIEluaGVyaXQgdGhlIGl0ZW1UeXBlLgoJCSovCgkJdHlwZS0+c3VidHlwZXMgPSBiYXNlVHlwZS0+c3VidHlwZXM7CgkgICAgfSBlbHNlIGlmIChWQVJJRVRZX1VOSU9OKGJhc2VUeXBlKSkgewoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsKCQkvKgoJCSogTk9URSB0aGF0IHdlIHdvbid0IGFzc2lnbiB0aGUgbWVtYmVyVHlwZXMgb2YgdGhlIGJhc2UsCgkJKiBzaW5jZSB0aGlzIHdpbGwgbWFrZSB0cm91YmxlIHdoZW4gZnJlZWluZyB0aGVtOyB3ZSB3aWxsCgkJKiB1c2UgYSBsb29rdXAgZnVuY3Rpb24gdG8gYWNjZXNzIHRoZW0gaW5zdGVhZC4KCQkqLwoJICAgIH0KCX0KCS8qCgkqIENoZWNrIGNvbnN0cmFpbnRzLgoJKgoJKiBUT0RPOiBTcGxpdCB0aGlzIHNvbWVob3csIHdlIG5lZWQgdG8ga25vdyBmaXJzdCBpZiB3ZSBjYW4gZGVyaXZlCgkqIGZyb20gdGhlIGJhc2UgdHlwZSBhdCBhbGwhCgkqLwoJaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBSZXN0cmljdGlvbgoJICAgICogKEZhY2V0cykKCSAgICAqIE5PVEU6IFNhdGlzZmFjdGlvbiBvZiAxIGFuZCAyIGFyaXNlIGZyb20gdGhlIGZpeHVwCgkgICAgKiBhcHBsaWVkIGJlZm9yZWhhbmQuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFDaGVja1NSQ1NpbXBsZVR5cGUocGN0eHQsIHR5cGUpOwoJICAgIHhtbFNjaGVtYUNoZWNrRmFjZXRWYWx1ZXModHlwZSwgcGN0eHQpOwoJICAgIGlmICgodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgfHwKCQkodHlwZS0+YmFzZVR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKQoJCXhtbFNjaGVtYURlcml2ZUFuZFZhbGlkYXRlRmFjZXRzKHBjdHh0LCB0eXBlKTsKCSAgICAvKgoJICAgICogV2hpdGVzcGFjZSB2YWx1ZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cFdoaXRlc3BhY2UodHlwZSk7CgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwT3B0aW1GYWNldHModHlwZSk7Cgl9CiAgICB9CgojaWZkZWYgREVCVUdfVFlQRQogICAgaWYgKHR5cGUtPm5vZGUgIT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiVHlwZSBvZiAlcyA6ICVzOiVkIDoiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5ub2RlLT5kb2MtPlVSTCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2V0TGluZU5vKHR5cGUtPm5vZGUpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJUeXBlIG9mICVzIDoiLCBuYW1lKTsKICAgIH0KICAgIGlmICgoSVNfU0lNUExFX1RZUEUodHlwZSkpIHx8IChJU19DT01QTEVYX1RZUEUodHlwZSkpKSB7Cglzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAic2ltcGxlXG4iKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVsZW1lbnRzXG4iKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAidW5rbm93biAhISFcbiIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZW1wdHlcbiIpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgoJCWlmICh4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCQkgICAgdHlwZS0+c3VidHlwZXMpKQoJCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkJIm1peGVkIGFzIGVtcHRpYWJsZSBwYXJ0aWNsZVxuIik7CgkJZWxzZQoJCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkXG4iKTsKCQlicmVhazsKCQkvKiBSZW1vdmVkLCBzaW5jZSBub3QgdXNlZC4gKi8KCQkvKgoJCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWQgb3IgZWxlbXNcbiIpOwoJCWJyZWFrOwoJCSovCgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJiYXNpY1xuIik7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIm5vdCByZWdpc3RlcmVkICEhIVxuIik7CgkJYnJlYWs7Cgl9CiAgICB9CiNlbmRpZgp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tGYWNldDoKICogQGZhY2V0OiAgdGhlIGZhY2V0CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBwY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQgb3IgTlVMTAogKiBAbmFtZTogdGhlIG9wdGlvbmFsIG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIGFuZCBjb21wdXRlcyB0aGUgdmFsdWVzIG9mIGZhY2V0cy4KICoKICogUmV0dXJucyAwIGlmIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYgbm90IHZhbGlkIGFuZAogKiAgICAgICAgIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYUNoZWNrRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpbnQgcmV0ID0gMCwgY3R4dEdpdmVuOwoKICAgIGlmICgoZmFjZXQgPT0gTlVMTCkgfHwgKHR5cGVEZWNsID09IE5VTEwpKQogICAgICAgIHJldHVybigtMSk7CiAgICAvKgogICAgKiBUT0RPOiB3aWxsIHRoZSBwYXJzZXIgY29udGV4dCBiZSBnaXZlbiBpZiB1c2VkIGZyb20KICAgICogdGhlIHJlbGF4TkcgbW9kdWxlPwogICAgKi8KICAgIGlmIChwY3R4dCA9PSBOVUxMKQoJY3R4dEdpdmVuID0gMDsKICAgIGVsc2UKCWN0eHRHaXZlbiA9IDE7CgogICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046IHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBPa2F5IHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBhdCB0aGF0IHBvaW50LgogICAgICAgICAgICAgICAgICovCgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKCQkvKiA0LjMuNS41IENvbnN0cmFpbnRzIG9uIGVudW1lcmF0aW9uIFNjaGVtYSBDb21wb25lbnRzCgkJKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IGVudW1lcmF0aW9uIHZhbGlkIHJlc3RyaWN0aW9uCgkJKiBJdCBpcyBhbiC3ZXJyb3K3IGlmIGFueSBtZW1iZXIgb2Yge3ZhbHVlfSBpcyBub3QgaW4gdGhlCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkJKgoJCSogbWluSW5jbHVzaXZlLCBtYXhJbmNsdXNpdmUsIG1pbkV4Y2x1c2l2ZSwgbWF4RXhjbHVzaXZlOgoJCSogVGhlIHZhbHVlILdtdXN0tyBiZSBpbiB0aGUKCQkqILd2YWx1ZSBzcGFjZbcgb2YgdGhlILdiYXNlIHR5cGW3LgoJCSovCgkJLyoKCQkqIFRoaXMgZnVuY3Rpb24gaXMgaW50ZW5kZWQgdG8gZGVsaXZlciBhIGNvbXBpbGVkIHZhbHVlCgkJKiBvbiB0aGUgZmFjZXQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24gb2YgWE1MIFNjaGVtYXRhIHRoZQoJCSogdHlwZSBob2xkaW5nIGEgZmFjZXQsIHdvbid0IGJlIGEgYnVpbHQtaW4gdHlwZS4KCQkqIFRodXMgdG8gZW5zdXJlIHRoYXQgb3RoZXIgQVBJCgkJKiBjYWxscyAocmVsYXhuZykgZG8gd29yaywgaWYgdGhlIGdpdmVuIHR5cGUgaXMgYSBidWlsdC1pbgoJCSogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZSAqaXMKCQkqIGFscmVhZHkqIHRoZSBiYXNlIHR5cGUuCgkJKi8KCQlpZiAodHlwZURlY2wtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkJICAgIGJhc2UgPSB0eXBlRGVjbC0+YmFzZVR5cGU7CgkJICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCSAgICAiYSB0eXBlIHVzZXIgZGVyaXZlZCB0eXBlIGhhcyBubyBiYXNlIHR5cGUiKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQl9IGVsc2UKCQkgICAgYmFzZSA9IHR5cGVEZWNsOwoJICAgICAgICAgICAgICAgICAKCQlpZiAoISBjdHh0R2l2ZW4pIHsKCQkgICAgLyoKCQkgICAgKiBBIGNvbnRleHQgaXMgbmVlZGVkIGlmIGNhbGxlZCBmcm9tIFJlbGF4TkcuCgkJICAgICovCQkgICAgCgkJICAgIHBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOwoJCSAgICBpZiAocGN0eHQgPT0gTlVMTCkKCQkJcmV0dXJuICgtMSk7CgkJfQoJCS8qCgkJKiBOT1RFOiBUaGlzIGNhbGwgZG9lcyBub3QgY2hlY2sgdGhlIGNvbnRlbnQgbm9kZXMsCgkJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldAoJCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqCgkJKiBvZiB0aGUgZmFjZXQuCgkJKi8JCQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkJICAgICh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LCBmYWNldC0+bm9kZSwgYmFzZSwKCQkgICAgZmFjZXQtPnZhbHVlLCAmKGZhY2V0LT52YWwpLCAxLCAxLCAwKTsKICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgewoJCSAgICBpZiAocmV0IDwgMCkgewoJCQkvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCQlpZiAoY3R4dEdpdmVuKSB7CQkJICAgIAoJCQkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsIGZhY2V0LT5ub2RlLCBOVUxMLAoJCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiIAoJCQkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkJImZhY2V0ICclcycgYWdhaW5zdCB0aGUgYmFzZSB0eXBlIiwKCQkJCWZhY2V0LT52YWx1ZSwgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpKTsKCQkJfQoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUU7CgkJICAgIC8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJICAgIGlmIChjdHh0R2l2ZW4pIHsKCQkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQkJICAgIHJldCwgZmFjZXQtPm5vZGUsICh4bWxTY2hlbWFUeXBlUHRyKSBmYWNldCwKCQkJICAgICJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgZG9lcyBub3QgdmFsaWRhdGUgIgoJCQkgICAgImFnYWluc3QgdGhlIGJhc2UgdHlwZSAnJXMnIiwKCQkJICAgIGZhY2V0LT52YWx1ZSwKCQkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCQliYXNlLT50YXJnZXROYW1lc3BhY2UsIGJhc2UtPm5hbWUpKTsKCQkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCSAgICB9CgkJICAgIGdvdG8gZXhpdDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmFjZXQtPnZhbCA9PSBOVUxMKSB7CgkJICAgIGlmIChjdHh0R2l2ZW4pIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCSAgICAidmFsdWUgd2FzIG5vdCBjb21wdXRlZCIpOwoJCSAgICB9CgkJICAgIFRPRE8KCQl9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBmYWNldC0+cmVnZXhwID0geG1sUmVnZXhwQ29tcGlsZShmYWNldC0+dmFsdWUpOwogICAgICAgICAgICBpZiAoZmFjZXQtPnJlZ2V4cCA9PSBOVUxMKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVBfUkVHRVhQX0lOVkFMSUQ7CgkJLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQlpZiAoY3R4dEdpdmVuKSB7CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQkJcmV0LCBmYWNldC0+bm9kZSwgdHlwZURlY2wsCgkJCSJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgJ3BhdHRlcm4nIGlzIG5vdCBhICIKCQkJInZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbiIsCgkJCWZhY2V0LT52YWx1ZSwgTlVMTCk7CgkJfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6ewoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUoCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05OSU5URUdFUiksCgkJICAgIGZhY2V0LT52YWx1ZSwgJihmYWNldC0+dmFsKSk7CiAgICAgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKCQkgICAgaWYgKHJldCA8IDApIHsKCQkJLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkJaWYgKGN0eHRHaXZlbikgewoJCQkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tGYWNldCIsCgkJCQkidmFsaWRhdGluZyBmYWNldCB2YWx1ZSIpOwoJCQl9CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgcmV0ID0gWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRTsKCQkgICAgLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkgICAgaWYgKGN0eHRHaXZlbikgewoJCQkvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQkJICAgIHJldCwgZmFjZXQtPm5vZGUsIHR5cGVEZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCAnJXMnIGlzIG5vdCBhIHZhbGlkICIKCQkJICAgICInbm9uTmVnYXRpdmVJbnRlZ2VyJyIsCgkJCSAgICBmYWNldC0+dmFsdWUsCgkJCSAgICB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6ewogICAgICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInByZXNlcnZlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1BSRVNFUlZFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJyZXBsYWNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgImNvbGxhcHNlIikpIHsKICAgICAgICAgICAgICAgICAgICBmYWNldC0+d2hpdGVzcGFjZSA9IFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRTsKICAgICAgICAgICAgICAgICAgICAvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCS8qIGVycm9yIHdhcyBwcmV2aW91c2x5OiBYTUxfU0NIRU1BUF9JTlZBTElEX1dISVRFX1NQQUNFICovCgkJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQkJICAgIHJldCwgZmFjZXQtPm5vZGUsIHR5cGVEZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSAnJXMnIG9mIHRoZSBmYWNldCAnd2hpdGVzcGFjZScgaXMgbm90ICIKCQkJICAgICJ2YWxpZCIsIGZhY2V0LT52YWx1ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CmV4aXQ6CiAgICBpZiAoKCEgY3R4dEdpdmVuKSAmJiAocGN0eHQgIT0gTlVMTCkpCgl4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChwY3R4dCk7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKCghIGN0eHRHaXZlbikgJiYgKHBjdHh0ICE9IE5VTEwpKQoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0VmFsdWVzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0ZhY2V0VmFsdWVzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCgkJCSAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gdHlwZURlY2wtPm5hbWU7CiAgICAvKgogICAgKiBOT1RFOiBJdCBpcyBpbnRlbmRlZCB0byB1c2UgdGhlIGZhY2V0cyBsaXN0LCBpbnN0ZWFkCiAgICAqIG9mIGZhY2V0U2V0LgogICAgKi8KICAgIGlmICh0eXBlRGVjbC0+ZmFjZXRzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0ID0gdHlwZURlY2wtPmZhY2V0czsKCgkvKgoJKiBUZW1wb3JhcmlseSBhc3NpZ24gdGhlICJzY2hlbWEiIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKCSogb2YgdGhlIHBhcnNlciBjb250ZXh0LiBUaGlzIGlzIG5lZWRlZCBmb3IgTk9UQVRJT04gdmFsaWRhdGlvbi4KCSovCglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpCgkJcmV0dXJuOwoJfQoJY3R4dC0+dmN0eHQtPnNjaGVtYSA9IGN0eHQtPnNjaGVtYTsKCgl3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUNoZWNrRmFjZXQoZmFjZXQsIHR5cGVEZWNsLCBjdHh0LCBuYW1lKTsKCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJfQoKCWN0eHQtPnZjdHh0LT5zY2hlbWEgPSBOVUxMOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWY6CiAqIEBjdHh0TUdyb3VwOiB0aGUgc2VhcmNoZWQgbW9kZWwgZ3JvdXAKICogQHNlbGZNR3JvdXA6IHRoZSBzZWNvbmQgc2VhcmNoZWQgbW9kZWwgZ3JvdXAKICogQHBhcnRpY2xlOiB0aGUgZmlyc3QgcGFydGljbGUKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgcGFydGljbGUgd2l0aCB0aGUgY2lyY3VsYXIgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UsCiAqIG90aGVyd2lzZSBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgZ3JvdXBEZWYsCgkJCSAgICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIHBhcnRpY2xlKQp7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaXJjID0gTlVMTDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIHRlcm07CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGdkZWY7CgogICAgZm9yICg7IHBhcnRpY2xlICE9IE5VTEw7IHBhcnRpY2xlID0gcGFydGljbGUtPm5leHQpIHsKCXRlcm0gPSBwYXJ0aWNsZS0+Y2hpbGRyZW47CglpZiAodGVybSA9PSBOVUxMKQoJICAgIGNvbnRpbnVlOwoJc3dpdGNoICh0ZXJtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJZ2RlZiA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyKSB0ZXJtOwoJCWlmIChnZGVmID09IGdyb3VwRGVmKQoJCSAgICByZXR1cm4gKHBhcnRpY2xlKTsKCQkvKgoJCSogTWFyayB0aGlzIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gdG8gYXZvaWQgaW5maW5pdGUKCQkqIHJlY3Vyc2lvbiBvbiBjaXJjdWxhciByZWZlcmVuY2VzIG5vdCB5ZXQgZXhhbWluZWQuCgkJKi8KCQlpZiAoZ2RlZi0+ZmxhZ3MgJiBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQpCgkJICAgIGNvbnRpbnVlOwoJCWlmIChnZGVmLT5jaGlsZHJlbiAhPSBOVUxMKSB7CgkJICAgIGdkZWYtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTU9ERUxfR1JPVVBfREVGX01BUktFRDsKCQkgICAgY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKGdyb3VwRGVmLAoJCQlnZGVmLT5jaGlsZHJlbi0+Y2hpbGRyZW4pOwoJCSAgICBnZGVmLT5mbGFncyBePSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQ7CgkJICAgIGlmIChjaXJjICE9IE5VTEwpCgkJCXJldHVybiAoY2lyYyk7CgkJfQoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKGdyb3VwRGVmLCB0ZXJtLT5jaGlsZHJlbik7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcjoKICogQGl0ZW06ICB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lCiAqCiAqIENoZWNrcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyB0byBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW0sCgkJCSAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IE1vZGVsIEdyb3VwIENvcnJlY3QKICAgICogMiBDaXJjdWxhciBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIHdpdGhpbiB0aGUge3BhcnRpY2xlc30KICAgICogb2YgYSBncm91cCB0aGVyZSBtdXN0IG5vdCBiZSBhdCBhbnkgZGVwdGggYSBwYXJ0aWNsZSB3aG9zZSB7dGVybX0KICAgICogaXMgdGhlIGdyb3VwIGl0c2VsZi4KICAgICovCiAgICBpZiAoKGl0ZW0gPT0gTlVMTCkgfHwKCShpdGVtLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgfHwKCShpdGVtLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKGl0ZW0sIGl0ZW0tPmNoaWxkcmVuLT5jaGlsZHJlbik7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCSAgICAvKgoJICAgICogVE9ETzogVGhlIGVycm9yIHJlcG9ydCBpcyBub3QgYWRlcXVhdGU6IHRoaXMgY29uc3RyYWludAoJICAgICogaXMgZGVmaW5lZCBmb3IgbW9kZWwgZ3JvdXBzIGJ1dCBub3QgZGVmaW5pdGlvbnMsIGJ1dCBzaW5jZQoJICAgICogdGhlcmUgY2Fubm90IGJlIGFueSBjaXJjdWxhciBtb2RlbCBncm91cHMgd2l0aG91dCBhIG1vZGVsIGdyb3VwCgkgICAgKiBkZWZpbml0aW9uIChpZiBub3QgdXNpbmcgYSBjb25zdHJ1Y3Rpb24gQVBJKSwgd2UgY2hlY2sgdGhvc2UKCSAgICAqIGRlZmludGlvbnMgb25seS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9NR19QUk9QU19DT1JSRUNUXzIsCgkJTlVMTCwgTlVMTCwgR0VUX05PREUoY2lyYyksCgkJIkNpcmN1bGFyIHJlZmVyZW5jZSB0byB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAnJXMnICIKCQkiZGVmaW5lZCIsIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGl0ZW0tPnRhcmdldE5hbWVzcGFjZSwgaXRlbS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLiBUaGlzIGlzIGEgZmF0YWwgZXJyb3IuCgkgICAgKi8KCSAgICBjaXJjLT5jaGlsZHJlbiA9IE5VTEw7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHcm91cERlZlRlcm1GaXh1cDoKICogQGl0ZW06ICB0aGUgcGFydGljbGUgd2l0aCBhIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gYXMgdGVybQogKiBAY3R4dDogIHRoZSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lCiAqCiAqIENoZWNrcyBjb3MtYWxsLWxpbWl0ZWQuCiAqCiAqIEFzc2lnbnMgdGhlIG1vZGVsIGdyb3VwIG9mIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zIHRvIHRoZSAidGVybSIKICogb2YgdGhlIHJlZmVyZW5jaW5nIHBhcnRpY2xlLgogKiBJbiB4bWxTY2hlbWFNaXNjUmVmRml4dXAgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zIHdhcyBhc3NpZ25lZAogKiB0byB0aGUgInRlcm0iLCBzaW5jZSBuZWVkZWQgZm9yIHRoZSBjaXJjdWxhcml0eSBjaGVjay4gCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFHcm91cERlZlRlcm1GaXh1cCh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtLAoJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQgQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKChpdGVtID09IE5VTEwpIHx8CgkoaXRlbS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEUpIHx8CgkoaXRlbS0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwKCShpdGVtLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHx8CgkoaXRlbS0+Y2hpbGRyZW4tPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuOwogICAgaXRlbS0+Y2hpbGRyZW4gPSBpdGVtLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAvKgogICAgKiBUT0RPOiBOb3QgbmljZSwgYnV0IHdlIHdpbGwgYW5jaG9yIGNvcy1hbGwtbGltaXRlZCBoZXJlLgogICAgKi8KICAgIGlmICgoaXRlbS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgJiYKCShpdGVtLT5tYXhPY2N1cnMgIT0gMSkpIHsKCS8qCgkqIFNQRUMgKDEuMikgInRoZSB7dGVybX0gcHJvcGVydHkgb2YgYSBwYXJ0aWNsZSB3aXRoCgkqIHttYXggb2NjdXJzfT0xd2hpY2ggaXMgcGFydCBvZiBhIHBhaXIgd2hpY2ggY29uc3RpdHV0ZXMgdGhlCgkqIHtjb250ZW50IHR5cGV9IG9mIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24uIgoJKi8KCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFX0dST1VQXzMsCgkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIGl0ZW0tPm5vZGUsCgkgICAgIlRoZSBwYXJ0aWNsZSdzICdtYXhPY2N1cnMnIG11c3QgYmUgMSwgc2luY2UgYW4geHM6YWxsIG1vZGVsICIKCSAgICAiZ3JvdXAgaXMgaXRzIHRlcm0iLCBOVUxMKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENpcmNBdHRyR3JSZWY6CiAqIEBjdHh0R3I6IHRoZSBzZWFyY2hlZCBhdHRyaWJ1dGUgZ3JvdXAKICogQGF0dHI6IHRoZSBjdXJyZW50IGF0dHJpYnV0ZSBsaXN0IHRvIGJlIHByb2Nlc3NlZAogKgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGJ5CiAqIHhtbFNjaGVtYUNoZWNrU1JDQXR0cmlidXRlR3JvdXBDaXJjdWxhciBvbmx5LgogKgogKiBSZXR1cm5zIHRoZSBjaXJjdWxhciBhdHRyaWJ1dGUgZ3JvdSByZWZlcmVuY2UsIG90aGVyd2lzZSBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUdldENpcmNBdHRyR3JSZWYoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY3R4dEdyLAoJCQkgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjaXJjID0gTlVMTCwgZ3I7CiAgICBpbnQgbWFya2VkOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBhdHRyaWJ1dGUgZ3JvdXAuCiAgICAqLwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJbWFya2VkID0gMDsKCWlmIChhdHRyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgewoJICAgIGdyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhdHRyOwoJICAgIGlmIChnci0+cmVmSXRlbSAhPSBOVUxMKSAgewoJCWlmIChnci0+cmVmSXRlbSA9PSBjdHh0R3IpCgkJICAgIHJldHVybiAoZ3IpOwoJCWVsc2UgaWYgKGdyLT5yZWZJdGVtLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQpIHsKCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogTWFyayBhcyB2aXNpdGVkIHRvIGF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbiBvbgoJCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkgICAgKi8KCQkgICAgZ3ItPnJlZkl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkJICAgIG1hcmtlZCA9IDE7CgkJfQoJICAgIH0KCSAgICBpZiAoZ3ItPmF0dHJpYnV0ZXMgIT0gTlVMTCkKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihjdHh0R3IsIGdyLT5hdHRyaWJ1dGVzKTsKCSAgICAvKgoJICAgICogVW5tYXJrIHRoZSB2aXNpdGVkIGdyb3VwJ3MgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChtYXJrZWQpCgkJZ3ItPnJlZkl0ZW0tPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkgICAgaWYgKGNpcmMgIT0gTlVMTCkKCQlyZXR1cm4gKGNpcmMpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNBdHRyaWJ1dGVHcm91cENpcmN1bGFyOgogKiBhdHRyR3I6ICB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgb2YgYXR0cmlidXRlIGdyb3Vwcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyR3IsCgkJCQkJeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJCWNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OgogICAgKiBBdHRyaWJ1dGUgR3JvdXAgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSwogICAgKiAzIENpcmN1bGFyIGdyb3VwIHJlZmVyZW5jZSBpcyBkaXNhbGxvd2VkIG91dHNpZGUgPHJlZGVmaW5lPi4KICAgICogVGhhdCBpcywgdW5sZXNzIHRoaXMgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3MgcGFyZW50IGlzCiAgICAqIDxyZWRlZmluZT4sIHRoZW4gYW1vbmcgdGhlIFtjaGlsZHJlbl0sIGlmIGFueSwgdGhlcmUgbXVzdAogICAgKiBub3QgYmUgYW4gPGF0dHJpYnV0ZUdyb3VwPiB3aXRoIHJlZiBbYXR0cmlidXRlXSB3aGljaCByZXNvbHZlcwogICAgKiB0byB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyA8YXR0cmlidXRlR3JvdXA+LiBJbmRpcmVjdAogICAgKiBjaXJjdWxhcml0eSBpcyBhbHNvIHJ1bGVkIG91dC4gVGhhdCBpcywgd2hlbiBRTmFtZSByZXNvbHV0aW9uCiAgICAqIChTY2hlbWEgRG9jdW1lbnQpICinMy4xNS4zKSBpcyBhcHBsaWVkIHRvIGEgt1FOYW1ltyBhcmlzaW5nIGZyb20KICAgICogYW55IDxhdHRyaWJ1dGVHcm91cD5zIHdpdGggYSByZWYgW2F0dHJpYnV0ZV0gYW1vbmcgdGhlIFtjaGlsZHJlbl0sCiAgICAqIGl0IG11c3Qgbm90IGJlIHRoZSBjYXNlIHRoYXQgYSC3UU5hbWW3IGlzIGVuY291bnRlcmVkIGF0IGFueSBkZXB0aAogICAgKiB3aGljaCByZXNvbHZlcyB0byB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyA8YXR0cmlidXRlR3JvdXA+LgogICAgKi8KICAgIC8qCiAgICAqIE9ubHkgZ2xvYmFsIGNvbXBvbmVudHMgY2FuIGJlIHJlZmVyZW5jZWQuCiAgICAqLwogICAgaWYgKCgoYXR0ckdyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpID09IDApIHx8CgkoYXR0ckdyLT5hdHRyaWJ1dGVzID09IE5VTEwpKQoJcmV0dXJuOwogICAgZWxzZSB7Cgl4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjaXJjOwoKCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKGF0dHJHciwgYXR0ckdyLT5hdHRyaWJ1dGVzKTsKCWlmIChjaXJjICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogUmVwb3J0IHRoZSByZWZlcmVuY2VkIGF0dHIgZ3JvdXAgYXMgUU5hbWUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV9HUk9VUF8zLAoJCU5VTEwsIE5VTEwsIGNpcmMtPm5vZGUsCgkJIkNpcmN1bGFyIHJlZmVyZW5jZSB0byB0aGUgYXR0cmlidXRlIGdyb3VwICclcycgIgoJCSJkZWZpbmVkIiwgYXR0ckdyLT5uYW1lKTsKCSAgICAvKgoJICAgICogTk9URTogV2Ugd2lsbCBjdXQgdGhlIHJlZmVyZW5jZSB0byBhdm9pZCBmdXJ0aGVyCgkgICAgKiBjb25mdXNpb24gb2YgdGhlIHByb2Nlc3Nvci4KCSAgICAqIEJBRFNQRUM6IFRoZSBzcGVjIHNob3VsZCBkZWZpbmUgaG93IHRvIHByb2Nlc3MgaW4gdGhpcyBjYXNlLgoJICAgICovCgkgICAgY2lyYy0+YXR0cmlidXRlcyA9IE5VTEw7CgkgICAgY2lyYy0+cmVmSXRlbSA9IE5VTEw7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyR3JwRml4dXA6CiAqIEBhdHRyZ3JwRGVjbDogIHRoZSBzY2hlbWEgYXR0cmlidXRlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBhdHRyaWJ1dGVzIGRlZmluaXRpb25zCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyR3JwRml4dXAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0cmdycCwKICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IGF0dHJncnAtPm5hbWU7CiAgICBpZiAoYXR0cmdycC0+YXR0cmlidXRlcyAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyZ3JwLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJlZjsKCiAgICAgICAgcmVmID0geG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXAoY3R4dC0+c2NoZW1hLCBhdHRyZ3JwLT5yZWYsCgkgICAgYXR0cmdycC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBhdHRyZ3JwLCBhdHRyZ3JwLT5ub2RlLAoJCSJyZWYiLCBhdHRyZ3JwLT5yZWYsIGF0dHJncnAtPnJlZk5zLAoJCVhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CglhdHRyZ3JwLT5yZWZJdGVtID0gcmVmOwoJLyoKCSogQ2hlY2sgZm9yIHNlbGYgcmVmZXJlbmNlIQoJKi8KICAgICAgICB4bWxTY2hlbWFBdHRyR3JwRml4dXAocmVmLCBjdHh0LCBOVUxMKTsKICAgICAgICBhdHRyZ3JwLT5hdHRyaWJ1dGVzID0gcmVmLT5hdHRyaWJ1dGVzOwoJYXR0cmdycC0+YXR0cmlidXRlV2lsZGNhcmQgPSByZWYtPmF0dHJpYnV0ZVdpbGRjYXJkOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXR0ckNoZWNrVmFsQ29uc3RyOgogKiBAaXRlbTogIGFuIHNjaGVtYSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogQXR0cmlidXRlIERlY2xhcmF0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogKiAgIChhLXByb3BzLWNvcnJlY3QpCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZS4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0cih4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CgogICAgLyoKICAgICogMiBpZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsCiAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGl0cyB2YWx1ZSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0CiAgICAqIHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIFN0cmluZyBWYWxpZCAopzMuMTQuNCkuCiAgICAqLwogICAgaWYgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpIHsKCWludCByZXQ7CgoJaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKCSAgICBQRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIiLAoJCSJ0eXBlIGlzIG1pc3NpbmciKTsKCSAgICByZXR1cm47Cgl9CglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LAoJICAgIGl0ZW0tPm5vZGUsIGl0ZW0tPnN1YnR5cGVzLCBpdGVtLT5kZWZWYWx1ZSwgJihpdGVtLT5kZWZWYWwpLAoJICAgIDEsIDEsIDApOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFBdHRyQ2hlY2tWYWxDb25zdHIiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKCQlyZXR1cm47CgkgICAgfQoJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0FfUFJPUFNfQ09SUkVDVF8yOwoJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQlyZXQsIGl0ZW0tPm5vZGUsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLAoJCSJUaGUgdmFsdWUgb2YgdGhlIHZhbHVlIGNvbnN0cmFpbnQgaXMgbm90IHZhbGlkIiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQogICAgfQp9CgpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFDaGVja1N1YnN0R3JvdXBDaXJjdWxhcih4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLAoJCQkJIHhtbFNjaGVtYUVsZW1lbnRQdHIgYW5jZXN0b3IpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwoKICAgIGlmIChTVUJTVF9HUk9VUF9BRkYoYW5jZXN0b3IpID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwogICAgaWYgKFNVQlNUX0dST1VQX0FGRihhbmNlc3RvcikgPT0gZWxlbURlY2wpCglyZXR1cm4gKGFuY2VzdG9yKTsKCiAgICBpZiAoU1VCU1RfR1JPVVBfQUZGKGFuY2VzdG9yKS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0NJUkNVTEFSKQoJcmV0dXJuIChOVUxMKTsKICAgIFNVQlNUX0dST1VQX0FGRihhbmNlc3RvciktPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQ0lSQ1VMQVI7CiAgICByZXQgPSB4bWxTY2hlbWFDaGVja1N1YnN0R3JvdXBDaXJjdWxhcihlbGVtRGVjbCwKCVNVQlNUX0dST1VQX0FGRihhbmNlc3RvcikpOwogICAgU1VCU1RfR1JPVVBfQUZGKGFuY2VzdG9yKS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRUxFTV9DSVJDVUxBUjsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1Qcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIEVsZW1lbnQgRGVjbGFyYXRpb24gUHJvcGVydGllcyBDb3JyZWN0IChlLXByb3BzLWNvcnJlY3QpCiAqCiAqIFNUQVRVUzoKICogICBtaXNzaW5nOiAoNikKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZiA9IEVMRU1fVFlQRShlbGVtRGVjbCk7CiAgICAvKgogICAgKiBTUEVDICgxKSAiVGhlIHZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uCiAgICAqIG11c3QgYmUgYXMgZGVzY3JpYmVkIGluIHRoZSBwcm9wZXJ0eSB0YWJsZWF1IGluIFRoZSBFbGVtZW50CiAgICAqIERlY2xhcmF0aW9uIFNjaGVtYSBDb21wb25lbnQgKKczLjMuMSksIG1vZHVsbyB0aGUgaW1wYWN0IG9mIE1pc3NpbmcKICAgICogU3ViLWNvbXBvbmVudHMgKKc1LjMpLiIKICAgICovCiAgICBpZiAoU1VCU1RfR1JPVVBfQUZGKGVsZW1EZWNsKSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQgPSBTVUJTVF9HUk9VUF9BRkYoZWxlbURlY2wpLCBjaXJjOwoKCXhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQoaGVhZCwgcGN0eHQsIE5VTEwpOwoJLyoKCSogU1BFQyAoMykgIklmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gZ3JvdXAKCSogYWZmaWxpYXRpb259LCB0aGVuIHtzY29wZX0gbXVzdCBiZSBnbG9iYWwuIgoJKi8KCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpID09IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF8zLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgZWxlbURlY2wtPm5vZGUsCgkJIk9ubHkgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGNhbiBoYXZlIGEgIgoJCSJzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb24iLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfMzsKCX0KCS8qCgkqIFRPRE86IFNQRUMgKDYpICJDaXJjdWxhciBzdWJzdGl0dXRpb24gZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLgoJKiBUaGF0IGlzLCBpdCBtdXN0IG5vdCBiZSBwb3NzaWJsZSB0byByZXR1cm4gdG8gYW4gZWxlbWVudCBkZWNsYXJhdGlvbgoJKiBieSByZXBlYXRlZGx5IGZvbGxvd2luZyB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0KCSogcHJvcGVydHkuIgoJKi8KCWlmIChoZWFkID09IGVsZW1EZWNsKQoJICAgIGNpcmMgPSBoZWFkOwoJZWxzZSBpZiAoU1VCU1RfR1JPVVBfQUZGKGhlYWQpICE9IE5VTEwpCgkgICAgY2lyYyA9IHhtbFNjaGVtYUNoZWNrU3Vic3RHcm91cENpcmN1bGFyKGhlYWQsIGhlYWQpOwoJZWxzZQoJICAgIGNpcmMgPSBOVUxMOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzYsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGNpcmMsIGNpcmMtPm5vZGUsCgkJIlRoZSBlbGVtZW50IGRlY2xhcmF0aW9uICclcycgZGVmaW5lcyBhIGNpcmN1bGFyICIKCQkic3Vic3RpdHV0aW9uIGdyb3VwIHRvIGVsZW1lbnQgZGVjbGFyYXRpb24gJyVzJyIsCgkJeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckEsIGNpcmMpLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCLCBoZWFkKSwKCQlOVUxMKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0ckEpCgkgICAgRlJFRV9BTkRfTlVMTChzdHJCKQoJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF82OwoJfQoJLyoKCSogU1BFQyAoNCkgIklmIHRoZXJlIGlzIGEge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sCgkqIHRoZSB7dHlwZSBkZWZpbml0aW9ufQoJKiBvZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB7dHlwZQoJKiBkZWZpbml0aW9ufSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIGdpdmVuIHRoZSB2YWx1ZQoJKiBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cAoJKiBhZmZpbGlhdGlvbn0sIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAopzMuNC42KQoJKiAoaWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzIGNvbXBsZXgpIG9yIGFzIGRlZmluZWQgaW4KCSogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSAoaWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzCgkqIHNpbXBsZSkuIgoJKgoJKiBOT1RFOiB7c3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnN9IG1lYW5zIHRoZSB2YWx1ZXMgb2YgdGhlCgkqIGF0dHJpYnV0ZSAiZmluYWwiLgoJKi8KCglpZiAodHlwZURlZiAhPSBFTEVNX1RZUEUoU1VCU1RfR1JPVVBfQUZGKGVsZW1EZWNsKSkpIHsKCSAgICBpbnQgc2V0ID0gMDsKCgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9FWFRFTlNJT04pCgkJc2V0IHw9IFNVQlNFVF9FWFRFTlNJT047CgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTikKCQlzZXQgfD0gU1VCU0VUX1JFU1RSSUNUSU9OOwoKCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0sodHlwZURlZiwKCQlFTEVNX1RZUEUoaGVhZCksIHNldCkgIT0gMCkgewoJCXhtbENoYXIgKnN0ckEgPSBOVUxMLCAqc3RyQiA9IE5VTEwsICpzdHJDID0gTlVMTDsKCgkJcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzQ7CgkJeG1sU2NoZW1hUEN1c3RvbUVyckV4dChwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzQsCgkJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgZWxlbURlY2wtPm5vZGUsCgkJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uICclcycgd2FzICIKCQkgICAgImVpdGhlciByZWplY3RlZCBieSB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwICIKCQkgICAgImFmZmlsaWF0aW9uICclcycsIG9yIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSBpdHMgdHlwZSAiCgkJICAgICJkZWZpbml0aW9uICclcyciLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQSwgdHlwZURlZiksCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJCLCBoZWFkKSwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckMsIEVMRU1fVFlQRShoZWFkKSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyQSkKCQlGUkVFX0FORF9OVUxMKHN0ckIpCgkJRlJFRV9BTkRfTlVMTChzdHJDKQoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDUpICJJZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gb3Ige3R5cGUgZGVmaW5pdGlvbn0ncwogICAgKiB7Y29udGVudCB0eXBlfQogICAgKiBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQgdGhlbiB0aGVyZSBtdXN0IG5vdCBiZSBhIHt2YWx1ZSBjb25zdHJhaW50fS4KICAgICogTm90ZTogVGhlIHVzZSBvZiBJRCBhcyBhIHR5cGUgZGVmaW5pdGlvbiBmb3IgZWxlbWVudHMgZ29lcyBiZXlvbmQKICAgICogWE1MIDEuMCwgYW5kIHNob3VsZCBiZSBhdm9pZGVkIGlmIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGlzIGRlc2lyZWQiCiAgICAqLwogICAgaWYgKChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkgJiYKCSgoSVNfU0lNUExFX1RZUEUodHlwZURlZikgJiYKCSAgeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGVEZWYsIFhNTF9TQ0hFTUFTX0lEKSkgfHwKCSAoSVNfQ09NUExFWF9UWVBFKHR5cGVEZWYpICYmCgkgIEhBU19TSU1QTEVfQ09OVEVOVCh0eXBlRGVmKSAmJgoJICB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUodHlwZURlZi0+Y29udGVudFR5cGVEZWYsCgkgICAgWE1MX1NDSEVNQVNfSUQpKSkpIHsKCglyZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNTsKCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzUsCgkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCBlbGVtRGVjbC0+bm9kZSwKCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiAob3IgdHlwZSBkZWZpbml0aW9uJ3MgY29udGVudCB0eXBlKSBpcyBvciAiCgkgICAgImlzIGRlcml2ZWQgZnJvbSBJRDsgdmFsdWUgY29uc3RyYWludHMgYXJlIG5vdCBhbGxvd2VkIGluICIKCSAgICAiY29uanVuY3Rpb24gd2l0aCBzdWNoIGEgdHlwZSBkZWZpbml0aW9uIiwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSB7CglpbnQgdmNyZXQ7Cgl4bWxOb2RlUHRyIG5vZGUgPSBOVUxMOwoKCS8qCgkqIFNQRUMgKDIpICJJZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsCgkqIHJlcHJlc2VudGF0aW9uIG9mIGl0cyB2YWx1ZSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZQoJKiB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQoJKiAopzMuMy42KS4iCgkqLwoJaWYgKHR5cGVEZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIocGN0eHQsIGVsZW1EZWNsLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0LCAiCgkJInR5cGUgaXMgbWlzc2luZy4uLiBza2lwcGluZyB2YWxpZGF0aW9uIG9mICIKCQkidGhlIHZhbHVlIGNvbnN0cmFpbnQiLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWlmIChlbGVtRGVjbC0+bm9kZSAhPSBOVUxMKSB7CgkgICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpCgkJbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGVsZW1EZWNsLT5ub2RlLAoJCSAgICBCQURfQ0FTVCAiZml4ZWQiKTsKCSAgICBlbHNlCgkJbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGVsZW1EZWNsLT5ub2RlLAoJCSAgICBCQURfQ0FTVCAiZGVmYXVsdCIpOwoJfQoJdmNyZXQgPSB4bWxTY2hlbWFQYXJzZUNoZWNrQ09TVmFsaWREZWZhdWx0KHBjdHh0LCBub2RlLAoJICAgIHR5cGVEZWYsIGVsZW1EZWNsLT52YWx1ZSwgJihlbGVtRGVjbC0+ZGVmVmFsKSk7CglpZiAodmNyZXQgIT0gMCkgewoJICAgIGlmICh2Y3JldCA8IDApIHsKCQlQRVJST1JfSU5UKCJ4bWxTY2hlbWFFbGVtQ2hlY2tWYWxDb25zdHIiLAoJCSAgICAiZmFpbGVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIGFuICIKCQkgICAgImVsZW1lbnQgZGVjbGFyYXRpb24iKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgcmV0dXJuICh2Y3JldCk7Cgl9CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtU3Vic3RHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVjbDogdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24KICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogU3Vic3RpdHV0aW9uIEdyb3VwIChjb3MtZXF1aXYtY2xhc3MpCiAqCiAqIEluIExpYnhtbDIgdGhlIHN1YnN0LiBncm91cHMgd2lsbCBiZSBwcmVjb21wdXRlZCwgaW4gdGVybXMgb2YgdGhhdAogKiBhIGxpc3Qgd2lsbCBiZSBidWlsdCBmb3IgZWFjaCBzdWJzdC4gZ3JvdXAgaGVhZCwgaG9sZGluZyBhbGwgZGlyZWN0CiAqIHJlZmVyZW50cyB0byB0aGlzIGhlYWQuCiAqIE5PVEUgdGhhdCB0aGlzIGZ1bmN0aW9uIG5lZWRzOgogKiAgIDEuIGNpcmN1bGFyIHN1YnN0LiBncm91cHMgdG8gYmUgY2hlY2tlZCBiZWZvcmVoYW5kCiAqICAgMi4gdGhlIGRlY2xhcmF0aW9uJ3MgdHlwZSB0byBiZSBkZXJpdmVkIGZyb20gdGhlIGhlYWQncyB0eXBlCiAqCiAqIFNUQVRVUzoKICoKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbVN1YnN0R3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIGlmICgoU1VCU1RfR1JPVVBfQUZGKGVsZW1EZWNsKSA9PSBOVUxMKSB8fAoJLyogU1BFQyAoMSkgIkl0cyB7YWJzdHJhY3R9IGlzIGZhbHNlLiIgKi8KCShlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZDsKCXhtbFNjaGVtYVR5cGVQdHIgaGVhZFR5cGUsIHR5cGU7CglpbnQgc2V0LCBtZXRoU2V0OwoJLyoKCSogU1BFQyAoMikgIkl0IGlzIHZhbGlkbHkgc3Vic3RpdHV0YWJsZSBmb3IgSEVBRCBzdWJqZWN0IHRvIEhFQUQncwoJKiB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBhcyB0aGUgYmxvY2tpbmcgY29uc3RyYWludCwgYXMgZGVmaW5lZCBpbgoJKiBTdWJzdGl0dXRpb24gR3JvdXAgT0sgKFRyYW5zaXRpdmUpICinMy4zLjYpLiIKCSovCglmb3IgKGhlYWQgPSBTVUJTVF9HUk9VUF9BRkYoZWxlbURlY2wpOyBoZWFkICE9IE5VTEw7CgkgICAgaGVhZCA9IFNVQlNUX0dST1VQX0FGRihoZWFkKSkgewoJICAgIHNldCA9IDA7CgkgICAgbWV0aFNldCA9IDA7CgkgICAgLyoKCSAgICAqIFRoZSBibG9ja2luZyBjb25zdHJhaW50cy4KCSAgICAqLwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OKQoJCWNvbnRpbnVlOwoJICAgIGhlYWRUeXBlID0gaGVhZC0+c3VidHlwZXM7CgkgICAgdHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKCSAgICBpZiAoaGVhZFR5cGUgPT0gdHlwZSkKCQlnb3RvIGFkZF9tZW1iZXI7CgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTikKCQlzZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTikKCQlzZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT047CgkgICAgLyoKCSAgICAqIFNQRUM6IFN1YnN0aXR1dGlvbiBHcm91cCBPSyAoVHJhbnNpdGl2ZSkgKDIuMykKCSAgICAqICJUaGUgc2V0IG9mIGFsbCB7ZGVyaXZhdGlvbiBtZXRob2R9cyBpbnZvbHZlZCBpbiB0aGUKCSAgICAqIGRlcml2YXRpb24gb2YgRCdzIHt0eXBlIGRlZmluaXRpb259IGZyb20gQydzIHt0eXBlIGRlZmluaXRpb259CgkgICAgKiBkb2VzIG5vdCBpbnRlcnNlY3Qgd2l0aCB0aGUgdW5pb24gb2YgdGhlIGJsb2NraW5nIGNvbnN0cmFpbnQsCgkgICAgKiBDJ3Mge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gKGlmIEMgaXMgY29tcGxleCwgb3RoZXJ3aXNlIHRoZQoJICAgICogZW1wdHkgc2V0KSBhbmQgdGhlIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9IChyZXNwZWN0aXZlbHkgdGhlCgkgICAgKiBlbXB0eSBzZXQpIG9mIGFueSBpbnRlcm1lZGlhdGUge3R5cGUgZGVmaW5pdGlvbn1zIGluIHRoZQoJICAgICogZGVyaXZhdGlvbiBvZiBEJ3Mge3R5cGUgZGVmaW5pdGlvbn0gZnJvbSBDJ3Mge3R5cGUgZGVmaW5pdGlvbn0uIgoJICAgICovCgkgICAgLyoKCSAgICAqIE9QVElNSVpFIFRPRE86IE9wdGltaXplIHRoaXMgYSBiaXQsIHNpbmNlLCBpZiB0cmF2ZXJzaW5nIHRoZQoJICAgICogc3Vic3QuaGVhZCBheGlzLCB0aGUgbWV0aFNldCBkb2VzIG5vdCBuZWVkIHRvIGJlIGNvbXB1dGVkIGZvcgoJICAgICogdGhlIGZ1bGwgZGVwdGggb3ZlciBhbmQgb3Zlci4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBUaGUgc2V0IG9mIGFsbCB7ZGVyaXZhdGlvbiBtZXRob2R9cyBpbnZvbHZlZCBpbiB0aGUgZGVyaXZhdGlvbgoJICAgICovCgkgICAgd2hpbGUgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlICE9IGhlYWRUeXBlKSkgewoJCWlmICgodHlwZS0+ZmxhZ3MgJgoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgJiYKCQkgICAgKChtZXRoU2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikgPT0gMCkpCgkJICAgIG1ldGhTZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT047CgoJCWlmICgodHlwZS0+ZmxhZ3MgJgoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSAmJgoJCSAgICAoKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSA9PSAwKSkKCQkgICAgbWV0aFNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OOwoKCQl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgfQoJICAgIC8qCgkgICAgKiBUaGUge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc30gb2YgYWxsIGludGVybWVkaWF0ZSB0eXBlcyArCgkgICAgKiB0aGUgaGVhZCdzIHR5cGUuCgkgICAgKi8KCSAgICB0eXBlID0gZWxlbURlY2wtPnN1YnR5cGVzLT5iYXNlVHlwZTsKCSAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CgkJaWYgKElTX0NPTVBMRVhfVFlQRSh0eXBlKSkgewoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSAmJgoJCQkoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSA9PSAwKSkKCQkgICAgc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pICYmCgkJCSgoc2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikgPT0gMCkpCgkJICAgIHNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OOwoJCX0gZWxzZQoJCSAgICBicmVhazsKCQlpZiAodHlwZSA9PSBoZWFkVHlwZSkKCQkgICAgYnJlYWs7CgkJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIH0KCSAgICBpZiAoKHNldCAhPSAwKSAmJgoJCSgoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSAmJgoJCShtZXRoU2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT04pKSB8fAoJCSgoc2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikgJiYKCQkobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pKSkpIHsKCQljb250aW51ZTsKCSAgICB9CmFkZF9tZW1iZXI6CgkgICAgeG1sU2NoZW1hQWRkRWxlbWVudFN1YnN0aXR1dGlvbk1lbWJlcihjdHh0LCBoZWFkLCBlbGVtRGVjbCk7CgkgICAgaWYgKChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fU1VCU1RfR1JPVVBfSEVBRCkgPT0gMCkKCQloZWFkLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1NVQlNUX0dST1VQX0hFQUQ7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGVsZW1lbnQgZGVjbGFyYXRpb24vcGFydGljbGUKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBjb25zdHJhaW50cyBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uLgogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCgkJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkKCXJldHVybjsKICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX0NIRUNLRUQpCglyZXR1cm47CiAgICBlbGVtRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9DSEVDS0VEOwogICAgaWYgKHhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdChjdHh0LCBlbGVtRGVjbCkgPT0gMCkKCXhtbFNjaGVtYUNoZWNrRWxlbVN1YnN0R3JvdXAoY3R4dCwgZWxlbURlY2wpOwp9CgovKioKICogeG1sU2NoZW1hTWlzY1JlZkZpeHVwOgogKiBAaXRlbTogIGFuIHNjaGVtYSBjb21wb25lbnQKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBpbnRlcm5hbCBuYW1lIG9mIHRoZSBjb21wb25lbnQKICoKICogUmVzb2x2ZXMgcmVmZXJlbmNlcyBvZiBtaXNjLiBzY2hlbWEgY29tcG9uZW50cy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYU1pc2NSZWZGaXh1cCh4bWxTY2hlbWFUcmVlSXRlbVB0ciBpdGVtLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkgewoJaWYgKChpdGVtLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgoJICAgIChpdGVtLT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGKSkgewoJICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJlZiA9ICh4bWxTY2hlbWFRTmFtZVJlZlB0cikgaXRlbS0+Y2hpbGRyZW47CgkgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgcmVmSXRlbTsKCSAgICAvKgoJICAgICogUmVzb2x2ZSB0aGUgcmVmZXJlbmNlLgoJICAgICovCgkgICAgaXRlbS0+Y2hpbGRyZW4gPSBOVUxMOwoJICAgIHJlZkl0ZW0gPSB4bWxTY2hlbWFHZXROYW1lZENvbXBvbmVudChjdHh0LT5zY2hlbWEsCgkJcmVmLT5pdGVtVHlwZSwgcmVmLT5uYW1lLCByZWYtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgaWYgKHJlZkl0ZW0gPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkgICAgTlVMTCwgR0VUX05PREUoaXRlbSksICJyZWYiLCByZWYtPm5hbWUsCgkJICAgIHJlZi0+dGFyZ2V0TmFtZXNwYWNlLCByZWYtPml0ZW1UeXBlLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCWlmIChyZWZJdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgewoJCSAgICAvKgoJCSAgICAqIE5PVEUgdGhhdCB3ZSB3aWxsIGFzc2lnbiB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgoJCSAgICAqIGl0c2VsZiB0byB0aGUgInRlcm0iIG9mIHRoZSBwYXJ0aWNsZS4gVGhpcyB3aWxsIGVhc2UKCQkgICAgKiB0aGUgY2hlY2sgZm9yIGNpcmN1bGFyIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLiBBZnRlcgoJCSAgICAqIHRoYXQgdGhlICJ0ZXJtIiB3aWxsIGJlIGFzc2lnbmVkIHRoZSBtb2RlbCBncm91cCBvZiB0aGUKCQkgICAgKiBtb2RlbCBncm91cCBkZWZpbml0aW9uLgoJCSAgICAqLwoJCSAgICBpdGVtLT5jaGlsZHJlbiA9IHJlZkl0ZW07CgkJfSBlbHNlCgkJICAgIGl0ZW0tPmNoaWxkcmVuID0gcmVmSXRlbTsKCSAgICB9Cgl9CiAgICB9Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoeG1sU2NoZW1hVmFsUHRyIHgsCgkJICAgICAgIHhtbFNjaGVtYVZhbFB0ciB5KSAKeyAgIAogICAgeG1sU2NoZW1hVHlwZVB0ciB0eCwgdHksIHB0eCwgcHR5OyAgICAKICAgIGludCByZXQ7CgogICAgd2hpbGUgKHggIT0gTlVMTCkgewoJLyogU2FtZSB0eXBlcy4gKi8KCXR4ID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoeG1sU2NoZW1hR2V0VmFsVHlwZSh4KSk7Cgl0eSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKHhtbFNjaGVtYUdldFZhbFR5cGUoeSkpOwoJcHR4ID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eCk7CglwdHkgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5KTsKCS8qCgkqICgxKSBpZiBhIGRhdGF0eXBlIFQnIGlzILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263IGZyb20gYW4KCSogYXRvbWljIGRhdGF0eXBlIFQgdGhlbiB0aGUgt3ZhbHVlIHNwYWNltyBvZiBUJyBpcyBhIHN1YnNldCBvZgoJKiB0aGUgt3ZhbHVlIHNwYWNltyBvZiBULiAqLwoJLyoKCSogKDIpIGlmIGRhdGF0eXBlcyBUJyBhbmQgVCcnIGFyZSC3ZGVyaXZlZLcgYnkgt3Jlc3RyaWN0aW9utwoJKiBmcm9tIGEgY29tbW9uIGF0b21pYyBhbmNlc3RvciBUIHRoZW4gdGhlILd2YWx1ZSBzcGFjZbdzIG9mIFQnCgkqIGFuZCBUJycgbWF5IG92ZXJsYXAuCgkqLwoJaWYgKHB0eCAhPSBwdHkpCgkgICAgcmV0dXJuKDApOwoJLyoKCSogV2UgYXNzdW1lIGNvbXB1dGVkIHZhbHVlcyB0byBiZSBub3JtYWxpemVkLCBzbyBkbyBhIGZhc3QKCSogc3RyaW5nIGNvbXBhcmlzb24gZm9yIHN0cmluZyBiYXNlZCB0eXBlcy4KCSovCglpZiAoKHB0eC0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSB8fAoJICAgIElTX0FOWV9TSU1QTEVfVFlQRShwdHgpKSB7CgkgICAgaWYgKCEgeG1sU3RyRXF1YWwoCgkJeG1sU2NoZW1hVmFsdWVHZXRBc1N0cmluZyh4KSwKCQl4bWxTY2hlbWFWYWx1ZUdldEFzU3RyaW5nKHkpKSkKCQlyZXR1cm4gKDApOwoJfSBlbHNlIHsKCSAgICByZXQgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzV2h0c3AoCgkJeCwgWE1MX1NDSEVNQV9XSElURVNQQUNFX1BSRVNFUlZFLAoJCXksIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSk7CgkgICAgaWYgKHJldCA9PSAtMikKCQlyZXR1cm4oLTEpOwoJICAgIGlmIChyZXQgIT0gMCkKCQlyZXR1cm4oMCk7Cgl9CgkvKgoJKiBMaXN0cy4KCSovCgl4ID0geG1sU2NoZW1hVmFsdWVHZXROZXh0KHgpOwoJaWYgKHggIT0gTlVMTCkgewoJICAgIHkgPSB4bWxTY2hlbWFWYWx1ZUdldE5leHQoeSk7CgkgICAgaWYgKHkgPT0gTlVMTCkKCQlyZXR1cm4gKDApOwkgICAgCgl9IGVsc2UgaWYgKHhtbFNjaGVtYVZhbHVlR2V0TmV4dCh5KSAhPSBOVUxMKQoJICAgIHJldHVybiAoMCk7CgllbHNlCgkgICAgcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyRml4dXA6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UuCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMvdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICAvKgogICAgKiBUT0RPOiBJZiBpbmNsdWRpbmcgdGhpcyBpcyBkb25lIHR3aWNlICghKSBmb3IgZXZlcnkgYXR0cmlidXRlLgogICAgKiAgICAgICAtPiBIbW0sIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgZG9uZS4KICAgICovCiAgICAvKgogICAgKiBUaGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gZWxlbWVudAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBbY2hpbGRyZW5dLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlIHNpbXBsZQogICAgKiB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIHR5cGUKICAgICogW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfSU5URVJOQUxfUkVTT0xWRUQpCglyZXR1cm47CiAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEOwogICAgaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGl0ZW0tPnR5cGVOYW1lICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJdHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBpdGVtLT50eXBlTmFtZSwKCSAgICBpdGVtLT50eXBlTnMpOwoJaWYgKCh0eXBlID09IE5VTEwpIHx8ICghIElTX1NJTVBMRV9UWVBFKHR5cGUpKSkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJCSJ0eXBlIiwgaXRlbS0+dHlwZU5hbWUsIGl0ZW0tPnR5cGVOcywKCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCX0gZWxzZQoJICAgIGl0ZW0tPnN1YnR5cGVzID0gdHlwZTsKCiAgICB9IGVsc2UgaWYgKGl0ZW0tPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7CgoJLyoKCSogV2UgaGF2ZSBhbiBhdHRyaWJ1dGUgdXNlIGhlcmU7IGFzc2lnbiB0aGUgcmVmZXJlbmNlZAoJKiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCgkqLwoJLyoKCSogVE9ETzogRXZhbHVhdGUsIHdoYXQgZXJyb3JzIGNvdWxkIG9jY3VyIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBub3QKCSogZm91bmQuIEl0IG1pZ2h0IGJlIHBvc3NpYmxlIHRoYXQgdGhlICJ0eXBlZml4dXAiIG1pZ2h0IGNyYXNoIGlmCgkqIG5vIHJlZiBkZWNsYXJhdGlvbiB3YXMgZm91bmQuCgkqLwoJZGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2woY3R4dC0+c2NoZW1hLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zKTsKICAgICAgICBpZiAoZGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkgICAgCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJCSJyZWYiLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zLAoJCVhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJaXRlbS0+cmVmRGVjbCA9IGRlY2w7CiAgICAgICAgeG1sU2NoZW1hQXR0ckZpeHVwKGRlY2wsIGN0eHQsIE5VTEwpOwogICAgICAgIGl0ZW0tPnN1YnR5cGVzID0gZGVjbC0+c3VidHlwZXM7CgkvKgoJKiBBdHRyaWJ1dGUgVXNlIENvcnJlY3QKCSogYXUtcHJvcHMtY29ycmVjdC4yOiBJZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIGEgZml4ZWQKCSoge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGVuIGlmIHRoZSBhdHRyaWJ1dGUgdXNlIGl0c2VsZiBoYXMgYQoJKiB7dmFsdWUgY29uc3RyYWludH0sIGl0IG11c3QgYWxzbyBiZSBmaXhlZCBhbmQgaXRzIHZhbHVlIG11c3QgbWF0Y2gKCSogdGhhdCBvZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0uCgkqLwoJaWYgKChkZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpICYmCgkgICAgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpKSB7CgkgICAgaWYgKChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0FVX1BST1BTX0NPUlJFQ1RfMiwKCQkgICAgTlVMTCwgTlVMTCwgaXRlbS0+bm9kZSwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gaGFzIGEgJ2ZpeGVkJyB2YWx1ZSBjb25zdHJhaW50ICIKCQkgICAgIiwgdGh1cyBpdCBtdXN0IGJlICdmaXhlZCcgaW4gYXR0cmlidXRlIHVzZSBhcyB3ZWxsIiwKCQkgICAgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQlpZiAoISB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChpdGVtLT5kZWZWYWwsIGRlY2wtPmRlZlZhbCkpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9BVV9QUk9QU19DT1JSRUNUXzIsCgkJCU5VTEwsIE5VTEwsIGl0ZW0tPm5vZGUsCgkJCSJUaGUgJ2ZpeGVkJyB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSBhdHRyaWJ1dGUgdXNlICIKCQkJIm11c3QgbWF0Y2ggdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbidzIHZhbHVlICIKCQkJImNvbnN0cmFpbnQgJyVzJyIsCgkJCWRlY2wtPmRlZlZhbHVlKTsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBGVVRVUkU6IE9uZSBzaG91bGQgY2hhbmdlIHRoZSB2YWx1ZXMgb2YgdGhlIGF0dHIuIHVzZQoJICAgICogaWYgZXZlciB2YWxpZGF0aW9uIHNob3VsZCBiZSBhdHRlbXB0ZWQgZXZlbiBpZiB0aGUKCSAgICAqIHNjaGVtYSBpdHNlbGYgd2FzIG5vdCBmdWxseSB2YWxpZC4KCSAgICAqLwoJfQogICAgfSBlbHNlIHsKCWl0ZW0tPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmOgogKiBAaWRjOiAgdGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogUmVzb2x2ZSBrZXlSZWYgcmVmZXJlbmNlcyB0byBrZXkvdW5pcXVlIElEQ3MuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmKHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGlkYy0+cmVmLT5uYW1lICE9IE5VTEwpIHsKCWlkYy0+cmVmLT5pdGVtID0gKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgeG1sSGFzaExvb2t1cDIoCgkgICAgY3R4dC0+c2NoZW1hLT5pZGNEZWYsCgkgICAgaWRjLT5yZWYtPm5hbWUsCgkgICAgaWRjLT5yZWYtPnRhcmdldE5hbWVzcGFjZSk7CiAgICAgICAgaWYgKGlkYy0+cmVmLT5pdGVtID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogSXQgaXMgYWN0dWFsbHkgbm90IGFuIGVycm9yIHRvIGZhaWwgdG8gcmVzb2x2ZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBpZGMsIGlkYy0+bm9kZSwKCQkicmVmZXIiLCBpZGMtPnJlZi0+bmFtZSwKCQlpZGMtPnJlZi0+dGFyZ2V0TmFtZXNwYWNlLAoJCVhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQgPSBOVUxMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBwcmVzZXJ2ZSA9IDA7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYQogICAgKiB0aGUgQVBJOyBpLmUuIG5vdCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgZG9jdW1lbnQuCiAgICAqLwoKICAgIHhtbFNjaGVtYUluaXRUeXBlcygpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IE5VTEw7CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgaWYgKGN0eHQtPlVSTCAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZEZpbGUoKGNvbnN0IGNoYXIgKikgY3R4dC0+VVJMLCBOVUxMLAoJICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgbG9hZCAnJXMnLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5VUkwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoY3R4dC0+YnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkTWVtb3J5KGN0eHQtPmJ1ZmZlciwgY3R4dC0+c2l6ZSwgTlVMTCwgTlVMTCwKCSAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX1BBUlNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgZG9jLT5VUkwgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiKTsKICAgICAgICBjdHh0LT5VUkwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIiwgLTEpOwogICAgfSBlbHNlIGlmIChjdHh0LT5kb2MgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IGN0eHQtPmRvYzsKCXByZXNlcnZlID0gMTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9USElOR19UT19QQVJTRSwKCQkgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZS5cbiIsCgkJICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogVGhlbiBleHRyYWN0IHRoZSByb290IGFuZCBTY2hlbWEgcGFyc2UgaXQKICAgICAqLwogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9ST09ULAoJCSAgICAgICJUaGUgc2NoZW1hIGhhcyBubyBkb2N1bWVudCBlbGVtZW50LlxuIiwgTlVMTCwgTlVMTCk7CglpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFJlbW92ZSBhbGwgdGhlIGJsYW5rIHRleHQgbm9kZXMKICAgICAqLwogICAgeG1sU2NoZW1hQ2xlYW51cERvYyhjdHh0LCByb290KTsKCiAgICAvKgogICAgICogVGhlbiBkbyB0aGUgcGFyc2luZyBmb3IgZ29vZAogICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZVNjaGVtYShjdHh0LCByb290KTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5wcmVzZXJ2ZSA9IHByZXNlcnZlOwogICAgY3R4dC0+c2NoZW1hID0gcmV0OwogICAgY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CgogICAgLyoKICAgICogUmVzb2x2ZSBiYXNlIHR5cGVzIG9mIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hUmVzb2x2ZVR5cGVEZWZzLCBjdHh0KTsKCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdDsKCiAgICBpZiAocmV0LT52b2xhdGlsZXMgIT0gTlVMTCkgewoJeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCA9ICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgcmV0LT52b2xhdGlsZXM7CglpbnQgaTsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJICAgIGl0ZW0gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGxpc3QtPml0ZW1zW2ldOwoJICAgIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkKCQl4bWxTY2hlbWFNaXNjUmVmRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7Cgl9CiAgICB9CiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyRml4dXAsIGN0eHQpOwogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZ3JvdXAgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckdycEZpeHVwLAogICAgICAgICAgICAgICAgY3R4dCk7CiAgICAvKgogICAgKiBSZXNvbHZlIGlkZW50aXR5LWNvbnN0cmFpbnQga2V5UmVmcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmlkY0RlZiwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmLCBjdHh0KTsKICAgIC8qCiAgICAqIENoZWNrIHR5cGUgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpCgl4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhciwgY3R4dCk7CiAgICAvKgogICAgKiBDaGVjayBtb2RlbCBncm91cHMgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKQoJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyLCBjdHh0KTsKICAgIC8qCiAgICAqIFNldCB0aGUgInRlcm0iIG9mIHBhcnRpY2xlcyBwb2ludGluZyB0byBtb2RlbCBncm91cCBkZWZpbml0aW9ucwogICAgKiB0byB0aGUgY29udGFpbmVkIG1vZGVsIGdyb3VwLgogICAgKi8KICAgIGlmIChyZXQtPnZvbGF0aWxlcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0ID0gKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSByZXQtPnZvbGF0aWxlczsKCWludCBpOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbTsKCglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgaXRlbSA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgbGlzdC0+aXRlbXNbaV07CgkgICAgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFKQoJCXhtbFNjaGVtYUdyb3VwRGVmVGVybUZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOwoJfQogICAgfQogICAgLyoKICAgICogQ2hlY2sgYXR0cmlidXRlIGdyb3VwcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpCgl4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIsIGN0eHQpOwogICAgLyoKICAgICAqIFRoZW4gZml4IHJlZmVyZW5jZXMgb2YgZWxlbWVudCBkZWNsYXJhdGlvbjsgYXBwbHkgY29uc3RyYWludHMuCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuRnVsbChyZXQtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYUVsZW1lbnRGaXh1cCwgY3R4dCk7CiAgICAvKgogICAgKiBXZSB3aWxsIHN0b3AgaGVyZSBpZiB0aGUgc2NoZW1hIHdhcyBub3QgdmFsaWQgdG8gYXZvaWQgaW50ZXJuYWwgZXJyb3JzCiAgICAqIG9uIG1pc3Npbmcgc3ViLWNvbXBvbmVudHMuIFRoaXMgaXMgbm90IGNvbmZvcm1pbmcgdG8gdGhlIHNwZWMsIHNpbmNlIGl0CiAgICAqIGFsbG93cyBtaXNzaW5nIGNvbXBvbmVudHMsIGJ1dCBpdCBtaWdodCBtYWtlIGZ1cnRoZXIgcHJvY2Vzc2luZyBjcmFzaC4KICAgICogU28gc2VlIGl0IGFzIGEgdmVyeSBzdHJpY3QgaGFuZGxpbmcsIHdoaWNoIG1pZ2h0IGJlIG1hZGUgbW9yZSBsYXggaW4gdGhlCiAgICAqIGZ1dHVyZS4KICAgICovCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdDsKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUZpeHVwLCBjdHh0KTsKICAgIC8qCiAgICAqIFZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMvdXNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgY3R4dCk7CiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmVsZW1EZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQsIGN0eHQpOwoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0OwoKICAgIC8qCiAgICAqIFRPRE86IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQsIGNvcy1hbGwtbGltaXRlZAogICAgKgogICAgKiBUaGVuIGJ1aWxkIHRoZSBjb250ZW50IG1vZGVsIGZvciBhbGwgY29tcGxleCB0eXBlcwogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsLCBjdHh0KTsKCmV4aXQ6CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYUZyZWUocmV0KTsKICAgICAgICByZXQgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGNhbGxiYWNrCiAqIEB3YXJuOiAgdGhlIHdhcm5pbmcgY2FsbGJhY2sKICogQGN0eDogIGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcwogKgogKiBTZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9ucyB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+dXNlckRhdGEgPSBjdHg7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBYTWwtU2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnI6IHRoZSBlcnJvciBjYWxsYmFjayByZXN1bHQKICogQHdhcm46IHRoZSB3YXJuaW5nIGNhbGxiYWNrIHJlc3VsdAogKiBAY3R4OiBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MgcmVzdWx0CiAqCiAqIEdldCB0aGUgY2FsbGJhY2sgaW5mb3JtYXRpb24gdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHBhcnNlciBjb250ZXh0CiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLCAwIG90aGVyd2lzZQogKi8KaW50CnhtbFNjaGVtYUdldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKEJBRF9DQVNUICJJbnRlcm5hbCBFcnJvciIpOwp9CgpzdGF0aWMgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZQp4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIC8qCiAgICAqIFRoZSBub3JtYWxpemF0aW9uIHR5cGUgY2FuIGJlIGNoYW5nZWQgb25seSBmb3IgdHlwZXMgd2hpY2ggYXJlIGRlcml2ZWQKICAgICogZnJvbSB4c2Q6c3RyaW5nLgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJLyoKCSogTm90ZSB0aGF0IHdlIGFzc3VtZSBhIHdoaXRlc3BhY2Ugb2YgcHJlc2VydmUgZm9yIGFueVNpbXBsZVR5cGUuCgkqLwoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHx8CgkgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKQoJICAgIHJldHVybihYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUFJFU0VSVkUpOwoJZWxzZSBpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfTk9STVNUUklORykKCSAgICByZXR1cm4oWE1MX1NDSEVNQV9XSElURVNQQUNFX1JFUExBQ0UpOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3CgkgICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvCgkgICAgKiBjb2xsYXBzZQoJICAgICogTm90ZSB0aGF0IHRoaXMgaW5jbHVkZXMgYnVpbHQtaW4gbGlzdCBkYXRhdHlwZXMuCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKTsKCX0KICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKSB7CgkvKgoJKiBGb3IgbGlzdCB0eXBlcyB0aGUgZmFjZXQgIndoaXRlU3BhY2UiIGlzIGZpeGVkIHRvICJjb2xsYXBzZSIuCgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0UpOwogICAgfSBlbHNlIGlmIChWQVJJRVRZX1VOSU9OKHR5cGUpKSB7CglyZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9VTktOT1dOKTsKICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9BVE9NSUModHlwZSkpIHsKCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9QUkVTRVJWRSkKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSk7CgllbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9SRVBMQUNFKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX1JFUExBQ0UpOwoJZWxzZQoJICAgIHJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKTsKICAgIH0KICAgIHJldHVybiAoLTEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU2ltcGxlIHR5cGUgdmFsaWRhdGlvbgkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRE9NIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBvc3RTY2hlbWFBc3NlbWJsZUZpeHVwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaW50IGksIG5iSXRlbXM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sICppdGVtczsKCgogICAgLyoKICAgICogRHVyaW5nIHRoZSBBc3NlbWJsZSBvZiB0aGUgc2NoZW1hIGN0eHQtPmN1ckl0ZW1zIGhhcwogICAgKiBiZWVuIGZpbGxlZCB3aXRoIHRoZSByZWxldmFudCBuZXcgaXRlbXMuIEZpeCB0aG9zZSB1cC4KICAgICovCiAgICBuYkl0ZW1zID0gY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXM7CiAgICBpdGVtcyA9ICh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtczsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQl4bWxTY2hlbWFSZXNvbHZlVHlwZURlZnMoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJCXhtbFNjaGVtYUF0dHJGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCXhtbFNjaGVtYUVsZW1lbnRGaXh1cCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSwgY3R4dCwKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJeG1sU2NoZW1hQXR0ckdycEZpeHVwKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSwKCQkgICAgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEU6CgkJeG1sU2NoZW1hTWlzY1JlZkZpeHVwKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJcmV0dXJuOwogICAgLyoKICAgICogQ2lyY3VsYXJpdHkgY2hlY2tzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCXhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVHcm91cENpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCXJldHVybjsKICAgIC8qCiAgICAqIFNldCB0aGUgInRlcm0iIG9mIHBhcnRpY2xlcyBwb2ludGluZyB0byBtb2RlbCBncm91cCBkZWZpbml0aW9ucwogICAgKiB0byB0aGUgY29udGFpbmVkIG1vZGVsIGdyb3VwLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCWlmICgoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEUpICYmCgkgICAgKCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0pLT5jaGlsZHJlbiAhPSBOVUxMKSAmJgoJICAgICgoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBpdGVtKS0+Y2hpbGRyZW4tPnR5cGUgPT0KCSAgICBYTUxfU0NIRU1BX1RZUEVfR1JPVVApKSB7CgkgICAgeG1sU2NoZW1hR3JvdXBEZWZUZXJtRml4dXAoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBpdGVtLAoJCWN0eHQsIE5VTEwpOwoJfQogICAgfQogICAgLyoKICAgICogRml4dXAgZm9yIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFUeXBlRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJcmV0dXJuOwogICAgLyoKICAgICogVmFsaWRhdGUgdmFsdWUgY29udHJhaW50IHZhbHVlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0sCgkJICAgIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudCgoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSwKCQkgICAgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJcmV0dXJuOwogICAgLyoKICAgICogQnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGNvbXBsZXggdHlwZXMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbChpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogdGhlIGV4aXN0aW5nIHNjaGVtYQogKiBAbm9kZTogdGhlIG5vZGUgdGhhdCBmaXJlZCB0aGUgYXNzZW1ibGluZwogKiBAbnNOYW1lOiB0aGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIG5ldyBzY2hlbWEKICogQGxvY2F0aW9uOiB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbikKewogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TnMsICpvbGR0bnM7CiAgICB4bWxEb2NQdHIgZG9jLCBvbGRkb2M7CiAgICBpbnQgb2xkZmxhZ3MsIHJldCA9IDAsIG9sZElzUzRTOwogICAgeG1sTm9kZVB0ciBkb2NFbGVtOwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKCiAgICAvKgogICAgKiBUaGlzIHNob3VsZCBiZSB1c2VkOgogICAgKiAxLiBvbiA8aW1wb3J0PihzKQogICAgKiAyLiBpZiByZXF1ZXN0ZWQgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZQogICAgKiAzLiBpZiByZXF1ZXN0ZWQgdmlhIHRoZSBBUEkKICAgICovCiAgICBpZiAoKHZjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIENyZWF0ZSBhIHRlbXBvcmFyeSBwYXJzZXIgY29udGV4dC4KICAgICovCiAgICBpZiAoKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSAmJgoJKHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh2Y3R4dCkgPT0gLTEpKQoJcmV0dXJuICgtMSk7CiAgICBwY3R4dCA9IHZjdHh0LT5wY3R4dDsKICAgIC8qCiAgICAqIFNldCB0aGUgY291bnRlciB0byBwcm9kdWNlIHVuaXF1ZSBuYW1lcyBmb3IgYW5vbnltb3VzIGl0ZW1zLgogICAgKi8KICAgIHBjdHh0LT5jb3VudGVyID0gc2NoZW1hLT5jb3VudGVyOwogICAgLyoKICAgICogQWNxdWlyZSB0aGUgc2NoZW1hIGRvY3VtZW50LgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYUFjcXVpcmVTY2hlbWFEb2MoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIHNjaGVtYSwKCW5vZGUsIG5zTmFtZSwgbG9jYXRpb24sICZkb2MsICZ0YXJnZXROcywgMCk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChkb2MgIT0gTlVMTCkKCSAgICB4bWxGcmVlRG9jKGRvYyk7CiAgICB9IGVsc2UgaWYgKGRvYyAhPSBOVUxMKSB7Cglkb2NFbGVtID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKCS8qCgkqIENyZWF0ZSBuZXcgYXNzZW1ibGUgaW5mby4KCSovCglpZiAocGN0eHQtPmFzc2VtYmxlID09IE5VTEwpIHsKCSAgICBwY3R4dC0+YXNzZW1ibGUgPSB4bWxTY2hlbWFOZXdBc3NlbWJsZSgpOwoJICAgIGlmIChwY3R4dC0+YXNzZW1ibGUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJICAgICJNZW1vcnkgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiwgIgoJCSAgICAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7CgkJeG1sRnJlZURvYyhkb2MpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCX0KCS8qCgkqIFNhdmUgYW5kIHJlc2V0IHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCW9sZGZsYWdzID0gc2NoZW1hLT5mbGFnczsKCW9sZHRucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJb2xkZG9jID0gc2NoZW1hLT5kb2M7CglvbGRJc1M0UyA9IHZjdHh0LT5wY3R4dC0+aXNTNFM7CgoJeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyhzY2hlbWEpOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROczsKCWlmICgodGFyZ2V0TnMgIT0gTlVMTCkgJiYKCSAgICB4bWxTdHJFcXVhbCh0YXJnZXROcywgeG1sU2NoZW1hTnMpKSB7CgkgICAgLyoKCSAgICAqIFdlIGFyZSBwYXJzaW5nIHRoZSBzY2hlbWEgZm9yIHNjaGVtYSEKCSAgICAqLwoJICAgIHZjdHh0LT5wY3R4dC0+aXNTNFMgPSAxOwoJfQoJLyogc2NoZW1hLT5uYkN1ckl0ZW1zID0gMDsgKi8KCXBjdHh0LT5zY2hlbWEgPSBzY2hlbWE7CglwY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwoJcGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwoKCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMocGN0eHQsIHNjaGVtYSwgZG9jRWxlbSk7CglpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApIHsKCSAgICB2Y3R4dC0+bmJlcnJvcnMgKz0gcGN0eHQtPm5iZXJyb3JzOwoJICAgIGdvdG8gZmluYWxseTsKCX0KCXhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwocGN0eHQsIHNjaGVtYSwgZG9jRWxlbS0+Y2hpbGRyZW4pOwoJaWYgKHBjdHh0LT5uYmVycm9ycyAhPSAwKSB7CgkgICAgdmN0eHQtPm5iZXJyb3JzICs9IHBjdHh0LT5uYmVycm9yczsKCSAgICBnb3RvIGZpbmFsbHk7Cgl9Cgl4bWxTY2hlbWFQb3N0U2NoZW1hQXNzZW1ibGVGaXh1cChwY3R4dCk7CglpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApCgkgICAgdmN0eHQtPm5iZXJyb3JzICs9IHBjdHh0LT5uYmVycm9yczsKZmluYWxseToKCS8qCgkqIFNldCB0aGUgY291bnRlciBvZiBpdGVtcy4KCSovCglzY2hlbWEtPmNvdW50ZXIgPSBwY3R4dC0+Y291bnRlcjsKCS8qCgkqIEZyZWUgdGhlIGxpc3Qgb2YgYXNzZW1ibGVkIGNvbXBvbmVudHMuCgkqLwoJcGN0eHQtPmFzc2VtYmxlLT5uYkl0ZW1zID0gMDsKCS8qCgkqIFJlc3RvcmUgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJdmN0eHQtPnBjdHh0LT5pc1M0UyA9IG9sZElzUzRTOwoJc2NoZW1hLT5mbGFncyA9IG9sZGZsYWdzOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBvbGR0bnM7CglzY2hlbWEtPmRvYyA9IG9sZGRvYzsKCXJldCA9IHBjdHh0LT5lcnI7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB4bWxTY2hlbWFBdHRySW5mb1B0cgp4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAkJICAgICAgCgkJCSBpbnQgbWV0YVR5cGUpCnsKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybiAoTlVMTCk7CiAgICB7CglpbnQgaTsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoKCWZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJICAgIGlhdHRyID0gdmN0eHQtPmF0dHJJbmZvc1tpXTsKCSAgICBpZiAoaWF0dHItPm1ldGFUeXBlID09IG1ldGFUeXBlKQoJCXJldHVybiAoaWF0dHIpOwoJfQoKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJOgogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRXhwYW5kcyBhbiBleGlzdGluZyBzY2hlbWEgYnkgYW4gYWRkaXRpb25hbCBzY2hlbWEgdXNpbmcKICogdGhlIHhzaTpzY2hlbWFMb2NhdGlvbiBvciB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGUKICogb2YgYW4gaW5zdGFuY2UuIElmIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGlzIHVzZWQsIEBub05hbWVzcGFjZQogKiBtdXN0IGJlIHNldCB0byAxLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kOwogICAgY29uc3QgeG1sQ2hhciAqbnNuYW1lID0gTlVMTCwgKmxvY2F0aW9uOwogICAgaW50IGNvdW50ID0gMDsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgogICAgLyoKICAgICogUGFyc2UgdGhlIHZhbHVlOyB3ZSB3aWxsIGFzc3VtZSBhbiBldmVuIG51bWJlciBvZiB2YWx1ZXMKICAgICogdG8gYmUgZ2l2ZW4gKHRoaXMgaXMgaG93IFhlcmNlcyBhbmQgWFNWIHdvcmspLgogICAgKi8KICAgIGlhdHRyID0geG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfU0NIRU1BX0xPQyk7CiAgICBpZiAoaWF0dHIgPT0gTlVMTCkKCXhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCVhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX05PX05TX1NDSEVNQV9MT0MpOwogICAgaWYgKGlhdHRyID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgY3VyID0gaWF0dHItPnZhbHVlOwogICAgZG8gewoJaWYgKGlhdHRyLT5tZXRhVHlwZSA9PSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DKSB7CgkgICAgLyoKCSAgICAqIEdldCB0aGUgbmFtZXNwYWNlIG5hbWUuCgkgICAgKi8KCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIGNvdW50Kys7CgkgICAgbnNuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+c2NoZW1hLT5kaWN0LCBjdXIsIGVuZCAtIGN1cik7CgkgICAgY3VyID0gZW5kOwoJfQoJLyoKCSogR2V0IHRoZSBVUkkuCgkqLwoJd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJICAgIGN1cisrOwoJZW5kID0gY3VyOwoJd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkgICAgZW5kKys7CglpZiAoZW5kID09IGN1cikKCSAgICBicmVhazsKCWNvdW50Kys7Cglsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwoJY3VyID0gZW5kOwoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHZjdHh0LCB2Y3R4dC0+c2NoZW1hLAoJICAgIGlhdHRyLT5ub2RlLCBuc25hbWUsIGxvY2F0aW9uKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJIiwKCQkiYXNzZW1ibGluZyBzY2hlbWF0YSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfSB3aGlsZSAoKmN1ciAhPSAwKTsKICAgIHJldHVybiAocmV0KTsKfQoKI2RlZmluZSBWQUxfQ1JFQVRFX0RJQ1QgaWYgKHZjdHh0LT5kaWN0ID09IE5VTEwpIHZjdHh0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgY29uc3QgeG1sQ2hhciAqcHJlZml4KQp7CiAgICBpZiAodmN0eHQtPnNheCAhPSBOVUxMKSB7CglpbnQgaSwgajsKCXhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlOwoJCglmb3IgKGkgPSB2Y3R4dC0+ZGVwdGg7IGkgPj0gMDsgaS0tKSB7CgkgICAgaWYgKHZjdHh0LT5lbGVtSW5mb3NbaV0tPm5iTnNCaW5kaW5ncyAhPSAwKSB7CgkJaW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW2ldOwoJCWZvciAoaiA9IDA7IGogPCBpbm9kZS0+bmJOc0JpbmRpbmdzICogMjsgaiArPSAyKSB7CgkJICAgIGlmICgoKHByZWZpeCA9PSBOVUxMKSAmJgoJCQkgICAgKGlub2RlLT5uc0JpbmRpbmdzW2pdID09IE5VTEwpKSB8fAoJCQkoKHByZWZpeCAhPSBOVUxMKSAmJiB4bWxTdHJFcXVhbChwcmVmaXgsCgkJCSAgICBpbm9kZS0+bnNCaW5kaW5nc1tqXSkpKSB7CgoJCQkvKgoJCQkqIE5vdGUgdGhhdCB0aGUgbmFtZXNwYWNlIGJpbmRpbmdzIGFyZSBhbHJlYWR5CgkJCSogaW4gYSBzdHJpbmcgZGljdC4KCQkJKi8KCQkJcmV0dXJuIChpbm9kZS0+bnNCaW5kaW5nc1tqKzFdKTsJCQkKCQkgICAgfQoJCX0KCSAgICB9Cgl9CglyZXR1cm4gKE5VTEwpOwojaWZkZWYgTElCWE1MX1dSSVRFUl9FTkFCTEVECiAgICB9IGVsc2UgaWYgKHZjdHh0LT5yZWFkZXIgIT0gTlVMTCkgewoJeG1sQ2hhciAqbnNOYW1lOwoJCgluc05hbWUgPSB4bWxUZXh0UmVhZGVyTG9va3VwTmFtZXNwYWNlKHZjdHh0LT5yZWFkZXIsIHByZWZpeCk7CglpZiAobnNOYW1lICE9IE5VTEwpIHsKCSAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgoJICAgIFZBTF9DUkVBVEVfRElDVDsKCSAgICByZXQgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5kaWN0LCBuc05hbWUsIC0xKTsKCSAgICB4bWxGcmVlKG5zTmFtZSk7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0dXJuIChOVUxMKTsKI2VuZGlmCiAgICB9IGVsc2UgewoJeG1sTnNQdHIgbnM7CgoJaWYgKCh2Y3R4dC0+aW5vZGUtPm5vZGUgPT0gTlVMTCkgfHwKCSAgICAodmN0eHQtPmlub2RlLT5ub2RlLT5kb2MgPT0gTlVMTCkpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UiLAoJCSJubyBub2RlIG9yIG5vZGUncyBkb2MgYXZhbGlhYmxlIik7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCW5zID0geG1sU2VhcmNoTnModmN0eHQtPmlub2RlLT5ub2RlLT5kb2MsCgkgICAgdmN0eHQtPmlub2RlLT5ub2RlLCBwcmVmaXgpOwoJaWYgKG5zICE9IE5VTEwpCgkgICAgcmV0dXJuIChucy0+aHJlZik7CglyZXR1cm4gKE5VTEwpOwogICAgfQp9CgovKgoqIFRoaXMgb25lIHdvcmtzIG9uIHRoZSBzY2hlbWEgb2YgdGhlIHZhbGlkYXRpb24gY29udGV4dC4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwgCQkJICAKCQkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICB4bWxTY2hlbWFWYWxQdHIgKnZhbCwKCQkJICBpbnQgdmFsTmVlZGVkKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICh2Y3R4dCAmJiAodmN0eHQtPnNjaGVtYSA9PSBOVUxMKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbiIsCgkgICAgImEgc2NoZW1hIGlzIG5lZWRlZCBvbiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0Iik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCAhPSAwKQoJcmV0dXJuIChyZXQpOwogICAgewoJeG1sQ2hhciAqbG9jYWxOYW1lID0gTlVMTDsKCXhtbENoYXIgKnByZWZpeCA9IE5VTEw7CgoJbG9jYWxOYW1lID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwoJaWYgKHByZWZpeCAhPSBOVUxMKSB7CgkgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lID0gTlVMTDsKCgkgICAgaWYgKHZjdHh0ICE9IE5VTEwpIAoJCW5zTmFtZSA9IHhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh2Y3R4dCwgQkFEX0NBU1QgcHJlZml4KTsKCSAgICBlbHNlIGlmIChub2RlICE9IE5VTEwpIHsKCQl4bWxOc1B0ciBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKCQlpZiAobnMgIT0gTlVMTCkKCQkgICAgbnNOYW1lID0gbnMtPmhyZWY7CgkgICAgfSBlbHNlIHsKCQl4bWxGcmVlKHByZWZpeCk7CgkJeG1sRnJlZShsb2NhbE5hbWUpOwoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIGlmIChuc05hbWUgPT0gTlVMTCkgewoJCXhtbEZyZWUocHJlZml4KTsKCQl4bWxGcmVlKGxvY2FsTmFtZSk7CgkJcmV0dXJuICgxKTsKCSAgICB9CgkgICAgaWYgKHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+bm90YURlY2wsIGxvY2FsTmFtZSwKCQluc05hbWUpICE9IE5VTEwpIHsKCQlpZiAodmFsTmVlZGVkICYmICh2YWwgIT0gTlVMTCkpIHsKCQkgICAgKCp2YWwpID0geG1sU2NoZW1hTmV3Tk9UQVRJT05WYWx1ZShCQURfQ0FTVCBsb2NhbE5hbWUsCgkJCUJBRF9DQVNUIHhtbFN0cmR1cChuc05hbWUpKTsKCQkgICAgaWYgKCp2YWwgPT0gTlVMTCkKCQkJcmV0ID0gLTE7CgkJfQoJICAgIH0gZWxzZQoJCXJldCA9IDE7CgkgICAgeG1sRnJlZShwcmVmaXgpOwoJICAgIHhtbEZyZWUobG9jYWxOYW1lKTsKCX0gZWxzZSB7CgkgICAgaWYgKHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+bm90YURlY2wsIHZhbHVlLCBOVUxMKSAhPSBOVUxMKSB7CgkJaWYgKHZhbE5lZWRlZCAmJiAodmFsICE9IE5VTEwpKSB7CgkJICAgICgqdmFsKSA9IHhtbFNjaGVtYU5ld05PVEFUSU9OVmFsdWUoCgkJCUJBRF9DQVNUIHhtbFN0cmR1cCh2YWx1ZSksIE5VTEwpOwoJCSAgICBpZiAoKnZhbCA9PSBOVUxMKQoJCQlyZXQgPSAtMTsKCQl9CgkgICAgfSBlbHNlCgkJcmV0dXJuICgxKTsKCX0KICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqICBWYWxpZGF0aW9uIG9mIGlkZW50aXR5LWNvbnN0cmFpbnRzIChJREMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUF1Z21lbnRJREM6CiAqIEBpZGNEZWY6IHRoZSBJREMgZGVmaW5pdGlvbgogKgogKiBDcmVhdGVzIGFuIGF1Z21lbnRlZCBJREMgZGVmaW5pdGlvbiBpdGVtLgogKgogKiBSZXR1cm5zIHRoZSBpdGVtLCBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF1Z21lbnRJREMoeG1sU2NoZW1hSURDUHRyIGlkY0RlZiwKCQkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKCiAgICBhaWRjID0gKHhtbFNjaGVtYUlEQ0F1Z1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENBdWcpKTsKICAgIGlmIChhaWRjID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkgICAgInhtbFNjaGVtYUF1Z21lbnRJREM6IGFsbG9jYXRpbmcgYW4gYXVnbWVudGVkIElEQyBkZWZpbml0aW9uIiwKCSAgICBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIGFpZGMtPmJ1YmJsZURlcHRoID0gLTE7CiAgICBhaWRjLT5kZWYgPSBpZGNEZWY7CiAgICBhaWRjLT5uZXh0ID0gTlVMTDsKICAgIGlmICh2Y3R4dC0+YWlkY3MgPT0gTlVMTCkKCXZjdHh0LT5haWRjcyA9IGFpZGM7CiAgICBlbHNlIHsKCWFpZGMtPm5leHQgPSB2Y3R4dC0+YWlkY3M7Cgl2Y3R4dC0+YWlkY3MgPSBhaWRjOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDTmV3QmluZGluZzoKICogQGlkY0RlZjogdGhlIElEQyBkZWZpbml0aW9uIG9mIHRoaXMgYmluZGluZwogKgogKiBDcmVhdGVzIGEgbmV3IElEQyBiaW5kaW5nLgogKgogKiBSZXR1cm5zIHRoZSBuZXcgYmluZGluZyBpbiBjYXNlIG9mIHN1Y2NlZWRlZCwgTlVMTCBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIKeG1sU2NoZW1hSURDTmV3QmluZGluZyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmKQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyKSB4bWxNYWxsb2MoCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCSAgICAiYWxsb2NhdGluZyBhIFBTVkkgSURDIGJpbmRpbmcgaXRlbSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDQmluZGluZykpOwogICAgcmV0LT5kZWZpbml0aW9uID0gaWRjRGVmOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIG5vZGUgdGFibGUgaXRlbQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgYW4gSURDIG5vZGUgdGFibGUgaXRlbXMuCiAqIFRoZXkgYXJlIHN0b3JlZCB0byBhdm9pZCBjb3B5aW5nIHRoZW0gaWYgSURDIG5vZGUtdGFibGVzIGFyZSBtZXJnZWQKICogd2l0aCBjb3JyZXNwb25kaW5nIHBhcmVudCBJREMgbm9kZS10YWJsZXMgKGJ1YmJsaW5nKS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZU5vZGVUYWJsZUl0ZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaXRlbSkKewogICAgLyoKICAgICogQWRkIHRvIGdvYmFsIGxpc3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5pZGNOb2RlcyA9PSBOVUxMKSB7Cgl2Y3R4dC0+aWRjTm9kZXMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxNYWxsb2MoMjAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgdGhlIElEQyBub2RlIHRhYmxlIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnNpemVJZGNOb2RlcyA9IDIwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUlkY05vZGVzIDw9IHZjdHh0LT5uYklkY05vZGVzKSB7Cgl2Y3R4dC0+c2l6ZUlkY05vZGVzICo9IDI7Cgl2Y3R4dC0+aWRjTm9kZXMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5pZGNOb2RlcywgdmN0eHQtPnNpemVJZGNOb2RlcyAqCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHZjdHh0LT5pZGNOb2Rlc1t2Y3R4dC0+bmJJZGNOb2RlcysrXSA9IGl0ZW07CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1N0b3JlS2V5OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIGtleQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgYW4gSURDIGtleS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZUtleSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSkKewogICAgLyoKICAgICogQWRkIHRvIGdvYmFsIGxpc3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCXZjdHh0LT5pZGNLZXlzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikKCSAgICB4bWxNYWxsb2MoNDAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIHRoZSBJREMga2V5IHN0b3JhZ2UgbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnNpemVJZGNLZXlzID0gNDA7CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5zaXplSWRjS2V5cyA8PSB2Y3R4dC0+bmJJZGNLZXlzKSB7Cgl2Y3R4dC0+c2l6ZUlkY0tleXMgKj0gMjsKCXZjdHh0LT5pZGNLZXlzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5pZGNLZXlzLCB2Y3R4dC0+c2l6ZUlkY0tleXMgKgoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CglpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgdGhlIElEQyBrZXkgc3RvcmFnZSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICB2Y3R4dC0+aWRjS2V5c1t2Y3R4dC0+bmJJZGNLZXlzKytdID0ga2V5OwoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtOgogKiBAYmluZDogdGhlIElEQyBiaW5kaW5nCiAqIEBudEl0ZW06IHRoZSBub2RlLXRhYmxlIGl0ZW0KICoKICogQXBwZW5kcyB0aGUgSURDIG5vZGUtdGFibGUgaXRlbSB0byB0aGUgYmluZGluZy4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbSh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kLAoJCQkJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbnRJdGVtKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCWJpbmQtPnNpemVOb2RlcyA9IDEwOwoJYmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJImFsbG9jYXRpbmcgYW4gYXJyYXkgb2YgSURDIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfSBlbHNlIGlmIChiaW5kLT5zaXplTm9kZXMgPD0gYmluZC0+bmJOb2RlcykgewoJYmluZC0+c2l6ZU5vZGVzICo9IDI7CgliaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxSZWFsbG9jKGJpbmQtPm5vZGVUYWJsZSwgYmluZC0+c2l6ZU5vZGVzICoKCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmIChiaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkicmUtYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9CiAgICBiaW5kLT5ub2RlVGFibGVbYmluZC0+bmJOb2RlcysrXSA9IG50SXRlbTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmc6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG1hdGNoZXI6IHRoZSBJREMgbWF0Y2hlcgogKgogKiBMb29rcyB1cCBhbiBQU1ZJIElEQyBiaW5kaW5nLCBmb3IgdGhlIElEQyBkZWZpbml0aW9uIGFuZAogKiBvZiB0aGUgZ2l2ZW4gbWF0Y2hlci4gSWYgbm9uZSBmb3VuZCwgYSBuZXcgb25lIGlzIGNyZWF0ZWQKICogYW5kIGFkZGVkIHRvIHRoZSBJREMgdGFibGUuCiAqCiAqIFJldHVybnMgYW4gSURDIGJpbmRpbmcgb3IgTlVMTCBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIKeG1sU2NoZW1hSURDQXF1aXJlQmluZGluZyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbmZvOwoKICAgIGluZm8gPSB2Y3R4dC0+ZWxlbUluZm9zW21hdGNoZXItPmRlcHRoXTsKCiAgICBpZiAoaW5mby0+aWRjVGFibGUgPT0gTlVMTCkgewoJaW5mby0+aWRjVGFibGUgPSB4bWxTY2hlbWFJRENOZXdCaW5kaW5nKG1hdGNoZXItPmFpZGMtPmRlZik7CglpZiAoaW5mby0+aWRjVGFibGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJcmV0dXJuKGluZm8tPmlkY1RhYmxlKTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kID0gTlVMTDsKCgliaW5kID0gaW5mby0+aWRjVGFibGU7CglkbyB7CgkgICAgaWYgKGJpbmQtPmRlZmluaXRpb24gPT0gbWF0Y2hlci0+YWlkYy0+ZGVmKQoJCXJldHVybihiaW5kKTsKCSAgICBpZiAoYmluZC0+bmV4dCA9PSBOVUxMKSB7CgkJYmluZC0+bmV4dCA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcobWF0Y2hlci0+YWlkYy0+ZGVmKTsKCQlpZiAoYmluZC0+bmV4dCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKE5VTEwpOwoJCXJldHVybihiaW5kLT5uZXh0KTsKCSAgICB9CgkgICAgYmluZCA9IGJpbmQtPm5leHQ7Cgl9IHdoaWxlIChiaW5kICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVLZXk6CiAqIEBrZXk6IHRoZSBJREMga2V5CiAqCiAqIEZyZWVzIGFuIElEQyBrZXkgdG9nZXRoZXIgd2l0aCBpdHMgY29tcGlsZWQgdmFsdWUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlS2V5KHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5KQp7CiAgICBpZiAoa2V5LT52YWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShrZXktPnZhbCk7CiAgICB4bWxGcmVlKGtleSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlQmluZGluZzoKICoKICogRnJlZXMgYW4gSURDIGJpbmRpbmcuIE5vdGUgdGhhdCB0aGUgbm9kZSB0YWJsZS1pdGVtcwogKiBhcmUgbm90IGZyZWVkLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgaWYgKGJpbmQtPm5vZGVUYWJsZSAhPSBOVUxMKSB7CglpZiAoYmluZC0+ZGVmaW5pdGlvbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIGludCBpOwoJICAgIC8qCgkgICAgKiBOb2RlLXRhYmxlIGl0ZW1zIGZvciBrZXlyZWZzIGFyZSBub3Qgc3RvcmVkIGdsb2JhbGx5CgkgICAgKiB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0LCBzaW5jZSB0aGV5IGFyZSBub3QgYnViYmxlZC4KCSAgICAqIFdlIG5lZWQgdG8gZnJlZSB0aGVtIGhlcmUuCgkgICAgKi8KCSAgICBmb3IgKGkgPSAwOyBpIDwgYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJeG1sRnJlZShiaW5kLT5ub2RlVGFibGVbaV0tPmtleXMpOwoJCXhtbEZyZWUoYmluZC0+bm9kZVRhYmxlW2ldKTsKCSAgICB9Cgl9Cgl4bWxGcmVlKGJpbmQtPm5vZGVUYWJsZSk7CiAgICB9CiAgICB4bWxGcmVlKGJpbmQpOwp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlOgogKiBAYmluZDogdGhlIGZpcnN0IElEQyBiaW5kaW5nIGluIHRoZSBsaXN0CiAqCiAqIEZyZWVzIGFuIElEQyB0YWJsZSwgaS5lLiBhbGwgdGhlIElEQyBiaW5kaW5ncyBpbiB0aGUgbGlzdC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlEQ0ZyZWVJRENUYWJsZSh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBwcmV2OwoKICAgIHdoaWxlIChiaW5kICE9IE5VTEwpIHsKCXByZXYgPSBiaW5kOwoJYmluZCA9IGJpbmQtPm5leHQ7Cgl4bWxTY2hlbWFJRENGcmVlQmluZGluZyhwcmV2KTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdDoKICogQG1hdGNoZXI6IHRoZSBmaXJzdCBJREMgbWF0Y2hlciBpbiB0aGUgbGlzdAogKgogKiBGcmVlcyBhIGxpc3Qgb2YgSURDIG1hdGNoZXJzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0KHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcikKewogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBuZXh0OwoKICAgIHdoaWxlIChtYXRjaGVyICE9IE5VTEwpIHsKCW5leHQgPSBtYXRjaGVyLT5uZXh0OwoJaWYgKG1hdGNoZXItPmtleVNlcXMgIT0gTlVMTCkgewoJICAgIGludCBpOwoJICAgIGZvciAoaSA9IDA7IGkgPCBtYXRjaGVyLT5zaXplS2V5U2VxczsgaSsrKQoJCWlmIChtYXRjaGVyLT5rZXlTZXFzW2ldICE9IE5VTEwpCgkJICAgIHhtbEZyZWUobWF0Y2hlci0+a2V5U2Vxc1tpXSk7CgkgICAgeG1sRnJlZShtYXRjaGVyLT5rZXlTZXFzKTsKCX0KCXhtbEZyZWUobWF0Y2hlcik7CgltYXRjaGVyID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBtYXRjaGVyOiB0aGUgSURDIG1hdGNoZXIKICogQHNlbDogdGhlIFhQYXRoIGluZm9ybWF0aW9uCiAqIEBwYXJlbnQ6IHRoZSBwYXJlbnQgInNlbGVjdG9yIiBzdGF0ZSBvYmplY3QgaWYgYW55CiAqIEB0eXBlOiAic2VsZWN0b3IiIG9yICJmaWVsZCIKICoKICogQ3JlYXRlcy9yZXVzZXMgYW5kIGFjdGl2YXRlcyBzdGF0ZSBvYmplY3RzIGZvciB0aGUgZ2l2ZW4KICogWFBhdGggaW5mb3JtYXRpb247IGlmIHRoZSBYUGF0aCBleHByZXNzaW9uIGNvbnNpc3RzIG9mIHVuaW9ucywKICogbXVsdGlwbGUgc3RhdGUgb2JqZWN0cyBhcmUgY3JlYXRlZCBmb3IgZXZlcnkgdW5pb25lZCBleHByZXNzaW9uLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCXhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciwKCQkJeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbCwKCQkJaW50IHR5cGUpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bzsKCiAgICAvKgogICAgKiBSZXVzZSB0aGUgc3RhdGUgb2JqZWN0cyBmcm9tIHRoZSBwb29sLgogICAgKi8KICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkgewoJc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVQb29sOwoJdmN0eHQtPnhwYXRoU3RhdGVQb29sID0gc3RvLT5uZXh0OwoJc3RvLT5uZXh0ID0gTlVMTDsKICAgIH0gZWxzZSB7CQoJLyoKCSogQ3JlYXRlIGEgbmV3IHN0YXRlIG9iamVjdC4KCSovCglzdG8gPSAoeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDU3RhdGVPYmopKTsKCWlmIChzdG8gPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkiYWxsb2NhdGluZyBhbiBJREMgc3RhdGUgb2JqZWN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgltZW1zZXQoc3RvLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDU3RhdGVPYmopKTsKICAgIH0JCiAgICAvKgogICAgKiBBZGQgdG8gZ2xvYmFsIGxpc3QuIAogICAgKi8JCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpCglzdG8tPm5leHQgPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CiAgICB2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBzdG87CgogICAgLyoKICAgICogRnJlZSB0aGUgb2xkIHhwYXRoIHZhbGlkYXRpb24gY29udGV4dC4KICAgICovCiAgICBpZiAoc3RvLT54cGF0aEN0eHQgIT0gTlVMTCkKCXhtbEZyZWVTdHJlYW1DdHh0KCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7CgogICAgLyoKICAgICogQ3JlYXRlIGEgbmV3IFhQYXRoIChwYXR0ZXJuKSB2YWxpZGF0aW9uIGNvbnRleHQuCiAgICAqLwogICAgc3RvLT54cGF0aEN0eHQgPSAodm9pZCAqKSB4bWxQYXR0ZXJuR2V0U3RyZWFtQ3R4dCgKCSh4bWxQYXR0ZXJuUHRyKSBzZWwtPnhwYXRoQ29tcCk7CiAgICBpZiAoc3RvLT54cGF0aEN0eHQgPT0gTlVMTCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3QiLAoJICAgICJmYWlsZWQgdG8gY3JlYXRlIGFuIFhQYXRoIHZhbGlkYXRpb24gY29udGV4dCIpOwoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgc3RvLT50eXBlID0gdHlwZTsKICAgIHN0by0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICBzdG8tPm1hdGNoZXIgPSBtYXRjaGVyOwogICAgc3RvLT5zZWwgPSBzZWw7CiAgICBzdG8tPm5iSGlzdG9yeSA9IDA7CiAgICAKI2lmIERFQlVHX0lEQwogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgU1RPIHB1c2ggJyVzJ1xuIiwKCXN0by0+c2VsLT54cGF0aCk7CiNlbmRpZgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVhQYXRoRXZhbHVhdGU6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGVUeXBlOiB0aGUgbm9kZVR5cGUgb2YgdGhlIGN1cnJlbnQgbm9kZQogKgogKiBFdmFsdWF0ZXMgYWxsIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgogKgogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgSUMgImZpZWxkIiBzdGF0ZSBvYmplY3RzIHdoaWNoIHJlc29sdmVkIHRvCiAqIHRoaXMgbm9kZSwgMCBpZiBub25lIHJlc29sdmVkIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgICAgICB4bWxFbGVtZW50VHlwZSBub2RlVHlwZSkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvLCBoZWFkID0gTlVMTCwgZmlyc3Q7CiAgICBpbnQgcmVzLCByZXNvbHZlZCA9IDAsIGRlcHRoID0gdmN0eHQtPmRlcHRoOwogICAgICAgIAogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKCiAgICBpZiAobm9kZVR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJZGVwdGgrKzsKI2lmIERFQlVHX0lEQwogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAKCSAgICAiSURDOiBFVkFMIG9uICVzLCBkZXB0aCAlZCwgdHlwZSAlZFxuIiwJICAgIAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSwgZGVwdGgsIG5vZGVUeXBlKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYKICAgIC8qCiAgICAqIFByb2Nlc3MgYWxsIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgogICAgKi8KICAgIGZpcnN0ID0gdmN0eHQtPnhwYXRoU3RhdGVzOwogICAgc3RvID0gZmlyc3Q7CiAgICB3aGlsZSAoc3RvICE9IGhlYWQpIHsKI2lmIERFQlVHX0lEQwoJaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgWyclcyddIHNlbGVjdG9yICclcydcbiIsIAoJCXN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5uYW1lLCBzdG8tPnNlbC0+eHBhdGgpOwoJZWxzZQoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFsnJXMnXSBmaWVsZCAnJXMnXG4iLCAKCQlzdG8tPm1hdGNoZXItPmFpZGMtPmRlZi0+bmFtZSwgc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICByZXMgPSB4bWxTdHJlYW1QdXNoKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoJZWxzZQoJICAgIHJlcyA9IHhtbFN0cmVhbVB1c2hBdHRyKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoKCWlmIChyZXMgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aEV2YWx1YXRlIiwKCQkiY2FsbGluZyB4bWxTdHJlYW1QdXNoKCkiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWlmIChyZXMgPT0gMCkKCSAgICBnb3RvIG5leHRfc3RvOwoJLyoKCSogRnVsbCBtYXRjaC4KCSovCiNpZiBERUJVR19JREMKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgICAgIgoJICAgICJNQVRDSFxuIik7CiNlbmRpZgoJLyoKCSogUmVnaXN0ZXIgYSBtYXRjaCBpbiB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkuCgkqLwoJaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkgICAgc3RvLT5oaXN0b3J5ID0gKGludCAqKSB4bWxNYWxsb2MoNSAqIHNpemVvZihpbnQpKTsKCSAgICBpZiAoc3RvLT5oaXN0b3J5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAiYWxsb2NhdGluZyB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkiLCBOVUxMKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICBzdG8tPnNpemVIaXN0b3J5ID0gMTA7Cgl9IGVsc2UgaWYgKHN0by0+c2l6ZUhpc3RvcnkgPD0gc3RvLT5uYkhpc3RvcnkpIHsKCSAgICBzdG8tPnNpemVIaXN0b3J5ICo9IDI7CgkgICAgc3RvLT5oaXN0b3J5ID0gKGludCAqKSB4bWxSZWFsbG9jKHN0by0+aGlzdG9yeSwKCQlzdG8tPnNpemVIaXN0b3J5ICogc2l6ZW9mKGludCkpOwoJICAgIGlmIChzdG8tPmhpc3RvcnkgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJyZS1hbGxvY2F0aW5nIHRoZSBzdGF0ZSBvYmplY3QgaGlzdG9yeSIsIE5VTEwpOwoJCXJldHVybigtMSk7CgkgICAgfQoJfQkJCglzdG8tPmhpc3Rvcnlbc3RvLT5uYkhpc3RvcnkrK10gPSBkZXB0aDsKCiNpZmRlZiBERUJVR19JREMKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgICAgICBwdXNoIG1hdGNoICclZCdcbiIsCgkgICAgdmN0eHQtPmRlcHRoKTsKI2VuZGlmCgoJaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpIHsKCSAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsOwoJICAgIC8qCgkgICAgKiBBY3RpdmF0ZSBzdGF0ZSBvYmplY3RzIGZvciB0aGUgSURDIGZpZWxkcyBvZgoJICAgICogdGhlIElEQyBzZWxlY3Rvci4KCSAgICAqLwojaWYgREVCVUdfSURDCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgICAiCgkJImFjdGl2YXRpbmcgZmllbGQgc3RhdGVzXG4iKTsKI2VuZGlmCgkgICAgc2VsID0gc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYtPmZpZWxkczsKCSAgICB3aGlsZSAoc2VsICE9IE5VTEwpIHsKCQlpZiAoeG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3QodmN0eHQsIHN0by0+bWF0Y2hlciwKCQkgICAgc2VsLCBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQpID09IC0xKQoJCSAgICByZXR1cm4gKC0xKTsKCQlzZWwgPSBzZWwtPm5leHQ7CgkgICAgfQoJfSBlbHNlIGlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSB7CgkgICAgLyoKCSAgICAqIEFuIElEQyBrZXkgbm9kZSB3YXMgZm91bmQgYnkgdGhlIElEQyBmaWVsZC4KCSAgICAqLwojaWYgREVCVUdfSURDCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJIklEQzogICAgIGtleSBmb3VuZFxuIik7CiNlbmRpZgoJICAgIC8qCgkgICAgKiBOb3RpZnkgdGhhdCB0aGUgY2hhcmFjdGVyIHZhbHVlIG9mIHRoaXMgbm9kZSBpcwoJICAgICogbmVlZGVkLgoJICAgICovCgkgICAgaWYgKHJlc29sdmVkID09IDApIHsKCQlpZiAoKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BX05PREVfSU5GT19WQUxVRV9ORUVERUQpID09IDApCgkJdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19WQUxVRV9ORUVERUQ7CgkgICAgfQoJICAgIHJlc29sdmVkKys7Cgl9Cm5leHRfc3RvOgoJaWYgKHN0by0+bmV4dCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEV2YWx1YXRlIGZpZWxkIHN0YXRlIG9iamVjdHMgY3JlYXRlZCBvbiB0aGlzIG5vZGUgYXMgd2VsbC4KCSAgICAqLwoJICAgIGhlYWQgPSBmaXJzdDsKCSAgICBzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7Cgl9IGVsc2UKCSAgICBzdG8gPSBzdG8tPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKHJlc29sdmVkKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGb3JtYXRJRENLZXlTZXF1ZW5jZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgIHhtbENoYXIgKipidWYsCgkJCSAgICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKnNlcSwKCQkJICAgICAgaW50IGNvdW50KQp7CiAgICBpbnQgaSwgcmVzOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwoKICAgICpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIlsiKTsKICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CglyZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlV2h0c3Aoc2VxW2ldLT52YWwsICZ2YWx1ZSwKCSAgICB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZShzZXFbaV0tPnR5cGUpKTsKCWlmIChyZXMgPT0gMCkKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIHZhbHVlKTsKCWVsc2UgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUZvcm1hdElEQ0tleVNlcXVlbmNlIiwKCQkiZmFpbGVkIHRvIGNvbXB1dGUgYSBjYW5vbmljYWwgdmFsdWUiKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI/Pz8iKTsKCX0KCWlmIChpIDwgY291bnQgLTEpCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJywgIik7CgllbHNlCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJaWYgKHZhbHVlICE9IE5VTEwpIHsKCSAgICB4bWxGcmVlKCh4bWxDaGFyICopIHZhbHVlKTsKCSAgICB2YWx1ZSA9IE5VTEw7Cgl9CiAgICB9CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICJdIik7CgogICAgcmV0dXJuIChCQURfQ0FTVCAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3Rvcnk6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6IHRoZSBzaW1wbGUvY29tcGxleCB0eXBlIG9mIHRoZSBjdXJyZW50IG5vZGUgaWYgYW55IGF0IGFsbAogKiBAdmFsOiB0aGUgcHJlY29tcGlsZWQgdmFsdWUKICoKICogUHJvY2Vzc2VzIGFuZCBwb3BzIHRoZSBoaXN0b3J5IGl0ZW1zIG9mIHRoZSBJREMgc3RhdGUgb2JqZWN0cy4KICogSURDIGtleS1zZXF1ZW5jZXMgYXJlIHZhbGlkYXRlZC9jcmVhdGVkIG9uIElEQyBiaW5kaW5ncy4KICogCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgIGludCBkZXB0aCkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvLCBuZXh0c3RvOwogICAgaW50IHJlcywgbWF0Y2hEZXB0aDsKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5ID0gTlVMTDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSA9IHZjdHh0LT5pbm9kZS0+dHlwZURlZjsKCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwoKI2lmIERFQlVHX0lEQwogICAgewoJeG1sQ2hhciAqc3RyID0gTlVMTDsKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAKCSAgICAiSURDOiBCQUNLIG9uICVzLCBkZXB0aCAlZFxuIiwKCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSksIHZjdHh0LT5kZXB0aCk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmICAgIAogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIHN0YXRlIG9iamVjdHMuCiAgICAqLwogICAgd2hpbGUgKHN0byAhPSBOVUxMKSB7CglyZXMgPSB4bWxTdHJlYW1Qb3AoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCWlmIChyZXMgPT0gLTEpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5IiwKCQkiY2FsbGluZyB4bWxTdHJlYW1Qb3AoKSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQojaWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBzdHJlYW0gcG9wICclcydcbiIsCgkgICAgc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCglpZiAoc3RvLT5uYkhpc3RvcnkgPT0gMCkKCSAgICBnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgoJbWF0Y2hEZXB0aCA9IHN0by0+aGlzdG9yeVtzdG8tPm5iSGlzdG9yeSAtMV07CgoJLyoKCSogT25seSBtYXRjaGVzIGF0IHRoZSBjdXJyZW50IGRlcHRoIGFyZSBvZiBpbnRlcmVzdC4KCSovCglpZiAobWF0Y2hEZXB0aCAhPSBkZXB0aCkgewoJICAgIHN0byA9IHN0by0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0JCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgewoJICAgIGlmICghIElTX1NJTVBMRV9UWVBFKHR5cGUpKSB7CgkJLyoKCQkqIE5vdCBxdWFsaWZpZWQgaWYgdGhlIGZpZWxkIHJlc29sdmVzIHRvIGEgbm9kZSBvZiBub24KCQkqIHNpbXBsZSB0eXBlLgoJCSovCQoJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0lEQywgTlVMTCwJCSAgICAKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLAoJCSAgICAiVGhlIGZpZWxkICclcycgZG9lcyBldmFsdWF0ZSB0byBhIG5vZGUgb2YgIgoJCSAgICAibm9uLXNpbXBsZSB0eXBlIiwgc3RvLT5zZWwtPnhwYXRoLCBOVUxMKTsKCQkKCQlzdG8tPm5iSGlzdG9yeS0tOwoJCWdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCSAgICB9CgkgICAgaWYgKChrZXkgPT0gTlVMTCkgJiYgKHZjdHh0LT5pbm9kZS0+dmFsID09IE5VTEwpKSB7CgkJLyoKCQkqIEZhaWxlZCB0byBwcm92aWRlIHRoZSBub3JtYWxpemVkIHZhbHVlOyBtYXliZQoJCSogdGhlIHZhbHVlIHdhcyBpbnZhbGlkLgoJCSovCgkJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJICAgICh4bWxTY2hlbWFUeXBlUHRyKSBzdG8tPm1hdGNoZXItPmFpZGMtPmRlZiwKCQkgICAgIldhcm5pbmc6IE5vIHByZWNvbXB1dGVkIHZhbHVlIGF2YWlsYWJsZSwgdGhlIHZhbHVlICIKCQkgICAgIndhcyBlaXRoZXIgaW52YWxpZCBvciBzb21ldGhpbmcgc3RyYW5nZSBoYXBwZW5kIik7CgkJc3RvLT5uYkhpc3RvcnktLTsKCQlnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIgPSBzdG8tPm1hdGNoZXI7CgkJeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5U2VxOwoJCWludCBwb3MsIGlkeDsKCQkKCQkvKgoJCSogVGhlIGtleSB3aWxsIGJlIGFuY2hvcmVkIG9uIHRoZSBtYXRjaGVyJ3MgbGlzdCBvZgoJCSoga2V5LXNlcXVlbmNlcy4gVGhlIHBvc2l0aW9uIGluIHRoaXMgbGlzdCBpcyBkZXRlcm1pbmVkCgkJKiBieSB0aGUgdGFyZ2V0IG5vZGUncyBkZXB0aCByZWxhdGl2ZSB0byB0aGUgbWF0Y2hlcidzCgkJKiBkZXB0aCBvZiBjcmVhdGlvbiAoaS5lLiB0aGUgZGVwdGggb2YgdGhlIHNjb3BlIGVsZW1lbnQpLgoJCSovCQkgICAgCgkJcG9zID0gc3RvLT5kZXB0aCAtIG1hdGNoZXItPmRlcHRoOwoJCWlkeCA9IHN0by0+c2VsLT5pbmRleDsKCQkKCQkvKgoJCSogQ3JlYXRlL2dyb3cgdGhlIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMuCgkJKi8KCQlpZiAobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB7CgkJICAgIGlmIChwb3MgPiA5KSAKCQkJbWF0Y2hlci0+c2l6ZUtleVNlcXMgPSBwb3MgKiAyOwoJCSAgICBlbHNlCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzID0gMTA7CgkJICAgIG1hdGNoZXItPmtleVNlcXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKikgCgkJCXhtbE1hbGxvYyhtYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsJCQkKCQkgICAgaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewkJCgkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkJICAgICJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybigtMSk7CgkJICAgIH0KCQkgICAgbWVtc2V0KG1hdGNoZXItPmtleVNlcXMsIDAsCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikpOwoJCX0gZWxzZSBpZiAocG9zID49IG1hdGNoZXItPnNpemVLZXlTZXFzKSB7CQoJCSAgICBpbnQgaSA9IG1hdGNoZXItPnNpemVLZXlTZXFzOwoJCSAgICAKCQkgICAgbWF0Y2hlci0+c2l6ZUtleVNlcXMgKj0gMjsKCQkgICAgbWF0Y2hlci0+a2V5U2VxcyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqKQoJCQl4bWxSZWFsbG9jKG1hdGNoZXItPmtleVNlcXMsCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikpOwoJCSAgICBpZiAobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkJICAgICJyZWFsbG9jYXRpbmcgYW4gYXJyYXkgb2Yga2V5LXNlcXVlbmNlcyIsCgkJCSAgICBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBUaGUgYXJyYXkgbmVlZHMgdG8gYmUgTlVMTGVkLgoJCSAgICAqIFRPRE86IFVzZSBtZW1zZXQ/CgkJICAgICovCgkJICAgIGZvciAoOyBpIDwgbWF0Y2hlci0+c2l6ZUtleVNlcXM7IGkrKykgCgkJCW1hdGNoZXItPmtleVNlcXNbaV0gPSBOVUxMOwkJCQoJCX0KCQkKCQkvKgoJCSogR2V0L2NyZWF0ZSB0aGUga2V5LXNlcXVlbmNlLgoJCSovCgkJa2V5U2VxID0gbWF0Y2hlci0+a2V5U2Vxc1twb3NdOwkJICAgIAoJCWlmIChrZXlTZXEgPT0gTlVMTCkgewkKCQkgICAgZ290byBjcmVhdGVfc2VxdWVuY2U7CgkJfSBlbHNlIHsKCQkgICAgaWYgKGtleVNlcVtpZHhdICE9IE5VTEwpIHsKCQkJLyoKCQkJKiBjdmMtaWRlbnRpdHktY29uc3RyYWludDoKCQkJKiAzIEZvciBlYWNoIG5vZGUgaW4gdGhlILd0YXJnZXQgbm9kZSBzZXS3IGFsbAoJCQkqIG9mIHRoZSB7ZmllbGRzfSwgd2l0aCB0aGF0IG5vZGUgYXMgdGhlIGNvbnRleHQKCQkJKiBub2RlLCBldmFsdWF0ZSB0byBlaXRoZXIgYW4gZW1wdHkgbm9kZS1zZXQgb3IKCQkJKiBhIG5vZGUtc2V0IHdpdGggZXhhY3RseSBvbmUgbWVtYmVyLCB3aGljaCBtdXN0CgkJCSogaGF2ZSBhIHNpbXBsZSB0eXBlLgoJCQkqIAoJCQkqIFRoZSBrZXkgd2FzIGFscmVhZHkgc2V0OyByZXBvcnQgYW4gZXJyb3IuCgkJCSovCgkJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAoJCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIG1hdGNoZXItPmFpZGMtPmRlZiwKCQkJICAgICJUaGUgZmllbGQgJyVzJyBldmFsdWF0ZXMgdG8gYSBub2RlLXNldCAiCgkJCSAgICAid2l0aCBtb3JlIHRoYW4gb25lIG1lbWJlciIsCgkJCSAgICBzdG8tPnNlbC0+eHBhdGgsIE5VTEwpOwoJCQlzdG8tPm5iSGlzdG9yeS0tOwoJCQlnb3RvIGRlcmVnaXN0ZXJfY2hlY2s7CgkJICAgIH0gZWxzZSB7CgkJCWdvdG8gY3JlYXRlX2tleTsKCQkgICAgfQoJCX0KCQkKY3JlYXRlX3NlcXVlbmNlOgoJCS8qCgkJKiBDcmVhdGUgYSBrZXktc2VxdWVuY2UuCgkJKi8KCQlrZXlTZXEgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSB4bWxNYWxsb2MoCgkJICAgIG1hdGNoZXItPmFpZGMtPmRlZi0+bmJGaWVsZHMgKiAKCQkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCQlpZiAoa2V5U2VxID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkJImFsbG9jYXRpbmcgYW4gSURDIGtleS1zZXF1ZW5jZSIsIE5VTEwpOwoJCSAgICByZXR1cm4oLTEpOwkJCQoJCX0JCgkJbWVtc2V0KGtleVNlcSwgMCwgbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkcyAqIAoJCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJCW1hdGNoZXItPmtleVNlcXNbcG9zXSA9IGtleVNlcTsKY3JlYXRlX2tleToKCQkvKgoJCSogQ3JlYXRlZCBhIGtleSBvbmNlIHBlciBub2RlIG9ubHkuCgkJKi8gIAoJCWlmIChrZXkgPT0gTlVMTCkgewoJCSAgICBrZXkgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikgeG1sTWFsbG9jKAoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleSkpOwoJCSAgICBpZiAoa2V5ID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCQkgICAgImFsbG9jYXRpbmcgYSBJREMga2V5IiwgTlVMTCk7CgkJCXhtbEZyZWUoa2V5U2VxKTsKCQkJbWF0Y2hlci0+a2V5U2Vxc1twb3NdID0gTlVMTDsKCQkJcmV0dXJuKC0xKTsJCQkKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIENvbnN1bWUgdGhlIGNvbXBpbGVkIHZhbHVlLgoJCSAgICAqLwoJCSAgICBrZXktPnR5cGUgPSB0eXBlOwoJCSAgICBrZXktPnZhbCA9IHZjdHh0LT5pbm9kZS0+dmFsOwoJCSAgICB2Y3R4dC0+aW5vZGUtPnZhbCA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogU3RvcmUgdGhlIGtleSBpbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hSURDU3RvcmVLZXkodmN0eHQsIGtleSkgPT0gLTEpIHsKCQkJeG1sU2NoZW1hSURDRnJlZUtleShrZXkpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0KCQlrZXlTZXFbaWR4XSA9IGtleTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpIHsKCQkKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxID0gTlVMTDsKCSAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOwoJICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG50SXRlbTsKCSAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7CgkgICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKCSAgICBpbnQgcG9zLCBpLCBqLCBuYktleXM7CgkgICAgLyoKCSAgICAqIEhlcmUgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIHNjZW5hcmlvOgoJICAgICogQW4gSURDICdzZWxlY3Rvcicgc3RhdGUgb2JqZWN0IHJlc29sdmVkIHRvIGEgdGFyZ2V0IG5vZGUsCgkgICAgKiBkdXJpbmcgdGhlIHRpbWUgdGhpcyB0YXJnZXQgbm9kZSB3YXMgaW4gdGhlIAoJICAgICogYW5jZXN0b3Itb3Itc2VsZiBheGlzLCB0aGUgJ2ZpZWxkJyBzdGF0ZSBvYmplY3QocykgbG9va2VkIAoJICAgICogb3V0IGZvciBtYXRjaGluZyBub2RlcyB0byBjcmVhdGUgYSBrZXktc2VxdWVuY2UgZm9yIHRoaXMgCgkgICAgKiB0YXJnZXQgbm9kZS4gTm93IHdlIGFyZSBiYWNrIHRvIHRoaXMgdGFyZ2V0IG5vZGUgYW5kIG5lZWQKCSAgICAqIHRvIHB1dCB0aGUga2V5LXNlcXVlbmNlLCB0b2dldGhlciB3aXRoIHRoZSB0YXJnZXQgbm9kZSAKCSAgICAqIGl0c2VsZiwgaW50byB0aGUgbm9kZS10YWJsZSBvZiB0aGUgY29ycmVzcG9uZGluZyBJREMgCgkgICAgKiBiaW5kaW5nLgoJICAgICovCgkgICAgbWF0Y2hlciA9IHN0by0+bWF0Y2hlcjsKCSAgICBpZGMgPSBtYXRjaGVyLT5haWRjLT5kZWY7CgkgICAgbmJLZXlzID0gaWRjLT5uYkZpZWxkczsKCSAgICBwb3MgPSBkZXB0aCAtIG1hdGNoZXItPmRlcHRoOwkJCgkgICAgLyoKCSAgICAqIENoZWNrIGlmIHRoZSBtYXRjaGVyIGhhcyBhbnkga2V5LXNlcXVlbmNlcyBhdCBhbGwsIHBsdXMKCSAgICAqIGlmIGl0IGhhcyBhIGtleS1zZXF1ZW5jZSBmb3IgdGhlIGN1cnJlbnQgdGFyZ2V0IG5vZGUuCgkgICAgKi8JCQoJICAgIGlmICgobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB8fAoJCShtYXRjaGVyLT5zaXplS2V5U2VxcyA8PSBwb3MpKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBrZXlTZXEgPSAmKG1hdGNoZXItPmtleVNlcXNbcG9zXSk7CQkKCSAgICBpZiAoKmtleVNlcSA9PSBOVUxMKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBmb3IgKGkgPSAwOyBpIDwgbmJLZXlzOyBpKyspIHsKCQlpZiAoKCprZXlTZXEpW2ldID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBOb3QgcXVhbGlmaWVkLCBpZiBub3QgYWxsIGZpZWxkcyBkaWQgcmVzb2x2ZS4KCQkgICAgKi8KCQkgICAgaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkgewoJCQkvKgoJCQkqIEFsbCBmaWVsZHMgb2YgYSAia2V5IiBJREMgbXVzdCByZXNvbHZlLgoJCQkqLwoJCQlnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQkgICAgfQkJICAgIAoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEFsbCBmaWVsZHMgZGlkIHJlc29sdmUuCgkgICAgKi8KCSAgICAKCSAgICAvKgoJICAgICogNC4xIElmIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBjYXRlZ29yeX0gaXMgdW5pcXVlKC9rZXkpLAoJICAgICogdGhlbiBubyB0d28gbWVtYmVycyBvZiB0aGUgt3F1YWxpZmllZCBub2RlIHNldLcgaGF2ZQoJICAgICogt2tleS1zZXF1ZW5jZXO3IHdob3NlIG1lbWJlcnMgYXJlIHBhaXJ3aXNlIGVxdWFsLCBhcwoJICAgICogZGVmaW5lZCBieSBFcXVhbCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCgkgICAgKgoJICAgICogR2V0IHRoZSBJREMgYmluZGluZyBmcm9tIHRoZSBtYXRjaGVyIGFuZCBjaGVjayBmb3IKCSAgICAqIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2VzLgoJICAgICovCgkgICAgYmluZCA9IHhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmcodmN0eHQsIG1hdGNoZXIpOwoJICAgIGlmICgoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSAmJiAKCQkoYmluZC0+bmJOb2RlcyAhPSAwKSkgewoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgY2tleSwgYmtleSwgKmJrZXlTZXE7CgkJCgkJaSA9IDA7CgkJcmVzID0gMDsKCQkvKgoJCSogQ29tcGFyZSB0aGUga2V5LXNlcXVlbmNlcywga2V5IGJ5IGtleS4KCQkqLwoJCWRvIHsKCQkgICAgYmtleVNlcSA9IGJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5czsJCSAgICAKCQkgICAgZm9yIChqID0gMDsgaiA8IG5iS2V5czsgaisrKSB7CgkJCWNrZXkgPSAoKmtleVNlcSlbal07CgkJCWJrZXkgPSBia2V5U2VxW2pdOwkJCQkJCQkKCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoY2tleS0+dmFsLCBia2V5LT52YWwpOwoJCQlpZiAocmVzID09IC0xKSB7CgkJCSAgICByZXR1cm4gKC0xKTsKCQkJfSBlbHNlIGlmIChyZXMgPT0gMCkKCQkJICAgIGJyZWFrOwoJCSAgICB9CgkJICAgIGlmIChyZXMgPT0gMSkgewoJCQkvKgoJCQkqIER1cGxpY2F0ZSBmb3VuZC4KCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgaSsrOwoJCX0gd2hpbGUgKGkgPCBiaW5kLT5uYk5vZGVzKTsKCQlpZiAoaSAhPSBiaW5kLT5uYk5vZGVzKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIC8qICAgCgkJICAgICogVE9ETzogVHJ5IHRvIHJlcG9ydCB0aGUga2V5LXNlcXVlbmNlLgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgaWRjLAoJCQkiRHVwbGljYXRlIGtleS1zZXF1ZW5jZSAlcyIsCgkJCXhtbFNjaGVtYUZvcm1hdElEQ0tleVNlcXVlbmNlKHZjdHh0LCAmc3RyLAoJCQkgICAgKCprZXlTZXEpLCBuYktleXMpLCBOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogQWRkIGEgbm9kZS10YWJsZSBpdGVtIHRvIHRoZSBJREMgYmluZGluZy4KCSAgICAqLwoJICAgIG50SXRlbSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgeG1sTWFsbG9jKAoJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZSkpOwoJICAgIGlmIChudEl0ZW0gPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIElEQyBub2RlLXRhYmxlIGl0ZW0iLCBOVUxMKTsKCQl4bWxGcmVlKCprZXlTZXEpOwoJCSprZXlTZXEgPSBOVUxMOwoJCXJldHVybigtMSk7CgkgICAgfQkKCSAgICBtZW1zZXQobnRJdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGUpKTsJCQoJICAgIAoJICAgIC8qIAoJICAgICogU3RvcmUgdGhlIG5vZGUtdGFibGUgaXRlbSBvbiBnbG9iYWwgbGlzdC4KCSAgICAqLwoJICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCQlpZiAoeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtKHZjdHh0LCBudEl0ZW0pID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEluaXQgdGhlIG5vZGUtdGFibGUgaXRlbS4gQ29uc3VtZSB0aGUga2V5LXNlcXVlbmNlLgoJICAgICovCgkgICAgbnRJdGVtLT5ub2RlID0gdmN0eHQtPm5vZGU7CgkgICAgbnRJdGVtLT5rZXlzID0gKmtleVNlcTsKCSAgICAqa2V5U2VxID0gTlVMTDsKCSAgICBpZiAoeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbShiaW5kLCBudEl0ZW0pID09IC0xKSB7CQkgICAgCgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJCSAgICAvKiAKCQkgICAgKiBGcmVlIHRoZSBpdGVtLCBzaW5jZSBrZXlyZWYgaXRlbXMgd29uJ3QgYmUKCQkgICAgKiBwdXQgb24gYSBnbG9iYWwgbGlzdC4KCQkgICAgKi8KCQkgICAgeG1sRnJlZShudEl0ZW0tPmtleXMpOwoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJfQoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAKCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwpzZWxlY3Rvcl9rZXlfZXJyb3I6CgkgICAgLyoKCSAgICAqIDQuMi4xIChLRVkpIFRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbmQgdGhlIAoJICAgICogt3F1YWxpZmllZCBub2RlIHNldLcgYXJlIGVxdWFsLCB0aGF0IGlzLCBldmVyeSAKCSAgICAqIG1lbWJlciBvZiB0aGUgt3RhcmdldCBub2RlIHNldLcgaXMgYWxzbyBhIG1lbWJlcgoJICAgICogb2YgdGhlILdxdWFsaWZpZWQgbm9kZSBzZXS3IGFuZCB2aWNlIHZlcnNhLgoJICAgICovCgkgICAgVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19JREMsICh4bWxTY2hlbWFUeXBlUHRyKSBpZGMsCgkJIkFsbCAna2V5JyBmaWVsZHMgbXVzdCBldmFsdWF0ZSB0byBhIG5vZGUiKTsKc2VsZWN0b3JfbGVhdmU6CgkgICAgLyoKCSAgICAqIEZyZWUgdGhlIGtleS1zZXF1ZW5jZSBpZiBub3QgYWRkZWQgdG8gdGhlIElEQyB0YWJsZS4KCSAgICAqLwoJICAgIGlmICgoa2V5U2VxICE9IE5VTEwpICYmICgqa2V5U2VxICE9IE5VTEwpKSB7CgkJeG1sRnJlZSgqa2V5U2VxKTsKCQkqa2V5U2VxID0gTlVMTDsKCSAgICB9Cgl9IC8qIGlmIHNlbGVjdG9yICovCgkKCXN0by0+bmJIaXN0b3J5LS07CgpkZXJlZ2lzdGVyX2NoZWNrOgoJLyoKCSogRGVyZWdpc3RlciBzdGF0ZSBvYmplY3RzIGlmIHRoZXkgcmVhY2ggdGhlIGRlcHRoIG9mIGNyZWF0aW9uLgoJKi8KCWlmICgoc3RvLT5uYkhpc3RvcnkgPT0gMCkgJiYgKHN0by0+ZGVwdGggPT0gZGVwdGgpKSB7CiNpZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBTVE8gcG9wICclcydcbiIsCgkJc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCgkgICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBzdG8pIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5IiwKCQkgICAgIlRoZSBzdGF0ZSBvYmplY3QgdG8gYmUgcmVtb3ZlZCBpcyBub3QgdGhlIGZpcnN0ICIKCQkgICAgImluIHRoZSBsaXN0Iik7CgkgICAgfQoJICAgIG5leHRzdG8gPSBzdG8tPm5leHQ7CgkgICAgLyoKCSAgICAqIFVubGluayBmcm9tIHRoZSBsaXN0IG9mIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgoJICAgICovCgkgICAgdmN0eHQtPnhwYXRoU3RhdGVzID0gc3RvLT5uZXh0OwoJICAgIHN0by0+bmV4dCA9IHZjdHh0LT54cGF0aFN0YXRlUG9vbDsKCSAgICAvKgoJICAgICogTGluayBpdCB0byB0aGUgcG9vbCBvZiByZXVzYWJsZSBzdGF0ZSBvYmplY3RzLgoJICAgICovCgkgICAgdmN0eHQtPnhwYXRoU3RhdGVQb29sID0gc3RvOwkgICAgCgkgICAgc3RvID0gbmV4dHN0bzsKCX0gZWxzZQoJICAgIHN0byA9IHN0by0+bmV4dDsKICAgIH0gLyogd2hpbGUgKHN0byAhPSBOVUxMKSAqLwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW1EZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKgogKiBDcmVhdGVzIGhlbHBlciBvYmplY3RzIHRvIGV2YWx1YXRlIElEQyBzZWxlY3RvcnMvZmllbGRzCiAqIHN1Y2Nlc3NpdmVseS4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciwgbGFzdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFJRENQdHIgaWRjLCByZWZJZGM7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKICAgICAgICAKICAgIGlkYyA9ICh4bWxTY2hlbWFJRENQdHIpIGVsZW1EZWNsLT5pZGNzOwogICAgaWYgKGlkYyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIAojaWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IFJFR0lTVEVSIG9uICVzLCBkZXB0aCAlZFxuIiwKCSAgICAoY2hhciAqKSB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSksIHZjdHh0LT5kZXB0aCk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCiAgICBpZiAodmN0eHQtPmlub2RlLT5pZGNNYXRjaGVycyAhPSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzIiwKCSAgICAiVGhlIGNoYWluIG9mIElEQyBtYXRjaGVycyBpcyBleHBlY3RlZCB0byBiZSBlbXB0eSIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBkbyB7CglpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgLyoKCSAgICAqIFNpbmNlIElEQ3MgYnViYmxlcyBhcmUgZXhwZW5zaXZlIHdlIG5lZWQgdG8ga25vdyB0aGUKCSAgICAqIGRlcHRoIGF0IHdoaWNoIHRoZSBidWJibGVzIHNob3VsZCBzdG9wOyB0aGlzIHdpbGwgYmUKCSAgICAqIHRoZSBkZXB0aCBvZiB0aGUgdG9wLW1vc3Qga2V5cmVmIElEQy4gSWYgbm8ga2V5cmVmCgkgICAgKiByZWZlcmVuY2VzIGEga2V5L3VuaXF1ZSBJREMsIHRoZSBidWJibGVEZXB0aCB3aWxsCgkgICAgKiBiZSAtMSwgaW5kaWNhdGluZyB0aGF0IG5vIGJ1YmJsZXMgYXJlIG5lZWRlZC4KCSAgICAqLwoJICAgIHJlZklkYyA9ICh4bWxTY2hlbWFJRENQdHIpIGlkYy0+cmVmLT5pdGVtOwoJICAgIGlmIChyZWZJZGMgIT0gTlVMTCkgewoJCS8qCgkJKiBMb29rdXAgdGhlIGF1Z21lbnRlZCBJREMuCgkJKi8KCQlhaWRjID0gdmN0eHQtPmFpZGNzOwoJCXdoaWxlIChhaWRjICE9IE5VTEwpIHsKCQkgICAgaWYgKGFpZGMtPmRlZiA9PSByZWZJZGMpCgkJCWJyZWFrOwoJCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCQl9CgkJaWYgKGFpZGMgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzIiwKCQkJIkNvdWxkIG5vdCBmaW5kIGFuIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgYW4gSURDICIKCQkJImRlZmluaXRpb24iKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkJaWYgKChhaWRjLT5idWJibGVEZXB0aCA9PSAtMSkgfHwKCQkgICAgKHZjdHh0LT5kZXB0aCA8IGFpZGMtPmJ1YmJsZURlcHRoKSkKCQkgICAgYWlkYy0+YnViYmxlRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CgkgICAgfQoJfQoJLyoKCSogTG9va3VwIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIHRoZSBJREMgZGVmaW5pdGlvbi4KCSovCglhaWRjID0gdmN0eHQtPmFpZGNzOwoJd2hpbGUgKGFpZGMgIT0gTlVMTCkgewoJICAgIGlmIChhaWRjLT5kZWYgPT0gaWRjKQoJCWJyZWFrOwoJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJfQoJaWYgKGFpZGMgPT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMiLAoJCSJDb3VsZCBub3QgZmluZCBhbiBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIGFuIElEQyBkZWZpbml0aW9uIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiBDcmVhdGUgYW4gSURDIG1hdGNoZXIgZm9yIGV2ZXJ5IElEQyBkZWZpbml0aW9uLgoJKi8KCW1hdGNoZXIgPSAoeG1sU2NoZW1hSURDTWF0Y2hlclB0cikgCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENNYXRjaGVyKSk7CglpZiAobWF0Y2hlciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgYW4gSURDIG1hdGNoZXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCW1lbXNldChtYXRjaGVyLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDTWF0Y2hlcikpOwoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICB2Y3R4dC0+aW5vZGUtPmlkY01hdGNoZXJzID0gbWF0Y2hlcjsKCWVsc2UKCSAgICBsYXN0LT5uZXh0ID0gbWF0Y2hlcjsKCWxhc3QgPSBtYXRjaGVyOwoKCW1hdGNoZXItPnR5cGUgPSBJRENfTUFUQ0hFUjsKCW1hdGNoZXItPmRlcHRoID0gdmN0eHQtPmRlcHRoOwkKCW1hdGNoZXItPmFpZGMgPSBhaWRjOwojaWYgREVCVUdfSURDCQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgcmVnaXN0ZXIgbWF0Y2hlclxuIik7CiNlbmRpZiAKCS8qCgkqIEluaXQgdGhlIGF1dG9tYXRvbiBzdGF0ZSBvYmplY3QuIAoJKi8KCWlmICh4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh2Y3R4dCwgbWF0Y2hlciwgCgkgICAgaWRjLT5zZWxlY3RvciwgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKCglpZGMgPSBpZGMtPm5leHQ7CiAgICB9IHdoaWxlIChpZGMgIT0gTlVMTCk7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlczogCiAqIEBkZXB0aDogdGhlIGN1cnJlbnQgdHJlZSBkZXB0aAogKgogKiBNZXJnZXMgSURDIGJpbmRpbmdzIG9mIGFuIGVsZW1lbnQgYXQgQGRlcHRoIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgSURDIAogKiBiaW5kaW5ncyBvZiBpdHMgcGFyZW50IGVsZW1lbnQuIElmIGEgZHVwbGljYXRlIG5vdGUtdGFibGUgZW50cnkgaXMgZm91bmQsIAogKiBib3RoLCB0aGUgcGFyZW50IG5vZGUtdGFibGUgZW50cnkgYW5kIGNoaWxkIGVudHJ5IGFyZSBkaXNjYXJkZWQgZnJvbSB0aGUgCiAqIG5vZGUtdGFibGUgb2YgdGhlIHBhcmVudC4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1YmJsZUlEQ05vZGVUYWJsZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOyAvKiBJREMgYmluZGluZ3Mgb2YgdGhlIGN1cnJlbnQgbm9kZS4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyICpwYXJUYWJsZSwgcGFyQmluZCA9IE5VTEwsIGxhc3RQYXJCaW5kID0gTlVMTDsgLyogcGFyZW50IElEQyBiaW5kaW5ncy4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG5vZGUsIHBhck5vZGUgPSBOVUxMOyAvKiBub2RlLXRhYmxlIGVudHJpZXMuICovCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSwgcGFyS2V5OyAvKiBrZXlzIG9mIGluIGEga2V5LXNlcXVlbmNlLiAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7CiAgICBpbnQgaSwgaiwgaywgcmV0ID0gMCwgb2xkTnVtLCBuZXdEdXBsczsKICAgIGludCBkdXBsVG9wOwoKICAgIC8qCiAgICAqIFRoZSBub2RlIHRhYmxlIGhhcyB0aGUgZm9sbG93aW5nIHNlY3Rpb25zOgogICAgKgogICAgKiAgTyAtLT4gb2xkIG5vZGUtdGFibGUgZW50cmllcyAoZmlyc3QpCiAgICAqICBPIAogICAgKiAgKyAtLT4gbmV3IG5vZGUtdGFibGUgZW50cmllcwogICAgKiAgKyAKICAgICogICUgLS0+IG5ldyBkdXBsaWNhdGUgbm9kZS10YWJsZSBlbnRyaWVzICAgIAogICAgKiAgJSAKICAgICogICMgLS0+IG9sZCBkdXBsaWNhdGUgbm9kZS10YWJsZSBlbnRyaWVzICAgIAogICAgKiAgIyAobGFzdCkKICAgICoKICAgICovCiAgICBiaW5kID0gdmN0eHQtPmlub2RlLT5pZGNUYWJsZTsgICAgICAgIAogICAgaWYgKGJpbmQgPT0gTlVMTCkgewoJLyogRmluZSwgbm8gdGFibGUsIG5vIGJ1YmJsZXMuICovCglyZXR1cm4gKDApOwogICAgfQogICAgCiAgICBwYXJUYWJsZSA9ICYodmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdLT5pZGNUYWJsZSk7CiAgICAvKgogICAgKiBXYWxrIGFsbCBiaW5kaW5nczsgY3JlYXRlIG5ldyBvciBhZGQgdG8gZXhpc3RpbmcgYmluZGluZ3MuCiAgICAqIFJlbW92ZSBkdXBsaWNhdGUga2V5LXNlcXVlbmNlcy4KICAgICovCnN0YXJ0X2JpbmRpbmc6CiAgICB3aGlsZSAoYmluZCAhPSBOVUxMKSB7CgkvKgoJKiBTa2lwIGtleXJlZiBJRENzLgoJKi8KCWlmIChiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgYmluZCA9IGJpbmQtPm5leHQ7CgkgICAgY29udGludWU7Cgl9CgkvKgoJKiBDaGVjayBpZiB0aGUga2V5L3VuaXF1ZSBJREMgdGFibGUgbmVlZHMgdG8gYmUgYnViYmxlZC4KCSovCglhaWRjID0gdmN0eHQtPmFpZGNzOwoJZG8gewoJICAgIGlmIChhaWRjLT5kZWYgPT0gYmluZC0+ZGVmaW5pdGlvbikgewoJCWlmICgoYWlkYy0+YnViYmxlRGVwdGggPT0gLTEpIHx8IAoJCSAgICAoYWlkYy0+YnViYmxlRGVwdGggPj0gdmN0eHQtPmRlcHRoKSkgewoJCSAgICBiaW5kID0gYmluZC0+bmV4dDsKCQkgICAgZ290byBzdGFydF9iaW5kaW5nOwoJCX0KCQlicmVhazsKCSAgICB9CgkgICAgYWlkYyA9IGFpZGMtPm5leHQ7Cgl9IHdoaWxlIChhaWRjICE9IE5VTEwpOwoKCWlmIChwYXJUYWJsZSAhPSBOVUxMKQoJICAgIHBhckJpbmQgPSAqcGFyVGFibGU7Cgl3aGlsZSAocGFyQmluZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFNlYXJjaCBhIG1hdGNoaW5nIHBhcmVudCBiaW5kaW5nIGZvciB0aGUKCSAgICAqIElEQyBkZWZpbml0aW9uLgoJICAgICovCgkgICAgaWYgKHBhckJpbmQtPmRlZmluaXRpb24gPT0gYmluZC0+ZGVmaW5pdGlvbikgewoKCQkvKgoJCSogQ29tcGFyZSBldmVyeSBub2RlLXRhYmxlIGVudHJ5IG9mIHRoZSBjaGlsZCBub2RlLCAKCQkqIGkuZS4gdGhlIGtleS1zZXF1ZW5jZSB3aXRoaW4sIC4uLgoJCSovCgkJb2xkTnVtID0gcGFyQmluZC0+bmJOb2RlczsgLyogU2tpcCBuZXdseSBhZGRlZCBpdGVtcy4gKi8KCQlkdXBsVG9wID0gb2xkTnVtICsgcGFyQmluZC0+bmJEdXBsczsKCQluZXdEdXBscyA9IDA7CgoJCWZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQkgICAgbm9kZSA9IGJpbmQtPm5vZGVUYWJsZVtpXTsKCQkgICAgaWYgKG5vZGUgPT0gTlVMTCkKCQkJY29udGludWU7CgkJICAgIC8qCgkJICAgICogLi4ud2l0aCBldmVyeSBrZXktc2VxdWVuY2Ugb2YgdGhlIHBhcmVudCBub2RlLCBhbHJlYWR5CgkJICAgICogZXZhbHVhdGVkIHRvIGJlIGEgZHVwbGljYXRlIGtleS1zZXF1ZW5jZS4KCQkgICAgKi8KCQkgICAgaWYgKHBhckJpbmQtPm5iRHVwbHMgIT0gMCkgewoJCQlqID0gYmluZC0+bmJOb2RlcyArIG5ld0R1cGxzOyAKCQkJd2hpbGUgKGogPCBkdXBsVG9wKSB7CgkJCSAgICBwYXJOb2RlID0gcGFyQmluZC0+bm9kZVRhYmxlW2pdOwoJCQkgICAgZm9yIChrID0gMDsgayA8IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOyBrKyspIHsKCQkJCWtleSA9IG5vZGUtPmtleXNba107CgkJCQlwYXJLZXkgPSBwYXJOb2RlLT5rZXlzW2tdOwoJCQkJcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5LT52YWwsCgkJCQkgICAgcGFyS2V5LT52YWwpOwoJCQkJaWYgKHJldCA9PSAtMSkgewoJCQkJICAgIC8qIFRPRE86IEludGVybmFsIGVycm9yICovCgkJCQkgICAgcmV0dXJuKC0xKTsKCQkJCX0gZWxzZSBpZiAocmV0ID09IDApCgkJCQkgICAgYnJlYWs7CgoJCQkgICAgfQoJCQkgICAgaWYgKHJldCA9PSAxKQoJCQkJLyogRHVwbGljYXRlIGZvdW5kLiAqLwoJCQkJYnJlYWs7CgkJCSAgICBqKys7CgkJCX0KCQkJaWYgKGogIT0gZHVwbFRvcCkgewoJCQkgICAgLyogRHVwbGljYXRlIGZvdW5kLiAqLwoJCQkgICAgY29udGludWU7CgkJCX0KCQkgICAgfQkJICAgIAoJCSAgICAvKgoJCSAgICAqIC4uLiBhbmQgd2l0aCBldmVyeSBrZXktc2VxdWVuY2Ugb2YgdGhlIHBhcmVudCBub2RlLgoJCSAgICAqLwkJICAgIAkJICAgIAoJCSAgICBqID0gMDsKCQkgICAgd2hpbGUgKGogPCBvbGROdW0pIHsKCQkJcGFyTm9kZSA9IHBhckJpbmQtPm5vZGVUYWJsZVtqXTsKCQkJLyoKCQkJKiBDb21wYXJlIGtleSBieSBrZXkuIAoJCQkqLwoJCQlmb3IgKGsgPSAwOyBrIDwgcGFyQmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGsrKykgewoJCQkgICAga2V5ID0gbm9kZS0+a2V5c1trXTsKCQkJICAgIHBhcktleSA9IHBhck5vZGUtPmtleXNba107CQkJCgoJCQkgICAgcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5LT52YWwsCgkJCQlwYXJLZXktPnZhbCk7CgkJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCQkvKiBUT0RPOiBJbnRlcm5hbCBlcnJvciAqLwoJCQkgICAgfSBlbHNlIGlmIChyZXQgPT0gMCkKCQkJCWJyZWFrOwoKCQkJfQoJCQlpZiAocmV0ID09IDEpCgkJCSAgICAvKgoJCQkgICAgKiBUaGUga2V5LXNlcXVlbmNlcyBhcmUgZXF1YWwuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCWorKzsKCQkgICAgfQoJCSAgICBpZiAoaiAhPSBvbGROdW0pIHsKCQkJLyoKCQkJKiBIYW5kbGUgZHVwbGljYXRlcy4KCQkJKi8KCQkJbmV3RHVwbHMrKzsKCQkJb2xkTnVtLS07CgkJCXBhckJpbmQtPm5iTm9kZXMtLTsKCQkJLyoKCQkJKiBNb3ZlIGxhc3Qgb2xkIGl0ZW0gdG8gcG9zIG9mIGR1cGxpY2F0ZS4KCQkJKi8KCQkJcGFyQmluZC0+bm9kZVRhYmxlW2pdID0gCgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGVbb2xkTnVtXTsKCQkJCgkJCWlmIChwYXJCaW5kLT5uYk5vZGVzICE9IG9sZE51bSkgewoJCQkgICAgLyoKCQkJICAgICogSWYgbmV3IGl0ZW1zIGV4aXN0LCBtb3ZlIGxhc3QgbmV3IGl0ZW0gdG8gCgkJCSAgICAqIGxhc3Qgb2Ygb2xkIGl0ZW1zLgoJCQkgICAgKi8KCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZVtvbGROdW1dID0gCgkJCQlwYXJCaW5kLT5ub2RlVGFibGVbcGFyQmluZC0+bmJOb2Rlc107CgkJCX0KCQkJLyoKCQkJKiBNb3ZlIGR1cGxpY2F0ZSB0byBsYXN0IHBvcyBvZiBuZXcvb2xkIGl0ZW1zLgoJCQkqLwoJCQlwYXJCaW5kLT5ub2RlVGFibGVbcGFyQmluZC0+bmJOb2Rlc10gPSBwYXJOb2RlOwkJCQoJCQkKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBBZGQgdGhlIG5vZGUtdGFibGUgZW50cnkgKG5vZGUgYW5kIGtleS1zZXF1ZW5jZSkgb2YgCgkJCSogdGhlIGNoaWxkIG5vZGUgdG8gdGhlIG5vZGUgdGFibGUgb2YgdGhlIHBhcmVudCBub2RlLgoJCQkqLwoJCQlpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsJCQkKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQkJCXhtbE1hbGxvYygxMCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJCQkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkJICAgICJhbGxvY2F0aW5nIElEQyBsaXN0IG9mIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCQkJCXJldHVybigtMSk7CgkJCSAgICB9CgkJCSAgICBwYXJCaW5kLT5zaXplTm9kZXMgPSAxOwoJCQl9IGVsc2UgaWYgKGR1cGxUb3AgPj0gcGFyQmluZC0+c2l6ZU5vZGVzKSB7CgkJCSAgICBwYXJCaW5kLT5zaXplTm9kZXMgKj0gMjsKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQkJCXhtbFJlYWxsb2MocGFyQmluZC0+bm9kZVRhYmxlLCBwYXJCaW5kLT5zaXplTm9kZXMgKiAKCQkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJCQkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkJICAgICJyZS1hbGxvY2F0aW5nIElEQyBsaXN0IG9mIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCQkJCXJldHVybigtMSk7CgkJCSAgICB9CgkJCX0KCQkJCgkJCS8qCgkJCSogTW92ZSBmaXJzdCBvbGQgZHVwbGljYXRlIHRvIGxhc3QgcG9zaXRpb24KCQkJKiBvZiBvbGQgZHVwbGljYXRlcyArMS4KCQkJKi8KCQkJaWYgKHBhckJpbmQtPm5iRHVwbHMgIT0gMCkgewoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW2R1cGxUb3BdID0KCQkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzICsgbmV3RHVwbHNdOwoJCQl9CgkJCS8qCgkJCSogTW92ZSBmaXJzdCBuZXcgZHVwbGljYXRlIHRvIGxhc3QgcG9zaXRpb24gb2YKCQkJKiBuZXcgZHVwbGljYXRlcyArMS4KCQkJKi8KCQkJaWYgKG5ld0R1cGxzICE9IDApIHsKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzICsgbmV3RHVwbHNdID0KCQkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXTsKCQkJfQoJCQkvKgoJCQkqIEFwcGVuZCB0aGUgbmV3IG5vZGUtdGFibGUgZW50cnkgdG8gdGhlICduZXcgbm9kZS10YWJsZQoJCQkqIGVudHJpZXMnIHNlY3Rpb24uCgkJCSovCgkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXSA9IG5vZGU7CgkJCXBhckJpbmQtPm5iTm9kZXMrKzsKCQkJZHVwbFRvcCsrOwoJCSAgICB9CgkJfQoJCXBhckJpbmQtPm5iRHVwbHMgKz0gbmV3RHVwbHM7CgkJYnJlYWs7CgkgICAgfQoJICAgIGlmIChwYXJCaW5kLT5uZXh0ID09IE5VTEwpCgkJbGFzdFBhckJpbmQgPSBwYXJCaW5kOwoJICAgIHBhckJpbmQgPSBwYXJCaW5kLT5uZXh0OwoJfQoJaWYgKChwYXJCaW5kID09IE5VTEwpICYmIChiaW5kLT5uYk5vZGVzICE9IDApKSB7CgkgICAgLyoKCSAgICAqIE5vIGJpbmRpbmcgZm9yIHRoZSBJREMgd2FzIGZvdW5kOiBjcmVhdGUgYSBuZXcgb25lIGFuZAoJICAgICogY29weSBhbGwgbm9kZS10YWJsZXMuCgkgICAgKi8KCSAgICBwYXJCaW5kID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhiaW5kLT5kZWZpbml0aW9uKTsKCSAgICBpZiAocGFyQmluZCA9PSBOVUxMKQoJCXJldHVybigtMSk7CgoJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQl4bWxNYWxsb2MoYmluZC0+bmJOb2RlcyAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJICAgIGlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkJeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcocGFyQmluZCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgcGFyQmluZC0+c2l6ZU5vZGVzID0gYmluZC0+bmJOb2RlczsKCSAgICBwYXJCaW5kLT5uYk5vZGVzID0gYmluZC0+bmJOb2RlczsKCSAgICBtZW1jcHkocGFyQmluZC0+bm9kZVRhYmxlLCBiaW5kLT5ub2RlVGFibGUsCgkJYmluZC0+bmJOb2RlcyAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJICAgIGlmICgqcGFyVGFibGUgPT0gTlVMTCkKCQkqcGFyVGFibGUgPSBwYXJCaW5kOwoJICAgIGVsc2UKCQlsYXN0UGFyQmluZC0+bmV4dCA9IHBhckJpbmQ7Cgl9CgliaW5kID0gYmluZC0+bmV4dDsKICAgIH0gIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtRGVjbDogdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24KICoKICogQ2hlY2sgdGhlIGN2Yy1pZGMta2V5cmVmIGNvbnN0cmFpbnRzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHJlZmJpbmQsIGJpbmQ7CgogICAgcmVmYmluZCA9IHZjdHh0LT5pbm9kZS0+aWRjVGFibGU7CiAgICAvKgogICAgKiBGaW5kIGEga2V5cmVmLgogICAgKi8KICAgIHdoaWxlIChyZWZiaW5kICE9IE5VTEwpIHsKCWlmIChyZWZiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgaW50IGksIGosIGssIHJlczsKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICpyZWZLZXlzLCAqa2V5czsKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIHJlZktleSwga2V5OwoKCSAgICAvKgoJICAgICogRmluZCB0aGUgcmVmZXJyZWQga2V5L3VuaXF1ZS4KCSAgICAqLwoJICAgIGJpbmQgPSB2Y3R4dC0+aW5vZGUtPmlkY1RhYmxlOwoJICAgIGRvIHsKCQlpZiAoKHhtbFNjaGVtYUlEQ1B0cikgcmVmYmluZC0+ZGVmaW5pdGlvbi0+cmVmLT5pdGVtID09IAoJCSAgICBiaW5kLT5kZWZpbml0aW9uKQoJCSAgICBicmVhazsKCQliaW5kID0gYmluZC0+bmV4dDsKCSAgICB9IHdoaWxlIChiaW5kICE9IE5VTEwpOwoKCSAgICAvKgoJICAgICogU2VhcmNoIGZvciBhIG1hdGNoaW5nIGtleS1zZXF1ZW5jZXMuCgkgICAgKi8KCSAgICBmb3IgKGkgPSAwOyBpIDwgcmVmYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJcmVzID0gMDsKCQlpZiAoYmluZCAhPSBOVUxMKSB7CQkgICAgCgkJICAgIHJlZktleXMgPSByZWZiaW5kLT5ub2RlVGFibGVbaV0tPmtleXM7CgkJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5uYk5vZGVzOyBqKyspIHsKCQkJa2V5cyA9IGJpbmQtPm5vZGVUYWJsZVtqXS0+a2V5czsKCQkJZm9yIChrID0gMDsgayA8IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOyBrKyspIHsKCQkJICAgIHJlZktleSA9IHJlZktleXNba107CgkJCSAgICBrZXkgPSBrZXlzW2tdOwoJCQkgICAgcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoa2V5LT52YWwsCgkJCQlyZWZLZXktPnZhbCk7CgkJCSAgICBpZiAocmVzID09IDApCgkJCQlicmVhazsKCQkJICAgIGVsc2UgaWYgKHJlcyA9PSAtMSkgewoJCQkJcmV0dXJuICgtMSk7CgkJCSAgICB9CgkJCX0KCQkJaWYgKHJlcyA9PSAxKSB7CgkJCSAgICAvKgoJCQkgICAgKiBNYXRjaCBmb3VuZC4KCQkJICAgICovCgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJfQoJCWlmIChyZXMgPT0gMCkgewoJCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqc3RyQiA9IE5VTEw7CgkJICAgIC8qIFRPRE86IFJlcG9ydCB0aGUga2V5LXNlcXVlbmNlLiAqLwoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSByZWZiaW5kLT5kZWZpbml0aW9uLAoJCQkiTm8gbWF0Y2ggZm91bmQgZm9yIGtleS1zZXF1ZW5jZSAlcyBvZiBrZXkgIgoJCQkicmVmZXJlbmNlICclcyciLAoJCQl4bWxTY2hlbWFGb3JtYXRJRENLZXlTZXF1ZW5jZSh2Y3R4dCwgJnN0ciwKCQkJICAgIHJlZmJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5cywKCQkJICAgIHJlZmJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzKSwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ckIsCgkJCSAgICByZWZiaW5kLT5kZWZpbml0aW9uLT50YXJnZXROYW1lc3BhY2UsCgkJCSAgICByZWZiaW5kLT5kZWZpbml0aW9uLT5uYW1lKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCKTsKCQl9CgkgICAgfQoJfQoJcmVmYmluZCA9IHJlZmJpbmQtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJWE1MIFJlYWRlciB2YWxpZGF0aW9uIGNvZGUgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgeG1sU2NoZW1hQXR0ckluZm9QdHIKeG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwogICAgLyoKICAgICogR3Jvdy9jcmVhdGUgbGlzdCBvZiBhdHRyaWJ1dGUgaW5mb3MuCiAgICAqLwogICAgaWYgKHZjdHh0LT5hdHRySW5mb3MgPT0gTlVMTCkgewoJdmN0eHQtPmF0dHJJbmZvcyA9ICh4bWxTY2hlbWFBdHRySW5mb1B0ciAqKQoJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0ckluZm9QdHIpKTsKCXZjdHh0LT5zaXplQXR0ckluZm9zID0gMTsKCWlmICh2Y3R4dC0+YXR0ckluZm9zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIGF0dHJpYnV0ZSBpbmZvIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUF0dHJJbmZvcyA8PSB2Y3R4dC0+bmJBdHRySW5mb3MpIHsKCXZjdHh0LT5zaXplQXR0ckluZm9zKys7Cgl2Y3R4dC0+YXR0ckluZm9zID0gKHhtbFNjaGVtYUF0dHJJbmZvUHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+YXR0ckluZm9zLAoJCXZjdHh0LT5zaXplQXR0ckluZm9zICogc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvUHRyKSk7CglpZiAodmN0eHQtPmF0dHJJbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyBhdHRyaWJ1dGUgaW5mbyBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZSB7CglpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbdmN0eHQtPm5iQXR0ckluZm9zKytdOwoJaWYgKGlhdHRyLT5sb2NhbE5hbWUgIT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8iLAoJCSJhdHRyIGluZm8gbm90IGNsZWFyZWQiKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaWF0dHItPm5vZGVUeXBlID0gWE1MX0FUVFJJQlVURV9OT0RFOwoJcmV0dXJuIChpYXR0cik7CiAgICB9CiAgICAvKgogICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlIGluZm8uCiAgICAqLwogICAgaWF0dHIgPSAoeG1sU2NoZW1hQXR0ckluZm9QdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICBpZiAoaWF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgImNyZWF0aW5nIG5ldyBhdHRyaWJ1dGUgaW5mbyIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChpYXR0ciwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICBpYXR0ci0+bm9kZVR5cGUgPSBYTUxfQVRUUklCVVRFX05PREU7CiAgICB2Y3R4dC0+YXR0ckluZm9zW3ZjdHh0LT5uYkF0dHJJbmZvcysrXSA9IGlhdHRyOwoKICAgIHJldHVybiAoaWF0dHIpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQl4bWxOb2RlUHRyIGF0dHJOb2RlLAoJCQljb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsCgkJCWNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkJaW50IG93bmVkTmFtZXMsCgkJCXhtbENoYXIgKnZhbHVlLAoJCQlpbnQgb3duZWRWYWx1ZSkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFQdXNoQXR0cmlidXRlIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKCkiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgYXR0ci0+bm9kZSA9IGF0dHJOb2RlOwogICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV047CiAgICBhdHRyLT5sb2NhbE5hbWUgPSBsb2NhbE5hbWU7CiAgICBhdHRyLT5uc05hbWUgPSBuc05hbWU7CiAgICBpZiAob3duZWROYW1lcykKCWF0dHItPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVM7CiAgICAvKgogICAgKiBFdmFsdWF0ZSBpZiBpdCdzIGFuIFhTSSBhdHRyaWJ1dGUuCiAgICAqLwogICAgaWYgKG5zTmFtZSAhPSBOVUxMKSB7CglpZiAoeG1sU3RyRXF1YWwobG9jYWxOYW1lLCBCQURfQ0FTVCAibmlsIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMOwkJCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJ0eXBlIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfU0NIRU1BX0xPQzsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iKSkgewoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uc05hbWUsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB7CgkJYXR0ci0+bWV0YVR5cGUgPSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxOYW1lc3BhY2VOcykpIHsKCSAgICBhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWE1MTlM7Cgl9CiAgICB9CiAgICBhdHRyLT52YWx1ZSA9IHZhbHVlOwogICAgaWYgKG93bmVkVmFsdWUpCglhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUzsKICAgIGlmIChhdHRyLT5tZXRhVHlwZSAhPSAwKQoJYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX01FVEE7CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhckVsZW1JbmZvKHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtKQp7CiAgICBpZiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9OQU1FUykgewoJRlJFRV9BTkRfTlVMTChpZWxlbS0+bG9jYWxOYW1lKTsKCUZSRUVfQU5EX05VTEwoaWVsZW0tPm5zTmFtZSk7CiAgICB9IGVsc2UgewoJaWVsZW0tPmxvY2FsTmFtZSA9IE5VTEw7CglpZWxlbS0+bnNOYW1lID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUykgewoJRlJFRV9BTkRfTlVMTChpZWxlbS0+dmFsdWUpOwogICAgfSBlbHNlIHsKCWllbGVtLT52YWx1ZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPnZhbCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUoaWVsZW0tPnZhbCk7CglpZWxlbS0+dmFsID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+aWRjTWF0Y2hlcnMgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0KGllbGVtLT5pZGNNYXRjaGVycyk7CglpZWxlbS0+aWRjTWF0Y2hlcnMgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5pZGNUYWJsZSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENGcmVlSURDVGFibGUoaWVsZW0tPmlkY1RhYmxlKTsKCWllbGVtLT5pZGNUYWJsZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPnJlZ2V4Q3R4dCAhPSBOVUxMKSB7Cgl4bWxSZWdGcmVlRXhlY0N0eHQoaWVsZW0tPnJlZ2V4Q3R4dCk7CglpZWxlbS0+cmVnZXhDdHh0ID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+bnNCaW5kaW5ncyAhPSBOVUxMKSB7Cgl4bWxGcmVlKCh4bWxDaGFyICoqKWllbGVtLT5uc0JpbmRpbmdzKTsKCWllbGVtLT5uc0JpbmRpbmdzID0gTlVMTDsKCWllbGVtLT5uYk5zQmluZGluZ3MgPSAwOwoJaWVsZW0tPnNpemVOc0JpbmRpbmdzID0gMDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm86CiAqIEB2Y3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQ3JlYXRlcy9yZXVzZXMgYW5kIGluaXRpYWxpemVzIHRoZSBlbGVtZW50IGluZm8gaXRlbSBmb3IKICogdGhlIGN1cnJlY3QgdHJlZSBkZXB0aC4KICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBpbmZvIGl0ZW0gb3IgTlVMTCBvbiBBUEkgb3IgaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vZGVJbmZvUHRyCnhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbmZvID0gTlVMTDsKCiAgICBpZiAodmN0eHQtPmRlcHRoID4gdmN0eHQtPnNpemVFbGVtSW5mb3MpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8iLAoJICAgICJpbmNvbnNpc3RlbnQgZGVwdGggZW5jb3VudGVyZWQiKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7Cgl2Y3R4dC0+ZWxlbUluZm9zID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyICopCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyB0aGUgZWxlbWVudCBpbmZvIGFycmF5IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCW1lbXNldCh2Y3R4dC0+ZWxlbUluZm9zLCAwLCAxMCAqIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJdmN0eHQtPnNpemVFbGVtSW5mb3MgPSAxMDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVFbGVtSW5mb3MgPD0gdmN0eHQtPmRlcHRoKSB7CglpbnQgaSA9IHZjdHh0LT5zaXplRWxlbUluZm9zOwoKCXZjdHh0LT5zaXplRWxlbUluZm9zICo9IDI7Cgl2Y3R4dC0+ZWxlbUluZm9zID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyICopCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+ZWxlbUluZm9zLCB2Y3R4dC0+c2l6ZUVsZW1JbmZvcyAqCgkgICAgc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyB0aGUgZWxlbWVudCBpbmZvIGFycmF5IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qCgkqIFdlIG5lZWQgdGhlIG5ldyBtZW1vcnkgdG8gYmUgTlVMTGVkLgoJKiBUT0RPOiBVc2UgbWVtc2V0IGluc3RlYWQ/CgkqLwoJZm9yICg7IGkgPCB2Y3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKQoJICAgIHZjdHh0LT5lbGVtSW5mb3NbaV0gPSBOVUxMOwogICAgfSBlbHNlCglpbmZvID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwoKICAgIGlmIChpbmZvID09IE5VTEwpIHsKCWluZm8gPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIpCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFOb2RlSW5mbykpOwoJaWYgKGluZm8gPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgYW4gZWxlbWVudCBpbmZvIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXSA9IGluZm87CiAgICB9IGVsc2UgewoJaWYgKGluZm8tPmxvY2FsTmFtZSAhPSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyIsCgkJImVsZW0gaW5mbyBoYXMgbm90IGJlZW4gY2xlYXJlZCIpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9CiAgICBtZW1zZXQoaW5mbywgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CiAgICBpbmZvLT5ub2RlVHlwZSA9IFhNTF9FTEVNRU5UX05PREU7CiAgICBpbmZvLT5kZXB0aCA9IHZjdHh0LT5kZXB0aDsKCiAgICByZXR1cm4gKGluZm8pOwp9CgojZGVmaW5lIEFDVElWQVRFX0FUVFJJQlVURShpdGVtKSB2Y3R4dC0+aW5vZGUgPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIpIGl0ZW07CiNkZWZpbmUgQUNUSVZBVEVfRUxFTSB2Y3R4dC0+aW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CiNkZWZpbmUgQUNUSVZBVEVfUEFSRU5UX0VMRU0gdmN0eHQtPmlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdOwoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQl4bWxTY2hlbWFWYWxUeXBlIHZhbFR5cGUsCgkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJeG1sU2NoZW1hVmFsUHRyIHZhbCwKCQkJdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJCWludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0LCBlcnJvciA9IDA7CgogICAgeG1sU2NoZW1hVHlwZVB0ciB0bXBUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluazsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgdW5zaWduZWQgbG9uZyBsZW4gPSAwOwogICAgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3czsKCiAgICAvKgogICAgKiBJbiBMaWJ4bWwyLCBkZXJpdmVkIGJ1aWx0LWluIHR5cGVzIGhhdmUgY3VycmVudGx5IG5vIGV4cGxpY2l0IGZhY2V0cy4KICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCglyZXR1cm4gKDApOwoKICAgIC8qCiAgICAqIE5PVEU6IERvIG5vdCBqdW1wIGF3YXksIGlmIHRoZSBmYWNldFNldCBvZiB0aGUgZ2l2ZW4gdHlwZSBpcwogICAgKiBlbXB0eTogdW50aWwgbm93LCAicGF0dGVybiIgYW5kICJlbnVtZXJhdGlvbiIgZmFjZXRzIG9mIHRoZQogICAgKiAqYmFzZSB0eXBlcyogbmVlZCB0byBiZSBjaGVja2VkIGFzIHdlbGwuCiAgICAqLwogICAgaWYgKHR5cGUtPmZhY2V0U2V0ID09IE5VTEwpCglnb3RvIHBhdHRlcm5fYW5kX2VudW07CgogICAgaWYgKCEgVkFSSUVUWV9BVE9NSUModHlwZSkpIHsKCWlmIChWQVJJRVRZX0xJU1QodHlwZSkpCgkgICAgZ290byB2YXJpZXR5X2xpc3Q7CgllbHNlCgkgICAgZ290byBwYXR0ZXJuX2FuZF9lbnVtOwogICAgfQogICAgLyoKICAgICogV2hpdGVzcGFjZSBoYW5kbGluZyBpcyBvbmx5IG9mIGltcG9ydGFuY2UgZm9yIHN0cmluZy1iYXNlZAogICAgKiB0eXBlcy4KICAgICovCiAgICB0bXBUeXBlID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eXBlKTsKICAgIGlmICgodG1wVHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSB8fAoJSVNfQU5ZX1NJTVBMRV9UWVBFKHRtcFR5cGUpKSB7Cgl3cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwogICAgfSBlbHNlCgl3cyA9IFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRTsKICAgIC8qCiAgICAqIElmIHRoZSB2YWx1ZSB3YXMgbm90IGNvbXB1dGVkIChmb3Igc3RyaW5nIG9yCiAgICAqIGFueVNpbXBsZVR5cGUgYmFzZWQgdHlwZXMpLCB0aGVuIHVzZSB0aGUgcHJvdmlkZWQKICAgICogdHlwZS4KICAgICovCiAgICBpZiAodmFsID09IE5VTEwpCgl2YWxUeXBlID0gdmFsVHlwZTsKICAgIGVsc2UKCXZhbFR5cGUgPSB4bWxTY2hlbWFHZXRWYWxUeXBlKHZhbCk7CiAgICAKICAgIHJldCA9IDA7CiAgICBmb3IgKGZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJLyoKCSogU2tpcCB0aGUgcGF0dGVybiAid2hpdGVTcGFjZSI6IGl0IGlzIHVzZWQgdG8KCSogZm9ybWF0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBiZWZvcmVoYW5kLgoJKi8KCXN3aXRjaCAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQljb250aW51ZTsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxlbmd0aEZhY2V0V2h0c3AoZmFjZXRMaW5rLT5mYWNldCwKCQkgICAgdmFsVHlwZSwgdmFsdWUsIHZhbCwgJmxlbiwgd3MpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldFdodHNwKGZhY2V0TGluay0+ZmFjZXQsIHdzLAoJCSAgICB2YWxUeXBlLCB2YWx1ZSwgdmFsLCB3cyk7CgkJYnJlYWs7Cgl9CglpZiAocmV0IDwgMCkgewoJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkidmFsaWRhdGluZyBhZ2FpbnN0IGEgYXRvbWljIHR5cGUgZmFjZXQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYUZhY2V0RXJyKGFjdHh0LCByZXQsIG5vZGUsCgkJdmFsdWUsIGxlbiwgdHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgZWxzZQoJCXJldHVybiAocmV0KTsKCSAgICBpZiAoZXJyb3IgPT0gMCkKCQllcnJvciA9IHJldDsKCX0KCXJldCA9IDA7CiAgICB9Cgp2YXJpZXR5X2xpc3Q6CiAgICBpZiAoISBWQVJJRVRZX0xJU1QodHlwZSkpCglnb3RvIHBhdHRlcm5fYW5kX2VudW07CiAgICAvKgogICAgKiAibGVuZ3RoIiwgIm1pbkxlbmd0aCIgYW5kICJtYXhMZW5ndGgiIG9mIGxpc3QgdHlwZXMuCiAgICAqLwogICAgcmV0ID0gMDsKICAgIGZvciAoZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7IGZhY2V0TGluayAhPSBOVUxMOwoJZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0KSB7CgkKCXN3aXRjaCAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgkJICAgIAoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTGlzdFNpbXBsZVR5cGVGYWNldChmYWNldExpbmstPmZhY2V0LAoJCSAgICB2YWx1ZSwgbGVuZ3RoLCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWNvbnRpbnVlOwoJfQoJaWYgKHJldCA8IDApIHsKCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJInZhbGlkYXRpbmcgYWdhaW5zdCBhIGxpc3QgdHlwZSBmYWNldCIpOwoJICAgIHJldHVybiAoLTEpOwoJfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkgICAgaWYgKGZpcmVFcnJvcnMpCQkKCQl4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCXZhbHVlLCBsZW5ndGgsIHR5cGUsIGZhY2V0TGluay0+ZmFjZXQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIGVsc2UKCQlyZXR1cm4gKHJldCk7CgkgICAgaWYgKGVycm9yID09IDApCgkJZXJyb3IgPSByZXQ7Cgl9CglyZXQgPSAwOwogICAgfQoKcGF0dGVybl9hbmRfZW51bToKICAgIGlmIChlcnJvciA+PSAwKSB7CglpbnQgZm91bmQgPSAwOwoJLyoKCSogUHJvY2VzcyBlbnVtZXJhdGlvbnMuIEZhY2V0IHZhbHVlcyBhcmUgaW4gdGhlIHZhbHVlIHNwYWNlCgkqIG9mIHRoZSBkZWZpbmluZyB0eXBlJ3MgYmFzZSB0eXBlLiBUaGlzIHNlZW1zIHRvIGJlIGEgYnVnIGluIHRoZQoJKiBYTUwgU2NoZW1hIDEuMCBzcGVjLiBVc2UgdGhlIHdoaXRlc3BhY2UgdHlwZSBvZiB0aGUgYmFzZSB0eXBlLgoJKiBPbmx5IHRoZSBmaXJzdCBzZXQgb2YgZW51bWVyYXRpb25zIGluIHRoZSBhbmNlc3Rvci1vci1zZWxmIGF4aXMKCSogaXMgdXNlZCBmb3IgdmFsaWRhdGlvbi4KCSovCglyZXQgPSAwOwoJdG1wVHlwZSA9IHR5cGU7CglkbyB7CgkgICAgZm9yIChmYWNldCA9IHRtcFR5cGUtPmZhY2V0czsgZmFjZXQgIT0gTlVMTDsgZmFjZXQgPSBmYWNldC0+bmV4dCkgewoJCWlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKQoJCSAgICBjb250aW51ZTsKCQlmb3VuZCA9IDE7CgkJcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoZmFjZXQtPnZhbCwgdmFsKTsKCQlpZiAocmV0ID09IDEpCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVGYWNldHMiLAoJCQkidmFsaWRhdGluZyBhZ2FpbnN0IGFuIGVudW1lcmF0aW9uIGZhY2V0Iik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CgkgICAgaWYgKHJldCAhPSAwKQoJCWJyZWFrOwoJICAgIHRtcFR5cGUgPSB0bXBUeXBlLT5iYXNlVHlwZTsKCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmCgkgICAgKHRtcFR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSk7CglpZiAoZm91bmQgJiYgKHJldCA9PSAwKSkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRDsKCSAgICBpZiAoZmlyZUVycm9ycykgewoJCXhtbFNjaGVtYUZhY2V0RXJyKGFjdHh0LCByZXQsIG5vZGUsCgkJICAgIHZhbHVlLCAwLCB0eXBlLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4gKHJldCk7CgkgICAgaWYgKGVycm9yID09IDApCgkJZXJyb3IgPSByZXQ7Cgl9CiAgICB9CgogICAgaWYgKGVycm9yID49IDApIHsKCWludCBmb3VuZDsKCS8qCgkqIFByb2Nlc3MgcGF0dGVycy4gUGF0dGVybiBmYWNldHMgYXJlIE9SZWQgYXQgdHlwZSBsZXZlbAoJKiBhbmQgQU5EZWQgaWYgZGVyaXZlZC4gV2FsayB0aGUgYmFzZSB0eXBlIGF4aXMuCgkqLwoJdG1wVHlwZSA9IHR5cGU7CglmYWNldCA9IE5VTEw7CglkbyB7CgkgICAgZm91bmQgPSAwOwoJICAgIGZvciAoZmFjZXRMaW5rID0gdG1wVHlwZS0+ZmFjZXRTZXQ7IGZhY2V0TGluayAhPSBOVUxMOwoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikKCQkgICAgY29udGludWU7CgkJZm91bmQgPSAxOwoJCS8qIAoJCSogTk9URSB0aGF0IGZvciBwYXR0ZXJucywgQHZhbHVlIG5lZWRzIHRvIGJlIHRoZQoJCSogbm9ybWFsaXplZCB2YXVsZS4KCQkqLwoJCXJldCA9IHhtbFJlZ2V4cEV4ZWMoZmFjZXRMaW5rLT5mYWNldC0+cmVnZXhwLCB2YWx1ZSk7CgkJaWYgKHJldCA9PSAxKQoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkJInZhbGlkYXRpbmcgYWdhaW5zdCBhIHBhdHRlcm4gZmFjZXQiKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfSBlbHNlIHsKCQkgICAgLyogCgkJICAgICogU2F2ZSB0aGUgbGFzdCBub24tdmFsaWRhdGluZyBmYWNldC4KCQkgICAgKi8KCQkgICAgZmFjZXQgPSBmYWNldExpbmstPmZhY2V0OwoJCX0KCSAgICB9CgkgICAgaWYgKGZvdW5kICYmIChyZXQgIT0gMSkpIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfUEFUVEVSTl9WQUxJRDsKCQlpZiAoZmlyZUVycm9ycykgewoJCSAgICB4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCQl2YWx1ZSwgMCwgdHlwZSwgZmFjZXQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0gZWxzZQoJCSAgICByZXR1cm4gKHJldCk7CgkJaWYgKGVycm9yID09IDApCgkJICAgIGVycm9yID0gcmV0OwoJCWJyZWFrOwoJICAgIH0KCSAgICB0bXBUeXBlID0gdG1wVHlwZS0+YmFzZVR5cGU7Cgl9IHdoaWxlICgodG1wVHlwZSAhPSBOVUxMKSAmJiAodG1wVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKTsKICAgIH0KCiAgICByZXR1cm4gKGVycm9yKTsKfQogCnN0YXRpYyB4bWxDaGFyICoKeG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQljb25zdCB4bWxDaGFyICp2YWx1ZSkKewogICAgc3dpdGNoICh4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKSkgewkKCWNhc2UgWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFOgoJICAgIHJldHVybiAoeG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcodmFsdWUpKTsKCWNhc2UgWE1MX1NDSEVNQV9XSElURVNQQUNFX1JFUExBQ0U6CgkgICAgcmV0dXJuICh4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSkpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gKE5VTEwpOwogICAgfQp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlUU5hbWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCSAgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkgICAgICAgeG1sU2NoZW1hVmFsUHRyICp2YWwsCgkJICAgICAgIGludCB2YWxOZWVkZWQpCnsKICAgIGludCByZXQ7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CiAgICB4bWxDaGFyICpsb2NhbCwgKnByZWZpeCA9IE5VTEw7CiAgICAKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAocmV0ID09IC0xKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVRTmFtZSIsCgkJImNhbGxpbmcgeG1sVmFsaWRhdGVRTmFtZSgpIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglyZXR1cm4oIFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSk7CiAgICB9CiAgICAvKgogICAgKiBOT1RFOiB4bWxTcGxpdFFOYW1lMiB3aWxsIGFsd2F5cyByZXR1cm4gYSBkdXBsaWNhdGVkCiAgICAqIHN0cmluZ3MuCiAgICAqLwogICAgbG9jYWwgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CiAgICBpZiAobG9jYWwgPT0gTlVMTCkKCWxvY2FsID0geG1sU3RyZHVwKHZhbHVlKTsKICAgIC8qCiAgICAqIE9QVElNSVpFIFRPRE86IFVzZSBmbGFncyBmb3I6CiAgICAqICAtIGlzIHRoZXJlIGFueSBuYW1lc3BhY2UgYmluZGluZz8KICAgICogIC0gaXMgdGhlcmUgYSBkZWZhdWx0IG5hbWVzcGFjZT8KICAgICovCiAgICBuc05hbWUgPSB4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UodmN0eHQsIHByZWZpeCk7CiAgICAKICAgIGlmIChwcmVmaXggIT0gTlVMTCkgewoJeG1sRnJlZShwcmVmaXgpOwoJLyoKCSogQSBuYW1lc3BhY2UgbXVzdCBiZSBmb3VuZCBpZiB0aGUgcHJlZml4IGlzCgkqIE5PVCBOVUxMLgoJKi8KCWlmIChuc05hbWUgPT0gTlVMTCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIHJldCwgTlVMTCwKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyAiCgkJImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluICIKCQkic2NvcGUiLCB2YWx1ZSwgTlVMTCk7CgkgICAgaWYgKGxvY2FsICE9IE5VTEwpCgkJeG1sRnJlZShsb2NhbCk7CgkgICAgcmV0dXJuIChyZXQpOwoJfQogICAgfQogICAgaWYgKHZhbE5lZWRlZCAmJiB2YWwpIHsKCWlmIChuc05hbWUgIT0gTlVMTCkKCSAgICAqdmFsID0geG1sU2NoZW1hTmV3UU5hbWVWYWx1ZSgKCQlCQURfQ0FTVCB4bWxTdHJkdXAobnNOYW1lKSwgQkFEX0NBU1QgbG9jYWwpOwoJZWxzZQoJICAgICp2YWwgPSB4bWxTY2hlbWFOZXdRTmFtZVZhbHVlKE5VTEwsCgkJQkFEX0NBU1QgbG9jYWwpOwogICAgfSBlbHNlCgl4bWxGcmVlKGxvY2FsKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qCiogY3ZjLXNpbXBsZS10eXBlCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCSAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICB4bWxTY2hlbWFWYWxQdHIgKnJldFZhbCwKCQkJICAgICBpbnQgZmlyZUVycm9ycywKCQkJICAgICBpbnQgbm9ybWFsaXplLAoJCQkgICAgIGludCBpc05vcm1hbGl6ZWQpCnsKICAgIGludCByZXQgPSAwLCB2YWxOZWVkZWQgPSAocmV0VmFsKSA/IDEgOiAwOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbCA9IE5VTEw7CiAgICB4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlIHdzOwogICAgeG1sQ2hhciAqbm9ybVZhbHVlID0gTlVMTDsKCiNkZWZpbmUgTk9STUFMSVpFKGF0eXBlKSBcCiAgICBpZiAoKCEgaXNOb3JtYWxpemVkKSAmJiBcCiAgICAobm9ybWFsaXplIHx8ICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEKSkpIHsgXAoJbm9ybVZhbHVlID0geG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoYXR5cGUsIHZhbHVlKTsgXAoJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSBcCgkgICAgdmFsdWUgPSBub3JtVmFsdWU7IFwKCWlzTm9ybWFsaXplZCA9IDE7IFwKICAgIH0KICAgIAogICAgaWYgKChyZXRWYWwgIT0gTlVMTCkgJiYgKCpyZXRWYWwgIT0gTlVMTCkpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSgqcmV0VmFsKTsKCSpyZXRWYWwgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogMy4xNC40IFNpbXBsZSBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwogICAgKiBWYWxpZGF0aW9uIFJ1bGU6IFN0cmluZyBWYWxpZAogICAgKi8KICAgIC8qCiAgICAqIDEgSXQgaXMgc2NoZW1hLXZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZAogICAgKiBieSBEYXRhdHlwZSBWYWxpZCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCiAgICAqLwogICAgLyoKICAgICogMi4xIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUWSBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVFkgZ2l2ZW4KICAgICogdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLCB0aGVuCiAgICAqIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZCBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4yIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUSUVTIG9yIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEVOVElUSUVTCiAgICAqIGdpdmVuIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwKICAgICogdGhlbiBldmVyeSB3aGl0ZXNwYWNlLWRlbGltaXRlZCBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkCiAgICAqIGVudGl0eSBuYW1lty4KICAgICovCiAgICAvKgogICAgKiAyLjMgb3RoZXJ3aXNlIG5vIGZ1cnRoZXIgY29uZGl0aW9uIGFwcGxpZXMuCiAgICAqLwogICAgaWYgKCghIHZhbE5lZWRlZCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUUpKQoJdmFsTmVlZGVkID0gMTsKICAgIGlmICh2YWx1ZSA9PSBOVUxMKQoJdmFsdWUgPSBCQURfQ0FTVCAiIjsKICAgIGlmIChJU19BTllfU0lNUExFX1RZUEUodHlwZSkgfHwgVkFSSUVUWV9BVE9NSUModHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgYmlUeXBlOyAvKiBUaGUgYnVpbHQtaW4gdHlwZS4gKi8KCS8qCgkqIFNQRUMgKDEuMi4xKSAiaWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcKCSogYSBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSIKCSovCgkvKgoJKiBXaGl0ZXNwYWNlLW5vcm1hbGl6ZS4KCSovCglOT1JNQUxJWkUodHlwZSk7CglpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBidWlsdC1pbiB0eXBlLgoJICAgICovCgkgICAgYmlUeXBlID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgd2hpbGUgKChiaVR5cGUgIT0gTlVMTCkgJiYKCQkoYmlUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpCgkJYmlUeXBlID0gYmlUeXBlLT5iYXNlVHlwZTsKCgkgICAgaWYgKGJpVHlwZSA9PSBOVUxMKSB7CgkJQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJICAgICJjb3VsZCBub3QgZ2V0IHRoZSBidWlsdC1pbiB0eXBlIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UKCSAgICBiaVR5cGUgPSB0eXBlOwoJLyoKCSogTk9UQVRJT05zIG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGhlcmUsIHNpbmNlIHRoZXkgbmVlZAoJKiB0byBsb29rdXAgaW4gdGhlIGhhc2h0YWJsZSBvZiBOT1RBVElPTiBkZWNsYXJhdGlvbnMgb2YgdGhlIHNjaGVtYS4KCSovCglpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgewkgICAgCgkgICAgc3dpdGNoIChiaVR5cGUtPmJ1aWx0SW5UeXBlKSB7CQkKCQljYXNlIFhNTF9TQ0hFTUFTX05PVEFUSU9OOgkJICAgIAoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uKAoJCQkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCwKCQkJKCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0KS0+c2NoZW1hLAoJCQlOVUxMLCB2YWx1ZSwgJnZhbCwgdmFsTmVlZGVkKTsKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BU19RTkFNRToKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVRTmFtZSgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCwKCQkJdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSk7CgkJICAgIGlmICh2YWxOZWVkZWQpCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCAmdmFsLCBOVUxMKTsKCQkgICAgZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgTlVMTCwgTlVMTCk7CgkJICAgIGJyZWFrOwoJICAgIH0KCX0gZWxzZSBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1BBUlNFUikgewkgICAgCgkgICAgc3dpdGNoIChiaVR5cGUtPmJ1aWx0SW5UeXBlKSB7CQkgICAgCgkJY2FzZSBYTUxfU0NIRU1BU19OT1RBVElPTjoKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbihOVUxMLAoJCQkoKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIGFjdHh0KS0+c2NoZW1hLCBub2RlLAoJCQl2YWx1ZSwgJnZhbCwgdmFsTmVlZGVkKTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKTsKCQkgICAgaWYgKHZhbE5lZWRlZCkKCQkJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGVOb05vcm0oYmlUeXBlLAoJCQkgICAgdmFsdWUsICZ2YWwsIG5vZGUpOwoJCSAgICBlbHNlCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCBOVUxMLCBub2RlKTsKCQkgICAgYnJlYWs7CgkgICAgfQkgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIFZhbGlkYXRpb24gdmlhIGEgcHVibGljIEFQSSBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LgoJICAgICovCgkgICAgVE9ETwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAidmFsaWRhdGluZyBhZ2FpbnN0IGEgYnVpbHQtaW4gdHlwZSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGlmIChWQVJJRVRZX0xJU1QodHlwZSkpCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJICAgIGVsc2UKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CSAgICAKCX0KCWlmICgocmV0ID09IDApICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSEFTX0ZBQ0VUUykpIHsKCSAgICAvKgoJICAgICogQ2hlY2sgZmFjZXRzLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJKHhtbFNjaGVtYVZhbFR5cGUpIGJpVHlwZS0+YnVpbHRJblR5cGUsIHZhbHVlLCB2YWwsCgkJMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJCSJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBhdG9taWMgc2ltcGxlIHR5cGUiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJaWYgKFZBUklFVFlfTElTVCh0eXBlKSkgCgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQllbHNlCgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsJCQoJICAgIH0KCX0KCWlmIChmaXJlRXJyb3JzICYmIChyZXQgPiAwKSkKCSAgICB4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKGFjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlLCAxKTsKICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKSB7CgoJeG1sU2NoZW1hVHlwZVB0ciBpdGVtVHlwZTsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcFZhbHVlID0gTlVMTDsKCXVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCXhtbFNjaGVtYVZhbFB0ciBwcmV2VmFsID0gTlVMTCwgY3VyVmFsID0gTlVMTDsKCS8qIDEuMi4yIGlmIHt2YXJpZXR5fSBpcyC3bGlzdLcgdGhlbiB0aGUgc3RyaW5nIG11c3QgYmUgYSBzZXF1ZW5jZQoJKiBvZiB3aGl0ZSBzcGFjZSBzZXBhcmF0ZWQgdG9rZW5zLCBlYWNoIG9mIHdoaWNoILdtYXRjaLdlcyBhIGxpdGVyYWwKCSogaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7aXRlbSB0eXBlIGRlZmluaXRpb259CgkqLwoJLyoKCSogTm90ZSB0aGF0IFhNTF9TQ0hFTUFTX1RZUEVfTk9STVZBTFVFTkVFREVEIHdpbGwgYmUgc2V0IGlmCgkqIHRoZSBsaXN0IHR5cGUgaGFzIGFuIGVudW0gb3IgcGF0dGVybiBmYWNldC4KCSovCglOT1JNQUxJWkUodHlwZSk7CgkvKgoJKiBWQUwgVE9ETzogT3B0aW1pemUgdmFsaWRhdGlvbiBvZiBlbXB0eSB2YWx1ZXMuCgkqIFZBTCBUT0RPOiBXZSBkbyBub3QgaGF2ZSBjb21wdXRlZCB2YWx1ZXMgZm9yIGxpc3RzLgoJKi8KCWl0ZW1UeXBlID0gR0VUX0xJU1RfSVRFTV9UWVBFKHR5cGUpOwkKCWN1ciA9IHZhbHVlOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wVmFsdWUgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBsZW4rKzsKCgkgICAgaWYgKHZhbE5lZWRlZCkKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLCBpdGVtVHlwZSwKCQkgICAgdG1wVmFsdWUsICZjdXJWYWwsIGZpcmVFcnJvcnMsIDAsIDEpOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLCBpdGVtVHlwZSwKCQkgICAgdG1wVmFsdWUsIE5VTEwsIGZpcmVFcnJvcnMsIDAsIDEpOwoJICAgIEZSRUVfQU5EX05VTEwodG1wVmFsdWUpOwoJICAgIGlmIChjdXJWYWwgIT0gTlVMTCkgewoJCS8qCgkJKiBBZGQgdG8gbGlzdCBvZiBjb21wdXRlZCB2YWx1ZXMuCgkJKi8KCQlpZiAodmFsID09IE5VTEwpCgkJICAgIHZhbCA9IGN1clZhbDsKCQllbHNlCgkJICAgIHhtbFNjaGVtYVZhbHVlQXBwZW5kKHByZXZWYWwsIGN1clZhbCk7CgkJcHJldlZhbCA9IGN1clZhbDsKCQljdXJWYWwgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgYW4gaXRlbSBvZiBsaXN0IHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQlicmVhazsKCSAgICB9CSAgICAKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwoJRlJFRV9BTkRfTlVMTCh0bXBWYWx1ZSk7CglpZiAoKHJldCA9PSAwKSAmJiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFMpKSB7CgkgICAgLyoKCSAgICAqIEFwcGx5IGZhY2V0cyAocGF0dGVybiwgZW51bWVyYXRpb24pLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJWE1MX1NDSEVNQVNfVU5LTk9XTiwgdmFsdWUsIHZhbCwKCQlsZW4sIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCQkidmFsaWRhdGluZyBmYWNldHMgb2YgbGlzdCBzaW1wbGUgdHlwZSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgfQoJfQoJaWYgKGZpcmVFcnJvcnMgJiYgKHJldCA+IDApKSB7CgkgICAgLyogCgkgICAgKiBSZXBvcnQgdGhlIG5vcm1hbGl6ZWQgdmFsdWUuCgkgICAgKi8KCSAgICBub3JtYWxpemUgPSAxOwoJICAgIE5PUk1BTElaRSh0eXBlKTsKCSAgICB4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKGFjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlLCAxKTsKCX0KICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTih0eXBlKSkgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyTGluazsKCS8qCgkqIFRPRE86IEZvciBhbGwgZGF0YXR5cGVzILdkZXJpdmVktyBieSC3dW5pb263ICB3aGl0ZVNwYWNlIGRvZXMKCSogbm90IGFwcGx5IGRpcmVjdGx5OyBob3dldmVyLCB0aGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263CgkqIHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlCgkqILdtZW1iZXJUeXBlc7cgYWdhaW5zdCB3aGljaCB0aGUgt3VuaW9utyBpcyBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkLgoJKgoJKiBUaGlzIG1lYW5zIHRoYXQgdGhlIHZhbHVlIGlzIG5vcm1hbGl6ZWQgYnkgdGhlIGZpcnN0IHZhbGlkYXRpbmcKCSogbWVtYmVyIHR5cGUsIHRoZW4gdGhlIGZhY2V0cyBvZiB0aGUgdW5pb24gdHlwZSBhcmUgYXBwbGllZC4gVGhpcwoJKiBuZWVkcyBjaGFuZ2luZyBvZiB0aGUgdmFsdWUhCgkqLwoKCS8qCgkqIDEuMi4zIGlmIHt2YXJpZXR5fSBpcyC3dW5pb263IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgYQoJKiBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2YgYXQgbGVhc3Qgb25lIG1lbWJlciBvZgoJKiB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9CgkqLwoJbWVtYmVyTGluayA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHR5cGUpOwoJaWYgKG1lbWJlckxpbmsgPT0gTlVMTCkgewoJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSJ1bmlvbiBzaW1wbGUgdHlwZSBoYXMgbm8gbWVtYmVyIHR5cGVzIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0JCgkvKgoJKiBBbHdheXMgbm9ybWFsaXplIHVuaW9uIHR5cGUgdmFsdWVzLCBzaW5jZSB3ZSBjdXJyZW50bHkKCSogY2Fubm90IHN0b3JlIHRoZSB3aGl0ZXNwYWNlIGluZm9ybWF0aW9uIHdpdGggdGhlIHZhbHVlCgkqIGl0c2VsZjsgb3RoZXJ3aXNlIGEgbGF0ZXIgdmFsdWUtY29tcGFyaXNvbiB3b3VsZCBiZQoJKiBub3QgcG9zc2libGUuCgkqLwoJd2hpbGUgKG1lbWJlckxpbmsgIT0gTlVMTCkgewoJICAgIGlmICh2YWxOZWVkZWQpIAoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoYWN0eHQsIG5vZGUsCgkJICAgIG1lbWJlckxpbmstPnR5cGUsIHZhbHVlLCAmdmFsLCAwLCAxLCAwKTsKCSAgICBlbHNlCgkJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShhY3R4dCwgbm9kZSwKCQkgICAgbWVtYmVyTGluay0+dHlwZSwgdmFsdWUsIE5VTEwsIDAsIDEsIDApOwoJICAgIGlmIChyZXQgPD0gMCkKCQlicmVhazsKCSAgICBtZW1iZXJMaW5rID0gbWVtYmVyTGluay0+bmV4dDsKCX0KCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJICAgICJ2YWxpZGF0aW5nIG1lbWJlcnMgb2YgdW5pb24gc2ltcGxlIHR5cGUiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzM7Cgl9CgkvKgoJKiBBcHBseSBmYWNldHMgKHBhdHRlcm4sIGVudW1lcmF0aW9uKS4KCSovCglpZiAoKHJldCA9PSAwKSAmJiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFMpKSB7CgkgICAgLyoKCSAgICAqIFRoZSBub3JtYWxpemF0aW9uIGJlaGF2aW9yIG9mILd1bmlvbrcgdHlwZXMgaXMgY29udHJvbGxlZCBieQoJICAgICogdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlILdtZW1iZXJUeXBlc7cKCSAgICAqIGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4KCSAgICAqLwoJICAgIE5PUk1BTElaRShtZW1iZXJMaW5rLT50eXBlKTsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyhhY3R4dCwgbm9kZSwgdHlwZSwKCQlYTUxfU0NIRU1BU19VTktOT1dOLCB2YWx1ZSwgdmFsLAoJCTAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCQkidmFsaWRhdGluZyBmYWNldHMgb2YgdW5pb24gc2ltcGxlIHR5cGUiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwkJCgkgICAgfQoJfQoJaWYgKGZpcmVFcnJvcnMgJiYgKHJldCA+IDApKQoJICAgIHhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoYWN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUsIDEpOwogICAgfQoKICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUobm9ybVZhbHVlKTsKICAgIGlmIChyZXQgPT0gMCkgewoJaWYgKHJldFZhbCAhPSBOVUxMKQoJICAgICpyZXRWYWwgPSB2YWw7CgllbHNlIGlmICh2YWwgIT0gTlVMTCkKCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUodmFsKTsKICAgIH0gZWxzZSBpZiAodmFsICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlVmFsdWUodmFsKTsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKG5vcm1WYWx1ZSk7CiAgICBpZiAodmFsICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlVmFsdWUodmFsKTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZFeHBhbmRRTmFtZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICBjb25zdCB4bWxDaGFyICoqbnNOYW1lLAoJCQkgICBjb25zdCB4bWxDaGFyICoqbG9jYWxOYW1lKQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBpZiAoKG5zTmFtZSA9PSBOVUxMKSB8fCAobG9jYWxOYW1lID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CiAgICAqbnNOYW1lID0gTlVMTDsKICAgICpsb2NhbE5hbWUgPSBOVUxMOwoKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA9PSAtMSkKCXJldHVybiAoLTEpOwogICAgaWYgKHJldCA+IDApIHsKCXhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLCBOVUxMLAoJICAgIHZhbHVlLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIDEpOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHsKCXhtbENoYXIgKmxvY2FsID0gTlVMTDsKCXhtbENoYXIgKnByZWZpeDsKCgkvKgoJKiBOT1RFOiB4bWxTcGxpdFFOYW1lMiB3aWxsIHJldHVybiBhIGR1cGxpY2F0ZWQKCSogc3RyaW5nLgoJKi8KCWxvY2FsID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwoJVkFMX0NSRUFURV9ESUNUOwoJaWYgKGxvY2FsID09IE5VTEwpCgkgICAgKmxvY2FsTmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIHZhbHVlLCAtMSk7CgllbHNlIHsKCSAgICAqbG9jYWxOYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbG9jYWwsIC0xKTsKCSAgICB4bWxGcmVlKGxvY2FsKTsKCX0KCgkqbnNOYW1lID0geG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHZjdHh0LCBwcmVmaXgpOwoKCWlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIHhtbEZyZWUocHJlZml4KTsKCSAgICAvKgoJICAgICogQSBuYW1lc3BhY2UgbXVzdCBiZSBmb3VuZCBpZiB0aGUgcHJlZml4IGlzIE5PVCBOVUxMLgoJICAgICovCgkgICAgaWYgKCpuc05hbWUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLCBOVUxMLAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJICAgICJUaGUgUU5hbWUgdmFsdWUgJyVzJyBoYXMgbm8gIgoJCSAgICAiY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUiLAoJCSAgICB2YWx1ZSwgTlVMTCk7CgkJcmV0dXJuICgyKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHIsCgkJCXhtbFNjaGVtYVR5cGVQdHIgKmxvY2FsVHlwZSwKCQkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgaW50IHJldCA9IDA7CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAoNCkKICAgICogQU5ECiAgICAqIFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KSAoY3ZjLWFzc2Vzcy1lbHQpCiAgICAqICAgKDEuMi4xLjIuMSkgLSAoMS4yLjEuMi40KQogICAgKiBIYW5kbGUgJ3hzaTp0eXBlJy4KICAgICovCiAgICBpZiAobG9jYWxUeXBlID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgICpsb2NhbFR5cGUgPSBOVUxMOwogICAgaWYgKGlhdHRyID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgZWxzZSB7Cgljb25zdCB4bWxDaGFyICpuc05hbWUgPSBOVUxMLCAqbG9jYWwgPSBOVUxMOwoJLyoKCSogVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhICp3YXJuaW5nKiB0aGF0IHRoZSB0eXBlIHdhcyBvdmVycmlkZW4KCSogYnkgdGhlIGluc3RhbmNlLgoJKi8KCUFDVElWQVRFX0FUVFJJQlVURShpYXR0cik7CgkvKgoJKiAoY3ZjLWVsdCkgKDMuMy40KSA6ICg0LjEpCgkqIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMikKCSovCglyZXQgPSB4bWxTY2hlbWFWRXhwYW5kUU5hbWUodmN0eHQsIGlhdHRyLT52YWx1ZSwKCSAgICAmbnNOYW1lLCAmbG9jYWwpOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hUU5hbWVFeHBhbmQoKSB0byB2YWxpZGF0ZSB0aGUgIgoJCSAgICAiYXR0cmlidXRlICd4c2k6dHlwZSciKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGV4aXQ7Cgl9CgkvKgoJKiAoY3ZjLWVsdCkgKDMuMy40KSA6ICg0LjIpCgkqIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMykKCSovCgkqbG9jYWxUeXBlID0geG1sU2NoZW1hR2V0VHlwZSh2Y3R4dC0+c2NoZW1hLCBsb2NhbCwgbnNOYW1lKTsKCWlmICgqbG9jYWxUeXBlID09IE5VTEwpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF80XzIsIE5VTEwsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSJUaGUgUU5hbWUgdmFsdWUgJyVzJyBvZiB0aGUgeHNpOnR5cGUgYXR0cmlidXRlIGRvZXMgbm90ICIKCQkicmVzb2x2ZSB0byBhIHR5cGUgZGVmaW5pdGlvbiIsCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgbnNOYW1lLCBsb2NhbCksIE5VTEwpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICByZXQgPSB2Y3R4dC0+ZXJyOwoJICAgIGdvdG8gZXhpdDsKCX0KCWlmIChlbGVtRGVjbCAhPSBOVUxMKSB7CgkgICAgaW50IHNldCA9IDA7CgoJICAgIC8qCgkgICAgKiBTUEVDIGN2Yy1lbHQgKDMuMy40KSA6ICg0LjMpIChUeXBlIERlcml2YXRpb24gT0spCgkgICAgKiAiVGhlILdsb2NhbCB0eXBlIGRlZmluaXRpb263IG11c3QgYmUgdmFsaWRseQoJICAgICogZGVyaXZlZCBmcm9tIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBnaXZlbiB0aGUgdW5pb24gb2YKCSAgICAqIHRoZSB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBhbmQgdGhlIHt0eXBlIGRlZmluaXRpb259J3MKCSAgICAqIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9LCBhcyBkZWZpbmVkIGluCgkgICAgKiBUeXBlIERlcml2YXRpb24gT0sgKENvbXBsZXgpICinMy40LjYpCgkgICAgKiAoaWYgaXQgaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiksCgkgICAgKiBvciBnaXZlbiB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfSBhcyBkZWZpbmVkIGluIFR5cGUKCSAgICAqIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpIChpZiBpdCBpcyBhIHNpbXBsZSB0eXBlCgkgICAgKiBkZWZpbml0aW9uKS4iCgkgICAgKgoJICAgICoge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc306IHRoZSAiYmxvY2siIG9uIHRoZSBlbGVtZW50IGRlY2wuCgkgICAgKiB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfTogdGhlICJibG9jayIgb24gdGhlIHR5cGUgZGVmLgoJICAgICovCgkgICAgaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTikgfHwKCQkoZWxlbURlY2wtPnN1YnR5cGVzLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSkKCQlzZXQgfD0gU1VCU0VUX0VYVEVOU0lPTjsKCgkgICAgaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OKSB8fAoJCShlbGVtRGVjbC0+c3VidHlwZXMtPmZsYWdzICYKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikpCgkJc2V0IHw9IFNVQlNFVF9SRVNUUklDVElPTjsKCgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LKCpsb2NhbFR5cGUsCgkJZWxlbURlY2wtPnN1YnR5cGVzLCBzZXQpICE9IDApIHsKCQl4bWxDaGFyICpzdHIgPSBOVUxMOwoKCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8zLCBOVUxMLCBOVUxMLAoJCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiAnJXMnLCBzcGVjaWZpZWQgYnkgeHNpOnR5cGUsIGlzICIKCQkgICAgImJsb2NrZWQgb3Igbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSAgICAib2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24iLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkoKmxvY2FsVHlwZSktPnRhcmdldE5hbWVzcGFjZSwKCQkJKCpsb2NhbFR5cGUpLT5uYW1lKSwKCQkgICAgTlVMTCk7CgkJRlJFRV9BTkRfTlVMTChzdHIpOwoJCXJldCA9IHZjdHh0LT5lcnI7CgkJKmxvY2FsVHlwZSA9IE5VTEw7CgkgICAgfQoJfQogICAgfQpleGl0OgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICBBQ1RJVkFURV9FTEVNOwogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtRGVjbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wgPSB2Y3R4dC0+aW5vZGUtPmRlY2w7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFjdHVhbFR5cGUgPSBFTEVNX1RZUEUoZWxlbURlY2wpOwoKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDEKICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwgTlVMTCwKCSAgICAiTm8gbWF0Y2hpbmcgZGVjbGFyYXRpb24gYXZhaWxhYmxlIik7CiAgICAgICAgcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDIKICAgICovCiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkgewoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfMiwgTlVMTCwKCSAgICAiVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gaXMgYWJzdHJhY3QiKTsKICAgICAgICByZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7CglpbnQgcmV0OwoJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiAzCgkqIEhhbmRsZSAneHNpOm5pbCcuCgkqLwoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkgICAgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMKTsKCWlmIChpYXR0cikgewoJICAgIEFDVElWQVRFX0FUVFJJQlVURShpYXR0cik7CgkgICAgLyoKCSAgICAqIFZhbGlkYXRlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkJKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIE5VTEwsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQk9PTEVBTiksCgkJaWF0dHItPnZhbHVlLCAmKGlhdHRyLT52YWwpLCAxLCAwLCAwKTsKCSAgICBBQ1RJVkFURV9FTEVNOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtRGVjbCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSB0byAiCgkJICAgICJ2YWxpZGF0ZSB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBpZiAocmV0ID09IDApIHsKCQlpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpID09IDApIHsKCQkgICAgLyoKCQkgICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjEKCQkgICAgKi8KCQkgICAgVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18xLCBOVUxMLAoJCQkiVGhlIGVsZW1lbnQgaXMgbm90ICduaWxsYWJsZSciKTsKCQkgICAgLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkJfSBlbHNlIHsKCQkgICAgaWYgKHhtbFNjaGVtYVZhbHVlR2V0QXNCb29sZWFuKGlhdHRyLT52YWwpKSB7CgkJCS8qCgkJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjIKCQkJKi8KCQkJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSAmJgoJCQkgICAgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewoJCQkgICAgVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzIsIE5VTEwsCgkJCQkiVGhlIGVsZW1lbnQgY2Fubm90IGJlICduaWxsZWQnIGJlY2F1c2UgIgoJCQkJInRoZXJlIGlzIGEgZml4ZWQgdmFsdWUgY29uc3RyYWludCBkZWZpbmVkICIKCQkJCSJmb3IgaXQiKTsKCQkJICAgICAvKiBEb2VzIG5vdCByZXR1cm4gYW4gZXJyb3Igb24gcHVycG9zZS4gKi8KCQkJfSBlbHNlCgkJCSAgICB2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9CgkJCQlYTUxfU0NIRU1BX0VMRU1fSU5GT19OSUxMRUQ7CgkJICAgIH0KCQl9CgkgICAgfQoJfQoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNAoJKiBIYW5kbGUgJ3hzaTp0eXBlJy4KCSovCglpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCSAgICBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9UWVBFKTsKCWlmIChpYXR0cikgewoJICAgIHhtbFNjaGVtYVR5cGVQdHIgbG9jYWxUeXBlID0gTlVMTDsKCgkgICAgcmV0ID0geG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUodmN0eHQsIGlhdHRyLCAmbG9jYWxUeXBlLAoJCWVsZW1EZWNsKTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0ID09IC0xKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2wiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSgpIHRvICIKCQkJInByb2Nlc3MgdGhlIGF0dHJpYnV0ZSAneHNpOnR5cGUnIik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQkvKiBEb2VzIG5vdCByZXR1cm4gYW4gZXJyb3Igb24gcHVycG9zZS4gKi8KCSAgICB9CgkgICAgaWYgKGxvY2FsVHlwZSAhPSBOVUxMKSB7CgkJdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19MT0NBTF9UWVBFOwoJCWFjdHVhbFR5cGUgPSBsb2NhbFR5cGU7CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogSURDOiBSZWdpc3RlciBpZGVudGl0eS1jb25zdHJhaW50IFhQYXRoIG1hdGNoZXJzLgogICAgKi8KICAgIGlmICgoZWxlbURlY2wtPmlkY3MgIT0gTlVMTCkgJiYKCSh4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzKHZjdHh0LCBlbGVtRGVjbCkgPT0gLTEpKQoJICAgIHJldHVybiAoLTEpOwogICAgLyoKICAgICogTm8gYWN0dWFsIHR5cGUgZGVmaW5pdGlvbi4KICAgICovCiAgICBpZiAoYWN0dWFsVHlwZSA9PSBOVUxMKSB7CiAgICAJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIpOwogICAgCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSk7CiAgICB9CiAgICAvKgogICAgKiBSZW1lbWJlciB0aGUgYWN0dWFsIHR5cGUgZGVmaW5pdGlvbi4KICAgICovCiAgICB2Y3R4dC0+aW5vZGUtPnR5cGVEZWYgPSBhY3R1YWxUeXBlOwoKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkF0dHJpYnV0ZXNTaW1wbGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKICAgIGludCByZXQgPSAwLCBpOwoKICAgIC8qCiAgICAqIFNQRUMgY3ZjLXR5cGUgKDMuMS4xKQogICAgKiAiVGhlIGF0dHJpYnV0ZXMgb2YgbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nIHRob3NlIHdob3NlIG5hbWVzcGFjZQogICAgKiBuYW1lIGlzIGlkZW50aWNhbCB0byBodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBhbmQKICAgICogd2hvc2UgbG9jYWwgbmFtZSBpcyBvbmUgb2YgdHlwZSwgbmlsLCBzY2hlbWFMb2NhdGlvbiBvcgogICAgKiBub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uLiIKICAgICovCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zID09IDApCglyZXR1cm4gKDApOwogICAgZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CglpYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoISBpYXR0ci0+bWV0YVR5cGUpIHsKCSAgICBBQ1RJVkFURV9BVFRSSUJVVEUoaWF0dHIpCgkgICAgeG1sU2NoZW1hSWxsZWdhbEF0dHJFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGlhdHRyLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMTsKICAgICAgICB9CiAgICB9CiAgICBBQ1RJVkFURV9FTEVNCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qCiogQ2xlYW51cCBjdXJyZW50bHkgdXNlZCBhdHRyaWJ1dGUgaW5mb3MuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IGk7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBhdHRyOwoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybjsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTKSB7CgkgICAgaWYgKGF0dHItPmxvY2FsTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUoKHhtbENoYXIgKikgYXR0ci0+bG9jYWxOYW1lKTsKCSAgICBpZiAoYXR0ci0+bnNOYW1lICE9IE5VTEwpCgkJeG1sRnJlZSgoeG1sQ2hhciAqKSBhdHRyLT5uc05hbWUpOwoJfQoJaWYgKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCSAgICBpZiAoYXR0ci0+dmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKCh4bWxDaGFyICopIGF0dHItPnZhbHVlKTsKCX0KCWlmIChhdHRyLT52YWwgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShhdHRyLT52YWwpOwoJICAgIGF0dHItPnZhbCA9IE5VTEw7Cgl9CgltZW1zZXQoYXR0ciwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvKSk7CiAgICB9CiAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwp9CgovKgoqIDMuNC40IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKKiAgIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoQ29tcGxleCBUeXBlKSAoY3ZjLWNvbXBsZXgtdHlwZSkKKiAzLjIuNCBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gVmFsaWRhdGlvbiBSdWxlcwoqICAgVmFsaWRhdGlvbiBSdWxlOiBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoY3ZjLWF0dHJpYnV0ZSkKKiAgIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpIChjdmMtYXUpCioKKiBPbmx5ICJhc3Nlc3NlZCIgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIHdpbGwgYmUgdmlzaWJsZSB0bwoqIElEQ3MuIEkuZS4gbm90ICJsYXgiICh3aXRob3V0IGRlY2xhcmF0aW9uKSBhbmQgInNraXAiIHdpbGQgYXR0cmlidXRlcy4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSB2Y3R4dC0+aW5vZGUtPnR5cGVEZWY7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGF0dHJVc2VMaW5rOwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJVc2UgPSBOVUxMLCBhdHRyRGVjbCA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBhdHRyLCB0bXBBdHRyOwogICAgaW50IGksIGZvdW5kLCBuYkF0dHJzOwogICAgaW50IHhwYXRoUmVzID0gMCwgcmVzLCB3aWxkSURzID0gMCwgZml4ZWQ7CgogICAgLyoKICAgICogU1BFQyAoY3ZjLWF0dHJpYnV0ZSkKICAgICogKDEpICJUaGUgZGVjbGFyYXRpb24gbXVzdCBub3QgYmUgt2Fic2VudLcgKHNlZSBNaXNzaW5nCiAgICAqIFN1Yi1jb21wb25lbnRzICinNS4zKSBmb3IgaG93IHRoaXMgY2FuIGZhaWwgdG8gYmUKICAgICogdGhlIGNhc2UpLiIKICAgICogKDIpICJJdHMge3R5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgYmUgYWJzZW50LiIKICAgICoKICAgICogTk9URSAoMSkgKyAoMik6IFRoaXMgaXMgbm90IGhhbmRsZWQgaGVyZSwgc2luY2Ugd2UgY3VycmVudGx5IGRvIG5vdAogICAgKiBhbGxvdyB2YWxpZGF0aW9uIGFnYWluc3Qgc2NoZW1hcyB3aGljaCBoYXZlIG1pc3Npbmcgc3ViLWNvbXBvbmVudHMuCiAgICAqCiAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCiAgICAqICgzKSAiRm9yIGVhY2ggYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gaW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24KICAgICogaXRlbSdzIFthdHRyaWJ1dGVzXSBleGNlcHRpbmcgdGhvc2Ugd2hvc2UgW25hbWVzcGFjZSBuYW1lXSBpcwogICAgKiBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kIHdob3NlCiAgICAqIFtsb2NhbCBuYW1lXSBpcyBvbmUgb2YgdHlwZSwgbmlsLCBzY2hlbWFMb2NhdGlvbiBvcgogICAgKiBub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uLCB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nCiAgICAqIG11c3QgYmUgdHJ1ZToKICAgICoKICAgICovICAKICAgIG5iQXR0cnMgPSB2Y3R4dC0+bmJBdHRySW5mb3M7CiAgICBmb3IgKGF0dHJVc2VMaW5rID0gdHlwZS0+YXR0cmlidXRlVXNlczsgYXR0clVzZUxpbmsgIT0gTlVMTDsKCWF0dHJVc2VMaW5rID0gYXR0clVzZUxpbmstPm5leHQpIHsKCiAgICAgICAgZm91bmQgPSAwOwoJYXR0clVzZSA9IGF0dHJVc2VMaW5rLT5hdHRyOwoJLyoKCSogVkFMIFRPRE86IEltcGxlbWVudCBhIHJlYWwgImF0dHJpYnV0ZSB1c2UiIGNvbXBvbmVudC4KCSovCglpZiAoYXR0clVzZS0+cmVmRGVjbCAhPSBOVUxMKQoJICAgIGF0dHJEZWNsID0gYXR0clVzZS0+cmVmRGVjbDsKCWVsc2UKCSAgICBhdHRyRGVjbCA9IGF0dHJVc2U7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IG5iQXR0cnM7IGkrKykgewoJICAgIGF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMykKCSAgICAqIFNraXAgbWV0YSBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKGF0dHItPm1ldGFUeXBlKQoJCWNvbnRpbnVlOwoJICAgIGlmIChhdHRyLT5sb2NhbE5hbWVbMF0gIT0gYXR0ckRlY2wtPm5hbWVbMF0pCgkJY29udGludWU7CgkgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5sb2NhbE5hbWUsIGF0dHJEZWNsLT5uYW1lKSkKCQljb250aW51ZTsKCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSkpCgkJY29udGludWU7CgkgICAgZm91bmQgPSAxOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJICAgICogKDMuMSkgIklmIHRoZXJlIGlzIGFtb25nIHRoZSB7YXR0cmlidXRlIHVzZXN9IGFuIGF0dHJpYnV0ZQoJICAgICogdXNlIHdpdGggYW4ge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gd2hvc2Uge25hbWV9IG1hdGNoZXMKCSAgICAqIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSdzIFtsb2NhbCBuYW1lXSBhbmQgd2hvc2UKCSAgICAqIHt0YXJnZXQgbmFtZXNwYWNlfSBpcyBpZGVudGljYWwgdG8gdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbgoJICAgICogaXRlbSdzIFtuYW1lc3BhY2UgbmFtZV0gKHdoZXJlIGFuILdhYnNlbnS3IHt0YXJnZXQgbmFtZXNwYWNlfQoJICAgICogaXMgdGFrZW4gdG8gYmUgaWRlbnRpY2FsIHRvIGEgW25hbWVzcGFjZSBuYW1lXSB3aXRoIG5vIHZhbHVlKSwKCSAgICAqIHRoZW4gdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0CgkgICAgKiB0byB0aGF0IGF0dHJpYnV0ZSB1c2UgYXMgcGVyIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpCgkgICAgKiAopzMuNS40KS4gSW4gdGhpcyBjYXNlIHRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBvZiB0aGF0CgkgICAgKiBhdHRyaWJ1dGUgdXNlIGlzIHRoZSC3Y29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9utyBmb3IgdGhlCgkgICAgKiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHJlc3BlY3QgdG8gU2NoZW1hLVZhbGlkaXR5CgkgICAgKiBBc3Nlc3NtZW50IChBdHRyaWJ1dGUpICinMy4yLjQpIGFuZAoJICAgICogQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpICinMy4yLjUpLgoJICAgICovCgkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEOwoJICAgIGF0dHItPnVzZSA9IGF0dHJVc2U7CgkgICAgLyoKCSAgICAqIENvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbi4KCSAgICAqLwoJICAgIGF0dHItPmRlY2wgPSBhdHRyRGVjbDsKCSAgICBhdHRyLT50eXBlRGVmID0gYXR0ckRlY2wtPnN1YnR5cGVzOwoJICAgIGJyZWFrOwoJfQoKCWlmIChmb3VuZCkKCSAgICBjb250aW51ZTsKCglpZiAoYXR0clVzZS0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSB7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBub24tZXhpc3RlbnQsIHJlcXVpcmVkIGF0dHJpYnV0ZXMuCgkgICAgKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSAgICAqICg0KSAiVGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IG9mIGVhY2ggYXR0cmlidXRlIHVzZSBpbgoJICAgICogdGhlIHthdHRyaWJ1dGUgdXNlc30gd2hvc2Uge3JlcXVpcmVkfSBpcyB0cnVlIG1hdGNoZXMgb25lCgkgICAgKiBvZiB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW1zIGluIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uCgkgICAgKiBpdGVtJ3MgW2F0dHJpYnV0ZXNdIGFzIHBlciBjbGF1c2UgMy4xIGFib3ZlLiIKCSAgICAqLwoJICAgIHRtcEF0dHIgPSB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKHZjdHh0KTsKCSAgICBpZiAodG1wQXR0ciA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgKCQkgICAgInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oKSIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICB0bXBBdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX01JU1NJTkc7CgkgICAgdG1wQXR0ci0+dXNlID0gYXR0clVzZTsKCSAgICB0bXBBdHRyLT5kZWNsID0gYXR0ckRlY2w7CSAgICAKCX0gZWxzZSBpZiAoKGF0dHJVc2UtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCSAgICAoKGF0dHJVc2UtPmRlZlZhbHVlICE9IE5VTEwpIHx8CgkgICAgIChhdHRyRGVjbC0+ZGVmVmFsdWUgIT0gTlVMTCkpKSB7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBub24tZXhpc3RlbnQsIG9wdGlvbmFsLCBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICB0bXBBdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CgkgICAgaWYgKHRtcEF0dHIgPT0gTlVMTCkgewoJCVZFUlJPUl9JTlQoCgkJICAgICJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKCkiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgdG1wQXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQ7CgkgICAgdG1wQXR0ci0+dXNlID0gYXR0clVzZTsKCSAgICB0bXBBdHRyLT5kZWNsID0gYXR0ckRlY2w7CgkgICAgdG1wQXR0ci0+dHlwZURlZiA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCSAgICB0bXBBdHRyLT5sb2NhbE5hbWUgPSBhdHRyRGVjbC0+bmFtZTsKCSAgICB0bXBBdHRyLT5uc05hbWUgPSBhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlOwoJfQogICAgfQogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIFZhbGlkYXRlIGFnYWluc3QgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkvKgoJKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJKiAoMy4yLjEpICJUaGVyZSBtdXN0IGJlIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LiIKCSovCglmb3IgKGkgPSAwOyBpIDwgbmJBdHRyczsgaSsrKSB7CgkgICAgYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgzKQoJICAgICogU2tpcCBtZXRhIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAoYXR0ci0+c3RhdGUgIT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKQoJCWNvbnRpbnVlOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJICAgICogKDMuMi4yKSAiVGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoCgkgICAgKiByZXNwZWN0IHRvIGl0IGFzIGRlZmluZWQgaW4gSXRlbSBWYWxpZCAoV2lsZGNhcmQpICinMy4xMC40KS4iCgkgICAgKgoJICAgICogU1BFQyBJdGVtIFZhbGlkIChXaWxkY2FyZCkgKGN2Yy13aWxkY2FyZCkKCSAgICAqICIuLi4gaXRzIFtuYW1lc3BhY2UgbmFtZV0gbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0bwoJICAgICogdGhlIHdpbGRjYXJkIGNvbnN0cmFpbnQsIGFzIGRlZmluZWQgaW4gV2lsZGNhcmQgYWxsb3dzCgkgICAgKiBOYW1lc3BhY2UgTmFtZSAopzMuMTAuNCkuIgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ1ZDV2lsZGNhcmROYW1lc3BhY2UodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJICAgIGF0dHItPm5zTmFtZSkpIHsKCQkvKgoJCSogSGFuZGxlIHByb2Nlc3NDb250ZW50cy4KCQkqCgkJKiBTUEVDIChjdmMtd2lsZGNhcmQpOgoJCSogcHJvY2Vzc0NvbnRlbnRzIHwgY29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9uOgoJCSogInN0cmljdCIgICAgICAgICAgIm11c3RGaW5kIgoJCSogImxheCIgICAgICAgICAgICAgIm5vbmUiCgkJKiAic2tpcCIgICAgICAgICAgICAic2tpcCIKCQkqLwoJCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09CgkJICAgIFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7CgkJICAgICAvKgoJCSAgICAqIGNvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbiA9ICJza2lwIgoJCSAgICAqCgkJICAgICogU1BFQyBQU1ZJIEFzc2Vzc21lbnQgT3V0Y29tZSAoQXR0cmlidXRlKQoJCSAgICAqIFt2YWxpZGl0eV0gPSAibm90S25vd24iCgkJICAgICogW3ZhbGlkYXRpb24gYXR0ZW1wdGVkXSA9ICJub25lIgoJCSAgICAqLwoJCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9TS0lQOwoJCSAgICBjb250aW51ZTsKCQl9CgkJLyoKCQkqIEZpbmQgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJCSovCgkJYXR0ci0+ZGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2wodmN0eHQtPnNjaGVtYSwKCQkgICAgYXR0ci0+bG9jYWxOYW1lLCBhdHRyLT5uc05hbWUpOwoJCWlmIChhdHRyLT5kZWNsICE9IE5VTEwpIHsKCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEOwoJCSAgICAvKgoJCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkJICAgICogKDUpICJMZXQgW0RlZmluaXRpb246XSAgdGhlIHdpbGQgSURzIGJlIHRoZSBzZXQgb2YKCQkgICAgKiBhbGwgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gdG8gd2hpY2ggY2xhdXNlIDMuMgoJCSAgICAqIGFwcGxpZWQgYW5kIHdob3NlILd2YWxpZGF0aW9utyByZXN1bHRlZCBpbiBhCgkJICAgICogt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgb2YgbXVzdEZpbmQgb3Igbm8KCQkgICAgKiC3Y29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9utyBhdCBhbGwsIGFuZCB3aG9zZQoJCSAgICAqIFtsb2NhbCBuYW1lXSBhbmQgW25hbWVzcGFjZSBuYW1lXSByZXNvbHZlIChhcwoJCSAgICAqIGRlZmluZWQgYnkgUU5hbWUgcmVzb2x1dGlvbiAoSW5zdGFuY2UpICinMy4xNS40KSkgdG8KCQkgICAgKiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gd2hvc2Uge3R5cGUgZGVmaW5pdGlvbn0gaXMKCQkgICAgKiBvciBpcyBkZXJpdmVkIGZyb20gSUQuIFRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcKCQkgICAgKiBtdXN0IGJlIHRydWU6IgoJCSAgICAqLwoJCSAgICBhdHRyLT50eXBlRGVmID0gYXR0ci0+ZGVjbC0+c3VidHlwZXM7CgkJICAgIGlmICh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoCgkJCWF0dHItPnR5cGVEZWYsIFhNTF9TQ0hFTUFTX0lEKSkgewoJCQkvKgoJCQkqIFNQRUMgKDUuMSkgIlRoZXJlIG11c3QgYmUgbm8gbW9yZSB0aGFuIG9uZQoJCQkqIGl0ZW0gaW4gt3dpbGQgSURzty4iCgkJCSovCgkJCWlmICh3aWxkSURzICE9IDApIHsKCQkJICAgIC8qIFZBTCBUT0RPICovCgkJCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfRFVQTElDQVRFX0lEOwoJCQkgICAgVE9ETwoJCQkgICAgY29udGludWU7CgkJCX0KCQkJd2lsZElEcysrOwoJCQkvKgoJCQkqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkJCSogKDUuMikgIklmILd3aWxkIElEc7cgaXMgbm9uLWVtcHR5LCB0aGVyZSBtdXN0IG5vdAoJCQkqIGJlIGFueSBhdHRyaWJ1dGUgdXNlcyBhbW9uZyB0aGUge2F0dHJpYnV0ZSB1c2VzfQoJCQkqIHdob3NlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3Mge3R5cGUgZGVmaW5pdGlvbn0KCQkJKiBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQuIgoJCQkqLwoJCQlmb3IgKGF0dHJVc2VMaW5rID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCQkJICAgIGF0dHJVc2VMaW5rICE9IE5VTEw7CgkJCSAgICBhdHRyVXNlTGluayA9IGF0dHJVc2VMaW5rLT5uZXh0KSB7CgkJCSAgICBpZiAoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKAoJCQkJYXR0clVzZUxpbmstPmF0dHItPnN1YnR5cGVzLAoJCQkJWE1MX1NDSEVNQVNfSUQpKSB7CgkJCQkvKiBWQUwgVE9ETyAqLwoJCQkJYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0FORF9VU0VfSUQ7CgkJCQlUT0RPCgkJCSAgICB9CgkJCX0KCQkgICAgfQoJCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PQoJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX0xBWF9OT19ERUNMOwoJCSAgICAvKgoJCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCQkgICAgKiBbdmFsaWRpdHldID0gIm5vdEtub3duIgoJCSAgICAqIFt2YWxpZGF0aW9uIGF0dGVtcHRlZF0gPSAibm9uZSIKCQkgICAgKi8KCQl9IGVsc2UgewoJCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfU1RSSUNUX05PX0RFQ0w7CgkJfQoJICAgIH0KCX0KICAgIH0KCgogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKCiAgICAvKgogICAgKiBWYWxpZGF0ZSB2YWx1ZXMsIGNyZWF0ZSBkZWZhdWx0IGF0dHJpYnV0ZXMsIGV2YWx1YXRlIElEQ3MuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CglhdHRyID0gdmN0eHQtPmF0dHJJbmZvc1tpXTsKCS8qCgkqIFZBTCBUT0RPOiBOb3RlIHRoYXQgd2Ugd29uJ3QgdHJ5IHRvIHJlc29sdmUgSURDcyB0bwoJKiAibGF4IiBhbmQgInNraXAiIHZhbGlkYXRlZCBhdHRyaWJ1dGVzLiBDaGVjayB3aGF0IHRvCgkqIGRvIGluIHRoaXMgY2FzZS4KCSovCglpZiAoKGF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfQVNTRVNTRUQpICYmCgkgICAgKGF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCkpCgkgICAgY29udGludWU7CgkvKgoJKiBWQUwgVE9ETzogV2hhdCB0byBkbyBpZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIG1pc3Npbmc/CgkqLwoJaWYgKGF0dHItPnR5cGVEZWYgPT0gTlVMTCkgewoJICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfTk9fVFlQRTsKCSAgICBjb250aW51ZTsKCX0KCglBQ1RJVkFURV9BVFRSSUJVVEUoYXR0cik7CglmaXhlZCA9IDA7Cgl4cGF0aFJlcyA9IDA7CgoJaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEV2YWx1YXRlIElEQ3MuCgkgICAgKi8KCSAgICB4cGF0aFJlcyA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUodmN0eHQsCgkJWE1MX0FUVFJJQlVURV9OT0RFKTsKCSAgICBpZiAoeHBhdGhSZXMgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0KCglpZiAoYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9ERUZBVUxUKSB7CgkgICAgLyoKCSAgICAqIERlZmF1bHQvZml4ZWQgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmICh4cGF0aFJlcykgewoJCWlmIChhdHRyLT51c2UtPmRlZlZhbHVlID09IE5VTEwpIHsKCQkgICAgYXR0ci0+dmFsdWUgPSAoeG1sQ2hhciAqKSBhdHRyLT51c2UtPmRlZlZhbHVlOwoJCSAgICBhdHRyLT52YWwgPSBhdHRyLT51c2UtPmRlZlZhbDsKCQl9IGVsc2UgewoJCSAgICBhdHRyLT52YWx1ZSA9ICh4bWxDaGFyICopIGF0dHItPmRlY2wtPmRlZlZhbHVlOwoJCSAgICBhdHRyLT52YWwgPSBhdHRyLT5kZWNsLT5kZWZWYWw7CgkJfQoJCS8qCgkJKiBJRENzIHdpbGwgY29uc3VtZSB0aGUgcHJlY29tcHV0ZWQgZGVmYXVsdCB2YWx1ZSwKCQkqIHNvIHdlIG5lZWQgdG8gY2xvbmUgaXQuCgkJKi8KCQlpZiAoYXR0ci0+dmFsID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkJImRlZmF1bHQvZml4ZWQgdmFsdWUgb24gYW4gYXR0cmlidXRlIHVzZSB3YXMgIgoJCQkibm90IHByZWNvbXB1dGVkIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWF0dHItPnZhbCA9IHhtbFNjaGVtYUNvcHlWYWx1ZShhdHRyLT52YWwpOwoJCWlmIChhdHRyLT52YWwgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFDb3B5VmFsdWUoKSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIFBTVkk6IEFkZCB0aGUgZGVmYXVsdCBhdHRyaWJ1dGUgdG8gdGhlIGN1cnJlbnQgZWxlbWVudC4KCSAgICAqIFZBTCBUT0RPOiBTaG91bGQgd2UgdXNlIHRoZSAqbm9ybWFsaXplZCogdmFsdWU/IFRoaXMgY3VycmVudGx5CgkgICAgKiAgIHVzZXMgdGhlICppbml0aWFsKiB2YWx1ZS4KCSAgICAqLwoJICAgIGlmICgodmN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgJiYKCQkoYXR0ci0+bm9kZSAhPSBOVUxMKSAmJiAoYXR0ci0+bm9kZS0+ZG9jICE9IE5VTEwpKSB7CgkJeG1sQ2hhciAqbm9ybVZhbHVlOwoJCWNvbnN0IHhtbENoYXIgKnZhbHVlOwoKCQl2YWx1ZSA9IGF0dHItPnZhbHVlOwoJCS8qCgkJKiBOb3JtYWxpemUgdGhlIHZhbHVlLgoJCSovCgkJbm9ybVZhbHVlID0geG1sU2NoZW1hTm9ybWFsaXplVmFsdWUoYXR0ci0+dHlwZURlZiwKCQkgICAgYXR0ci0+dmFsdWUpOwoJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkgICAgdmFsdWUgPSBCQURfQ0FTVCBub3JtVmFsdWU7CgoJCWlmIChhdHRyLT5uc05hbWUgPT0gTlVMTCkgewoJCSAgICBpZiAoeG1sTmV3UHJvcChhdHRyLT5ub2RlLT5wYXJlbnQsCgkJCWF0dHItPmxvY2FsTmFtZSwgdmFsdWUpID09IE5VTEwpIHsKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkJICAgICJjYWxsbGluZyB4bWxOZXdQcm9wKCkiKTsKCQkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCQkgICAgeG1sRnJlZShub3JtVmFsdWUpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgeG1sTnNQdHIgbnM7CgoJCSAgICBucyA9IHhtbFNlYXJjaE5zQnlIcmVmKGF0dHItPm5vZGUtPmRvYywKCQkJYXR0ci0+bm9kZS0+cGFyZW50LCBhdHRyLT5uc05hbWUpOwoJCSAgICBpZiAobnMgPT0gTlVMTCkgewoJCQl4bWxDaGFyIHByZWZpeFsxMl07CgkJCWludCBjb3VudGVyID0gMDsKCgkJCS8qCgkJCSogQ3JlYXRlIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG9uIHRoZSB2YWxpZGF0aW9uCgkJCSogcm9vdCBub2RlIGlmIG5vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpcyBpbiBzY29wZS4KCQkJKi8KCQkJZG8gewoJCQkgICAgc25wcmludGYoKGNoYXIgKikgcHJlZml4LCAxMiwgInAlZCIsIGNvdW50ZXIrKyk7CgkJCSAgICBucyA9IHhtbFNlYXJjaE5zKGF0dHItPm5vZGUtPmRvYywKCQkJCWF0dHItPm5vZGUtPnBhcmVudCwgQkFEX0NBU1QgcHJlZml4KTsKCQkJICAgIGlmIChjb3VudGVyID4gMTAwMCkgewoJCQkJVkVSUk9SX0lOVCgKCQkJCSAgICAieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkJCSAgICAiY291bGQgbm90IGNvbXB1dGUgYSBucyBwcmVmaXggZm9yIGEgIgoJCQkJICAgICJkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZSIpOwoJCQkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCQkJICAgIHhtbEZyZWUobm9ybVZhbHVlKTsKCQkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJCSAgICB9CgkJCX0gd2hpbGUgKG5zICE9IE5VTEwpOwoJCQlucyA9IHhtbE5ld05zKHZjdHh0LT52YWxpZGF0aW9uUm9vdCwKCQkJICAgIGF0dHItPm5zTmFtZSwgQkFEX0NBU1QgcHJlZml4KTsKCQkgICAgfQoJCSAgICB4bWxOZXdOc1Byb3AoYXR0ci0+bm9kZS0+cGFyZW50LCBucywKCQkJYXR0ci0+bG9jYWxOYW1lLCB2YWx1ZSk7CgkJfQoJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkgICAgeG1sRnJlZShub3JtVmFsdWUpOwoJICAgIH0KCSAgICAvKgoJICAgICogR28gZGlyZWN0bHkgdG8gSURDIGV2YWx1YXRpb24uCgkgICAgKi8KCSAgICBnb3RvIGV2YWxfaWRjczsKCX0KCS8qCgkqIFZhbGlkYXRlIHRoZSB2YWx1ZS4KCSovCglpZiAodmN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogRnJlZSBsYXN0IGNvbXB1dGVkIHZhbHVlOyBqdXN0IGZvciBzYWZldHkgcmVhc29ucy4KCSAgICAqLwoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+dmFsdWUpOwoJICAgIHZjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CgkvKgoJKiBOb3RlIHRoYXQgdGhlIGF0dHJpYnV0ZSAqdXNlKiBjYW4gYmUgdW5hdmFpbGFibGUsIGlmCgkqIHRoZSBhdHRyaWJ1dGUgd2FzIGEgd2lsZCBhdHRyaWJ1dGUuCgkqLwoJaWYgKChhdHRyLT5kZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpIHx8CgkgICAgKChhdHRyLT51c2UgIT0gTlVMTCkgJiYKCSAgICAgKGF0dHItPnVzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSkpCgkgICAgZml4ZWQgPSAxOwoJZWxzZQoJICAgIGZpeGVkID0gMDsKCS8qCgkqIFNQRUMgKGN2Yy1hdHRyaWJ1dGUpCgkqICgzKSAiVGhlIGl0ZW0ncyC3bm9ybWFsaXplZCB2YWx1ZbcgbXVzdCBiZSBsb2NhbGx5ILd2YWxpZLcKCSogd2l0aCByZXNwZWN0IHRvIHRoYXQge3R5cGUgZGVmaW5pdGlvbn0gYXMgcGVyIAoJKiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLiIKCSoKCSogVkFMIFRPRE86IERvIHdlIGFscmVhZHkgaGF2ZSB0aGUKCSogIm5vcm1hbGl6ZWQgYXR0cmlidXRlIHZhbHVlIiBoZXJlPwoJKi8KCWlmICh4cGF0aFJlcyB8fCBmaXhlZCkgewoJICAgIGF0dHItPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRDsKCSAgICAvKgoJICAgICogUmVxdWVzdCBhIGNvbXB1dGVkIHZhbHVlLgoJICAgICovCgkgICAgcmVzID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQkoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQlhdHRyLT5ub2RlLCBhdHRyLT50eXBlRGVmLCBhdHRyLT52YWx1ZSwgJihhdHRyLT52YWwpLAoJCTEsIDEsIDApOwoJfSBlbHNlIHsKCSAgICByZXMgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJCSh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCWF0dHItPm5vZGUsIGF0dHItPnR5cGVEZWYsIGF0dHItPnZhbHVlLCBOVUxMLAoJCTEsIDAsIDApOwoJfQoJICAgIAoJaWYgKHJlcyAhPSAwKSB7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVN0cmVhbVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCSAgICAvKgoJICAgICogU1BFQyBQU1ZJIEFzc2Vzc21lbnQgT3V0Y29tZSAoQXR0cmlidXRlKQoJICAgICogW3ZhbGlkaXR5XSA9ICJpbnZhbGlkIgoJICAgICovCgkgICAgZ290byBldmFsX2lkY3M7Cgl9CgoJaWYgKGZpeGVkKSB7CgkgICAgaW50IHdzOwoJICAgIC8qCgkgICAgKiBTUEVDIEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpIChjdmMtYXUpCgkgICAgKiAiRm9yIGFuIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIGJlt3ZhbGlktwoJICAgICogd2l0aCByZXNwZWN0IHRvIGFuIGF0dHJpYnV0ZSB1c2UgaXRzICpub3JtYWxpemVkKgoJICAgICogdmFsdWW3IG11c3QgbWF0Y2ggdGhlICpjYW5vbmljYWwqIGxleGljYWwKCSAgICAqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhdHRyaWJ1dGUgdXNlJ3Mge3ZhbHVlCgkgICAgKiBjb25zdHJhaW50fXZhbHVlLCBpZiBpdCBpcyBwcmVzZW50IGFuZCBmaXhlZC4iCgkgICAgKgoJICAgICogVkFMIFRPRE86IFRoZSByZXF1aXJlbWVudCBmb3IgdGhlICpjYW5vbmljYWwqIHZhbHVlCgkgICAgKiB3aWxsIGJlIHJlbW92ZWQgaW4gWE1MIFNjaGVtYSAxLjEuCgkgICAgKi8KCSAgICAvKgoJICAgICogU1BFQyBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoY3ZjLWF0dHJpYnV0ZSkKCSAgICAqICg0KSAiVGhlIGl0ZW0ncyAqYWN0dWFsKiB2YWx1ZbcgbXVzdCBtYXRjaCB0aGUgKnZhbHVlKiBvZgoJICAgICogdGhlIHt2YWx1ZSBjb25zdHJhaW50fSwgaWYgaXQgaXMgcHJlc2VudCBhbmQgZml4ZWQuIgoJICAgICovCgkgICAgd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZShhdHRyLT50eXBlRGVmKTsKCSAgICBpZiAoYXR0ci0+dmFsID09IE5VTEwpIHsKCQkvKiBWQUwgVE9ETzogQSB2YWx1ZSB3YXMgbm90IHByZWNvbXB1dGVkLiAqLwoJCVRPRE8KCQlnb3RvIGV2YWxfaWRjczsKCSAgICB9CgkgICAgaWYgKChhdHRyLT51c2UgIT0gTlVMTCkgJiYKCQkoYXR0ci0+dXNlLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJCWlmIChhdHRyLT51c2UtPmRlZlZhbCA9PSBOVUxMKSB7CgkJICAgIC8qIFZBTCBUT0RPOiBBIGRlZmF1bHQgdmFsdWUgd2FzIG5vdCBwcmVjb21wdXRlZC4gKi8KCQkgICAgVE9ETwoJCSAgICBnb3RvIGV2YWxfaWRjczsKCQl9CgkJYXR0ci0+dmNWYWx1ZSA9IGF0dHItPnVzZS0+ZGVmVmFsdWU7CgkJLyoKCQlpZiAoeG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKGF0dHItPnZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzLAoJCSAgICBhdHRyLT51c2UtPmRlZlZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzKSAhPSAwKSB7CgkJKi8KCQlpZiAoISB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChhdHRyLT52YWwsIGF0dHItPnVzZS0+ZGVmVmFsKSkKCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRTsKCSAgICB9IGVsc2UgewoJCWlmIChhdHRyLT5kZWNsLT5kZWZWYWwgPT0gTlVMTCkgewoJCSAgICAvKiBWQUwgVE9ETzogQSBkZWZhdWx0IHZhbHVlIHdhcyBub3QgcHJlY29tcHV0ZWQuICovCgkJICAgIFRPRE8KCQkgICAgZ290byBldmFsX2lkY3M7CgkJfQoJCWF0dHItPnZjVmFsdWUgPSBhdHRyLT5kZWNsLT5kZWZWYWx1ZTsKCQkvKgoJCWlmICh4bWxTY2hlbWFDb21wYXJlVmFsdWVzV2h0c3AoYXR0ci0+dmFsLAoJCSAgICAoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MsCgkJICAgIGF0dHJEZWNsLT5kZWZWYWwsCgkJICAgICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cykgIT0gMCkgewoJCSovCgkJaWYgKCEgeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoYXR0ci0+dmFsLCBhdHRyLT5kZWNsLT5kZWZWYWwpKQoJCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX0ZJWEVEX1ZBTFVFOwoJICAgIH0KCSAgICAvKgoJICAgICogW3ZhbGlkaXR5XSA9ICJ2YWxpZCIKCSAgICAqLwoJfQpldmFsX2lkY3M6CgkvKgoJKiBFdmFsdWF0ZSBJRENzLgoJKi8KCWlmICh4cGF0aFJlcykgewoJICAgIGlmICh4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHZjdHh0LAoJCXZjdHh0LT5kZXB0aCArMSkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0KICAgIH0KCiAgICAvKgogICAgKiBSZXBvcnQgZXJyb3JzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoKGF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSkgfHwKCSAgICAoYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRCkgfHwKCSAgICAoYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVApIHx8CgkgICAgKGF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9MQVhfTk9fREVDTCkpCgkgICAgY29udGludWU7CglBQ1RJVkFURV9BVFRSSUJVVEUoYXR0cik7Cglzd2l0Y2ggKGF0dHItPnN0YXRlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HOiB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIEFDVElWQVRFX0VMRU07CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV80LCBOVUxMLCBOVUxMLAoJCQkiVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nIiwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIGF0dHItPmRlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgIGF0dHItPmRlY2wtPm5hbWUpLAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGJyZWFrOwoJCX0KCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX05PX1RZUEU6CgkJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19BVFRSSUJVVEVfMiwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRToKCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19BVSwgTlVMTCwgTlVMTCwKCQkgICAgIlRoZSB2YWx1ZSAnJXMnIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCAiCgkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLCAKCQkgICAgYXR0ci0+dmFsdWUsIGF0dHItPnZjVmFsdWUpOwkJCgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX1NUUklDVF9OT19ERUNMOgoJCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfV0lMRENBUkQsIE5VTEwsCgkJICAgICJObyBtYXRjaGluZyBnbG9iYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSwgYnV0ICIKCQkgICAgImRlbWFuZGVkIGJ5IHRoZSBzdHJpY3Qgd2lsZGNhcmQiKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTjoKCQlpZiAoYXR0ci0+bWV0YVR5cGUpCgkJICAgIGJyZWFrOwoJCS8qCgkJKiBNQVlCRSBWQUwgVE9ETzogT25lIG1pZ2h0IHJlcG9ydCBkaWZmZXJlbnQgZXJyb3IgbWVzc2FnZXMKCQkqIGZvciB0aGUgZm9sbG93aW5nIGVycm9ycy4KCQkqLwoJCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8xLCBhdHRyLCBOVUxMKTsKCQl9IGVsc2UgewoJCSAgICB4bWxTY2hlbWFJbGxlZ2FsQXR0ckVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMiwgYXR0ciwgTlVMTCk7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgaW50ICpza2lwKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB2Y3R4dC0+aW5vZGUtPmRlY2w7CiAgICAvKgogICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IHdhcyBhbHJlYWR5IGlkZW50aWZpZWQgdG8gYmUKICAgICogbWF0Y2hpbmcgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmICgoc2tpcCA9PSBOVUxMKSB8fCAod2lsZCA9PSBOVUxMKSB8fAoJKHdpbGQtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkIiwKCSAgICAiYmFkIGFyZ3VtZW50cyIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAqc2tpcCA9IDA7CiAgICBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJLyoKCSogVVJHRU5UIFZBTCBUT0RPOiBGaXggdGhlIGNvbnRlbnQgbW9kZWwgdG8gcmVqZWN0CgkqICIjI290aGVyIiB3aWxkY2FyZHMuCgkqLwoJaWYgKHhtbFNjaGVtYUNoZWNrQ1ZDV2lsZGNhcmROYW1lc3BhY2Uod2lsZCwKCSAgICB2Y3R4dC0+aW5vZGUtPm5zTmFtZSkgIT0gMCkgewoJICAgIGlmICgod2lsZC0+bWluT2NjdXJzID09IDEpICYmICh3aWxkLT5tYXhPY2N1cnMgPT0gMSkpIHsKCQl4bWxTY2hlbWFOb2RlSW5mb1B0ciBwaW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aCAtMV07CgkJLyoKCQkqIFZBTCBUT0RPOiBXb3JrYXJvdW5kIHBvc3NpYmxlICpvbmx5KiBpZiBtaW5PY2N1cnMgYW5kCgkJKiBtYXhPY2N1cnMgYXJlIDEuCgkJKi8KCQl4bWxTY2hlbWFDb21wbGV4VHlwZUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkgICAgLyogVkFMIFRPRE86IGVycm9yIGNvZGU/ICovCgkJICAgIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwgTlVMTCwKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHdpbGQsCgkJICAgICJUaGlzIGVsZW1lbnQgaXMgbm90IGFjY2VwdGVkIGJ5IHRoZSB3aWxkY2FyZCIsCgkJICAgIDAsIDAsIE5VTEwpOwoJCXZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CgkJaWYgKChwaW5vZGUtPmZsYWdzICYKCQkgICAgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UKSA9PSAwKQoJCSAgICBwaW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVDsKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9OT1RfRVhQRUNURUQ7CgkJcmV0dXJuIChYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQpOwoJICAgIH0KCSAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7CgkJKnNraXAgPSAxOwoJCXJldHVybiAoMCk7CgkgICAgfQoJICAgIHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9CgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgPT0gWE1MX1NDSEVNQVNfQU5ZX1NLSVApIHsKCS8qCgkqIFVSR0VOVCBWQUwgVE9ETzogRWl0aGVyIHdlIG5lZWQgdG8gcG9zaXRpb24gdGhlIHN0cmVhbSB0byB0aGUKCSogbmV4dCBzaWJsaW5nLCBvciB3YWxrIHRoZSB3aG9sZSBzdWJ0cmVlLgoJKi8KCSpza2lwID0gMTsKCXJldHVybiAoMCk7CiAgICB9CiAgICB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wgPSBOVUxMOwoKCWRlY2wgPSB4bWxIYXNoTG9va3VwMyh2Y3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUsCgkgICAgTlVMTCk7CglpZiAoZGVjbCAhPSBOVUxMKSB7CgkgICAgdmN0eHQtPmlub2RlLT5kZWNsID0gZGVjbDsKCSAgICByZXR1cm4gKDApOwoJfQogICAgfQogICAgaWYgKHdpbGQtPnByb2Nlc3NDb250ZW50cyA9PSBYTUxfU0NIRU1BU19BTllfU1RSSUNUKSB7CgkvKiBWQUwgVE9ETzogQ2hhbmdlIHRvIHByb3BlciBlcnJvciBjb2RlLiAqLwoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwgKHhtbFNjaGVtYVR5cGVQdHIpIHdpbGQsCgkgICAgIk5vIG1hdGNoaW5nIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIGF2YWlsYWJsZSwgYnV0ICIKCSAgICAiZGVtYW5kZWQgYnkgdGhlIHN0cmljdCB3aWxkY2FyZCIpOwoJcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkgewoJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgkvKgoJKiBTUEVDIFZhbGlkYXRpb24gUnVsZTogU2NoZW1hLVZhbGlkaXR5IEFzc2Vzc21lbnQgKEVsZW1lbnQpCgkqICgxLjIuMS4yLjEpIC0gKDEuMi4xLjIuMyApCgkqCgkqIFVzZSB0aGUgeHNpOnR5cGUgYXR0cmlidXRlIGZvciB0aGUgdHlwZSBkZWZpbml0aW9uLgoJKi8KCWlhdHRyID0geG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJICAgIFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1RZUEUpOwoJaWYgKGlhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUodmN0eHQsIGlhdHRyLAoJCSYodmN0eHQtPmlub2RlLT50eXBlRGVmKSwgTlVMTCkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1XaWxkY2FyZCIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKCkgdG8gIgoJCSAgICAicHJvY2VzcyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAvKgoJICAgICogRG9uJ3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuCgkgICAgKi8KCSAgICByZXR1cm4gKDApOwoJfQogICAgfQogICAgLyoKICAgICogU1BFQyBWYWxpZGF0aW9uIFJ1bGU6IFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KQogICAgKgogICAgKiBGYWxsYmFjayB0byAiYW55VHlwZSIuCiAgICAqLwogICAgdmN0eHQtPmlub2RlLT50eXBlRGVmID0KCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgcmV0dXJuICgwKTsKfQoKLyoKKiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdDoKKgoqIFRoaXMgd2lsbCBiZSBjYWxsZWQgaWY6IG5vdCBuaWxsZWQsIG5vIGNvbnRlbnQgYW5kIGEgZGVmYXVsdC9maXhlZAoqIHZhbHVlIGlzIHByb3ZpZGVkLgoqLwoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKeyAgIAogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSA9IHZjdHh0LT5pbm9kZTsKCiAgICAvKgogICAgKiBjb3MtdmFsaWQtZGVmYXVsdDoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKICAgICogRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCB3aXRoIHJlc3BlY3QgdG8gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8gICAgCiAgICBpZiBJU19DT01QTEVYX1RZUEUoaW5vZGUtPnR5cGVEZWYpIHsKCS8qCgkqIENvbXBsZXggdHlwZS4KCSoKCSogU1BFQyAoMi4xKSAiaXRzIHtjb250ZW50IHR5cGV9IG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCgkqIG9yIG1peGVkLiIKCSogU1BFQyAoMi4yLjIpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgbWl4ZWQsIHRoZW4gdGhlIHtjb250ZW50CgkqIHR5cGV9J3MgcGFydGljbGUgbXVzdCBiZSC3ZW1wdGlhYmxltyBhcyBkZWZpbmVkIGJ5IAoJKiBQYXJ0aWNsZSBFbXB0aWFibGUgKKczLjkuNikuIgoJKi8KCWlmICgoISBIQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSAmJgoJICAgICgoISBIQVNfTUlYRURfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHx8CgkgICAgICghIElTX1BBUlRJQ0xFX0VNUFRJQUJMRShpbm9kZS0+dHlwZURlZikpKSkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMTsKCSAgICAvKiBOT1RFIHRoYXQgdGhpcyBjb3ZlcnMgKDIuMi4yKSBhcyB3ZWxsLiAqLwoJICAgIFZFUlJPUihyZXQsIE5VTEwsCgkJIkZvciBhIHN0cmluZyB0byBiZSBhIHZhbGlkIGRlZmF1bHQsIHRoZSB0eXBlIGRlZmluaXRpb24gIgoJCSJtdXN0IGJlIGEgc2ltcGxlIHR5cGUgb3IgYSBjb21wbGV4IHR5cGUgd2l0aCBzaW1wbGUgY29udGVudCAiCgkJIm9yIG1peGVkIGNvbnRlbnQgYW5kIGEgcGFydGljbGUgZW1wdGlhYmxlIik7CgkgICAgcmV0dXJuKHJldCk7Cgl9CiAgICB9CQogICAgLyoKICAgICogMSBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgc3RyaW5nIAogICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKICAgICogVmFsaWQgKKczLjE0LjQpLgogICAgKgogICAgKiBBTkQKICAgICoKICAgICogMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCiAgICAqIHN0cmluZyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKICAgICogYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgogICAgKi8gIAogICAgaWYgKElTX1NJTVBMRV9UWVBFKGlub2RlLT50eXBlRGVmKSkgewoKCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkgICAgTlVMTCwgaW5vZGUtPnR5cGVEZWYsIHZhbHVlLCB2YWwsIDEsIDEsIDApOwoKICAgIH0gZWxzZSBpZiAoSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoKCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkgICAgTlVMTCwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLCB2YWx1ZSwgdmFsLCAxLCAxLCAwKTsKICAgIH0KICAgIGlmIChyZXQgPCAwKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCIsCgkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CiAgICB9ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWQ29udGVudE1vZGVsQ2FsbGJhY2soeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0IEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBpdGVtLAoJCQkgICAgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGUpCnsKICAgIGlub2RlLT5kZWNsID0gaXRlbTsKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7CgoJaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHsKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIGNhbGxiYWNrIGZvciAnJXMnIFtkZWNsYXJhdGlvbl1cbiIsCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQlpbm9kZS0+bG9jYWxOYW1lLCBpbm9kZS0+bnNOYW1lKSk7Cgl9IGVsc2UgewoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAiQVVUT01BVE9OIGNhbGxiYWNrIGZvciAnJXMnIFt3aWxkY2FyZF1cbiIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIGlub2RlLT5sb2NhbE5hbWUsIGlub2RlLT5uc05hbWUpKTsKCgl9CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7ICAgIAogICAgdmN0eHQtPmlub2RlID0geG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyh2Y3R4dCk7CiAgICBpZiAodmN0eHQtPmlub2RlID09IE5VTEwpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKCkiKTsKCXJldHVybiAoLTEpOwogICAgfSAgIAogICAgdmN0eHQtPm5iQXR0ckluZm9zID0gMDsKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGUsCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlKQp7CiAgICBpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEKQoJcmV0dXJuICh4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJICAgICh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCBOVUxMLAoJICAgIHR5cGUsIHZhbHVlLCAmKGlub2RlLT52YWwpLCAxLCAxLCAwKSk7CiAgICBlbHNlCglyZXR1cm4gKHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkgICAgKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIE5VTEwsCgkgICAgdHlwZSwgdmFsdWUsIE5VTEwsIDEsIDAsIDApKTsKfQoKCgovKiAKKiBQcm9jZXNzIEVORCBvZiBlbGVtZW50LgoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlID0gdmN0eHQtPmlub2RlOwoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCXhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHZjdHh0KTsKICAgIGlmIChpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEKSB7CgkvKgoJKiBUaGlzIGVsZW1lbnQgd2FzIG5vdCBleHBlY3RlZDsKCSogd2Ugd2lsbCBub3QgdmFsaWRhdGUgY2hpbGQgZWxlbWVudHMgb2YgYnJva2VuIHBhcmVudHMuCgkqIFNraXAgdmFsaWRhdGlvbiBvZiBhbGwgY29udGVudCBvZiB0aGUgcGFyZW50LgoJKi8KCXZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGggLTE7Cglnb3RvIGVuZF9lbGVtOwogICAgfSAgICAKICAgIGlmICgoaW5vZGUtPnR5cGVEZWYgPT0gTlVMTCkgfHwKCShpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfQkFEX1RZUEUpKSB7CgkvKgoJKiAxLiB0aGUgdHlwZSBkZWZpbml0aW9uIG1pZ2h0IGJlIG1pc3NpbmcgaWYgdGhlIGVsZW1lbnQgd2FzCgkqICAgIGVycm9yIHByb25lCgkqIDIuIGl0IG1pZ2h0IGJlIGFic3RyYWN0LgoJKi8KCWdvdG8gZW5kX2VsZW07CiAgICB9CiAgICAvKgogICAgKiBDaGVjayB0aGUgY29udGVudCBtb2RlbC4KICAgICovCiAgICBpZiAoKGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHx8CgkoaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykpIHsKCgkvKgoJKiBXb3JrYXJvdW5kIGZvciAiYW55VHlwZSIuCgkqLwoJaWYgKGlub2RlLT50eXBlRGVmLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKQoJICAgIGdvdG8gY2hhcmFjdGVyX2NvbnRlbnQ7CQkJCgkKCWlmICgoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UKSA9PSAwKSB7CgkgICAgeG1sQ2hhciAqdmFsdWVzWzEwXTsKCSAgICBpbnQgdGVybWluYWwsIG5idmFsID0gMTAsIG5ibmVnOwoKCSAgICBpZiAoaW5vZGUtPnJlZ2V4Q3R4dCA9PSBOVUxMKSB7CgkJLyoKCQkqIENyZWF0ZSB0aGUgcmVnZXggY29udGV4dC4KCQkqLwoJCWlub2RlLT5yZWdleEN0eHQgPQoJCSAgICB4bWxSZWdOZXdFeGVjQ3R4dChpbm9kZS0+dHlwZURlZi0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykgeG1sU2NoZW1hVkNvbnRlbnRNb2RlbENhbGxiYWNrLAoJCSAgICB2Y3R4dCk7CgkJaWYgKGlub2RlLT5yZWdleEN0eHQgPT0gTlVMTCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtIiwKCQkJImZhaWxlZCB0byBjcmVhdGUgYSByZWdleCBjb250ZXh0Iik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBjcmVhdGUgb24gJyVzJ1xuIiwgaW5vZGUtPmxvY2FsTmFtZSk7CiNlbmRpZgkgICAgCgkgICAgfQoJICAgIC8qCgkgICAgKiBHZXQgaG9sZCBvZiB0aGUgc3RpbGwgZXhwZWN0ZWQgY29udGVudCwgc2luY2UgYSBmdXJ0aGVyCgkgICAgKiBjYWxsIHRvIHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKCkgd2lsbCBsb29zZSB0aGlzIGluZm9ybWF0aW9uLgoJICAgICovIAoJICAgIHhtbFJlZ0V4ZWNOZXh0VmFsdWVzKGlub2RlLT5yZWdleEN0eHQsCgkJJm5idmFsLCAmbmJuZWcsICZ2YWx1ZXNbMF0sICZ0ZXJtaW5hbCk7CgkgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoaW5vZGUtPnJlZ2V4Q3R4dCwgTlVMTCwgTlVMTCk7CgkgICAgaWYgKHJldCA8PSAwKSB7CQkKCQkvKgoJCSogU3RpbGwgbWlzc2luZyBzb21ldGhpbmcuCgkJKi8KCQlyZXQgPSAxOwoJCWlub2RlLT5mbGFncyB8PQoJCSAgICBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQ7CgkJeG1sU2NoZW1hQ29tcGxleFR5cGVFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwgTlVMTCwgTlVMTCwKCQkgICAgIk1pc3NpbmcgY2hpbGQgZWxlbWVudChzKSIsCgkJICAgIG5idmFsLCBuYm5lZywgdmFsdWVzKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gbWlzc2luZyBFUlJPUiBvbiAnJXMnXG4iLAoJCSAgICBpbm9kZS0+bG9jYWxOYW1lKTsKI2VuZGlmCgkgICAgfSBlbHNlIHsKCQkvKgoJCSogQ29udGVudCBtb2RlbCBpcyBzYXRpc2ZpZWQuCgkJKi8KCQlyZXQgPSAwOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBzdWNjZWVkZWQgb24gJyVzJ1xuIiwKCQkgICAgaW5vZGUtPmxvY2FsTmFtZSk7CiNlbmRpZgoJICAgIH0KCgl9CiAgICB9CiAgICBpZiAoaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykKCWdvdG8gZW5kX2VsZW07CgpjaGFyYWN0ZXJfY29udGVudDoKCiAgICBpZiAodmN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+dmFsdWUpOwoJdmN0eHQtPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGNoYXJhY3RlciBjb250ZW50LgogICAgKi8KICAgIGlmIChpbm9kZS0+ZGVjbCA9PSBOVUxMKSB7CgkvKgoJKiBTcGVlZHVwIGlmIG5vIGRlY2xhcmF0aW9uIGV4aXN0cy4KCSovCglpZiAoSVNfU0lNUExFX1RZUEUoaW5vZGUtPnR5cGVEZWYpKSB7CSAgICAKCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCWlub2RlLCBpbm9kZS0+dHlwZURlZiwgaW5vZGUtPnZhbHVlKTsKCX0gZWxzZSBpZiAoSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZURlZiwKCQlpbm9kZS0+dmFsdWUpOwoJfQkJCglpZiAocmV0IDwgMCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGVuZF9lbGVtOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNSAKICAgICogVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNS4xIAogICAgKiBJZiB0aGUgZGVjbGFyYXRpb24gaGFzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCAKICAgICogdGhlIGl0ZW0gaGFzIG5laXRoZXIgZWxlbWVudCBub3IgY2hhcmFjdGVyIFtjaGlsZHJlbl0gYW5kIAogICAgKiBjbGF1c2UgMy4yIGhhcyBub3QgYXBwbGllZCwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgaWYgKChpbm9kZS0+ZGVjbC0+dmFsdWUgIT0gTlVMTCkgJiYKCShpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkgJiYgCgkoISBJTk9ERV9OSUxMRUQoaW5vZGUpKSkgewoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjEgCgkqIElmIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgaXMgYSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utwoJKiB0aGVuIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9CgkqIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBkZWZhdWx0IGZvciB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIAoJKiBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4gCgkqLwoJLyogCgkqIE5PVEU6ICdsb2NhbCcgYWJvdmUgbWVhbnMgdHlwZXMgYXF1aXJlZCBieSB4c2k6dHlwZS4KCSogTk9URTogQWx0aG91Z2ggdGhlICpjYW5vbmljYWwqIHZhbHVlIGlzIHN0YXRlZCwgaXQgaXMgbm90CgkqIHJlbGV2YW50IGlmIGNhbm9uaWNhbCBvciBub3QuIEFkZGl0aW9uYWxseSBYTUwgU2NoZW1hIDEuMQoJKiB3aWxsIHJlbW92ZWQgdGhpcyByZXF1aXJlbWVudCBhcyB3ZWxsLgoJKi8KCWlmIChpbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19MT0NBTF9UWVBFKSB7CgoJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KHZjdHh0LAoJCWlub2RlLT5kZWNsLT52YWx1ZSwgJihpbm9kZS0+dmFsKSk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBlbmRfZWxlbTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFN0b3AgaGVyZSwgdG8gYXZvaWQgcmVkdW5kYW50IHZhbGlkYXRpb24gb2YgdGhlIHZhbHVlCgkgICAgKiAoc2VlIGZvbGxvd2luZykuCgkgICAgKi8KCSAgICBnb3RvIGRlZmF1bHRfcHN2aTsKCX0JCgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMiAKCSogVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSB1c2VkIGFzIGl0cyAKCSogt25vcm1hbGl6ZWQgdmFsdWW3IG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIAoJKiC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpCgkqICinMy4zLjQpLgoJKi8JICAgIAoJaWYgKElTX1NJTVBMRV9UWVBFKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLCBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJfSBlbHNlIGlmIChIQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLAoJCWlub2RlLT5kZWNsLT52YWx1ZSk7CSAgICAKCX0KCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZW5kX2VsZW07Cgl9CgpkZWZhdWx0X3Bzdmk6CgkvKgoJKiBQU1ZJOiBDcmVhdGUgYSB0ZXh0IG5vZGUgb24gdGhlIGluc3RhbmNlIGVsZW1lbnQuCgkqLwoJaWYgKCh2Y3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSAmJgoJICAgIChpbm9kZS0+bm9kZSAhPSBOVUxMKSkgewoJICAgIHhtbE5vZGVQdHIgdGV4dENoaWxkOwoJICAgIHhtbENoYXIgKm5vcm1WYWx1ZTsKCSAgICAvKgoJICAgICogVkFMIFRPRE86IE5vcm1hbGl6ZSB0aGUgdmFsdWUuCgkgICAgKi8JICAgIAoJICAgIG5vcm1WYWx1ZSA9IHhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKGlub2RlLT50eXBlRGVmLAoJCWlub2RlLT5kZWNsLT52YWx1ZSk7CgkgICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSB7CgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChCQURfQ0FTVCBub3JtVmFsdWUpOwoJCXhtbEZyZWUobm9ybVZhbHVlKTsKCSAgICB9IGVsc2UKCQl0ZXh0Q2hpbGQgPSB4bWxOZXdUZXh0KGlub2RlLT5kZWNsLT52YWx1ZSk7CgkgICAgaWYgKHRleHRDaGlsZCA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbE5ld1RleHQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfSBlbHNlCgkJeG1sQWRkQ2hpbGQoaW5vZGUtPm5vZGUsIHRleHRDaGlsZCk7CSAgICAKCX0KCQogICAgfSBlbHNlIGlmICghIElOT0RFX05JTExFRChpbm9kZSkpIHsJCgkvKgoJKiA1LjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCgkqIHRvIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgCgkqIFZhbGlkIChUeXBlKSAopzMuMy40KS4KCSovCQoJaWYgKElTX1NJTVBMRV9UWVBFKGlub2RlLT50eXBlRGVmKSkgewoJICAgICAvKgoJICAgICogU1BFQyAoY3ZjLXR5cGUpICgzLjEpCgkgICAgKiAiSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIC4uLiIKCSAgICAqICgzLjEuMykgIklmIGNsYXVzZSAzLjIgb2YgRWxlbWVudCBMb2NhbGx5IFZhbGlkCgkgICAgKiAoRWxlbWVudCkgKKczLjMuNCkgZGlkIG5vdCBhcHBseSwgdGhlbiB0aGUgt25vcm1hbGl6ZWQgdmFsdWW3CgkgICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgZGVmaW5lZAoJICAgICogYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KCSAgICAqLwkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQkgICAgaW5vZGUsIGlub2RlLT50eXBlRGVmLCBpbm9kZS0+dmFsdWUpOwoJfSBlbHNlIGlmIChIQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy10eXBlKSAoMy4yKSAiSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIGNvbXBsZXggdHlwZQoJICAgICogZGVmaW5pdGlvbiwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUKCSAgICAqILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB0eXBlIGRlZmluaXRpb24gYXMgcGVyCgkgICAgKiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkgKKczLjQuNCk7IgoJICAgICoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgyLjIpCgkgICAgKiAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgLi4uIAoJICAgICogdGhlILdub3JtYWxpemVkIHZhbHVltyBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzCgkgICAgKiC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gYXMKCSAgICAqIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4iCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCWlub2RlLCBpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGVEZWYsIGlub2RlLT52YWx1ZSk7Cgl9CQoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBlbmRfZWxlbTsKCX0KCS8qCgkqIDUuMi4yIElmIHRoZXJlIGlzIGEgZml4ZWQge3ZhbHVlIGNvbnN0cmFpbnR9IGFuZCBjbGF1c2UgMy4yIGhhcyAKCSogbm90IGFwcGxpZWQsIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSovCglpZiAoKGlub2RlLT5kZWNsLT52YWx1ZSAhPSBOVUxMKSAmJgoJICAgIChpbm9kZS0+ZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSkgewoKCSAgICAvKgoJICAgICogVE9ETzogV2Ugd2lsbCBuZWVkIGEgY29tcHV0ZWQgdmFsdWUsIHdoZW4gY29tcGFyaXNvbiBpcwoJICAgICogZG9uZSBvbiBjb21wdXRlZCB2YWx1ZXMuCgkgICAgKi8KCSAgICAvKgoJICAgICogNS4yLjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAoJICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgoJICAgICovCgkgICAgaWYgKGlub2RlLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQpIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzE7CgkJVkVSUk9SKHJldCwgTlVMTCwKCQkgICAgIlRoZSBjb250ZW50IG11c3Qgbm90IGNvbnRhaW50IGVsZW1lbnQgbm9kZXMgc2luY2UgIgoJCSAgICAidGhlcmUgaXMgYSBmaXhlZCB2YWx1ZSBjb25zdHJhaW50Iik7CgkJZ290byBlbmRfZWxlbTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiA1LjIuMi4yIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCAKCQkqIGJlIHRydWU6CgkJKi8JCQoJCWlmIChIQVNfTUlYRURfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHsKCQkgICAgLyoKCQkgICAgKiA1LjIuMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSC3YWN0dWFsIHR5cGUgCgkJICAgICogZGVmaW5pdGlvbrcgaXMgbWl4ZWQsIHRoZW4gdGhlICppbml0aWFsIHZhbHVlKiBvZiB0aGUgCgkJICAgICogaXRlbSBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiAKCQkgICAgKiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgoJCSAgICAqCgkJICAgICogLi4uIHRoZSAqaW5pdGlhbCB2YWx1ZSogb2YgYW4gZWxlbWVudCBpbmZvcm1hdGlvbiAKCQkgICAgKiBpdGVtIGlzIHRoZSBzdHJpbmcgY29tcG9zZWQgb2YsIGluIG9yZGVyLCB0aGUgCgkJICAgICogW2NoYXJhY3RlciBjb2RlXSBvZiBlYWNoIGNoYXJhY3RlciBpbmZvcm1hdGlvbiBpdGVtIGluIAoJCSAgICAqIHRoZSBbY2hpbGRyZW5dIG9mIHRoYXQgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtLgoJCSAgICAqLwkJICAgCgkJICAgIGlmICghIHhtbFN0ckVxdWFsKGlub2RlLT52YWx1ZSwgaW5vZGUtPmRlY2wtPnZhbHVlKSl7CgkJCS8qIAoJCQkqIFZBTCBUT0RPOiBSZXBvcnQgaW52YWxpZCAmIGV4cGVjdGVkIHZhbHVlcyBhcyB3ZWxsLgoJCQkqIFZBTCBUT0RPOiBJbXBsZW1lbnQgdGhlIGNhbm9uaWNhbCBzdHVmZi4KCQkJKi8KCQkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8yXzE7CgkJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgCgkJCSAgICByZXQsIE5VTEwsIE5VTEwsCgkJCSAgICAiVGhlIGluaXRpYWwgdmFsdWUgJyVzJyBkb2VzIG5vdCBtYXRjaCB0aGUgZml4ZWQgIgoJCQkgICAgInZhbHVlIGNvbnN0cmFpbnQgJyVzJyIsCgkJCSAgICBpbm9kZS0+dmFsdWUsIGlub2RlLT5kZWNsLT52YWx1ZSk7CgkJCWdvdG8gZW5kX2VsZW07CgkJICAgIH0KCQl9IGVsc2UgaWYgKEhBU19TSU1QTEVfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHsKCQkgICAgLyoKCQkgICAgKiA1LjIuMi4yLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSC3YWN0dWFsIHR5cGUgCgkJICAgICogZGVmaW5pdGlvbrcgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSAKCQkgICAgKiAqYWN0dWFsIHZhbHVlKiBvZiB0aGUgaXRlbSBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgCgkJICAgICogbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFZBTCBUT0RPOiAqYWN0dWFsIHZhbHVlKiBpcyB0aGUgbm9ybWFsaXplZCB2YWx1ZSwgaW1wbC4KCQkgICAgKiAgICAgICAgICAgdGhpcy4KCQkgICAgKiBWQUwgVE9ETzogUmVwb3J0IGludmFsaWQgJiBleHBlY3RlZCB2YWx1ZXMgYXMgd2VsbC4KCQkgICAgKiBWQUwgVE9ETzogSW1wbGVtZW50IGEgY29tcGFyaXNvbiB3aXRoIHRoZSBjb21wdXRlZCB2YWx1ZXMuCgkJICAgICovCgkJICAgIGlmICghIHhtbFN0ckVxdWFsKGlub2RlLT52YWx1ZSwKCQkJICAgIGlub2RlLT5kZWNsLT52YWx1ZSkpIHsKCQkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8yXzI7CgkJCXhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkJICAgIHJldCwgTlVMTCwgTlVMTCwKCQkJICAgICJUaGUgYWN0dWFsIHZhbHVlICclcycgZG9lcyBub3QgbWF0Y2ggdGhlIGZpeGVkICIKCQkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLCAKCQkJICAgIGlub2RlLT52YWx1ZSwKCQkJICAgIGlub2RlLT5kZWNsLT52YWx1ZSk7CgkJCWdvdG8gZW5kX2VsZW07CgkJICAgIH0JCSAgICAKCQl9CgkgICAgfQkgICAgCgl9CiAgICB9CiAgICAKZW5kX2VsZW06CiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkgewoJLyogVE9ETzogcmFpc2UgZXJyb3I/ICovCglyZXR1cm4gKDApOwogICAgfQogICAgaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKQoJdmN0eHQtPnNraXBEZXB0aCA9IC0xOwogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIGhpc3Rvcnkgb2YgWFBhdGggc3RhdGUgb2JqZWN0cy4KICAgICovICAgIAogICAgaWYgKHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkodmN0eHQsIHZjdHh0LT5kZXB0aCkgPT0gLTEpCglnb3RvIGludGVybmFsX2Vycm9yOwogICAgLyoKICAgICogVE9ETzogNiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gZWFjaCBvZiAKICAgICogdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb25zfSBhcyBwZXIgSWRlbnRpdHktY29uc3RyYWludCAKICAgICogU2F0aXNmaWVkICinMy4xMS40KS4KICAgICovCiAgICAvKgogICAgKiBWYWxpZGF0ZSBJREMga2V5cmVmcy4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWYodmN0eHQpID09IC0xKQoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIC8qCiAgICAqIE1lcmdlL2ZyZWUgdGhlIElEQyB0YWJsZS4KICAgICovCiAgICBpZiAoaW5vZGUtPmlkY1RhYmxlICE9IE5VTEwpIHsKI2lmZGVmIERFQlVHX0lEQwoJeG1sU2NoZW1hRGVidWdEdW1wSURDVGFibGUoc3Rkb3V0LAoJICAgIGlub2RlLT5uc05hbWUsCgkgICAgaW5vZGUtPmxvY2FsTmFtZSwKCSAgICBpbm9kZS0+aWRjVGFibGUpOwojZW5kaWYKCWlmICh2Y3R4dC0+ZGVwdGggPiAwKSB7CgkgICAgLyoKCSAgICAqIE1lcmdlIHRoZSBJREMgbm9kZSB0YWJsZSB3aXRoIHRoZSB0YWJsZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh2Y3R4dCkgPT0gLTEpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCX0JCiAgICB9CiAgICAvKgogICAgKiBDbGVhciB0aGUgY3VycmVudCBpZWxlbS4KICAgICogVkFMIFRPRE86IERvbid0IGZyZWUgdGhlIFBTVkkgSURDIHRhYmxlcyBpZiB0aGV5IGFyZQogICAgKiByZXF1ZXN0ZWQgZm9yIHRoZSBQU1ZJLgogICAgKi8KICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8oaW5vZGUpOwogICAgLyoKICAgICogU2tpcCBmdXJ0aGVyIHByb2Nlc3NpbmcgaWYgd2UgYXJlIG9uIHRoZSB2YWxpZGF0aW9uIHJvb3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5kZXB0aCA9PSAwKSB7Cgl2Y3R4dC0+ZGVwdGgtLTsKCXZjdHh0LT5pbm9kZSA9IE5VTEw7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogUmVzZXQgdGhlIGJ1YmJsZURlcHRoIGlmIG5lZWRlZC4KICAgICovCiAgICBpZiAodmN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjID0gdmN0eHQtPmFpZGNzOwoJZG8gewoJICAgIGlmIChhaWRjLT5idWJibGVEZXB0aCA9PSB2Y3R4dC0+ZGVwdGgpIHsKCQkvKgoJCSogQSBidWJibGVEZXB0aCBvZiBhIGtleS91bmlxdWUgSURDIG1hdGNoZXMgdGhlIGN1cnJlbnQKCQkqIGRlcHRoLCB0aGlzIG1lYW5zIHRoYXQgd2UgYXJlIGxlYXZpbmcgdGhlIHNjb3BlIG9mIHRoZQoJCSogdG9wLW1vc3Qga2V5cmVmIElEQy4KCQkqLwoJCWFpZGMtPmJ1YmJsZURlcHRoID0gLTE7CgkgICAgfQoJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJfSB3aGlsZSAoYWlkYyAhPSBOVUxMKTsKICAgIH0KICAgIHZjdHh0LT5kZXB0aC0tOyAgICAgICAgCiAgICB2Y3R4dC0+aW5vZGUgPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CiAgICAvKgogICAgKiBWQUwgVE9ETzogNyBJZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzIHRoZSC3dmFsaWRhdGlvbiByb290tywgaXQgbXVzdCBiZSAKICAgICogt3ZhbGlktyBwZXIgVmFsaWRhdGlvbiBSb290IFZhbGlkIChJRC9JRFJFRikgKKczLjMuNCkuCiAgICAqLwogICAgcmV0dXJuIChyZXQpOwoKaW50ZXJuYWxfZXJyb3I6CiAgICB2Y3R4dC0+ZXJyID0gLTE7CiAgICByZXR1cm4gKC0xKTsKfQoKLyoKKiAzLjQuNCBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBWYWxpZGF0aW9uIFJ1bGVzCiogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkgKGN2Yy1jb21wbGV4LXR5cGUpCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBwaWVsZW07CiAgICB4bWxTY2hlbWFUeXBlUHRyIHB0eXBlOwogICAgaW50IHJldCA9IDA7CgogICAgaWYgKHZjdHh0LT5kZXB0aCA8PSAwKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkgICAgIm5vdCBpbnRlbmRlZCBmb3IgdGhlIHZhbGlkYXRpb24gcm9vdCIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBwaWVsZW0gPSB2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aCAtMV07CiAgICBpZiAocGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZKQoJcGllbGVtLT5mbGFncyBePSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKICAgIC8qCiAgICAqIEhhbmRsZSAnbmlsbGVkJyBlbGVtZW50cy4KICAgICovCiAgICBpZiAoSU5PREVfTklMTEVEKHBpZWxlbSkpIHsKCS8qCgkqIFNQRUMgKGN2Yy1lbHQpICgzLjMuNCkgOiAoMy4yLjEpCgkqLwoJQUNUSVZBVEVfUEFSRU5UX0VMRU07CglyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8xOwoJVkVSUk9SKHJldCwgTlVMTCwKCSAgICAiTmVpdGhlciBjaGFyYWN0ZXIgbm9yIGVsZW1lbnQgY29udGVudCBpcyBhbGxvd2VkLCAiCgkgICAgImJlY2F1c2UgdGhlIGVsZW1lbnQgd2FzICduaWxsZWQnIik7CglBQ1RJVkFURV9FTEVNOwoJZ290byB1bmV4cGVjdGVkX2VsZW07CiAgICB9CgogICAgcHR5cGUgPSBwaWVsZW0tPnR5cGVEZWY7CgogICAgaWYgKHB0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKSB7CgkvKgoJKiBXb3JrYXJvdW5kIGZvciAiYW55VHlwZSI6IHdlIGhhdmUgY3VycmVudGx5IG5vIGNvbnRlbnQgbW9kZWwKCSogYXNzaWduZWQgZm9yICJhbnlUeXBlIiwgc28gaGFuZGxlIGl0IGV4cGxpY2l0ZWx5LgoJKiAiYW55VHlwZSIgaGFzIGFuIHVuYm91bmRlZCwgbGF4ICJhbnkiIHdpbGRjYXJkLgoJKi8KCXZjdHh0LT5pbm9kZS0+ZGVjbCA9IHhtbFNjaGVtYUdldEVsZW0odmN0eHQtPnNjaGVtYSwKCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwKCSAgICB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CgoJaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgInhzaTp0eXBlIi4KCSAgICAqIFNQRUMgKGN2Yy1hc3Nlc3MtZWx0KSAoMS4yLjEuMi4xKSAtICgxLjIuMS4yLjMpCgkgICAgKi8KCSAgICBpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCQlYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9UWVBFKTsKCSAgICBpZiAoaWF0dHIgIT0gTlVMTCkgewoJCXJldCA9IHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHZjdHh0LCBpYXR0ciwKCQkgICAgJih2Y3R4dC0+aW5vZGUtPnR5cGVEZWYpLCBOVUxMKTsKCQlpZiAocmV0ICE9IDApIHsKCQkgICAgaWYgKHJldCA9PSAtMSkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSgpIHRvICIKCQkJICAgICJwcm9jZXNzIHRoZSBhdHRyaWJ1dGUgJ3hzaTpuaWwnIik7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIHJldHVybiAocmV0KTsKCQl9CgkgICAgfSBlbHNlIHsKCQkgLyoKCQkgKiBGYWxsYmFjayB0byAiYW55VHlwZSIuCgkJICoKCQkgKiBTUEVDIChjdmMtYXNzZXNzLWVsdCkKCQkgKiAiSWYgdGhlIGl0ZW0gY2Fubm90IGJlILdzdHJpY3RseSBhc3Nlc3NlZLcsIFsuLi5dCgkJICogYW4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3Mgc2NoZW1hIHZhbGlkaXR5IG1heSBiZSBsYXhseQoJCSAqIGFzc2Vzc2VkIGlmIGl0cyC3Y29udGV4dC1kZXRlcm1pbmVkIGRlY2xhcmF0aW9utyBpcyBub3QKCQkgKiBza2lwIGJ5ILd2YWxpZGF0aW5ntyB3aXRoIHJlc3BlY3QgdG8gdGhlILd1ci10eXBlCgkJICogZGVmaW5pdGlvbrcgYXMgcGVyIEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkgKKczLjMuNCkuIgoJCSovCgkJdmN0eHQtPmlub2RlLT50eXBlRGVmID0KCQkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KCiAgICBzd2l0Y2ggKHB0eXBlLT5jb250ZW50VHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CgkgICAgLyoKCSAgICAqIFNQRUMgKDIuMSkgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbXB0eSwgdGhlbiB0aGUKCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4iCgkgICAgKi8KCSAgICBBQ1RJVkFURV9QQVJFTlRfRUxFTQoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8xOwoJICAgIFZFUlJPUihyZXQsIE5VTEwsCgkJIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJCSJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZW1wdHkiKTsKCSAgICBBQ1RJVkFURV9FTEVNCgkgICAgZ290byB1bmV4cGVjdGVkX2VsZW07CgkgICAgYnJlYWs7CgoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6IHsKCSAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleEN0eHQ7CgkgICAgeG1sQ2hhciAqdmFsdWVzWzEwXTsKCSAgICBpbnQgdGVybWluYWwsIG5idmFsID0gMTAsIG5ibmVnOwoKCSAgICAvKiBWQUwgVE9ETzogT3B0aW1pemVkICJhbnlUeXBlIiB2YWxpZGF0aW9uLiovCgoJICAgIGlmIChwdHlwZS0+Y29udE1vZGVsID09IE5VTEwpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUNoaWxkRWxlbSIsCgkJICAgICJ0eXBlIGhhcyBlbGVtIGNvbnRlbnQgYnV0IG5vIGNvbnRlbnQgbW9kZWwiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFNhZmV0eSBiZWxmIGZvciBldmFsdWF0aW9uIGlmIHRoZSBjb250LiBtb2RlbCB3YXMgYWxyZWFkeQoJICAgICogZXhhbWluZWQgdG8gYmUgaW52YWxpZC4KCSAgICAqLwoJICAgIGlmIChwaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCSAgICAidmFsaWRhdGluZyBlbGVtLCBidXQgZWxlbSBjb250ZW50IGlzIGFscmVhZHkgaW52YWxpZCIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCgkgICAgcmVnZXhDdHh0ID0gcGllbGVtLT5yZWdleEN0eHQ7CgkgICAgaWYgKHJlZ2V4Q3R4dCA9PSBOVUxMKSB7CgkJLyoKCQkqIENyZWF0ZSB0aGUgcmVnZXggY29udGV4dC4KCQkqLwoJCXJlZ2V4Q3R4dCA9IHhtbFJlZ05ld0V4ZWNDdHh0KHB0eXBlLT5jb250TW9kZWwsCgkJICAgICh4bWxSZWdFeGVjQ2FsbGJhY2tzKSB4bWxTY2hlbWFWQ29udGVudE1vZGVsQ2FsbGJhY2ssCgkJICAgIHZjdHh0KTsKCQlpZiAocmVnZXhDdHh0ID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCQkiZmFpbGVkIHRvIGNyZWF0ZSBhIHJlZ2V4IGNvbnRleHQiKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCXBpZWxlbS0+cmVnZXhDdHh0ID0gcmVnZXhDdHh0OwojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIkFVVE9NQVRBIGNyZWF0ZSBvbiAnJXMnXG4iLAoJCSAgICBwaWVsZW0tPmxvY2FsTmFtZSk7CiNlbmRpZgoJICAgIH0KCgkgICAgLyoKCSAgICAqIFNQRUMgKDIuNCkgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHkgb3IgbWl4ZWQsCgkgICAgKiB0aGVuIHRoZSBzZXF1ZW5jZSBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtJ3MKCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLCBpZiBhbnksIHRha2VuIGluCgkgICAgKiBvcmRlciwgaXMgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHtjb250ZW50IHR5cGV9J3MKCSAgICAqIHBhcnRpY2xlLCBhcyBkZWZpbmVkIGluIEVsZW1lbnQgU2VxdWVuY2UgTG9jYWxseSBWYWxpZAoJICAgICogKFBhcnRpY2xlKSAopzMuOS40KS4iCgkgICAgKi8KCSAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZzIocmVnZXhDdHh0LAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZSk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJICAgIGlmIChyZXQgPCAwKQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSJBVVRPTUFUT04gcHVzaCBFUlJPUiBmb3IgJyVzJyBvbiAnJXMnXG4iLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCBwaWVsZW0tPmxvY2FsTmFtZSk7CgkgICAgZWxzZQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSJBVVRPTUFUT04gcHVzaCBPSyBmb3IgJyVzJyBvbiAnJXMnXG4iLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCBwaWVsZW0tPmxvY2FsTmFtZSk7CiNlbmRpZgoJICAgIGlmICh2Y3R4dC0+ZXJyID09IFhNTF9TQ0hFTUFWX0lOVEVSTkFMKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxSZWdFeGVjUHVzaFN0cmluZzIoKSIpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFJlZ0V4ZWNFcnJJbmZvKHJlZ2V4Q3R4dCwgTlVMTCwgJm5idmFsLCAmbmJuZWcsCgkJICAgICZ2YWx1ZXNbMF0sICZ0ZXJtaW5hbCk7CgkJeG1sU2NoZW1hQ29tcGxleFR5cGVFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwgTlVMTCxOVUxMLAoJCSAgICAiVGhpcyBlbGVtZW50IGlzIG5vdCBleHBlY3RlZCIsCgkJICAgIG5idmFsLCBuYm5lZywgdmFsdWVzKTsKCQlyZXQgPSB2Y3R4dC0+ZXJyOwoJCWdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIH0gZWxzZQoJCXJldCA9IDA7Cgl9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKCSAgICBBQ1RJVkFURV9QQVJFTlRfRUxFTQoJICAgIGlmIChJU19DT01QTEVYX1RZUEUocHR5cGUpKSB7CgkJLyoKCQkqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpICgyLjIpCgkJKiAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbgoJCSogdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gZWxlbWVudCBpbmZvcm1hdGlvbgoJCSogaXRlbSBbY2hpbGRyZW5dLCAuLi4iCgkJKi8KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMjsKCQlWRVJST1IocmV0LCBOVUxMLCAiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIik7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU1BFQyAoY3ZjLXR5cGUpICgzLjEuMikgIlRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdAoJCSogaGF2ZSBubyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4iCgkJKi8KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMjsKCQlWRVJST1IocmV0LCBOVUxMLCAiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgc2ltcGxlIik7CgkgICAgfQoJICAgIEFDVElWQVRFX0VMRU0KCSAgICByZXQgPSB2Y3R4dC0+ZXJyOwoJICAgIGdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIGJyZWFrOwoKCWRlZmF1bHQ6CgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7CnVuZXhwZWN0ZWRfZWxlbToKICAgIC8qCiAgICAqIFBvcCB0aGlzIGVsZW1lbnQgYW5kIHNldCB0aGUgc2tpcERlcHRoIHRvIHNraXAKICAgICogYWxsIGZ1cnRoZXIgY29udGVudCBvZiB0aGUgcGFyZW50IGVsZW1lbnQuCiAgICAqLwogICAgdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX05PVF9FWFBFQ1RFRDsKICAgIHBpZWxlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UOwogICAgcmV0dXJuIChyZXQpOwp9CgojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1QgMQojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX0NSRUFURUQgMgojZGVmaW5lIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFIDMKCnN0YXRpYyBpbnQKeG1sU2NoZW1hVlB1c2hUZXh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgIGludCBub2RlVHlwZSwgY29uc3QgeG1sQ2hhciAqdmFsdWUsIGludCBsZW4sCgkJICBpbnQgbW9kZSwgaW50ICpjb25zdW1lZCkKewogICAgLyoKICAgICogVW5mb3J0dW5hdGVseSB3ZSBoYXZlIHRvIGR1cGxpY2F0ZSB0aGUgdGV4dCBzb21ldGltZXMuCiAgICAqIE9QVElNSVpFOiBNYXliZSB3ZSBjb3VsZCBza2lwIGl0LCBpZjoKICAgICogICAxLiBjb250ZW50IHR5cGUgaXMgc2ltcGxlCiAgICAqICAgMi4gd2hpdGVzcGFjZSBpcyAiY29sbGFwc2UiCiAgICAqICAgMy4gaXQgY29uc2lzdHMgb2Ygd2hpdGVzcGFjZSBvbmx5CiAgICAqCiAgICAqIFByb2Nlc3MgY2hhcmFjdGVyIGNvbnRlbnQuCiAgICAqLwogICAgaWYgKGNvbnN1bWVkICE9IE5VTEwpCgkqY29uc3VtZWQgPSAwOwogICAgaWYgKElOT0RFX05JTExFRCh2Y3R4dC0+aW5vZGUpKSB7CgkvKiAKCSogU1BFQyBjdmMtZWx0ICgzLjMuNCAtIDMuMi4xKQoJKiAiVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gY2hhcmFjdGVyIG9yCgkqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLiIKCSovCglWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMSwgTlVMTCwKCSAgICAiTmVpdGhlciBjaGFyYWN0ZXIgbm9yIGVsZW1lbnQgY29udGVudCBpcyBhbGxvd2VkICIKCSAgICAiYmVjYXVzZSB0aGUgZWxlbWVudCBpcyAnbmlsbGVkJyIpOwoJcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDIuMSkgIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbXB0eSwgdGhlbiB0aGUKICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgogICAgKi8KICAgIGlmICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09CgkgICAgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7ICAgIAoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8xLCBOVUxMLAoJICAgICJDaGFyYWN0ZXIgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZW1wdHkiKTsKCXJldHVybiAodmN0eHQtPmVycik7CiAgICB9CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0KCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpIHsKCWlmICgobm9kZVR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAoISB4bWxTY2hlbWFJc0JsYW5rKCh4bWxDaGFyICopIHZhbHVlLCBsZW4pKSkgewoJICAgIC8qIAoJICAgICogU1BFQyBjdmMtY29tcGxleC10eXBlICgyLjMpIAoJICAgICogIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIAoJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gCgkgICAgKiBpdGVtIFtjaGlsZHJlbl0gb3RoZXIgdGhhbiB0aG9zZSB3aG9zZSBbY2hhcmFjdGVyIAoJICAgICogY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgCgkgICAgKiBFZGl0aW9uKV0uIgoJICAgICovCgkgICAgVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8zLCBOVUxMLAoJCSJDaGFyYWN0ZXIgY29udGVudCBvdGhlciB0aGFuIHdoaXRlc3BhY2UgaXMgbm90IGFsbG93ZWQgIgoJCSJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgJ2VsZW1lbnQtb25seSciKTsKCSAgICByZXR1cm4gKHZjdHh0LT5lcnIpOwoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIAogICAgaWYgKCh2YWx1ZSA9PSBOVUxMKSB8fCAodmFsdWVbMF0gPT0gMCkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogU2F2ZSB0aGUgdmFsdWUuCiAgICAqIE5PVEUgdGhhdCBldmVuIGlmIHRoZSBjb250ZW50IHR5cGUgaXMgKm1peGVkKiwgd2UgbmVlZCB0aGUKICAgICogKmluaXRpYWwgdmFsdWUqIGZvciBkZWZhdWx0L2ZpeGVkIHZhbHVlIGNvbnN0cmFpbnRzLgogICAgKi8KICAgIGlmICgodmN0eHQtPmlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpICYmCgkoKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKSB8fAoJKHZjdHh0LT5pbm9kZS0+ZGVjbC0+dmFsdWUgPT0gTlVMTCkpKQoJcmV0dXJuICgwKTsKICAgIAogICAgaWYgKHZjdHh0LT5pbm9kZS0+dmFsdWUgPT0gTlVMTCkgewoJLyoKCSogU2V0IHRoZSB2YWx1ZS4KCSovCglzd2l0Y2ggKG1vZGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1Q6CgkJLyoKCQkqIFdoZW4gd29ya2luZyBvbiBhIHRyZWUuCgkJKi8KCQl2Y3R4dC0+aW5vZGUtPnZhbHVlID0gdmFsdWU7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9DUkVBVEVEOgoJCS8qCgkJKiBXaGVuIHdvcmtpbmcgd2l0aCB0aGUgcmVhZGVyLgoJCSogVGhlIHZhbHVlIHdpbGwgYmUgZnJlZWQgYnkgdGhlIGVsZW1lbnQgaW5mby4KCQkqLwoJCXZjdHh0LT5pbm9kZS0+dmFsdWUgPSB2YWx1ZTsKCQlpZiAoY29uc3VtZWQgIT0gTlVMTCkKCQkgICAgKmNvbnN1bWVkID0gMTsKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9CgkJICAgIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEU6CgkJLyoKCQkqIFdoZW4gd29ya2luZyB3aXRoIFNBWC4KCQkqIFRoZSB2YWx1ZSB3aWxsIGJlIGZyZWVkIGJ5IHRoZSBlbGVtZW50IGluZm8uCgkJKi8KCQlpZiAobGVuICE9IC0xKQoJCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0gQkFEX0NBU1QgeG1sU3RybmR1cCh2YWx1ZSwgbGVuKTsKCQllbHNlCgkJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPSBCQURfQ0FTVCB4bWxTdHJkdXAodmFsdWUpOwoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0KCQkgICAgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0gZWxzZSB7CQoJLyoKCSogQ29uY2F0IHRoZSB2YWx1ZS4KCSovCQoJaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUykgewoJICAgIHZjdHh0LT5pbm9kZS0+dmFsdWUgPSBCQURfQ0FTVCB4bWxTdHJuY2F0KAoJCSh4bWxDaGFyICopIHZjdHh0LT5pbm9kZS0+dmFsdWUsIHZhbHVlLCBsZW4pOwoJfSBlbHNlIHsKCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0KCQlCQURfQ0FTVCB4bWxTdHJuY2F0TmV3KHZjdHh0LT5pbm9kZS0+dmFsdWUsIHZhbHVlLCBsZW4pOwoJICAgIHZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7Cgl9CiAgICB9CQoKICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IHJldCA9IDA7CgogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJgoJKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCSAgICAiaW4gc2tpcC1zdGF0ZSIpOwoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIGlmICh2Y3R4dC0+eHNpQXNzZW1ibGUpIHsKCWlmICh4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJKHZjdHh0KSA9PSAtMSkKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgaWYgKHZjdHh0LT5kZXB0aCA+IDApIHsKCS8qCgkqIFZhbGlkYXRlIHRoaXMgZWxlbWVudCBhZ2FpbnN0IHRoZSBjb250ZW50IG1vZGVsCgkqIG9mIHRoZSBwYXJlbnQuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0odmN0eHQpOwoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFTdHJlYW1WYWxpZGF0ZUNoaWxkRWxlbWVudCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBleGl0OwoJfQoJaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKQoJICAgIGdvdG8gZXhpdDsKCWlmICgodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpICYmCgkgICAgKHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9PSBOVUxMKSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJInRoZSBjaGlsZCBlbGVtZW50IHdhcyB2YWxpZCBidXQgbmVpdGhlciB0aGUgIgoJCSJkZWNsYXJhdGlvbiBub3IgdGhlIHR5cGUgd2FzIHNldCIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogR2V0IHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgdmFsaWRhdGlvbiByb290LgoJKi8KCXZjdHh0LT5pbm9kZS0+ZGVjbCA9IHhtbFNjaGVtYUdldEVsZW0odmN0eHQtPnNjaGVtYSwKCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwKCSAgICB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CglpZiAodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzE7CgkgICAgVkVSUk9SKHJldCwgTlVMTCwKCQkiTm8gbWF0Y2hpbmcgZ2xvYmFsIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSAiCgkJImZvciB0aGUgdmFsaWRhdGlvbiByb290Iik7CgkgICAgZ290byBleGl0OwoJfQogICAgfQoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkKCWdvdG8gdHlwZV92YWxpZGF0aW9uOwoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmRlY2wtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkgewoJaW50IHNraXA7CgkvKgoJKiBXaWxkY2FyZHMuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQodmN0eHQsICZza2lwKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZXhpdDsKCX0KCWlmIChza2lwKSB7CgkgICAgdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKCSAgICBnb3RvIGV4aXQ7Cgl9CgkvKgoJKiBUaGUgZGVjbGFyYXRpb24gbWlnaHQgYmUgc2V0IGJ5IHRoZSB3aWxkY2FyZCB2YWxpZGF0aW9uLAoJKiB3aGVuIHRoZSBwcm9jZXNzQ29udGVudHMgaXMgImxheCIgb3IgInN0cmljdCIuCgkqLwoJaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgewoJICAgIC8qCgkgICAgKiBDbGVhciB0aGUgImRlY2wiIGZpZWxkIHRvIG5vdCBjb25mdXNlIGZ1cnRoZXIgcHJvY2Vzc2luZy4KCSAgICAqLwoJICAgIHZjdHh0LT5pbm9kZS0+ZGVjbCA9IE5VTEw7CgkgICAgZ290byB0eXBlX3ZhbGlkYXRpb247Cgl9CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhZ2FpbnN0IHRoZSBkZWNsYXJhdGlvbi4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsKHZjdHh0KTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKHJldCA8IDApIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2woKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGV4aXQ7CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhZ2FpbnN0IHRoZSB0eXBlIGRlZmluaXRpb24uCiAgICAqLwp0eXBlX3ZhbGlkYXRpb246CgogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9PSBOVUxMKSB7Cgl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9CQURfVFlQRTsKCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzE7CiAgICAJVkVSUk9SKHJldCwgTlVMTCwKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7Cglnb3RvIGV4aXQ7CiAgICB9ICAgIAogICAgaWYgKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUKSB7Cgl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9CQURfVFlQRTsKCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzI7CiAgICAJICAgIFZFUlJPUihyZXQsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic3RyYWN0Iik7CQoJZ290byBleGl0OwogICAgfQogICAgLyoKICAgICogRXZhbHVhdGUgSURDcy4gRG8gaXQgaGVyZSwgc2luY2UgbmV3IElEQyBtYXRjaGVycyBhcmUgcmVnaXN0ZXJlZAogICAgKiBkdXJpbmcgdmFsaWRhdGlvbiBhZ2FpbnN0IHRoZSBkZWNsYXJhdGlvbi4gVGhpcyBtdXN0IGJlIGRvbmUKICAgICogX2JlZm9yZV8gYXR0cmlidXRlIHZhbGlkYXRpb24uCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSh2Y3R4dCwgWE1MX0VMRU1FTlRfTk9ERSk7CiAgICBpZiAocmV0ID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoKSIpOwoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIC8qCiAgICAqIFZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKElTX0NPTVBMRVhfVFlQRSh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYpKSB7CglpZiAoKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB8fAoJICAgICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkpIHsKCgkgICAgcmV0ID0geG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4KHZjdHh0KTsKCX0KICAgIH0gZWxzZSBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCglyZXQgPSB4bWxTY2hlbWFWQXR0cmlidXRlc1NpbXBsZSh2Y3R4dCk7CiAgICB9CiAgICAvKgogICAgKiBDbGVhciByZWdpc3RlcmVkIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKQoJeG1sU2NoZW1hQ2xlYXJBdHRySW5mb3ModmN0eHQpOwogICAgaWYgKHJldCA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCSAgICAiY2FsbGluZyBhdHRyaWJ1dGVzIHZhbGlkYXRpb24iKTsKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBEb24ndCByZXR1cm4gYW4gZXJyb3IgaWYgYXR0cmlidXRlcyBhcmUgaW52YWxpZCBvbiBwdXJwb3NlLgogICAgKi8KICAgIHJldCA9IDA7CgpleGl0OgogICAgaWYgKHJldCAhPSAwKQoJdmN0eHQtPnNraXBEZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4gKC0xKTsKfQoKI2lmZGVmIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQKc3RhdGljIGludAp4bWxTY2hlbWFWUmVhZGVyV2Fsayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGNvbnN0IGludCBXSFRTUCA9IDEzLCBTSUdOX1dIVFNQID0gMTQsIEVORF9FTEVNID0gMTU7CiAgICBpbnQgZGVwdGgsIG5vZGVUeXBlLCByZXQgPSAwLCBjb25zdW1lZDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtOwoKICAgIHZjdHh0LT5kZXB0aCA9IC0xOwogICAgcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CiAgICAvKgogICAgKiBNb3ZlIHRvIHRoZSBkb2N1bWVudCBlbGVtZW50LgogICAgKi8KICAgIHdoaWxlIChyZXQgPT0gMSkgewoJbm9kZVR5cGUgPSB4bWxUZXh0UmVhZGVyTm9kZVR5cGUodmN0eHQtPnJlYWRlcik7CglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkKCSAgICBnb3RvIHJvb3RfZm91bmQ7CglyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKICAgIH0KICAgIGdvdG8gZXhpdDsKCnJvb3RfZm91bmQ6CgogICAgZG8gewoJZGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7Cglub2RlVHlwZSA9IHhtbFRleHRSZWFkZXJOb2RlVHlwZSh2Y3R4dC0+cmVhZGVyKTsKCglpZiAobm9kZVR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJICAgIAoJICAgIHZjdHh0LT5kZXB0aCsrOwoJICAgIGlmICh4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSh2Y3R4dCkgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZWxlbSA9IHZjdHh0LT5pbm9kZTsKCSAgICBpZWxlbS0+bG9jYWxOYW1lID0geG1sVGV4dFJlYWRlckxvY2FsTmFtZSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZWxlbS0+bnNOYW1lID0geG1sVGV4dFJlYWRlck5hbWVzcGFjZVVyaSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZWxlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9OQU1FUzsKCSAgICAvKgoJICAgICogSXMgdGhlIGVsZW1lbnQgZW1wdHk/CgkgICAgKi8KCSAgICByZXQgPSB4bWxUZXh0UmVhZGVySXNFbXB0eUVsZW1lbnQodmN0eHQtPnJlYWRlcik7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sVGV4dFJlYWRlcklzRW1wdHlFbGVtZW50KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZiAocmV0KSB7CgkJaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVnaXN0ZXIgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIHZjdHh0LT5uYkF0dHJJbmZvcyA9IDA7CgkgICAgcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb0ZpcnN0QXR0cmlidXRlKHZjdHh0LT5yZWFkZXIpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWYgKHJldCA9PSAxKSB7CgkJZG8gewoJCSAgICAvKgoJCSAgICAqIFZBTCBUT0RPOiBIb3cgZG8gd2Uga25vdyB0aGF0IHRoZSByZWFkZXIgd29ya3Mgb24gYQoJCSAgICAqIG5vZGUgdHJlZSwgdG8gYmUgYWJsZSB0byBwYXNzIGEgbm9kZSBoZXJlPwoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwgTlVMTCwKCQkJKGNvbnN0IHhtbENoYXIgKikgeG1sVGV4dFJlYWRlckxvY2FsTmFtZSh2Y3R4dC0+cmVhZGVyKSwKCQkJeG1sVGV4dFJlYWRlck5hbWVzcGFjZVVyaSh2Y3R4dC0+cmVhZGVyKSwgMSwKCQkJeG1sVGV4dFJlYWRlclZhbHVlKHZjdHh0LT5yZWFkZXIpLCAxKSA9PSAtMSkgewoKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb05leHRBdHRyaWJ1dGUodmN0eHQtPnJlYWRlcik7CgkJICAgIGlmIChyZXQgPT0gLTEpIHsKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sVGV4dFJlYWRlck1vdmVUb0ZpcnN0QXR0cmlidXRlKCkiKTsKCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkgICAgfQoJCX0gd2hpbGUgKHJldCA9PSAxKTsKCQkvKgoJCSogQmFjayB0byBlbGVtZW50IHBvc2l0aW9uLgoJCSovCgkJcmV0ID0geG1sVGV4dFJlYWRlck1vdmVUb0VsZW1lbnQodmN0eHQtPnJlYWRlcik7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9FbGVtZW50KCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KCSAgICAqLwoJICAgIHJldD0geG1sU2NoZW1hVmFsaWRhdGVFbGVtKHZjdHh0KTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0ID09IC0xKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBleGl0OwoJICAgIH0KCSAgICBpZiAodmN0eHQtPmRlcHRoID09IHZjdHh0LT5za2lwRGVwdGgpIHsKCQlpbnQgY3VyRGVwdGg7CgkJLyoKCQkqIFNraXAgYWxsIGNvbnRlbnQuCgkJKi8KCQlpZiAoKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZKSA9PSAwKSB7CgkJICAgIHJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwoJCSAgICBjdXJEZXB0aCA9IHhtbFRleHRSZWFkZXJEZXB0aCh2Y3R4dC0+cmVhZGVyKTsKCQkgICAgd2hpbGUgKChyZXQgPT0gMSkgJiYgKGN1ckRlcHRoICE9IGRlcHRoKSkgewoJCQlyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKCQkJY3VyRGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7CgkJICAgIH0KCQkgICAgaWYgKHJldCA8IDApIHsKCQkJLyoKCQkJKiBWQUwgVE9ETzogQSByZWFkZXIgZXJyb3Igb2NjdXJlZDsgd2hhdCB0byBkbyBoZXJlPwoJCQkqLwoJCQlyZXQgPSAxOwoJCQlnb3RvIGV4aXQ7CgkJICAgIH0KCQl9CgkJZ290byBsZWF2ZV9lbGVtOwoJICAgIH0KCSAgICAvKgoJICAgICogUkVBREVSIFZBTCBUT0RPOiBJcyBhbiBFTkRfRUxFTSByZWFsbHkgbmV2ZXIgY2FsbGVkCgkgICAgKiBpZiB0aGUgZWxlbSBpcyBlbXB0eT8KCSAgICAqLwoJICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCQlnb3RvIGxlYXZlX2VsZW07Cgl9IGVsc2UgaWYgKG5vZGVUeXBlID09IEVORF9FTEVNKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgRU5EIG9mIGVsZW1lbnQuCgkgICAgKi8KbGVhdmVfZWxlbToKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHZjdHh0KTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oKSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlnb3RvIGV4aXQ7CgkgICAgfQoJICAgIGlmICh2Y3R4dC0+ZGVwdGggPj0gMCkKCQlpZWxlbSA9IHZjdHh0LT5pbm9kZTsKCSAgICBlbHNlCgkJaWVsZW0gPSBOVUxMOwoJfSBlbHNlIGlmICgobm9kZVR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gV0hUU1ApIHx8CgkgICAgKG5vZGVUeXBlID09IFNJR05fV0hUU1ApKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgY2hhcmFjdGVyIGNvbnRlbnQuCgkgICAgKi8KCSAgICB4bWxDaGFyICp2YWx1ZTsKCgkgICAgaWYgKChub2RlVHlwZSA9PSBXSFRTUCkgfHwgKG5vZGVUeXBlID09IFNJR05fV0hUU1ApKQoJCW5vZGVUeXBlID0gWE1MX1RFWFRfTk9ERTsKCgkgICAgdmFsdWUgPSB4bWxUZXh0UmVhZGVyVmFsdWUodmN0eHQtPnJlYWRlcik7CgkgICAgcmV0ID0geG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBub2RlVHlwZSwgQkFEX0NBU1QgdmFsdWUsCgkJLTEsIFhNTF9TQ0hFTUFfUFVTSF9URVhUX0NSRUFURUQsICZjb25zdW1lZCk7CgkgICAgaWYgKCEgY29uc3VtZWQpCgkJeG1sRnJlZSh2YWx1ZSk7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVlB1c2hUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCX0gZWxzZSBpZiAoKG5vZGVUeXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwKCSAgICAobm9kZVR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkpIHsKCSAgICAvKgoJICAgICogVkFMIFRPRE86IFdoYXQgdG8gZG8gd2l0aCBlbnRpdGllcz8KCSAgICAqLwoJICAgIFRPRE8KCX0KCS8qCgkqIFJlYWQgbmV4dCBub2RlLgoJKi8KCXJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwogICAgfSB3aGlsZSAocmV0ID09IDEpOwoKZXhpdDoKICAgIHJldHVybiAocmV0KTsKaW50ZXJuYWxfZXJyb3I6CiAgICByZXR1cm4gKC0xKTsKfQojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTQVggdmFsaWRhdGlvbiBoYW5kbGVycwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZmRlZiBYTUxfU0NIRU1BX1NBWF9FTkFCTEVECi8qCiogUHJvY2VzcyB0ZXh0IGNvbnRlbnQuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVRleHQodm9pZCAqY3R4LCAKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIGNoLCAKCQkgICAgICAgaW50IGxlbikKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICBpZiAoeG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBYTUxfVEVYVF9OT0RFLCBjaCwgbGVuLAoJWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEUsIE5VTEwpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7Cgl2Y3R4dC0+ZXJyID0gLTE7Cgl4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIH0KfQoKLyoKKiBQcm9jZXNzIENEQVRBIGNvbnRlbnQuCiovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbih2b2lkICpjdHgsIAoJCQkgICAgIGNvbnN0IHhtbENoYXIgKiBjaCwgCgkJCSAgICAgaW50IGxlbikKeyAgIAogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgaWYgKHZjdHh0LT5pbm9kZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICBpZiAoeG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFLCBjaCwgbGVuLAoJWE1MX1NDSEVNQV9QVVNIX1RFWFRfVk9MQVRJTEUsIE5VTEwpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24iLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7Cgl2Y3R4dC0+ZXJyID0gLTE7Cgl4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIH0KfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hU0FYSGFuZGxlUmVmZXJlbmNlKHZvaWQgKmN0eCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPCAwKQoJcmV0dXJuOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgLyogU0FYIFZBTCBUT0RPOiBXaGF0IHRvIGRvIGhlcmU/ICovCiAgICBUT0RPCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zKHZvaWQgKmN0eCwKCQkJCSBjb25zdCB4bWxDaGFyICogbG9jYWxuYW1lLCAKCQkJCSBjb25zdCB4bWxDaGFyICogcHJlZml4IEFUVFJJQlVURV9VTlVTRUQsIAoJCQkJIGNvbnN0IHhtbENoYXIgKiBVUkksIAoJCQkJIGludCBuYl9uYW1lc3BhY2VzLCAKCQkJCSBjb25zdCB4bWxDaGFyICoqIG5hbWVzcGFjZXMsIAoJCQkJIGludCBuYl9hdHRyaWJ1dGVzLCAKCQkJCSBpbnQgbmJfZGVmYXVsdGVkIEFUVFJJQlVURV9VTlVTRUQsIAoJCQkJIGNvbnN0IHhtbENoYXIgKiogYXR0cmlidXRlcykKeyAgCiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHg7CiAgICBpbnQgcmV0OwogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaWVsZW07CiAgICBpbnQgaSwgajsKICAgIAogICAgLyoKICAgICogU0FYIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggbmJfZGVmYXVsdGVkPwogICAgKi8KICAgIC8qCiAgICAqIFNraXAgZWxlbWVudHMgaWYgaW5zaWRlIGEgInNraXAiIHdpbGRjYXJkIG9yIGludmFsaWQuCiAgICAqLwogICAgdmN0eHQtPmRlcHRoKys7CiAgICBpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmICh2Y3R4dC0+ZGVwdGggPj0gdmN0eHQtPnNraXBEZXB0aCkpCglyZXR1cm47CiAgICAvKgogICAgKiBQdXNoIHRoZSBlbGVtZW50LgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSh2Y3R4dCkgPT0gLTEpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSgpIik7Cglnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CiAgICBpZWxlbS0+bG9jYWxOYW1lID0gbG9jYWxuYW1lOwogICAgaWVsZW0tPm5zTmFtZSA9IFVSSTsKICAgIGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKICAgIC8qCiAgICAqIFJlZ2lzdGVyIG5hbWVzcGFjZXMgb24gdGhlIGVsZW0gaW5mby4KICAgICovICAgIAogICAgaWYgKG5iX25hbWVzcGFjZXMgIT0gMCkgewoJLyoKCSogQWx0aG91Z2ggdGhlIHBhcnNlciBidWlsZHMgaXRzIG93biBuYW1lc3BhY2UgbGlzdCwKCSogd2UgaGF2ZSBubyBhY2Nlc3MgdG8gaXQsIHNvIHdlJ2xsIHVzZSBhbiBvd24gb25lLgoJKi8KICAgICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG5iX25hbWVzcGFjZXM7IGkrKywgaiArPSAyKSB7CSAgICAKCSAgICAvKgoJICAgICogU3RvcmUgcHJlZml4IGFuZCBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwkgICAKCSAgICBpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbE1hbGxvYygxMCAqCgkJCXNpemVvZihjb25zdCB4bWxDaGFyICopKTsKCQlpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCQkiYWxsb2NhdGluZyBuYW1lc3BhY2UgYmluZGluZ3MgZm9yIFNBWCB2YWxpZGF0aW9uIiwKCQkJTlVMTCk7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWllbGVtLT5uYk5zQmluZGluZ3MgPSAwOwoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyA9IDU7CgkgICAgfSBlbHNlIGlmIChpZWxlbS0+c2l6ZU5zQmluZGluZ3MgPD0gaWVsZW0tPm5iTnNCaW5kaW5ncykgewoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyAqPSAyOwoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbFJlYWxsb2MoCgkJCSh2b2lkICopIGllbGVtLT5uc0JpbmRpbmdzLAoJCQlpZWxlbS0+c2l6ZU5zQmluZGluZ3MgKiAyICogc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJCWlmIChpZWxlbS0+bnNCaW5kaW5ncyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJCSJyZS1hbGxvY2F0aW5nIG5hbWVzcGFjZSBiaW5kaW5ncyBmb3IgU0FYIHZhbGlkYXRpb24iLAoJCQlOVUxMKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoKCSAgICBpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMl0gPSBuYW1lc3BhY2VzW2pdOwoJICAgIGlmIChuYW1lc3BhY2VzW2orMV1bMF0gPT0gMCkgewoJCS8qCgkJKiBIYW5kbGUgeG1sbnM9IiIuCgkJKi8KCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0gTlVMTDsKCSAgICB9IGVsc2UKCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0KCQkgICAgbmFtZXNwYWNlc1tqKzFdOwoJICAgIGllbGVtLT5uYk5zQmluZGluZ3MrKzsJICAgIAkgICAgCgl9CiAgICB9CiAgICAvKgogICAgKiBSZWdpc3RlciBhdHRyaWJ1dGVzLgogICAgKiBTQVggVkFMIFRPRE86IFdlIGFyZSBub3QgYWRkaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgogICAgKiBhdHRyaWJ1dGVzIHlldC4KICAgICovCiAgICBpZiAobmJfYXR0cmlidXRlcyAhPSAwKSB7Cgl4bWxDaGFyICp2YWx1ZTsKCiAgICAgICAgZm9yIChqID0gMCwgaSA9IDA7IGkgPCBuYl9hdHRyaWJ1dGVzOyBpKyssIGogKz0gNSkgewoJICAgIC8qCgkgICAgKiBEdXBsaWNhdGUgdGhlIHZhbHVlLgoJICAgICovCSAKCSAgICB2YWx1ZSA9IHhtbFN0cm5kdXAoYXR0cmlidXRlc1tqKzNdLAoJCWF0dHJpYnV0ZXNbais0XSAtIGF0dHJpYnV0ZXNbaiszXSk7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwKCQlOVUxMLCBhdHRyaWJ1dGVzW2pdLCBhdHRyaWJ1dGVzW2orMl0sIDAsCgkJdmFsdWUsIDEpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJfQogICAgfQogICAgLyoKICAgICogVmFsaWRhdGUgdGhlIGVsZW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtKHZjdHh0KTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKHJldCA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zIiwKCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0ZUVsZW0oKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGV4aXQ7CiAgICB9ICAgIAoKZXhpdDoKICAgIHJldHVybjsKaW50ZXJuYWxfZXJyb3I6CiAgICB2Y3R4dC0+ZXJyID0gLTE7CiAgICB4bWxTdG9wUGFyc2VyKHZjdHh0LT5wYXJzZXJDdHh0KTsKICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zKHZvaWQgKmN0eCwKCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBsb2NhbG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBwcmVmaXggQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBVUkkgQVRUUklCVVRFX1VOVVNFRCkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwogICAgaW50IHJlczsKCiAgICAvKgogICAgKiBTa2lwIGVsZW1lbnRzIGlmIGluc2lkZSBhICJza2lwIiB3aWxkY2FyZCBvciBpZiBpbnZhbGlkLgogICAgKi8KICAgIGlmICh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSB7CglpZiAodmN0eHQtPmRlcHRoID4gdmN0eHQtPnNraXBEZXB0aCkgewoJICAgIHZjdHh0LT5kZXB0aC0tOwoJICAgIHJldHVybjsKCX0gZWxzZQoJICAgIHZjdHh0LT5za2lwRGVwdGggPSAtMTsKICAgIH0KICAgIC8qCiAgICAqIFNBWCBWQUwgVE9ETzogSnVzdCBhIHRlbXBvcmFyeSBjaGVjay4KICAgICovCiAgICBpZiAoKCF4bWxTdHJFcXVhbCh2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgbG9jYWxuYW1lKSkgfHwKCSgheG1sU3RyRXF1YWwodmN0eHQtPmlub2RlLT5uc05hbWUsIFVSSSkpKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnMiLAoJICAgICJlbGVtIHBvcCBtaXNtYXRjaCIpOwogICAgfQogICAgcmVzID0geG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSh2Y3R4dCk7CiAgICBpZiAocmVzICE9IDApIHsKCWlmIChyZXMgPCAwKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zIiwKCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKCkiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJZ290byBleGl0OwogICAgfQpleGl0OgogICAgcmV0dXJuOwppbnRlcm5hbF9lcnJvcjoKICAgIHZjdHh0LT5lcnIgPSAtMTsKICAgIHhtbFN0b3BQYXJzZXIodmN0eHQtPnBhcnNlckN0eHQpOwogICAgcmV0dXJuOwp9CiNlbmRpZgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpb24gaW50ZXJmYWNlcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFOZXdWYWxpZEN0eHQ6CiAqIEBzY2hlbWE6ICBhIHByZWNvbXBpbGVkIFhNTCBTY2hlbWFzCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQgYmFzZWQgb24gdGhlIGdpdmVuIHNjaGVtYS4KICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SOwogICAgcmV0LT5zY2hlbWEgPSBzY2hlbWE7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhclZhbGlkQ3R4dDoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0OwogKiBsZWF2ZXMgc29tZSBmaWVsZHMgYWxpdmUgaW50ZW5kZWQgZm9yIHJldXNlIG9mIHRoZSBjb250ZXh0LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYXJWYWxpZEN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpZiAodmN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgdmN0eHQtPmZsYWdzID0gMDsKICAgIHZjdHh0LT52YWxpZGF0aW9uUm9vdCA9IE5VTEw7CiAgICB2Y3R4dC0+ZG9jID0gTlVMTDsKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAogICAgdmN0eHQtPnJlYWRlciA9IE5VTEw7CiNlbmRpZgogICAgaWYgKHZjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKHZjdHh0LT52YWx1ZSk7Cgl2Y3R4dC0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogQXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbi4KICAgICovCiAgICBpZiAodmN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBjdXIgPSB2Y3R4dC0+YWlkY3MsIG5leHQ7CglkbyB7CgkgICAgbmV4dCA9IGN1ci0+bmV4dDsKCSAgICB4bWxGcmVlKGN1cik7CgkgICAgY3VyID0gbmV4dDsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKCXZjdHh0LT5haWRjcyA9IE5VTEw7CiAgICB9CiAgICBpZiAodmN0eHQtPmlkY05vZGVzICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaXRlbTsKCglmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPm5iSWRjTm9kZXM7IGkrKykgewoJICAgIGl0ZW0gPSB2Y3R4dC0+aWRjTm9kZXNbaV07CgkgICAgeG1sRnJlZShpdGVtLT5rZXlzKTsKCSAgICB4bWxGcmVlKGl0ZW0pOwoJfQoJeG1sRnJlZSh2Y3R4dC0+aWRjTm9kZXMpOwoJdmN0eHQtPmlkY05vZGVzID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIE5vdGUgdGhhdCB3ZSB3b24ndCBkZWxldGUgdGhlIFhQYXRoIHN0YXRlIHBvb2wgaGVyZS4KICAgICovCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QodmN0eHQtPnhwYXRoU3RhdGVzKTsKCXZjdHh0LT54cGF0aFN0YXRlcyA9IE5VTEw7CiAgICB9CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgaW5mby4KICAgICovCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCXhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHZjdHh0KTsKICAgIH0KICAgIC8qCiAgICAqIEVsZW1lbnQgaW5mby4KICAgICovCiAgICBpZiAodmN0eHQtPmVsZW1JbmZvcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYU5vZGVJbmZvUHRyIGVpOwoKCWZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKSB7CgkgICAgZWkgPSB2Y3R4dC0+ZWxlbUluZm9zW2ldOwoJICAgIGlmIChlaSA9PSBOVUxMKQoJCWJyZWFrOwoJICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8oZWkpOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KGN0eHQtPnBjdHh0KTsKICAgIGlmIChjdHh0LT5pZGNOb2RlcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjTm9kZXM7IGkrKykgewoJICAgIGl0ZW0gPSBjdHh0LT5pZGNOb2Rlc1tpXTsKCSAgICB4bWxGcmVlKGl0ZW0tPmtleXMpOwoJICAgIHhtbEZyZWUoaXRlbSk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmlkY05vZGVzKTsKICAgIH0KICAgIGlmIChjdHh0LT5pZGNLZXlzICE9IE5VTEwpIHsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjS2V5czsgaSsrKQoJICAgIHhtbFNjaGVtYUlEQ0ZyZWVLZXkoY3R4dC0+aWRjS2V5c1tpXSk7Cgl4bWxGcmVlKGN0eHQtPmlkY0tleXMpOwogICAgfQoKICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlcyk7CiAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QoY3R4dC0+eHBhdGhTdGF0ZVBvb2wpOwoKICAgIC8qCiAgICAqIEF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb24uCiAgICAqLwogICAgaWYgKGN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBjdXIgPSBjdHh0LT5haWRjcywgbmV4dDsKCWRvIHsKCSAgICBuZXh0ID0gY3VyLT5uZXh0OwoJICAgIHhtbEZyZWUoY3VyKTsKCSAgICBjdXIgPSBuZXh0OwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPmF0dHJJbmZvcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGF0dHI7CgoJLyogSnVzdCBhIHBhcmFub2lkIGNhbGwgdG8gdGhlIGNsZWFudXAuICovCglpZiAoY3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCSAgICB4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyhjdHh0KTsKCWZvciAoaSA9IDA7IGkgPCBjdHh0LT5zaXplQXR0ckluZm9zOyBpKyspIHsKCSAgICBhdHRyID0gY3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIHhtbEZyZWUoYXR0cik7Cgl9Cgl4bWxGcmVlKGN0eHQtPmF0dHJJbmZvcyk7CiAgICB9CiAgICBpZiAoY3R4dC0+ZWxlbUluZm9zICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hTm9kZUluZm9QdHIgZWk7CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykgewoJICAgIGVpID0gY3R4dC0+ZWxlbUluZm9zW2ldOwoJICAgIGlmIChlaSA9PSBOVUxMKQoJCWJyZWFrOwoJICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8oZWkpOwoJICAgIHhtbEZyZWUoZWkpOwoJfQoJeG1sRnJlZShjdHh0LT5lbGVtSW5mb3MpOwogICAgfQogICAgaWYgKGN0eHQtPmRpY3QgIT0gTlVMTCkKCXhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoY3R4dC0+cGN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFZhbGlkRXJyb3JzOgogKiBAY3R4dDoJYSBYTUwtU2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgZnVuY3Rpb24gcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbiByZXN1bHQKICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0IHJlc3VsdAogKgogKiBHZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkJCQl4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkT3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFWYWxpZE9wdGlvbgogKgogKiBTZXRzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFTZXRWYWxpZE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSBpbnQgb3B0aW9ucykKCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFWYWxpZE9wdGlvbi4KICAgICogVE9ETzogSXMgdGhlcmUgYW4gb3RoZXIsIG1vcmUgZWFzeSB0byBtYWludGFpbiwKICAgICogd2F5PwogICAgKi8KICAgIGZvciAoaSA9IDE7IGkgPCAoaW50KSBzaXplb2YoaW50KSAqIDg7IGkrKykgewogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogR2V0IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQgb3B0aW9ucy4KICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9yIC0xIG9uIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpCgp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZEb2NXYWxrKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbSA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIG5vZGUsIHZhbFJvb3Q7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CgogICAgLyogRE9DIFZBTCBUT0RPOiBNb3ZlIHRoaXMgdG8gdGhlIHN0YXJ0IGZ1bmN0aW9uLiAqLwogICAgdmFsUm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KHZjdHh0LT5kb2MpOwogICAgaWYgKHZhbFJvb3QgPT0gTlVMTCkgewoJLyogVkFMIFRPRE86IEVycm9yIGNvZGU/ICovCglWRVJST1IoMSwgTlVMTCwgIlRoZSBkb2N1bWVudCBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudCIpOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHZjdHh0LT5kZXB0aCA9IC0xOwogICAgdmN0eHQtPnZhbGlkYXRpb25Sb290ID0gdmFsUm9vdDsKICAgIG5vZGUgPSB2YWxSb290OwogICAgd2hpbGUgKG5vZGUgIT0gTlVMTCkgewoJaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJICAgIGdvdG8gbmV4dF9zaWJsaW5nOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoKCSAgICAvKgoJICAgICogSW5pdCB0aGUgbm9kZS1pbmZvLgoJICAgICovCgkgICAgdmN0eHQtPmRlcHRoKys7CgkgICAgaWYgKHhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtKHZjdHh0KSA9PSAtMSkKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGllbGVtID0gdmN0eHQtPmlub2RlOwoJICAgIGllbGVtLT5ub2RlID0gbm9kZTsKCSAgICBpZWxlbS0+bG9jYWxOYW1lID0gbm9kZS0+bmFtZTsKCSAgICBpZiAobm9kZS0+bnMgIT0gTlVMTCkKCQlpZWxlbS0+bnNOYW1lID0gbm9kZS0+bnMtPmhyZWY7CgkgICAgaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwoJICAgIC8qCgkgICAgKiBSZWdpc3RlciBhdHRyaWJ1dGVzLgoJICAgICogRE9DIFZBTCBUT0RPOiBXZSBkbyBub3QgcmVnaXN0ZXIgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCgkgICAgKiBhdHRyaWJ1dGVzIHlldC4KCSAgICAqLwoJICAgIHZjdHh0LT5uYkF0dHJJbmZvcyA9IDA7CgkgICAgaWYgKG5vZGUtPnByb3BlcnRpZXMgIT0gTlVMTCkgewoJCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJCWRvIHsKCQkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpCgkJCW5zTmFtZSA9IGF0dHItPm5zLT5ocmVmOwoJCSAgICBlbHNlCgkJCW5zTmFtZSA9IE5VTEw7CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUodmN0eHQsCgkJCSh4bWxOb2RlUHRyKSBhdHRyLAoJCQlhdHRyLT5uYW1lLCBuc05hbWUsIDAsCgkJCXhtbE5vZGVMaXN0R2V0U3RyaW5nKGF0dHItPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpLCAxKTsKCQkgICAgaWYgKHJldCA9PSAtMSkgewoJCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFEb2NXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoKSIpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCX0gd2hpbGUgKGF0dHIpOwoJICAgIH0KCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIGVsZW1lbnQuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW0odmN0eHQpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPT0gLTEpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hRG9jV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCS8qCgkJKiBEb24ndCBzdG9wIHZhbGlkYXRpb247IGp1c3Qgc2tpcCB0aGUgY29udGVudAoJCSogb2YgdGhpcyBlbGVtZW50LgoJCSovCgkJZ290byBsZWF2ZV9ub2RlOwoJICAgIH0KCSAgICBpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmCgkJKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCQlnb3RvIGxlYXZlX25vZGU7Cgl9IGVsc2UgaWYgKChub2RlLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CgkgICAgKG5vZGUtPnR5cGUgPT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyBjaGFyYWN0ZXIgY29udGVudC4KCSAgICAqLwoJICAgIGlmIChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCQlpZWxlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CgkgICAgcmV0ID0geG1sU2NoZW1hVlB1c2hUZXh0KHZjdHh0LCBub2RlLT50eXBlLCBub2RlLT5jb250ZW50LAoJCS0xLCBYTUxfU0NIRU1BX1BVU0hfVEVYVF9QRVJTSVNULCBOVUxMKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZEb2NXYWxrIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVlB1c2hUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBTaG91bGQgd2Ugc2tpcCBmdXJ0aGVyIHZhbGlkYXRpb24gb2YgdGhlCgkgICAgKiBlbGVtZW50IGNvbnRlbnQgaGVyZT8KCSAgICAqLwoJfSBlbHNlIGlmICgobm9kZS0+dHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CgkgICAgKG5vZGUtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkpIHsKCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggZW50aXRpZXM/CgkgICAgKi8KCSAgICBUT0RPCgl9IGVsc2UgewoJICAgIGdvdG8gbGVhdmVfbm9kZTsKCSAgICAvKgoJICAgICogRE9DIFZBTCBUT0RPOiBYSW5jbHVkZSBub2RlcywgZXRjLgoJICAgICovCgl9CgkvKgoJKiBXYWxrIHRoZSBkb2MuCgkqLwoJaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsKCSAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CgkgICAgY29udGludWU7Cgl9CmxlYXZlX25vZGU6CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkgICAgLyoKCSAgICAqIExlYXZpbmcgdGhlIHNjb3BlIG9mIGFuIGVsZW1lbnQuCgkgICAgKi8KCSAgICBpZiAobm9kZSAhPSB2Y3R4dC0+aW5vZGUtPm5vZGUpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWRG9jV2FsayIsCgkJICAgICJlbGVtZW50IHBvc2l0aW9uIG1pc21hdGNoIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkRvY1dhbGsiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoJICAgIGlmIChub2RlID09IHZhbFJvb3QpCgkJZ290byBleGl0OwoJfQpuZXh0X3NpYmxpbmc6CglpZiAobm9kZS0+bmV4dCAhPSBOVUxMKQoJICAgIG5vZGUgPSBub2RlLT5uZXh0OwoJZWxzZSB7CgkgICAgbm9kZSA9IG5vZGUtPnBhcmVudDsKCSAgICBnb3RvIGxlYXZlX25vZGU7Cgl9CiAgICB9CgpleGl0OgogICAgcmV0dXJuIChyZXQpOwppbnRlcm5hbF9lcnJvcjoKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZTdGFydCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIFNvbWUgaW5pdGlhbGl6YXRpb24uCiAgICAqLwogICAgdmN0eHQtPmVyciA9IDA7CiAgICB2Y3R4dC0+bmJlcnJvcnMgPSAwOwogICAgdmN0eHQtPmRlcHRoID0gLTE7CiAgICB2Y3R4dC0+c2tpcERlcHRoID0gLTE7CiAgICAvKgogICAgKiBDcmVhdGUgYSBzY2hlbWEgKyBwYXJzZXIgaWYgbmVjZXNzYXJ5LgogICAgKi8KICAgIGlmICh2Y3R4dC0+c2NoZW1hID09IE5VTEwpIHsKCglpZiAoKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSAmJgoJICAgKHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh2Y3R4dCkgPT0gLTEpKQoJICAgcmV0dXJuICgtMSk7CgoJdmN0eHQtPnNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYSh2Y3R4dC0+cGN0eHQpOwoJaWYgKHZjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZTdGFydFZhbGlkYXRpb24iLAoJCSAgICAiY3JlYXRpbmcgYSBzY2hlbWEiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXZjdHh0LT54c2lBc3NlbWJsZSA9IDE7CiAgICB9IGVsc2UKCXZjdHh0LT54c2lBc3NlbWJsZSA9IDA7CiAgICAvKgogICAgKiBBdWdtZW50IHRoZSBJREMgZGVmaW5pdGlvbnMuCiAgICAqLwogICAgaWYgKHZjdHh0LT5zY2hlbWEtPmlkY0RlZiAhPSBOVUxMKSB7Cgl4bWxIYXNoU2Nhbih2Y3R4dC0+c2NoZW1hLT5pZGNEZWYsCgkgICAgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdWdtZW50SURDLCB2Y3R4dCk7CiAgICB9CiAgICBpZiAodmN0eHQtPmRvYyAhPSBOVUxMKSB7CgkvKgoJKiBUcmVlIHZhbGlkYXRpb24uCgkqLwoJcmV0ID0geG1sU2NoZW1hVkRvY1dhbGsodmN0eHQpOwojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECiAgICB9IGVsc2UgaWYgKHZjdHh0LT5yZWFkZXIgIT0gTlVMTCkgewoJLyoKCSogWE1MIFJlYWRlciB2YWxpZGF0aW9uLgoJKi8KI2lmZGVmIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQKCXJldCA9IHhtbFNjaGVtYVZSZWFkZXJXYWxrKHZjdHh0KTsKI2VuZGlmCiNlbmRpZgogICAgfSBlbHNlIGlmICgodmN0eHQtPnNheCAhPSBOVUxMKSAmJiAodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkpIHsKCS8qCgkqIFNBWCB2YWxpZGF0aW9uLgoJKi8KCS8qIHJldCA9IHhtbFNBWFVzZXJQYXJzZUZpbGUoY3R4dC0+c2F4LCBjdHh0LCB1cmkpOyAqLwoJcmV0ID0geG1sUGFyc2VEb2N1bWVudCh2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9IGVsc2UgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlN0YXJ0VmFsaWRhdGlvbiIsCgkgICAgIm5vIGluc3RhbmNlIHRvIHZhbGlkYXRlIik7CglyZXQgPSAtMTsKICAgIH0KCiAgICBpZiAodmN0eHQtPnhzaUFzc2VtYmxlKSB7CglpZiAodmN0eHQtPnNjaGVtYSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZSh2Y3R4dC0+c2NoZW1hKTsKCSAgICB2Y3R4dC0+c2NoZW1hID0gTlVMTDsKCX0KICAgIH0KICAgIHhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0KHZjdHh0KTsKICAgIGlmIChyZXQgPT0gMCkKCXJldCA9IHZjdHh0LT5lcnI7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudCBub2RlCiAqCiAqIFZhbGlkYXRlIGEgYnJhbmNoIG9mIGEgdHJlZSwgc3RhcnRpbmcgd2l0aCB0aGUgZ2l2ZW4gQGVsZW0uCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBhbmQgaXRzIHN1YnRyZWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IKICogY29kZSBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpIHx8IChlbGVtLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CgogICAgY3R4dC0+ZG9jID0gZWxlbS0+ZG9jOwogICAgY3R4dC0+bm9kZSA9IGVsZW07CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGVsZW07CiAgICByZXR1cm4oeG1sU2NoZW1hVlN0YXJ0KGN0eHQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2MoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIGN0eHQtPm5vZGUgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKGN0eHQtPm5vZGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0RPQ1VNRU5UX0VMRU1FTlRfTUlTU0lORywKCSAgICAoeG1sTm9kZVB0cikgZG9jLCBOVUxMLAoJICAgICJUaGUgZG9jdW1lbnQgaGFzIG5vIGRvY3VtZW50IGVsZW1lbnQiLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGN0eHQtPm5vZGU7CiAgICByZXR1cm4gKHhtbFNjaGVtYVZTdGFydChjdHh0KSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGlucHV0OiAgdGhlIGlucHV0IHRvIHVzZSBmb3IgcmVhZGluZyB0aGUgZGF0YQogKiBAZW5jOiAgYW4gb3B0aW9uYWwgZW5jb2RpbmcgaW5mb3JtYXRpb24KICogQHNheDogIGEgU0FYIGhhbmRsZXIgZm9yIHRoZSByZXN1bHRpbmcgZXZlbnRzCiAqIEB1c2VyX2RhdGE6ICB0aGUgY29udGV4dCB0byBwcm92aWRlIHRvIHRoZSBTQVggaGFuZGxlci4KICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dCwgeG1sQ2hhckVuY29kaW5nIGVuYywKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU0FYSGFuZGxlclB0ciBzYXgsIHZvaWQgKnVzZXJfZGF0YSkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChpbnB1dCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIGN0eHQtPmlucHV0ID0gaW5wdXQ7CiAgICBjdHh0LT5lbmMgPSBlbmM7CiAgICBjdHh0LT5zYXggPSBzYXg7CiAgICBjdHh0LT51c2VyX2RhdGEgPSB1c2VyX2RhdGE7CiAgICBUT0RPIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZpbGU6CiAqIEBjdHh0OiBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGZpbGVuYW1lOiB0aGUgVVJJIG9mIHRoZSBpbnN0YW5jZQogKiBAb3B0aW9uczogYSBmdXR1cmUgc2V0IG9mIG9wdGlvbnMsIGN1cnJlbnRseSB1bnVzZWQKICoKICogRG8gYSBzY2hlbWFzIHZhbGlkYXRpb24gb2YgdGhlIGdpdmVuIHJlc291cmNlLCBpdCB3aWxsIHVzZSB0aGUKICogU0FYIHN0cmVhbWFibGUgdmFsaWRhdGlvbiBpbnRlcm5hbGx5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRmlsZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBmaWxlbmFtZSwKCQkgICAgICBpbnQgb3B0aW9ucyBBVFRSSUJVVEVfVU5VU0VEKQp7CiNpZmRlZiBYTUxfU0NIRU1BX1NBWF9FTkFCTEVECiAgICBpbnQgcmV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZmlsZW5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAKICAgIGN0eHQtPnNheCA9ICh4bWxTQVhIYW5kbGVyUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNBWEhhbmRsZXIpKTsKICAgIGlmIChjdHh0LT5zYXggPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LAoJICAgICJjcmVhdGluZyBTQVggaGFuZGxlciIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBtZW1zZXQoY3R4dC0+c2F4LCAwLCBzaXplb2YoeG1sU0FYSGFuZGxlcikpOwogICAgY3R4dC0+cGFyc2VyQ3R4dCA9IHhtbENyZWF0ZUZpbGVQYXJzZXJDdHh0KGZpbGVuYW1lKTsKICAgIGlmIChjdHh0LT5wYXJzZXJDdHh0ID09IE5VTEwpIHsKCXhtbFNjaGVtYUludGVybmFsRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIGN0eHQsCgkgICAgInhtbFNjaGVtYVZhbGlkYXRlRmlsZSIsICJjcmVhdGluZyBhIHBhcnNlciBjb250ZXh0Iik7Cgl4bWxGcmVlKGN0eHQtPnNheCk7CglyZXR1cm4gKC0xKTsKICAgIH0KI2lmZGVmIExJQlhNTF9TQVgxX0VOQUJMRUQKICAgIGlmIChjdHh0LT5wYXJzZXJDdHh0LT5zYXggIT0gKHhtbFNBWEhhbmRsZXJQdHIpICZ4bWxEZWZhdWx0U0FYSGFuZGxlcikKI2VuZGlmIC8qIExJQlhNTF9TQVgxX0VOQUJMRUQgKi8KCXhtbEZyZWUoY3R4dC0+cGFyc2VyQ3R4dC0+c2F4KTsKICAgIC8qCiAgICAqIEluaXQgdGhlIFNBWCBoYW5kbGVyLgogICAgKi8KICAgIGN0eHQtPnNheC0+c3RhcnRFbGVtZW50TnMgPSB4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROczsKICAgIGN0eHQtPnNheC0+ZW5kRWxlbWVudE5zID0geG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zOwogICAgLyoKICAgICogTm90ZSB0aGF0IHdlIHVzZSB0aGUgc2FtZSB0ZXh0LWZ1bmN0aW9uIGZvciBib3RoLCB0byBwcmV2ZW50CiAgICAqIHRoZSBwYXJzZXIgZnJvbSB0ZXN0aW5nIGZvciBpZ25vcmFibGUgd2hpdGVzcGFjZS4KICAgICovCiAgICBjdHh0LT5zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgPSB4bWxTY2hlbWFTQVhIYW5kbGVUZXh0OwogICAgY3R4dC0+c2F4LT5jaGFyYWN0ZXJzID0geG1sU2NoZW1hU0FYSGFuZGxlVGV4dDsKCiAgICBjdHh0LT5zYXgtPmNkYXRhQmxvY2sgPSB4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb247CiAgICBjdHh0LT5zYXgtPnJlZmVyZW5jZSA9IHhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZTsKICAgIGN0eHQtPnNheC0+aW5pdGlhbGl6ZWQgPSBYTUxfU0FYMl9NQUdJQzsKICAgIC8qCiAgICAqIEluaXQgdGhlIHBhcnNlciBjb250ZXh0LgogICAgKi8KICAgIGN0eHQtPnBhcnNlckN0eHQtPnNheCA9IGN0eHQtPnNheDsKICAgIGN0eHQtPnBhcnNlckN0eHQtPnNheDIgPSAxOwogICAgY3R4dC0+cGFyc2VyQ3R4dC0+dXNlckRhdGEgPSBjdHh0OwogICAgLyogVkFMIFRPRE86IFNldCBlcnJvciBoYW5kbGVycy4gKi8KCiAgICBjdHh0LT5mbGFncyB8PSBYTUxfU0NIRU1BX1ZBTElEX0NUWFRfRkxBR19TVFJFQU07CiAgICByZXQgPSB4bWxTY2hlbWFWU3RhcnQoY3R4dCk7CgogICAgLyoKICAgICogVVJHRU5UIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggd2VsbC1mb3JtZWRuZXNzIGVycm9ycz8KICAgICovCiAgICBpZiAoKHJldCA9PSAwKSAmJiAoISBjdHh0LT5wYXJzZXJDdHh0LT53ZWxsRm9ybWVkKSkgewoJcmV0ID0gY3R4dC0+cGFyc2VyQ3R4dC0+ZXJyTm87CglpZiAocmV0ID09IDApCgkgICAgLyogVVJHRU5UIFZBTCBUT0RPOiBFcnJvciBjb2RlPyAqLwoJICAgIHJldCA9IDE7Cgl4bWxTY2hlbWFFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgY3R4dCwgcmV0LCBOVUxMLAoJICAgICJUaGUgaW5zdGFuY2UgZG9jdW1lbnQgJyVzJyBpcyBub3Qgd2VsbC1mb3JtZWQiLAoJICAgIEJBRF9DQVNUIGZpbGVuYW1lLCBOVUxMKTsJCiAgICB9ICAgIAogICAgY3R4dC0+cGFyc2VyQ3R4dC0+c2F4ID0gTlVMTDsKICAgIHhtbEZyZWVQYXJzZXJDdHh0KGN0eHQtPnBhcnNlckN0eHQpOwogICAgeG1sRnJlZShjdHh0LT5zYXgpOwogICAgY3R4dC0+c2F4ID0gTlVMTDsKCiAgICByZXR1cm4gKHJldCk7CiNlbHNlCiAgICByZXR1cm4gKC0xKTsKI2VuZGlmIC8qIFhNTF9TQ0hFTUFfU0FYX0VOQUJMRUQgKi8KfQoKI2lmZGVmIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlUmVhZGVyOgogKiBAY3R4dDogYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEByZWFkZXI6IGFuIFhNTCByZWFkZXIuCiAqCiAqIERvIGEgc2NoZW1hcyB2YWxpZGF0aW9uIG9mIHRoZSBnaXZlbiByZXNvdXJjZSwgdXNpbmcgdGhlIHJlYWRlci4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZVJlYWRlcih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJeG1sVGV4dFJlYWRlclB0ciByZWFkZXIpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAocmVhZGVyID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgY3R4dC0+cmVhZGVyID0gcmVhZGVyOwogICAgY3R4dC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9WQUxJRF9DVFhUX0ZMQUdfU1RSRUFNOwogICAgcmV0dXJuKHhtbFNjaGVtYVZTdGFydChjdHh0LCBOVUxMKSk7Cn0KI2VuZGlmIC8qIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQgKi8KCiNkZWZpbmUgYm90dG9tX3htbHNjaGVtYXMKI2luY2x1ZGUgImVsZmdjY2hhY2suaCIKI2VuZGlmIC8qIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQgKi8K