LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlCiAqICAgICBuZWVkIHRvIHZhbGlkYXRlIGFsbCBzY2hlbWEgYXR0cmlidXRlcyAocmVmLCB0eXBlLCBuYW1lKQogKiAgICAgYWdhaW5zdCB0aGVpciB0eXBlcy4KICogICAtIEVsaW1pbmF0ZSBpdGVtIGNyZWF0aW9uIGZvcjogPz8KICoKICogTk9URVM6CiAqICAgLSBFbGltYXRlZCBpdGVtIGNyZWF0aW9uIGZvcjogPHJlc3RyaWN0aW9uPiwgPGV4dGVuc2lvbj4sCiAqICAgICA8c2ltcGxlQ29udGVudD4sIDxjb21wbGV4Q29udGVudD4sIDxsaXN0PiwgPHVuaW9uPgogKgogKi8KI2RlZmluZSBJTl9MSUJYTUwKI2luY2x1ZGUgImxpYnhtbC5oIgoKI2lmZGVmIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQKCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CiNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hcy5oPgojaW5jbHVkZSA8bGlieG1sL3NjaGVtYXNJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxzY2hlbWFzdHlwZXMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxhdXRvbWF0YS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHJlZ2V4cC5oPgojaW5jbHVkZSA8bGlieG1sL2RpY3QuaD4KI2luY2x1ZGUgPGxpYnhtbC9lbmNvZGluZy5oPgojaW5jbHVkZSA8bGlieG1sL3htbElPLmg+CiNpZmRlZiBMSUJYTUxfUEFUVEVSTl9FTkFCTEVECiNpbmNsdWRlIDxsaWJ4bWwvcGF0dGVybi5oPgojZW5kaWYKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAojaW5jbHVkZSA8bGlieG1sL3htbHJlYWRlci5oPgojZW5kaWYKCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMAoKLyogI2RlZmluZSBERUJVR19JREMgMSAqLwoKLyogI2RlZmluZSBERUJVR19JTkNMVURFUyAxICovCgovKiAjZGVmaW5lIEVOQUJMRV9QQVJUSUNMRV9SRVNUUklDVElPTiAxICovCgovKiAjZGVmaW5lIEVOQUJMRV9SRURFRklORSAqLwoKI2RlZmluZSBEVU1QX0NPTlRFTlRfTU9ERUwKCiNpZmRlZiBMSUJYTUxfUkVBREVSX0VOQUJMRUQKLyogI2RlZmluZSBYTUxfU0NIRU1BX1JFQURFUl9FTkFCTEVEICovCiNlbmRpZgoKI2RlZmluZSBVTkJPVU5ERUQgKDEgPDwgMzApCiNkZWZpbmUgVE9ETyAJCQkJCQkJCVwKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAkJCQlcCgkgICAgIlVuaW1wbGVtZW50ZWQgYmxvY2sgYXQgJXM6JWRcbiIsCQkJCVwKICAgICAgICAgICAgX19GSUxFX18sIF9fTElORV9fKTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFIChjb25zdCB4bWxDaGFyICopICIjIyIKCi8qCiAqIFRoZSBYTUwgU2NoZW1hcyBuYW1lc3BhY2VzCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFJbnN0YW5jZU5zID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSI7CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sTmFtZXNwYWNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDAveG1sbnMvIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImVsZW1lbnQgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJhdHRyaWJ1dGUgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImF0dHJpYnV0ZSB1c2UiOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbU1vZGVsR3JEZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIm1vZGVsIGdyb3VwIjsKI2lmIDAKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUVsZW1Nb2RlbEdyUmVmID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJtb2RlbCBncm91cCByZWYuIjsKI2VuZGlmCgojZGVmaW5lIElTX1NDSEVNQShub2RlLCB0eXBlKQkJCQkJCVwKICAgKChub2RlICE9IE5VTEwpICYmIChub2RlLT5ucyAhPSBOVUxMKSAmJgkJCQlcCiAgICAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgdHlwZSkpICYmCQlcCiAgICAoeG1sU3RyRXF1YWwobm9kZS0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpCgojZGVmaW5lIEZSRUVfQU5EX05VTEwoc3RyKQkJCQkJCVwKICAgIGlmIChzdHIgIT0gTlVMTCkgewkJCQkJCQlcCgl4bWxGcmVlKCh4bWxDaGFyICopIHN0cik7CQkJCQkJCVwKCXN0ciA9IE5VTEw7CQkJCQkJCVwKICAgIH0KCiNkZWZpbmUgSVNfQU5ZVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCgojZGVmaW5lIElTX0NPTVBMRVhfVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8ICAgIFwKICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCgojZGVmaW5lIElTX1NJTVBMRV9UWVBFKGl0ZW0pICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwgICAgIFwKICAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpKQoKI2RlZmluZSBJU19BTllfU0lNUExFX1RZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgICBcCiAgICAgIChpdGVtLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkKCiNkZWZpbmUgSVNfTk9UX1RZUEVGSVhFRChpdGVtKSAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgICBcCiAgICAgKChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfUkVTT0xWRUQpID09IDApKQoKI2RlZmluZSBIQVNfQ09NUExFWF9DT05URU5UKGl0ZW0pCQkJIFwKICAgICgoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB8fCAgXAogICAgIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHx8ICBcCiAgICAgKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykpCgojZGVmaW5lIEhBU19TSU1QTEVfQ09OVEVOVChpdGVtKQkJCSBcCiAgICAoKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8ICBcCiAgICAgKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpCgojZGVmaW5lIEhBU19NSVhFRF9DT05URU5UKGl0ZW0pCShpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpCgojZGVmaW5lIElTX1BBUlRJQ0xFX0VNUFRJQUJMRShpdGVtKSBcCiAgICAoeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0tPnN1YnR5cGVzKSkKCiNkZWZpbmUgR0VUX05PREUoaXRlbSkgeG1sU2NoZW1hR2V0Q29tcG9uZW50Tm9kZSgoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBpdGVtKQoKI2RlZmluZSBHRVRfTElTVF9JVEVNX1RZUEUoaXRlbSkgaXRlbS0+c3VidHlwZXMKCiNkZWZpbmUgVkFSSUVUWV9BVE9NSUMoaXRlbSkgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykKI2RlZmluZSBWQVJJRVRZX0xJU1QoaXRlbSkgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpCiNkZWZpbmUgVkFSSUVUWV9VTklPTihpdGVtKSAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pCgojZGVmaW5lIElTX01PREVMX0dST1VQKGl0ZW0pICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkgfHwgXAogICAgIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHx8ICAgXAogICAgIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpKQoKI2RlZmluZSBJTk9ERV9OSUxMRUQoaXRlbSkgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fTklMTEVEKQoKI2RlZmluZSBFTEVNX1RZUEUoaXRlbSkgaXRlbS0+c3VidHlwZXMKCiNkZWZpbmUgR0VUX1BBUlRJQ0xFKGl0ZW0pICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgaXRlbS0+c3VidHlwZXM7CgojZGVmaW5lIFNVQlNUX0dST1VQX0FGRihpdGVtKSBpdGVtLT5yZWZEZWNsCgojaWYgMAojZGVmaW5lIFdYU19HRVRfTkVYVChpdGVtKSB4bWxTY2hlbWFHZXROZXh0Q29tcG9uZW50KCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGl0ZW0pCiNlbmRpZgoKI2RlZmluZSBTVUJTRVRfUkVTVFJJQ1RJT04gIDE8PDAKI2RlZmluZSBTVUJTRVRfRVhURU5TSU9OICAgIDE8PDEKI2RlZmluZSBTVUJTRVRfU1VCU1RJVFVUSU9OIDE8PDIKI2RlZmluZSBTVUJTRVRfTElTVCAgICAgICAgIDE8PDMKI2RlZmluZSBTVUJTRVRfVU5JT04gICAgICAgIDE8PDQKCiNkZWZpbmUgWE1MX1NDSEVNQVNfUEFSU0VfRVJST1IJCTEKCiNkZWZpbmUgU0NIRU1BU19QQVJTRV9PUFRJT05TIFhNTF9QQVJTRV9OT0VOVAoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHhtbFNjaGVtYU5vZGVJbmZvOwp0eXBlZGVmIHhtbFNjaGVtYU5vZGVJbmZvICp4bWxTY2hlbWFOb2RlSW5mb1B0cjsKCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSXRlbUxpc3QgeG1sU2NoZW1hQXNzZW1ibGU7CnR5cGVkZWYgeG1sU2NoZW1hQXNzZW1ibGUgKnhtbFNjaGVtYUFzc2VtYmxlUHRyOwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1MaXN0IHhtbFNjaGVtYUl0ZW1MaXN0Owp0eXBlZGVmIHhtbFNjaGVtYUl0ZW1MaXN0ICp4bWxTY2hlbWFJdGVtTGlzdFB0cjsKc3RydWN0IF94bWxTY2hlbWFJdGVtTGlzdCB7CiAgICB2b2lkICoqaXRlbXM7ICAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgbmJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IHNpemVJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwp9OwoKLyoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1MaXN0Q2hhaW4geG1sU2NoZW1hSXRlbUxpc3RDaGFpbjsKdHlwZWRlZiB4bWxTY2hlbWFJdGVtTGlzdENoYWluIHhtbFNjaGVtYUl0ZW1MaXN0Q2hhaW5QdHI7CnN0cnVjdCBfeG1sU2NoZW1hSXRlbUxpc3RDaGFpbiB7CiAgICB4bWxTY2hlbWFJdGVtTGlzdENoYWluUHRyIG5leHQ7CiAgICB4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0Owp9CiovCgovKgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSXRlbUxpc3RDaGFpbiB4bWxTY2hlbWFJdGVtTGlzdENoYWluOwp0eXBlZGVmIHhtbFNjaGVtYUl0ZW1MaXN0Q2hhaW4geG1sU2NoZW1hSXRlbUxpc3RDaGFpblB0cjsKc3RydWN0IF94bWxTY2hlbWFJdGVtTGlzdENoYWluIHsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0Q2hhaW5QdHIgbmV4dDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3Q7Cn0KKi8KCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBYnN0cmFjdEN0eHQgeG1sU2NoZW1hQWJzdHJhY3RDdHh0Owp0eXBlZGVmIHhtbFNjaGVtYUFic3RyYWN0Q3R4dCAqeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUFic3RyYWN0Q3R4dCB7CiAgICBpbnQgdHlwZTsKfTsKCi8qKgogKiB4bWxTY2hlbWFDb250YWluZXI6IAogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUNvbnRhaW5lciB4bWxTY2hlbWFDb250YWluZXI7CnR5cGVkZWYgeG1sU2NoZW1hQ29udGFpbmVyICp4bWxTY2hlbWFDb250YWluZXJQdHI7CnN0cnVjdCBfeG1sU2NoZW1hQ29udGFpbmVyIHsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHR5cGVEZWZzOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgYXR0ckRlY2xzOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgZWxlbURlY2xzOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgYXR0ckdyb3VwRGVmczsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIG1vZGVsR3JvdXBEZWZzOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbm90YXRpb25EZWNsczsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGFubm90YXRpb25zOwogICAgeG1sU2NoZW1hSXRlbUxpc3RQdHIgbG9jYWxzOwp9OwoKI2RlZmluZSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSIDEKI2RlZmluZSBYTUxfU0NIRU1BX0NUWFRfVkFMSURBVE9SIDIKCnN0cnVjdCBfeG1sU2NoZW1hUGFyc2VyQ3R4dCB7CiAgICBpbnQgdHlwZTsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTY2hlbWFWYWxpZEVycm9yIGVycjsKICAgIGludCBuYmVycm9yczsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIC8qIHhtbFNjaGVtYVB0ciB0b3BzY2hlbWE7CSBUaGUgbWFpbiBzY2hlbWEgKi8KICAgIC8qIHhtbEhhc2hUYWJsZVB0ciBuYW1lc3BhY2VzOwkgSGFzaCB0YWJsZSBvZiBuYW1lc3BhY2VzIHRvIHNjaGVtYXMgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIGNvbnN0IHhtbENoYXIgKmNvbnRhaW5lcjsgICAvKiB0aGUgY3VycmVudCBlbGVtZW50LCBncm91cCwgLi4uICovCiAgICBpbnQgY291bnRlcjsKCiAgICBjb25zdCB4bWxDaGFyICpVUkw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHByZXNlcnZlOwkJLyogV2hldGhlciB0aGUgZG9jIHNob3VsZCBiZSBmcmVlZCAgKi8KCiAgICBjb25zdCBjaGFyICpidWZmZXI7CiAgICBpbnQgc2l6ZTsKCiAgICAvKgogICAgICogVXNlZCB0byBidWlsZCBjb21wbGV4IGVsZW1lbnQgY29udGVudCBtb2RlbHMKICAgICAqLwogICAgeG1sQXV0b21hdGFQdHIgYW07CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBlbmQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXRlOwoKICAgIHhtbERpY3RQdHIgZGljdDsJCS8qIGRpY3Rpb25uYXJ5IGZvciBpbnRlcm5lZCBzdHJpbmcgbmFtZXMgKi8KICAgIGludCAgICAgICAgaW5jbHVkZXM7CS8qIHRoZSBpbmNsdXNpb24gbGV2ZWwsIDAgZm9yIHJvb3Qgb3IgaW1wb3J0cyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHBhcmVudEl0ZW07IC8qIFRoZSBjdXJyZW50IHBhcmVudCBzY2hlbWEgaXRlbSAqLwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzZW1ibGU7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKICAgIGNvbnN0IHhtbENoYXIgKipsb2NhbEltcG9ydHM7IC8qIGxpc3Qgb2YgbG9jYWxseSBpbXBvcnRlZCBuYW1lc3BhY2VzICovCiAgICBpbnQgc2l6ZUxvY2FsSW1wb3J0czsKICAgIGludCBuYkxvY2FsSW1wb3J0czsKICAgIHhtbEhhc2hUYWJsZVB0ciBzdWJzdEdyb3VwczsKICAgIGludCBpc1M0UzsKICAgIGludCBpc1JlZGVmaW5lOwogICAgeG1sU2NoZW1hQ29udGFpbmVyUHRyIGNvbXBDb250YWluZXI7Cn07CgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRCAyCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9QUk9ISUJJVEVEIDMKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HIDQKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUUgNQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX05PX1RZUEUgNgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX0ZJWEVEX1ZBTFVFIDcKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQgOAojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVkFMSURBVEVfVkFMVUUgOQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX1dJTERfU1RSSUNUX05PX0RFQ0wgMTAKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0hBU19BVFRSX1VTRSAxMQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSEFTX0FUVFJfREVDTCAxMgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9TS0lQIDEzCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX0xBWF9OT19ERUNMIDE0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9EVVBMSUNBVEVfSUQgMTUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0FORF9VU0VfSUQgMTYKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX01FVEEgMTcKCi8qKgogKiB4bWxTY2hlbWFCYXNpY0l0ZW06CiAqCiAqIFRoZSBhYnN0cmFjdCBiYXNlIHR5cGUgZm9yIHNjaGVtYSBjb21wb25lbnRzLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUJhc2ljSXRlbSB4bWxTY2hlbWFCYXNpY0l0ZW07CnR5cGVkZWYgeG1sU2NoZW1hQmFzaWNJdGVtICp4bWxTY2hlbWFCYXNpY0l0ZW1QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQmFzaWNJdGVtIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7Cn07CgojZGVmaW5lIFhNTF9TQ0hFTUFfU0NIRU1BX1JFRl9JTVBPUlQgMQojZGVmaW5lIFhNTF9TQ0hFTUFfU0NIRU1BX1JFRl9JTkNMVURFIDIKI2RlZmluZSBYTUxfU0NIRU1BX1NDSEVNQV9SRUZfUkVERUZJTkUgMwoKI2RlZmluZSBYTUxfU0NIRU1BX1NDSEVNQV9SRUZfUkVMX0NISUxEIDEKI2RlZmluZSBYTUxfU0NIRU1BX1NDSEVNQV9SRUZfUkVMX1BBUkVOVCAyCi8qKgogKiB4bWxTY2hlbWFTY2hlbWFSZWY6IAogKgogKiBVc2VkIHRvIGNyZWF0ZSBhIGdyYXBoIG9mIHNjaGVtYSByZWxhdGlvbnNoaXBzLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVNjaGVtYVJlZiB4bWxTY2hlbWFTY2hlbWFSZWY7CnR5cGVkZWYgeG1sU2NoZW1hU2NoZW1hUmVmICp4bWxTY2hlbWFTY2hlbWFSZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hU2NoZW1hUmVmIHsKICAgIHhtbFNjaGVtYVNjaGVtYVJlZlB0ciBuZXh0OwogICAgaW50IHR5cGU7IC8qIEUuZy4gWE1MX1NDSEVNQV9TQ0hFTUFfUkVGX0lNUE9SVCAqLwogICAgaW50IHJlbGF0aW9uOyAgICAKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7Cn07CgovKioKICogeG1sU2NoZW1hQW5ub3RJdGVtOgogKgogKiBUaGUgYWJzdHJhY3QgYmFzZSB0eXBlIGZvciBhbm5vdGF0ZWQgc2NoZW1hIGNvbXBvbmVudHMuCiAqIChFeHRlbmRzIHhtbFNjaGVtYUJhc2ljSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBbm5vdEl0ZW0geG1sU2NoZW1hQW5ub3RJdGVtOwp0eXBlZGVmIHhtbFNjaGVtYUFubm90SXRlbSAqeG1sU2NoZW1hQW5ub3RJdGVtUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUFubm90SXRlbSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7Cn07CgovKioKICogeG1sU2NoZW1hVHJlZUl0ZW06CiAqCiAqIFRoZSBhYnN0cmFjdCBiYXNlIHR5cGUgZm9yIHRyZWUtbGlrZSBzdHJ1Y3R1cmVkIHNjaGVtYSBjb21wb25lbnRzLgogKiAoRXh0ZW5kcyB4bWxTY2hlbWFBbm5vdEl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hVHJlZUl0ZW0geG1sU2NoZW1hVHJlZUl0ZW07CnR5cGVkZWYgeG1sU2NoZW1hVHJlZUl0ZW0gKnhtbFNjaGVtYVRyZWVJdGVtUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVRyZWVJdGVtIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIG5leHQ7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaGlsZHJlbjsKfTsKCi8qKgogKiB4bWxTY2hlbWFRTmFtZVJlZjoKICoKICogQSBjb21wb25lbnQgcmVmZXJlbmNlIGl0ZW0gKG5vdCBhIHNjaGVtYSBjb21wb25lbnQpCiAqIChFeHRlbmRzIHhtbFNjaGVtYUJhc2ljSXRlbSkKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFRTmFtZVJlZiB4bWxTY2hlbWFRTmFtZVJlZjsKdHlwZWRlZiB4bWxTY2hlbWFRTmFtZVJlZiAqeG1sU2NoZW1hUU5hbWVSZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUU5hbWVSZWYgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOwogICAgeG1sU2NoZW1hVHlwZVR5cGUgaXRlbVR5cGU7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBhcnRpY2xlOgogKgogKiBBIHBhcnRpY2xlIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUGFydGljbGUgeG1sU2NoZW1hUGFydGljbGU7CnR5cGVkZWYgeG1sU2NoZW1hUGFydGljbGUgKnhtbFNjaGVtYVBhcnRpY2xlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBhcnRpY2xlIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIG5leHQ7IC8qIG5leHQgcGFydGljbGUgKE9SICJlbGVtZW50IGRlY2wiIE9SICJ3aWxkY2FyZCIpICovCiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaGlsZHJlbjsgLyogdGhlICJ0ZXJtIiAoIm1vZGVsIGdyb3VwIiBPUiAiZ3JvdXAgZGVmaW5pdGlvbiIpICovCiAgICBpbnQgbWluT2NjdXJzOwogICAgaW50IG1heE9jY3VyczsKICAgIHhtbE5vZGVQdHIgbm9kZTsKfTsKCi8qKgogKiB4bWxTY2hlbWFNb2RlbEdyb3VwOgogKgogKiBBIG1vZGVsIGdyb3VwIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hVHJlZUl0ZW0pCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB4bWxTY2hlbWFNb2RlbEdyb3VwOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXAgKnhtbFNjaGVtYU1vZGVsR3JvdXBQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOyAvKiBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIFhNTF9TQ0hFTUFfVFlQRV9BTEwgKi8KICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90OwogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgbmV4dDsgLyogbm90IHVzZWQgKi8KICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIGNoaWxkcmVuOyAvKiBmaXJzdCBwYXJ0aWNsZSAoT1IgImVsZW1lbnQgZGVjbCIgT1IgIndpbGRjYXJkIikgKi8KICAgIHhtbE5vZGVQdHIgbm9kZTsKfTsKCiNkZWZpbmUgWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEIDE8PDAKLyoqCiAqIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWY6CiAqCiAqIEEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiBjb21wb25lbnQuCiAqIChFeHRlbmRzIHhtbFNjaGVtYVRyZWVJdGVtKQogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXBEZWYgeG1sU2NoZW1hTW9kZWxHcm91cERlZjsKdHlwZWRlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmICp4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXBEZWYgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsgLyogWE1MX1NDSEVNQV9UWVBFX0dST1VQICovCiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIG5leHQ7IC8qIG5vdCB1c2VkICovCiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaGlsZHJlbjsgLyogdGhlICJtb2RlbCBncm91cCIgKi8KICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBpbnQgZmxhZ3M7Cn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDIHhtbFNjaGVtYUlEQzsKdHlwZWRlZiB4bWxTY2hlbWFJREMgKnhtbFNjaGVtYUlEQ1B0cjsKCi8qKgogKiB4bWxTY2hlbWFJRENTZWxlY3Q6CiAqCiAqIFRoZSBpZGVudGl0eS1jb25zdHJhaW50ICJmaWVsZCIgYW5kICJzZWxlY3RvciIgaXRlbSwgaG9sZGluZyB0aGUKICogWFBhdGggZXhwcmVzc2lvbi4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENTZWxlY3QgeG1sU2NoZW1hSURDU2VsZWN0Owp0eXBlZGVmIHhtbFNjaGVtYUlEQ1NlbGVjdCAqeG1sU2NoZW1hSURDU2VsZWN0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ1NlbGVjdCB7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgbmV4dDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGM7CiAgICBpbnQgaW5kZXg7IC8qIGFuIGluZGV4IHBvc2l0aW9uIGlmIHNpZ25pZmljYW50IGZvciBJREMga2V5LXNlcXVlbmNlcyAqLwogICAgY29uc3QgeG1sQ2hhciAqeHBhdGg7IC8qIHRoZSBYUGF0aCBleHByZXNzaW9uICovCiAgICB2b2lkICp4cGF0aENvbXA7IC8qIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCn07CgovKioKICogeG1sU2NoZW1hSURDOgogKgogKiBUaGUgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIGNvbXBvbmVudC4KICogKEV4dGVuZHMgeG1sU2NoZW1hQW5ub3RJdGVtKQogKi8KCnN0cnVjdCBfeG1sU2NoZW1hSURDIHsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGU7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBuZXh0OwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWxlY3RvcjsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBmaWVsZHM7CiAgICBpbnQgbmJGaWVsZHM7CiAgICB4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWY7Cn07CgovKioKICogeG1sU2NoZW1hSURDQXVnOgogKgogKiBUaGUgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbiB1c2VkIGZvciB2YWxpZGF0aW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ0F1ZyB4bWxTY2hlbWFJRENBdWc7CnR5cGVkZWYgeG1sU2NoZW1hSURDQXVnICp4bWxTY2hlbWFJRENBdWdQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDQXVnIHsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBuZXh0OyAvKiBuZXh0IGluIGEgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDUHRyIGRlZjsgLyogdGhlIElEQyBkZWZpbml0aW9uICovCiAgICBpbnQgYnViYmxlRGVwdGg7IC8qIHRoZSBsb3dlc3QgdHJlZSBsZXZlbCB0byB3aGljaCBJREMKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVzIG5lZWQgdG8gYmUgYnViYmxlZCB1cHdhcmRzICovCn07CgovKioKICogeG1sU2NoZW1hUFNWSUlEQ0tleVNlcXVlbmNlOgogKgogKiBUaGUga2V5IHNlcXVlbmNlIG9mIGEgbm9kZSB0YWJsZSBpdGVtLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENLZXkgeG1sU2NoZW1hUFNWSUlEQ0tleTsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDS2V5ICp4bWxTY2hlbWFQU1ZJSURDS2V5UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENLZXkgewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbDsKfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDTm9kZToKICoKICogVGhlIG5vZGUgdGFibGUgaXRlbSBvZiBhIG5vZGUgdGFibGUuCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ05vZGUgeG1sU2NoZW1hUFNWSUlEQ05vZGU7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ05vZGUgKnhtbFNjaGVtYVBTVklJRENOb2RlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENOb2RlIHsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmtleXM7CiAgICBpbnQgbm9kZUxpbmU7CiAgICBpbnQgbm9kZVFOYW1lSUQ7ICAgIAoKfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZzoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgYmluZGluZyBpdGVtIG9mIHRoZSBbaWRlbnRpdHktY29uc3RyYWludCB0YWJsZV0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmc7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgKnhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENCaW5kaW5nIHsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIG5leHQ7IC8qIG5leHQgYmluZGluZyBvZiBhIHNwZWNpZmljIG5vZGUgKi8KICAgIHhtbFNjaGVtYUlEQ1B0ciBkZWZpbml0aW9uOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICpub2RlVGFibGU7IC8qIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMgKi8KICAgIGludCBuYk5vZGVzOyAvKiBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IHNpemVOb2RlczsgLyogc2l6ZSBvZiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IG5iRHVwbHM7IC8qIG51bWJlciBvZiBhbHJlYWR5IGlkZW50aWZpZWQgZHVwbGljYXRlcyBpbiB0aGUgbm9kZQogICAgICAgICAgICAgICAgICAgIHRhYmxlICovCiAgICAvKiBpbnQgbmJLZXlzOyBudW1iZXIgb2Yga2V5cyBpbiBlYWNoIGtleS1zZXF1ZW5jZSAqLwp9OwoKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IgMQojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCAyCgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9NQVRDSEVTIC0yCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX0JMT0NLRUQgLTMKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENNYXRjaGVyIHhtbFNjaGVtYUlEQ01hdGNoZXI7CnR5cGVkZWYgeG1sU2NoZW1hSURDTWF0Y2hlciAqeG1sU2NoZW1hSURDTWF0Y2hlclB0cjsKCi8qKgogKiB4bWxTY2hlbWFJRENTdGF0ZU9iajoKICoKICogVGhlIHN0YXRlIG9iamVjdCB1c2VkIHRvIGV2YWx1YXRlIFhQYXRoIGV4cHJlc3Npb25zLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1N0YXRlT2JqIHhtbFNjaGVtYUlEQ1N0YXRlT2JqOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ1N0YXRlT2JqICp4bWxTY2hlbWFJRENTdGF0ZU9ialB0cjsKc3RydWN0IF94bWxTY2hlbWFJRENTdGF0ZU9iaiB7CiAgICBpbnQgdHlwZTsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIG5leHQ7IC8qIG5leHQgaWYgaW4gYSBsaXN0ICovCiAgICBpbnQgZGVwdGg7IC8qIGRlcHRoIG9mIGNyZWF0aW9uICovCiAgICBpbnQgKmhpc3Rvcnk7IC8qIGxpc3Qgb2YgKGRlcHRoLCBzdGF0ZS1pZCkgdHVwbGVzICovCiAgICBpbnQgbmJIaXN0b3J5OwogICAgaW50IHNpemVIaXN0b3J5OwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyOyAvKiB0aGUgY29ycmVzcG9uZGVudCBmaWVsZC9zZWxlY3RvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRjaGVyICovCiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsOwogICAgdm9pZCAqeHBhdGhDdHh0Owp9OwoKI2RlZmluZSBJRENfTUFUQ0hFUiAwCgovKioKICogeG1sU2NoZW1hSURDTWF0Y2hlcjoKICoKICogVXNlZCB0byAgSURDIHNlbGVjdG9ycyAoYW5kIGZpZWxkcykgc3VjY2Vzc2l2ZWx5LgogKi8Kc3RydWN0IF94bWxTY2hlbWFJRENNYXRjaGVyIHsKICAgIGludCB0eXBlOwogICAgaW50IGRlcHRoOyAvKiB0aGUgdHJlZSBkZXB0aCBhdCBjcmVhdGlvbiB0aW1lICovCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7IC8qIG5leHQgaW4gdGhlIGxpc3QgKi8KICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOyAvKiB0aGUgYXVnbWVudGVkIElEQyBpdGVtICovCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxczsgLyogdGhlIGtleS1zZXF1ZW5jZXMgb2YgdGhlIHRhcmdldAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzICovCiAgICBpbnQgc2l6ZUtleVNlcXM7CiAgICBpbnQgdGFyZ2V0RGVwdGg7Cn07CgovKgoqIEVsZW1lbnQgaW5mbyBmbGFncy4KKi8KI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTICAxPDwwCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMgMTw8MQojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX05JTExFRAkgICAgICAgMTw8MgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0xPQ0FMX1RZUEUJICAgICAgIDE8PDMKCiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fVkFMVUVfTkVFREVEICAgICAgMTw8NAojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZICAgICAgICAgICAgIDE8PDUKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfQ09OVEVOVCAgICAgICAxPDw2CgojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0hBU19FTEVNX0NPTlRFTlQgIDE8PDcKI2RlZmluZSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FUlJfQkFEX0NPTlRFTlQgIDE8PDgKI2RlZmluZSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfTk9UX0VYUEVDVEVEICAxPDw5CiNkZWZpbmUgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFICAxPDwxMAoKLyoqCiAqIHhtbFNjaGVtYU5vZGVJbmZvOgogKgogKiBIb2xkcyBpbmZvcm1hdGlvbiBvZiBhbiBlbGVtZW50IG5vZGUuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYU5vZGVJbmZvIHsKICAgIGludCBub2RlVHlwZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCBub2RlTGluZTsgICAgCiAgICBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWU7CiAgICBjb25zdCB4bWxDaGFyICpuc05hbWU7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWw7IC8qIHRoZSBwcmUtY29tcHV0ZWQgdmFsdWUgaWYgYW55ICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWY7IC8qIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24gaWYgYW55ICovCgogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBub2RlIGluZm8gZmxhZ3MgKi8KCiAgICBpbnQgdmFsTmVlZGVkOwogICAgaW50IG5vcm1WYWw7CgogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOyAvKiB0aGUgZWxlbWVudC9hdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGlkY1RhYmxlOyAvKiB0aGUgdGFibGUgb2YgUFNWSSBJREMgYmluZGluZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgdGhlIHNjb3BlIGVsZW1lbnQqLwogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBpZGNNYXRjaGVyczsgLyogdGhlIElEQyBtYXRjaGVycyBmb3IgdGhlIHNjb3BlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50ICovCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleEN0eHQ7CgogICAgY29uc3QgeG1sQ2hhciAqKm5zQmluZGluZ3M7IC8qIE5hbWVzcGFjZSBiaW5kaW5ncyBvbiB0aGlzIGVsZW1lbnQgKi8KICAgIGludCBuYk5zQmluZGluZ3M7CiAgICBpbnQgc2l6ZU5zQmluZGluZ3M7Cn07CgovKgoqIEBtZXRhVHlwZSB2YWx1ZXMgb2YgeG1sU2NoZW1hQXR0ckluZm8uCiovCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSAxCiNkZWZpbmUgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTklMIDIKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DIDMKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9OT19OU19TQ0hFTUFfTE9DIDQKI2RlZmluZSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TIDUKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRySW5mbyB4bWxTY2hlbWFBdHRySW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFBdHRySW5mbyAqeG1sU2NoZW1hQXR0ckluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXR0ckluZm8gewogICAgaW50IG5vZGVUeXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IG5vZGVMaW5lOyAgICAKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbDsgLyogdGhlIHByZS1jb21wdXRlZCB2YWx1ZSBpZiBhbnkgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZjsgLyogdGhlIGNvbXBsZXgvc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBpZiBhbnkgKi8KICAgIGludCBmbGFnczsgLyogY29tYmluYXRpb24gb2Ygbm9kZSBpbmZvIGZsYWdzICovCgogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7IC8qIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciB1c2U7ICAvKiB0aGUgYXR0cmlidXRlIHVzZSAqLwogICAgaW50IHN0YXRlOwogICAgaW50IG1ldGFUeXBlOwogICAgY29uc3QgeG1sQ2hhciAqdmNWYWx1ZTsgLyogdGhlIHZhbHVlIGNvbnN0cmFpbnQgdmFsdWUgKi8KICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIHBhcmVudDsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFfVkFMSURfQ1RYVF9GTEFHX1NUUkVBTSAxCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHQ6CiAqCiAqIEEgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQKICovCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIGludCB0eXBlOwogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7IC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7ICAgICAgICAvKiBUaGUgc2NoZW1hIGluIHVzZSAqLwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0OwogICAgeG1sQ2hhckVuY29kaW5nIGVuYzsKICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4OwogICAgeG1sUGFyc2VyQ3R4dFB0ciBwYXJzZXJDdHh0OwogICAgdm9pZCAqdXNlcl9kYXRhOwoKICAgIGludCBlcnI7CiAgICBpbnQgbmJlcnJvcnM7CgogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sTm9kZVB0ciBjdXI7CiAgICAvKiB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7ICovCgogICAgeG1sUmVnRXhlY0N0eHRQdHIgcmVnZXhwOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbHVlOwoKICAgIGludCB2YWx1ZVdTOwogICAgaW50IG9wdGlvbnM7CiAgICB4bWxOb2RlUHRyIHZhbGlkYXRpb25Sb290OwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKICAgIGludCB4c2lBc3NlbWJsZTsKCiAgICBpbnQgZGVwdGg7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciAqZWxlbUluZm9zOyAvKiBhcnJheSBvZiBlbGVtZW50IGluZm9ybWF0aW9ucyAqLwogICAgaW50IHNpemVFbGVtSW5mb3M7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZTsgLyogdGhlIGN1cnJlbnQgZWxlbWVudCBpbmZvcm1hdGlvbiAqLwoKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjczsgLyogYSBsaXN0IG9mIGF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb25zICovCgogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgeHBhdGhTdGF0ZXM7IC8qIGZpcnN0IGFjdGl2ZSBzdGF0ZSBvYmplY3QuICovCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlUG9vbDsgLyogZmlyc3Qgc3RvcmVkIHN0YXRlIG9iamVjdC4gKi8KCiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqaWRjTm9kZXM7IC8qIGxpc3Qgb2YgYWxsIElEQyBub2RlLXRhYmxlIGVudHJpZXMqLwogICAgaW50IG5iSWRjTm9kZXM7CiAgICBpbnQgc2l6ZUlkY05vZGVzOwoKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmlkY0tleXM7IC8qIGxpc3Qgb2YgYWxsIElEQyBub2RlLXRhYmxlIGVudHJpZXMgKi8KICAgIGludCBuYklkY0tleXM7CiAgICBpbnQgc2l6ZUlkY0tleXM7CgogICAgaW50IGZsYWdzOwoKICAgIHhtbERpY3RQdHIgZGljdDsKCiNpZmRlZiBMSUJYTUxfUkVBREVSX0VOQUJMRUQKICAgIHhtbFRleHRSZWFkZXJQdHIgcmVhZGVyOwojZW5kaWYKCiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciAqYXR0ckluZm9zOwogICAgaW50IG5iQXR0ckluZm9zOwogICAgaW50IHNpemVBdHRySW5mb3M7CgogICAgaW50IHNraXBEZXB0aDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIG5vZGVRTmFtZXM7Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgaW4gdGhlIHNjaGVtYXMgaW1wb3J0U2NoZW1hcyBoYXNoIHRhYmxlCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHhtbFNjaGVtYUltcG9ydDsKdHlwZWRlZiB4bWxTY2hlbWFJbXBvcnQgKnhtbFNjaGVtYUltcG9ydFB0cjsKc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgewogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAvKiBub3QgdXNlZCBhbnkgbW9yZSAqLwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCBpc01haW47Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgYXNzb2NpYXRlZCB0byBpbmNsdWRlcyBpbiBhIHNjaGVtYXMKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHhtbFNjaGVtYUluY2x1ZGU7CnR5cGVkZWYgeG1sU2NoZW1hSW5jbHVkZSAqeG1sU2NoZW1hSW5jbHVkZVB0cjsKc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgbmV4dDsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGNvbnN0IHhtbENoYXIgKm9yaWdUYXJnZXROYW1lc3BhY2U7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7Cn07CgovKioKICogeG1sU2NoZW1hU3Vic3RHcm91cDoKICoKICoKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHhtbFNjaGVtYVN1YnN0R3JvdXA7CnR5cGVkZWYgeG1sU2NoZW1hU3Vic3RHcm91cCAqeG1sU2NoZW1hU3Vic3RHcm91cFB0cjsKc3RydWN0IF94bWxTY2hlbWFTdWJzdEdyb3VwIHsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgaGVhZDsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIG1lbWJlcnM7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU29tZSBwcmVkZWNsYXJhdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CiNpZmRlZiBFTkFCTEVfUkVERUZJTkUKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZVJlZGVmaW5lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKI2VuZGlmCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSk7CnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbXBvcnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0ZhY2V0VmFsdWVzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KTsKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYXJWYWxpZEN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KTsKc3RhdGljIHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUKeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUsCgkJCSBpbnQgd2l0aFBhcnRpY2xlKTsKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZUxpbmtQdHIKeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKc3RhdGljIHZvaWQKeG1sU2NoZW1hSW50ZXJuYWxFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgY29uc3QgY2hhciAqZnVuY05hbWUsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlKTsKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICAgIGludCBzdWJzZXQpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wsCgkJCQkgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCUhlbHBlciBmdW5jdGlvbnMJCQkgICAgICAgICoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZzoKICogQHR5cGU6IHRoZSB0eXBlIG9mIHRoZSBzY2hlbWEgaXRlbQogKgogKiBSZXR1cm5zIHRoZSBjb21wb25lbnQgbmFtZSBvZiBhIHNjaGVtYSBpdGVtLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpCnsKICAgIHN3aXRjaCAodHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIHJldHVybihCQURfQ0FTVCAic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICByZXR1cm4oQkFEX0NBU1QgImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybihCQURfQ0FTVCAiZWxlbWVudCBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybihCQURfQ0FTVCAiYXR0cmlidXRlIGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJICAgIHJldHVybihCQURfQ0FTVCAiYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgoJICAgIHJldHVybihCQURfQ0FTVCAibm90YXRpb24gZGVjbGFyYXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJICAgIHJldHVybihCQURfQ0FTVCAibW9kZWwgZ3JvdXAgKHNlcXVlbmNlKSIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJICAgIHJldHVybihCQURfQ0FTVCAibW9kZWwgZ3JvdXAgKGNob2ljZSkiKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIm1vZGVsIGdyb3VwIChhbGwpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCSAgICByZXR1cm4oQkFEX0NBU1QgInBhcnRpY2xlIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJICAgIHJldHVybihCQURfQ0FTVCAiSURDICh1bmlxdWUpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJICAgIHJldHVybihCQURfQ0FTVCAiSURDIChrZXkpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJICAgIHJldHVybihCQURfQ0FTVCAiSURDIChrZXlyZWYpIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkgICAgcmV0dXJuKEJBRF9DQVNUICJ3aWxkY2FyZCAoYW55KSIpOwoJY2FzZSBYTUxfU0NIRU1BX0VYVFJBX1FOQU1FUkVGOgoJICAgIHJldHVybihCQURfQ0FTVCAiW2hlbHBlciBjb21wb25lbnRdIFFOYW1lIHJlZmVyZW5jZSIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oQkFEX0NBU1QgIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENvbXBvbmVudE5vZGU6CiAqIEBpdGVtOiBhIHNjaGVtYSBjb21wb25lbnQKICoKICogUmV0dXJucyBub2RlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2NoZW1hIGNvbXBvbmVudC4KICogTk9URSB0aGF0IHN1Y2ggYSBub2RlIG5lZWQgbm90IGJlIGF2YWlsYWJsZTsgcGx1cywgYSBjb21wb25lbnQncwogKiBub2RlIG5lZWQgbm90IHRvIHJlZmxlY3QgdGhlIGNvbXBvbmVudCBkaXJlY3RseSwgc2luY2UgdGhlcmUgaXMgbm8KICogb25lLXRvLW9uZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgWE1MIFNjaGVtYSByZXByZXNlbnRhdGlvbiBhbmQKICogdGhlIGNvbXBvbmVudCByZXByZXNlbnRhdGlvbi4KICovCnN0YXRpYyB4bWxOb2RlUHRyCnhtbFNjaGVtYUdldENvbXBvbmVudE5vZGUoeG1sU2NoZW1hQmFzaWNJdGVtUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+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+bmJlcnJvcnMrKzsKICAgICAgICBjdHh0LT5lcnIgPSBYTUxfU0NIRU1BVl9JTlRFUk5BTDsKICAgIH0KICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1YsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFFcnIzOgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIEBzdHIzOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFcnIzTGluZSh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgY3R4dCwgIAoJICAgICAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGludCBsaW5lLCBjb25zdCBjaGFyICptc2csCgkgICAgICBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CiAgICAKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKCWlmIChjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsKCSAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHh0OwoJICAgIGNvbnN0IGNoYXIgKmZpbGUgPSBOVUxMOwoKCSAgICB2Y3R4dC0+bmJlcnJvcnMrKzsKCSAgICB2Y3R4dC0+ZXJyID0gZXJyb3I7CgkgICAgY2hhbm5lbCA9IHZjdHh0LT5lcnJvcjsKCSAgICBzY2hhbm5lbCA9IHZjdHh0LT5zZXJyb3I7CgkgICAgZGF0YSA9IHZjdHh0LT51c2VyRGF0YTsKCgkgICAgLyoKCSAgICAqIEVycm9yIG5vZGUuIElmIHdlIHNwZWNpZnkgYSBsaW5lIG51bWJlciwgdGhlbgoJICAgICogZG8gbm90IGNoYW5uZWwgYW55IG5vZGUgdG8gdGhlIGVycm9yIGZ1bmN0aW9uLgoJICAgICovCgkgICAgaWYgKGxpbmUgPT0gMCkgewoJCWlmICgobm9kZSA9PSBOVUxMKSAmJgoJCSAgICAodmN0eHQtPmRlcHRoID49IDApICYmCgkJICAgICh2Y3R4dC0+aW5vZGUgIT0gTlVMTCkpIHsKCQkgICAgbm9kZSA9IHZjdHh0LT5pbm9kZS0+bm9kZTsKCQl9CgkJLyoKCQkqIEdldCBmaWxlbmFtZSBhbmQgbGluZSBpZiBubyBub2RlLXRyZWUuCgkJKi8KCQlpZiAoKG5vZGUgPT0gTlVMTCkgJiYKCQkgICAgKHZjdHh0LT5wYXJzZXJDdHh0ICE9IE5VTEwpICYmCgkJICAgICh2Y3R4dC0+cGFyc2VyQ3R4dC0+aW5wdXQgIT0gTlVMTCkpIHsKCQkgICAgZmlsZSA9IHZjdHh0LT5wYXJzZXJDdHh0LT5pbnB1dC0+ZmlsZW5hbWU7CgkJICAgIGxpbmUgPSB2Y3R4dC0+cGFyc2VyQ3R4dC0+aW5wdXQtPmxpbmU7CgkJfQoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIE92ZXJyaWRlIHRoZSBnaXZlbiBub2RlJ3MgKGlmIGFueSkgcG9zaXRpb24KCQkqIGFuZCBjaGFubmVsIG9ubHkgdGhlIGdpdmVuIGxpbmUgbnVtYmVyLgoJCSovCgkJbm9kZSA9IE5VTEw7CgkJLyoKCQkqIEdldCBmaWxlbmFtZS4KCQkqLwoJCWlmICh2Y3R4dC0+ZG9jICE9IE5VTEwpCgkJICAgIGZpbGUgPSAoY29uc3QgY2hhciAqKSB2Y3R4dC0+ZG9jLT5VUkw7CgkJZWxzZSBpZiAoKHZjdHh0LT5wYXJzZXJDdHh0ICE9IE5VTEwpICYmCgkJICAgICh2Y3R4dC0+cGFyc2VyQ3R4dC0+aW5wdXQgIT0gTlVMTCkpCgkJICAgIGZpbGUgPSB2Y3R4dC0+cGFyc2VyQ3R4dC0+aW5wdXQtPmZpbGVuYW1lOwoJICAgIH0JICAgICAgIAoJICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwKCQlub2RlLCBYTUxfRlJPTV9TQ0hFTUFTViwKCQllcnJvciwgWE1MX0VSUl9FUlJPUiwgZmlsZSwgbGluZSwKCQkoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLAoJCShjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgc3RyMyk7CgoJfSBlbHNlIGlmIChjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsKCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIGN0eHQ7CgoJICAgIHBjdHh0LT5uYmVycm9ycysrOwoJICAgIHBjdHh0LT5lcnIgPSBlcnJvcjsKCSAgICBjaGFubmVsID0gcGN0eHQtPmVycm9yOwoJICAgIHNjaGFubmVsID0gcGN0eHQtPnNlcnJvcjsKCSAgICBkYXRhID0gcGN0eHQtPnVzZXJEYXRhOwoJICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwKCQlub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKCQllcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKCQkoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLAoJCShjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgc3RyMyk7Cgl9IGVsc2UgewoJICAgIFRPRE8KCX0KICAgIH0gICAgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFFcnIzOgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIEBzdHIzOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFcnIzKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwgIAoJICAgICAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm1zZywKCSAgICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsIGNvbnN0IHhtbENoYXIgKnN0cjIsIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbFNjaGVtYUVycjNMaW5lKGFjdHh0LCBlcnJvciwgbm9kZSwgMCwgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCSAgICAgaW50IGVycm9yLCB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm1zZywKCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sU2NoZW1hRXJyMyhhY3R4dCwgZXJyb3IsIG5vZGUsIG1zZywgc3RyMSwgc3RyMiwgTlVMTCk7Cn0KCnN0YXRpYyB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKHhtbENoYXIgKiogbXNnLAoJCQkgICAgeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgIGlmIChub2RlICE9IE5VTEwpIHsKCS8qCgkqIFdvcmsgb24gdHJlZSBub2Rlcy4KCSovCglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxOb2RlUHRyIGVsZW0gPSBub2RlLT5wYXJlbnQ7CgkgICAgCgkgICAgKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7CgkgICAgaWYgKGVsZW0tPm5zICE9IE5VTEwpCgkJKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBlbGVtLT5ucy0+aHJlZiwgZWxlbS0+bmFtZSkpOwoJICAgIGVsc2UKCQkqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJICAgIE5VTEwsIGVsZW0tPm5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiJywgIik7CgkgICAgKm1zZyA9IHhtbFN0cmNhdCgqbXNnLCBCQURfQ0FTVCAiYXR0cmlidXRlICciKTsJICAgIAoJfSBlbHNlIHsKCSAgICAqbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCX0KCWlmIChub2RlLT5ucyAhPSBOVUxMKQoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCSAgICBub2RlLT5ucy0+aHJlZiwgbm9kZS0+bmFtZSkpOwoJZWxzZQoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCSAgICBOVUxMLCBub2RlLT5uYW1lKSk7CglGUkVFX0FORF9OVUxMKHN0cik7CgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICInOiAiKTsKICAgIH0gZWxzZSBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgewoJeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQ7CgkvKgoJKiBXb3JrIG9uIG5vZGUgaW5mb3MuCgkqLwkKCWlmICh2Y3R4dC0+aW5vZGUtPm5vZGVUeXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewoJICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtID0KCQl2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF07CgoJICAgICptc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQlpZWxlbS0+bnNOYW1lLCBpZWxlbS0+bG9jYWxOYW1lKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIicsICIpOwoJICAgICptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgImF0dHJpYnV0ZSAnIik7CSAgICAKCX0gZWxzZSB7CgkgICAgKm1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7Cgl9CgkqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgdmN0eHQtPmlub2RlLT5uc05hbWUsIHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSk7CglGUkVFX0FORF9OVUxMKHN0cik7CgkqbXNnID0geG1sU3RyY2F0KCptc2csIEJBRF9DQVNUICInOiAiKTsKICAgIH0gZWxzZSB7CglUT0RPCglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgLyoKICAgICogVkFMIFRPRE86IFRoZSBvdXRwdXQgb2YgdGhlIGdpdmVuIHNjaGVtYSBjb21wb25lbnQgaXMgY3VycmVudGx5CiAgICAqIGRpc2FibGVkLgogICAgKi8KI2lmIDAgICAgCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHhtbFNjaGVtYUlzR2xvYmFsSXRlbSh0eXBlKSkpIHsKCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIiBbIik7CgkqbXNnID0geG1sU3RyY2F0KCptc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAwKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCSptc2cgPSB4bWxTdHJjYXQoKm1zZywgQkFEX0NBU1QgIl0iKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKCptc2cpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJbnRlcm5hbEVycjIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgY29uc3QgY2hhciAqZnVuY05hbWUsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEw7CgogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJJbnRlcm5hbCBlcnJvcjogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBmdW5jTmFtZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLCAiKTsgICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKCiAgICBpZiAoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikKCXhtbFNjaGVtYUVycihhY3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIE5VTEwsCgkgICAgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyKTsKCiAgICBlbHNlIGlmIChhY3R4dC0+dHlwZSA9PSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSKQkKCXhtbFNjaGVtYUVycihhY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIE5VTEwsCgkgICAgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyKTsKCiAgICBGUkVFX0FORF9OVUxMKG1zZykKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hSW50ZXJuYWxFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgY29uc3QgY2hhciAqZnVuY05hbWUsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxTY2hlbWFJbnRlcm5hbEVycjIoYWN0eHQsIGZ1bmNOYW1lLCBtZXNzYWdlLCBOVUxMLCBOVUxMKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUEludGVybmFsRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJICAgICBjb25zdCBjaGFyICpmdW5jTmFtZSwKCQkgICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sU2NoZW1hSW50ZXJuYWxFcnIyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LCBmdW5jTmFtZSwgbWVzc2FnZSwKCXN0cjEsIHN0cjIpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDdXN0b21FcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOyAgIAogICAgeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwKCShjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMik7CiAgICBGUkVFX0FORF9OVUxMKG1zZykKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hS2V5cmVmRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaWRjTm9kZSwKCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgQVRUUklCVVRFX1VOVVNFRCwKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTCwgKnFuYW1lID0gTlVMTDsKICAgIAogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICclcyc6ICIpOyAgICAgICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIHhtbFNjaGVtYUVycjNMaW5lKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJZXJyb3IsIE5VTEwsIGlkY05vZGUtPm5vZGVMaW5lLCAoY29uc3QgY2hhciAqKSBtc2csCgl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmcW5hbWUsCgkgICAgdmN0eHQtPm5vZGVRTmFtZXMtPml0ZW1zW2lkY05vZGUtPm5vZGVRTmFtZUlEICsxXSwKCSAgICB2Y3R4dC0+bm9kZVFOYW1lcy0+aXRlbXNbaWRjTm9kZS0+bm9kZVFOYW1lSURdKSwgCglzdHIxLCBzdHIyKTsKICAgIEZSRUVfQU5EX05VTEwocW5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKQoJcmV0dXJuIChub2RlLT50eXBlKTsKICAgIGlmICgoYWN0eHQtPnR5cGUgPT0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUikgJiYKCSgoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQpLT5pbm9kZSAhPSBOVUxMKSkKCXJldHVybiAoICgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPmlub2RlLT5ub2RlVHlwZSk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFJc0dsb2JhbEl0ZW0oeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgxKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIGlmICggKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0pLT5mbGFncyAmCgkJWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJLyogTm90ZSB0aGF0IGF0dHJpYnV0ZSBncm91cHMgYXJlIGFsd2F5cyBnbG9iYWwuICovCglkZWZhdWx0OgoJICAgIHJldHVybigxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCSAgICAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgaW50IGRpc3BsYXlWYWx1ZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXROb2RlRm9yRXJyb3IoJm1zZywgYWN0eHQsIG5vZGUpOwoKICAgIGlmIChkaXNwbGF5VmFsdWUgfHwgKHhtbFNjaGVtYUV2YWxFcnJvck5vZGVUeXBlKGFjdHh0LCBub2RlKSA9PQoJICAgIFhNTF9BVFRSSUJVVEVfTk9ERSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyVzJyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBvZiAiKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGEgdmFsaWQgIgoJICAgICJ2YWx1ZSBvZiAiKTsKCiAgICBpZiAoISB4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwogICAgZWxzZQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInRoZSAiKTsKCiAgICBpZiAoVkFSSUVUWV9BVE9NSUModHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiYXRvbWljIHR5cGUiKTsKICAgIGVsc2UgaWYgKFZBUklFVFlfTElTVCh0eXBlKSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJsaXN0IHR5cGUiKTsKICAgIGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidW5pb24gdHlwZSIpOwoKICAgIGlmICh4bWxTY2hlbWFJc0dsb2JhbEl0ZW0odHlwZSkpIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCWlmICh0eXBlLT5idWlsdEluVHlwZSAhPSAwKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInhzOiIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJfSBlbHNlIAoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCgkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkgICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlLCB0eXBlLT5uYW1lKSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwoJRlJFRV9BTkRfTlVMTChzdHIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKGRpc3BsYXlWYWx1ZSB8fCAoeG1sU2NoZW1hRXZhbEVycm9yTm9kZVR5cGUoYWN0eHQsIG5vZGUpID09CgkgICAgWE1MX0FUVFJJQlVURV9OT0RFKSkKCXhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwogICAgZWxzZQoJeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKHhtbENoYXIgKiogc3RyLAoJCQkgICAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBuaSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgbm9kZS0+bnMtPmhyZWYsIG5vZGUtPm5hbWUpKTsKCWVsc2UKCSAgICByZXR1cm4gKHhtbFNjaGVtYUZvcm1hdFFOYW1lKHN0ciwgTlVMTCwgbm9kZS0+bmFtZSkpOwogICAgfSBlbHNlIGlmIChuaSAhPSBOVUxMKQoJcmV0dXJuICh4bWxTY2hlbWFGb3JtYXRRTmFtZShzdHIsIG5pLT5uc05hbWUsIG5pLT5sb2NhbE5hbWUpKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxTY2hlbWFBdHRySW5mb1B0ciBuaSwKCQkJeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0Tm9kZUZvckVycm9yKCZtc2csIGFjdHh0LCBub2RlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iKTsKICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywKCXhtbFNjaGVtYUZvcm1hdEVycm9yTm9kZVFOYW1lKCZzdHIsICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgbmksIG5vZGUpLAoJTlVMTCk7ICAgICAgICAKICAgIEZSRUVfQU5EX05VTEwoc3RyKQogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0ciBhY3R4dCwKCQkgICAgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlIEFUVFJJQlVURV9VTlVTRUQsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWludCBuYnZhbCwKCQkJaW50IG5ibmVnLAoJCQl4bWxDaGFyICoqdmFsdWVzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbENoYXIgKmxvY2FsTmFtZSwgKm5zTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGludCBpLCBpc19ub3Q7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCBhY3R4dCwgbm9kZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuIik7CiAgICAvKgogICAgKiBOb3RlIHRoYXQgaXMgZG9lcyBub3QgbWFrZSBzZW5zZSB0byByZXBvcnQgdGhhdCB3ZSBoYXZlIGEKICAgICogd2lsZGNhcmQgaGVyZSwgc2luY2UgdGhlIHdpbGRjYXJkIG1pZ2h0IGJlIHVuZm9sZGVkIGludG8KICAgICogbXVsdGlwbGUgdHJhbnNpdGlvbnMuCiAgICAqLwogICAgaWYgKG5idmFsICsgbmJuZWcgPiAwKSB7CglpZiAobmJ2YWwgKyBuYm5lZyA+IDEpIHsKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiBFeHBlY3RlZCBpcyBvbmUgb2YgKCAiKTsKCX0gZWxzZQoJICAgIHN0ciA9IHhtbFN0cmR1cChCQURfQ0FTVCAiIEV4cGVjdGVkIGlzICggIik7Cgluc05hbWUgPSBOVUxMOwogICAgCSAgICAKCWZvciAoaSA9IDA7IGkgPCBuYnZhbCArIG5ibmVnOyBpKyspIHsKCSAgICBjdXIgPSB2YWx1ZXNbaV07CgkgICAgaWYgKGN1ciA9PSBOVUxMKQoJICAgICAgICBjb250aW51ZTsKCSAgICBpZiAoKGN1clswXSA9PSAnbicpICYmIChjdXJbMV0gPT0gJ28nKSAmJiAoY3VyWzJdID09ICd0JykgJiYKCSAgICAgICAgKGN1clszXSA9PSAnICcpKSB7CgkgICAgICAgIGlzX25vdCA9IDE7CgkJY3VyICs9IDQ7CgkJc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgIiMjb3RoZXIiKTsKCSAgICB9IGVsc2UgewoJICAgICAgICBpc19ub3QgPSAwOwoJICAgIH0KCSAgICAvKgoJICAgICogR2V0IHRoZSBsb2NhbCBuYW1lLgoJICAgICovCgkgICAgbG9jYWxOYW1lID0gTlVMTDsKCSAgICAKCSAgICBlbmQgPSBjdXI7CgkgICAgaWYgKCplbmQgPT0gJyonKSB7CgkJbG9jYWxOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICIqIik7CgkJZW5kKys7CgkgICAgfSBlbHNlIHsKCQl3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCplbmQgIT0gJ3wnKSkKCQkgICAgZW5kKys7CgkJbG9jYWxOYW1lID0geG1sU3RybmNhdChsb2NhbE5hbWUsIEJBRF9DQVNUIGN1ciwgZW5kIC0gY3VyKTsKCSAgICB9CQkKCSAgICBpZiAoKmVuZCAhPSAwKSB7CQkgICAgCgkJZW5kKys7CgkJLyoKCQkqIFNraXAgIip8KiIgaWYgdGhleSBjb21lIHdpdGggbmVnYXRlZCBleHByZXNzaW9ucywgc2luY2UKCQkqIHRoZXkgcmVwcmVzZW50IHRoZSBzYW1lIG5lZ2F0ZWQgd2lsZGNhcmQuCgkJKi8KCQlpZiAoKG5ibmVnID09IDApIHx8ICgqZW5kICE9ICcqJykgfHwgKCpsb2NhbE5hbWUgIT0gJyonKSkgewoJCSAgICAvKgoJCSAgICAqIEdldCB0aGUgbmFtZXNwYWNlIG5hbWUuCgkJICAgICovCgkJICAgIGN1ciA9IGVuZDsKCQkgICAgaWYgKCplbmQgPT0gJyonKSB7CgkJCW5zTmFtZSA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyp9Iik7CgkJICAgIH0gZWxzZSB7CgkJCXdoaWxlICgqZW5kICE9IDApCgkJCSAgICBlbmQrKzsKCQkJCgkJCWlmIChpID49IG5idmFsKQoJCQkgICAgbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7IyNvdGhlcjoiKTsKCQkJZWxzZQoJCQkgICAgbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Iik7CgkJCQoJCQluc05hbWUgPSB4bWxTdHJuY2F0KG5zTmFtZSwgQkFEX0NBU1QgY3VyLCBlbmQgLSBjdXIpOwoJCQluc05hbWUgPSB4bWxTdHJjYXQobnNOYW1lLCBCQURfQ0FTVCAifSIpOwoJCSAgICB9CgkJICAgIHN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUIG5zTmFtZSk7CgkJICAgIEZSRUVfQU5EX05VTEwobnNOYW1lKQoJCX0gZWxzZSB7CgkJICAgIEZSRUVfQU5EX05VTEwobG9jYWxOYW1lKTsKCQkgICAgY29udGludWU7CgkJfQoJICAgIH0JICAgICAgICAKCSAgICBzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCBsb2NhbE5hbWUpOwoJICAgIEZSRUVfQU5EX05VTEwobG9jYWxOYW1lKTsKCQkKCSAgICBpZiAoaSA8IG5idmFsICsgbmJuZWcgLTEpCgkJc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgIiwgIik7Cgl9CQoJc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgIiApLlxuIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBzdHIpOwoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9IGVsc2UKICAgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlxuIik7CiAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgeG1sRnJlZShtc2cpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGYWNldEVycih4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICB4bWxOb2RlUHRyIG5vZGUsCgkJICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkgIHVuc2lnbmVkIGxvbmcgbGVuZ3RoLAoJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCgkJICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgeG1sU2NoZW1hVHlwZVR5cGUgZmFjZXRUeXBlOwogICAgaW50IG5vZGVUeXBlID0geG1sU2NoZW1hRXZhbEVycm9yTm9kZVR5cGUoYWN0eHQsIG5vZGUpOwoKICAgIHhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCBhY3R4dCwgbm9kZSk7CiAgICBpZiAoZXJyb3IgPT0gWE1MX1NDSEVNQVZfQ1ZDX0VOVU1FUkFUSU9OX1ZBTElEKSB7CglmYWNldFR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOwoJLyoKCSogSWYgZW51bWVyYXRpb25zIGFyZSB2YWxpZGF0ZWQsIG9uZSBtdXN0IG5vdCBleHBlY3QgdGhlCgkqIGZhY2V0IHRvIGJlIGdpdmVuLgoJKi8JCiAgICB9IGVsc2UJCglmYWNldFR5cGUgPSBmYWNldC0+dHlwZTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJbIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiZmFjZXQgJyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXRUeXBlKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJ10gIik7CiAgICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CgkvKgoJKiBVc2UgYSBkZWZhdWx0IG1lc3NhZ2UuCgkqLwoJaWYgKChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEgpIHx8CgkgICAgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKSkgewoKCSAgICBjaGFyIGxlblsyNV0sIGFjdExlblsyNV07CgoJICAgIC8qIEZJWE1FLCBUT0RPOiBXaGF0IGlzIHRoZSBtYXggZXhwZWN0ZWQgc3RyaW5nIGxlbmd0aCBvZiB0aGUKCSAgICAqIHRoaXMgdmFsdWU/CgkgICAgKi8KCSAgICBpZiAobm9kZVR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgaGFzIGEgbGVuZ3RoIG9mICclcyc7ICIpOwoKCSAgICBzbnByaW50ZihsZW4sIDI0LCAiJWx1IiwgeG1sU2NoZW1hR2V0RmFjZXRWYWx1ZUFzVUxvbmcoZmFjZXQpKTsKCSAgICBzbnByaW50ZihhY3RMZW4sIDI0LCAiJWx1IiwgbGVuZ3RoKTsKCgkgICAgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBkaWZmZXJzIGZyb20gdGhlIGFsbG93ZWQgbGVuZ3RoIG9mICclcycuXG4iKTsgICAgIAoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBleGNlZWRzIHRoZSBhbGxvd2VkIG1heGltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEgpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgCgkJQkFEX0NBU1QgInRoaXMgdW5kZXJydW5zIHRoZSBhbGxvd2VkIG1pbmltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICAKCSAgICBpZiAobm9kZVR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCXhtbFNjaGVtYUVycjMoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csCgkJICAgIHZhbHVlLCAoY29uc3QgeG1sQ2hhciAqKSBhY3RMZW4sIChjb25zdCB4bWxDaGFyICopIGxlbik7CgkgICAgZWxzZSAKCQl4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csCgkJICAgIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCQoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgYW4gZWxlbWVudCAiCgkJIm9mIHRoZSBzZXQgeyVzfS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCXhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldChhY3R4dCwgJnN0ciwgdHlwZSkpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhY2NlcHRlZCAiCgkJImJ5IHRoZSBwYXR0ZXJuICclcycuXG4iKTsKCSAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCAKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkUpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbGVzcyB0aGFuIHRoZSAiCgkJIm1pbmltdW0gdmFsdWUgYWxsb3dlZCAoJyVzJykuXG4iKTsKCSAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLAoJCWZhY2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRSkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBncmVhdGVyIHRoYW4gdGhlICIKCQkibWF4aW11bSB2YWx1ZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIG11c3QgYmUgbGVzcyB0aGFuICIKCQkiJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIG11c3QgYmUgbW9yZSB0aGFuICIKCQkiJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFMpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaGFzIG1vcmUgIgoJCSJkaWdpdHMgdGhhbiBhcmUgYWxsb3dlZCAoJyVzJykuXG4iKTsKCSAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciopIG1zZywgdmFsdWUsCgkJZmFjZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFMpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaGFzIG1vcmUgZnJhY3Rpb25hbCAiCgkJImRpZ2l0cyB0aGFuIGFyZSBhbGxvd2VkICgnJXMnKS5cbiIpOwoJICAgIHhtbFNjaGVtYUVycihhY3R4dCwgZXJyb3IsIG5vZGUsIChjb25zdCBjaGFyKikgbXNnLCB2YWx1ZSwKCQlmYWNldC0+dmFsdWUpOwoJfSBlbHNlIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsJCQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgZmFjZXQtdmFsaWQuXG4iKTsKCSAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsJCgl9IGVsc2UgewkgICAgCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBpcyBub3QgZmFjZXQtdmFsaWQuXG4iKTsKCSAgICB4bWxTY2hlbWFFcnIoYWN0eHQsIGVycm9yLCBub2RlLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwoJfQogICAgfSBlbHNlIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwoJeG1sU2NoZW1hRXJyKGFjdHh0LCBlcnJvciwgbm9kZSwgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyKTsKICAgIH0gICAgICAgIAogICAgRlJFRV9BTkRfTlVMTChzdHIpCiAgICB4bWxGcmVlKG1zZyk7Cn0KCiNkZWZpbmUgVkVSUk9SKGVyciwgdHlwZSwgbXNnKSBcCiAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIGVyciwgTlVMTCwgdHlwZSwgbXNnLCBOVUxMLCBOVUxMKTsKCiNkZWZpbmUgVkVSUk9SX0lOVChmdW5jLCBtc2cpIHhtbFNjaGVtYUludGVybmFsRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCBmdW5jLCBtc2cpOwoKI2RlZmluZSBQRVJST1JfSU5UKGZ1bmMsIG1zZykgeG1sU2NoZW1hSW50ZXJuYWxFcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsIGZ1bmMsIG1zZyk7CiNkZWZpbmUgUEVSUk9SX0lOVDIoZnVuYywgbXNnKSB4bWxTY2hlbWFJbnRlcm5hbEVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBjdHh0LCBmdW5jLCBtc2cpOwoKI2RlZmluZSBBRVJST1JfSU5UKGZ1bmMsIG1zZykgeG1sU2NoZW1hSW50ZXJuYWxFcnIoYWN0eHQsIGZ1bmMsIG1zZyk7CgoKLyoqCiAqIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mICB0aGUgb3duZXIKICogQG93bmVyTmFtZTogdGhlIG5hbWUgb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGFzIGFuIGVsZW1lbnQgbm9kZQogKiBAbm9kZTogdGhlIHBhcmVudCBlbGVtZW50IG5vZGUgb2YgdGhlIG1pc3NpbmcgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0pOwoKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsICIlczogJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLAoJICAgICIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nLlxuIiwKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgUU5hbWUKICogQHJlZk5hbWU6IHRoZSByZWZlcmVuY2VkIGxvY2FsIG5hbWUKICogQHJlZlVSSTogdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIFVSSQogKiBAbWVzc2FnZTogb3B0aW9uYWwgbWVzc2FnZQogKgogKiBVc2VkIHRvIHJlcG9ydCBRTmFtZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgZmFpbGVkIHRvIHJlc29sdmUKICogdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCB4bWxDaGFyICpyZWZOYW1lLAoJCQkgY29uc3QgeG1sQ2hhciAqcmVmVVJJLAoJCQkgeG1sU2NoZW1hVHlwZVR5cGUgcmVmVHlwZSwKCQkJIGNvbnN0IGNoYXIgKnJlZlR5cGVTdHIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJBID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtKTsKICAgIGlmIChyZWZUeXBlU3RyID09IE5VTEwpCglyZWZUeXBlU3RyID0gKGNvbnN0IGNoYXIgKikgeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyhyZWZUeXBlKTsKCXhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwKCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJICAgICIlcywgYXR0cmlidXRlICclcyc6IFRoZSBRTmFtZSB2YWx1ZSAnJXMnIGRvZXMgbm90IHJlc29sdmUgdG8gYShuKSAiCgkgICAgIiVzLlxuIiwgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lLAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHJBLCByZWZVUkksIHJlZk5hbWUpLAoJICAgIEJBRF9DQVNUIHJlZlR5cGVTdHIsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChkZXMpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZSBkdXJpbmcgdGhlIHBhcnNlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbENoYXIgKipvd25lckRlcywKCQkJeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCXhtbEF0dHJQdHIgYXR0ciwKCQkJY29uc3QgY2hhciAqbXNnKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlCglkZXMgPSAqb3duZXJEZXM7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlcywgYXR0cmlidXRlICclcyc6ICVzLlxuIiwKCUJBRF9DQVNUIGRlcywgYXR0ci0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBhdHRyaWJ1dGUncyBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgYXR0cmlidXRlJ3Mgb3duZXIgaXRlbQogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZSBkdXJpbmcgdGhlIHBhcnNlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sQXR0clB0ciBhdHRyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50KTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UKCWRlcyA9ICpvd25lckRlczsKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLAoJIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iLCBCQURfQ0FTVCBkZXMsCgl4bWxTY2hlbWFGb3JtYXRRTmFtZU5zKCZzdHJBLCBhdHRyLT5ucywgYXR0ci0+bmFtZSkpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckEpOwp9CgovKioKICogeG1sU2NoZW1hUEFxdWlyZURlczoKICogQGRlczogdGhlIGZpcnN0IGRlc2lnbmF0aW9uCiAqIEBpdGVtRGVzOiB0aGUgc2Vjb25kIGRlc2lnbmF0aW9uCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogQ3JlYXRlcyBhIGRlc2lnbmF0aW9uIGZvciBhbiBpdGVtLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEFxdWlyZURlcyh4bWxDaGFyICoqZGVzLAoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtKQp7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChkZXMsIE5VTEwsIGl0ZW0sIGl0ZW1FbGVtKTsKICAgIGVsc2UgaWYgKCppdGVtRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoaXRlbURlcywgTlVMTCwgaXRlbSwgaXRlbUVsZW0pOwoJKmRlcyA9ICppdGVtRGVzOwogICAgfSBlbHNlCgkqZGVzID0gKml0ZW1EZXM7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjI6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMzogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtKTsKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXM6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICBpZiAoKGl0ZW1FbGVtID09IE5VTEwpICYmIChpdGVtICE9IE5VTEwpKQoJaXRlbUVsZW0gPSBpdGVtLT5ub2RlOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtRWxlbSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkoY29uc3QgY2hhciAqKSBtc2csIEJBRF9DQVNUIGRlcywgc3RyMSwgc3RyMiwgc3RyMywgTlVMTCk7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSkKewogICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LCBlcnJvciwgaXRlbURlcywgaXRlbSwgaXRlbUVsZW0sIG1lc3NhZ2UsCglzdHIxLCBOVUxMLCBOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBBdHRyVXNlRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSB0eXBlCiAqIEBpdGVtOiB0aGUgc2NoZW1hIHR5cGUKICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIHR5cGUKICogQGF0dHI6IHRoZSBpbnZhbGlkIHNjaGVtYSBhdHRyaWJ1dGUKICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiB0aGUgb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gYXR0cmlidXRlIHVzZSBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBBdHRyVXNlRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIGNvbnN0IHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgaXRlbSwgTlVMTCk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLCAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csCglCQURfQ0FTVCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsCgkoeG1sU2NoZW1hVHlwZVB0cikgYXR0ciwgTlVMTCkpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgYXR0ci0+bm9kZSwgZXJyb3IsCgkoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIE5VTEwpOwogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0VycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSB0eXBlCiAqIEBpdGVtOiB0aGUgc2NoZW1hIHR5cGUKICogQGJhc2VJdGVtOiB0aGUgYmFzZSB0eXBlIG9mIHR5cGUKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIGF0b21pYyBzaW1wbGUgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZUl0ZW0sCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW0tPm5vZGUpOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtLT5ub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQgb24gdHlwZXMgZGVyaXZlZCBmcm9tIHRoZSAiCgkidHlwZSAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0clQsIE5VTEwsIGJhc2VJdGVtLCBOVUxMKSwKCU5VTEwsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIDxsaXN0PiBhbmQgPHVuaW9uPi4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJICB4bWxDaGFyICoqaXRlbURlcywKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW0tPm5vZGUpOwogICAgeG1sU2NoZW1hUEVycihjdHh0LCBpdGVtLT5ub2RlLCBlcnJvciwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQuXG4iLAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBlbGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50IG5vZGUKICogQGF0dHI6IHRoZSBiYWQgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxBdHRyUHRyIGF0dHIsCgkJCSBjb25zdCBjaGFyICpuYW1lMSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlCglkZXMgPSAqb3duZXJEZXM7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGF0dHJpYnV0ZXMgJyVzJyBhbmQgJyVzJyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLlxuIiwKCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZTEsIEJBRF9DQVNUIG5hbWUyLCBOVUxMLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKgogKiB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgdHlwZSBzcGVjaWZpZXIKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IGlmIGV4aXN0ZW50IAogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB2YWx1ZTogdGhlIHZhbGlkYXRlZCB2YWx1ZQogKgogKiBSZXBvcnRzIGEgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQU2ltcGxlVHlwZUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtIEFUVFJJQlVURV9VTlVTRUQsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQljb25zdCBjaGFyICpleHBlY3RlZCwKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjEsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdE5vZGVGb3JFcnJvcigmbXNnLCAoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBjdHh0LCBub2RlKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBkZWZhdWx0IG1lc3NhZ2VzLgoJKi8JCglpZiAodHlwZSAhPSBOVUxMKSB7CgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInJXMnIGlzIG5vdCBhIHZhbGlkIHZhbHVlIG9mICIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCBhICIKCQkidmFsaWQgdmFsdWUgb2YgIik7CQoJICAgIGlmICghIHhtbFNjaGVtYUlzR2xvYmFsSXRlbSh0eXBlKSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlIGxvY2FsICIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAidGhlICIpOwoJICAgIAoJICAgIGlmIChWQVJJRVRZX0FUT01JQyh0eXBlKSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiYXRvbWljIHR5cGUiKTsKCSAgICBlbHNlIGlmIChWQVJJRVRZX0xJU1QodHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgImxpc3QgdHlwZSIpOwoJICAgIGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgInVuaW9uIHR5cGUiKTsKCSAgICAKCSAgICBpZiAoeG1sU2NoZW1hSXNHbG9iYWxJdGVtKHR5cGUpKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKCQlpZiAodHlwZS0+YnVpbHRJblR5cGUgIT0gMCkgewoJCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAieHM6Iik7CgkJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHR5cGUtPm5hbWUpOwoJCX0gZWxzZSAKCQkgICAgbXNnID0geG1sU3RyY2F0KG1zZywKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSwgdHlwZS0+bmFtZSkpOwoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInLiIpOwoJCUZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IHZhbGlkLiIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCAiCgkJInZhbGlkLiIpOwoJfQkKCWlmIChleHBlY3RlZCkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgRXhwZWN0ZWQgaXMgJyIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIGV4cGVjdGVkKTsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJy5cbiIpOwoJfSBlbHNlCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlxuIik7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgTlVMTCk7CgllbHNlCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCBtZXNzYWdlKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKCXhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIChjb25zdCBjaGFyKikgbXNnLCBzdHIxLCBzdHIyLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIC8qIENsZWFudXAuICovICAgIAogICAgRlJFRV9BTkRfTlVMTChtc2cpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ29udGVudEVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb253ZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBpdGVtIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVyRWxlbTogdGhlIG5vZGUgb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAY2hpbGQ6IHRoZSBpbnZhbGlkIGNoaWxkIG5vZGUKICogQG1lc3NhZ2U6IHRoZSBvcHRpb25hbCBlcnJvciBtZXNzYWdlCiAqIEBjb250ZW50OiB0aGUgb3B0aW9uYWwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGNvcnJlY3QgY29udGVudAogKgogKiBSZXBvcnRzIGFuIGVycm9yIGNvbmNlcm5pbmcgdGhlIGNvbnRlbnQgb2YgYSBzY2hlbWEgZWxlbWVudC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDb250ZW50RXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgIHhtbENoYXIgKipvd25lckRlcywKCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCSAgICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJICAgICB4bWxOb2RlUHRyIGNoaWxkLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgIGNvbnN0IGNoYXIgKmNvbnRlbnQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UKCWRlcyA9ICpvd25lckRlczsKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCSAgICAiJXM6ICVzLlxuIiwKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZSB7CglpZiAoY29udGVudCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgb3duZXJFbGVtLCBjaGlsZCwgZXJyb3IsCgkJIiVzOiBUaGUgY29udGVudCBpcyBub3QgdmFsaWQuIEV4cGVjdGVkIGlzICVzLlxuIiwKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIGNvbnRlbnQpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIsCgkJQkFEX0NBU1QgZGVzLCBOVUxMKTsKCX0KICAgIH0KICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTdHJlYW1hYmxlIGVycm9yIGZ1bmN0aW9ucyAgICAgICAgICAgICAgICAgICAgICAqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGhlbHBlciBmdW5jdGlvbnMJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJQWxsb2NhdGlvbiBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3U2NoZW1hRm9yUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEFsbG9jYXRlIGEgbmV3IFNjaGVtYSBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXNzZW1ibGVQdHIKeG1sU2NoZW1hTmV3QXNzZW1ibGUodm9pZCkKewogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBc3NlbWJsZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgLyogeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7ICovCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgcmV0LT5pdGVtcyA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUl0ZW1MaXN0UHRyCnhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKHZvaWQpCnsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0UHRyIHJldDsKCiAgICByZXQgPSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUl0ZW1MaXN0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCSAgICAiYWxsb2NhdGluZyBhbiBpdGVtIGxpc3Qgc3RydWN0dXJlIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUl0ZW1MaXN0KSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUl0ZW1MaXN0Q2xlYXIoeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCkKewogICAgaWYgKGxpc3QtPml0ZW1zICE9IE5VTEwpIHsKCXhtbEZyZWUobGlzdC0+aXRlbXMpOwoJbGlzdC0+aXRlbXMgPSBOVUxMOwogICAgfQogICAgbGlzdC0+bmJJdGVtcyA9IDA7CiAgICBsaXN0LT5zaXplSXRlbXMgPSAwOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUl0ZW1MaXN0QWRkKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QsIHZvaWQgKml0ZW0pCnsKICAgIGlmIChsaXN0LT5pdGVtcyA9PSBOVUxMKSB7CglsaXN0LT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoCgkgICAgMjAgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgbmV3IGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CglsaXN0LT5zaXplSXRlbXMgPSAyMDsKICAgIH0gZWxzZSBpZiAobGlzdC0+c2l6ZUl0ZW1zIDw9IGxpc3QtPm5iSXRlbXMpIHsKCWxpc3QtPnNpemVJdGVtcyAqPSAyOwoJbGlzdC0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhsaXN0LT5pdGVtcywKCSAgICBsaXN0LT5zaXplSXRlbXMgKiBzaXplb2Yodm9pZCAqKSk7CglpZiAobGlzdC0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImdyb3dpbmcgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgbGlzdC0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4oLTEpOwoJfQogICAgfQogICAgLyogKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgKikgbGlzdC0+aXRlbXMpW2xpc3QtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBpdGVtOyAqLwogICAgbGlzdC0+aXRlbXNbbGlzdC0+bmJJdGVtcysrXSA9IGl0ZW07CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJdGVtTGlzdEZyZWU6CiAqIEBhbm5vdDogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBhbm5vdGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSXRlbUxpc3RGcmVlKHhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QpCnsKICAgIGlmIChsaXN0ID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAobGlzdC0+aXRlbXMgIT0gTlVMTCkKCXhtbEZyZWUobGlzdC0+aXRlbXMpOwogICAgeG1sRnJlZShsaXN0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUNvbnRhaW5lclB0cgp4bWxTY2hlbWFDb250YWluZXJDcmVhdGUodm9pZCkKewogICAgeG1sU2NoZW1hQ29udGFpbmVyUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hQ29udGFpbmVyUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUNvbnRhaW5lcikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGNvbXBvbmVudCBjb250YWluZXIiLAoJICAgIE5VTEwpOwoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUNvbnRhaW5lcikpOwogICAgcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNvbnRhaW5lckZyZWUoeG1sU2NoZW1hQ29udGFpbmVyUHRyIGNvbnQpCnsKICAgIGlmIChjb250ID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAoY29udC0+dHlwZURlZnMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjb250LT50eXBlRGVmcyk7CiAgICBpZiAoY29udC0+YXR0ckRlY2xzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoY29udC0+YXR0ckRlY2xzKTsKICAgIGlmIChjb250LT5lbGVtRGVjbHMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjb250LT5lbGVtRGVjbHMpOwogICAgaWYgKGNvbnQtPmF0dHJHcm91cERlZnMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjb250LT5hdHRyR3JvdXBEZWZzKTsKICAgIGlmIChjb250LT5tb2RlbEdyb3VwRGVmcyAhPSBOVUxMKQoJeG1sU2NoZW1hSXRlbUxpc3RGcmVlKGNvbnQtPm1vZGVsR3JvdXBEZWZzKTsKICAgIGlmIChjb250LT5ub3RhdGlvbkRlY2xzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoY29udC0+bm90YXRpb25EZWNscyk7CiAgICBpZiAoY29udC0+YW5ub3RhdGlvbnMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjb250LT5hbm5vdGF0aW9ucyk7CiAgICBpZiAoY29udC0+bG9jYWxzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoY29udC0+bG9jYWxzKTsKICAgIHhtbEZyZWUoY29udCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uTWVtYmVyOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAaGVhZDogIHRoZSBoZWFkIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKICogQG1lbWJlcjogdGhlIG5ldyBtZW1iZXIgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cAogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWRkRWxlbWVudFN1YnN0aXR1dGlvbk1lbWJlcih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkLAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBtZW1iZXIpCnsKICAgIHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIgc3Vic3RHcm91cDsKCiAgICBpZiAocGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwoKICAgIGlmIChwY3R4dC0+c3Vic3RHcm91cHMgPT0gTlVMTCkgewoJcGN0eHQtPnN1YnN0R3JvdXBzID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIHBjdHh0LT5kaWN0KTsKCWlmIChwY3R4dC0+c3Vic3RHcm91cHMgPT0gTlVMTCkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIHN1YnN0R3JvdXAgPSB4bWxIYXNoTG9va3VwMihwY3R4dC0+c3Vic3RHcm91cHMsIGhlYWQtPm5hbWUsCgloZWFkLT50YXJnZXROYW1lc3BhY2UpOwogICAgaWYgKHN1YnN0R3JvdXAgPT0gTlVMTCkgewoJaW50IHJlczsKCglzdWJzdEdyb3VwID0gKHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hU3Vic3RHcm91cCkpOwoJaWYgKHN1YnN0R3JvdXAgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCQkieG1sU2NoZW1hQWRkRWxlbWVudFN1YnN0aXR1dGlvbiwgYWxsb2NhdGluZyBhIHN1YnN0aXR1dGlvbiAiCgkJImdyb3VwIGNvbnRhaW5lciIsCgkJTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglzdWJzdEdyb3VwLT5tZW1iZXJzID0geG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCWlmIChzdWJzdEdyb3VwLT5tZW1iZXJzID09IE5VTEwpIHsKCSAgICB4bWxGcmVlKHN1YnN0R3JvdXApOwoJICAgIHJldHVybiAoLTEpOwoJfQoJc3Vic3RHcm91cC0+aGVhZCA9IGhlYWQ7CgoJcmVzID0geG1sSGFzaEFkZEVudHJ5MihwY3R4dC0+c3Vic3RHcm91cHMsCgkgICAgaGVhZC0+bmFtZSwgaGVhZC0+dGFyZ2V0TmFtZXNwYWNlLCBzdWJzdEdyb3VwKTsKCWlmIChyZXMgIT0gMCkgewoJICAgIHhtbEZyZWUoc3Vic3RHcm91cC0+bWVtYmVycyk7CgkgICAgeG1sRnJlZShzdWJzdEdyb3VwKTsKCSAgICB4bWxTY2hlbWFQRXJyKHBjdHh0LCBtZW1iZXItPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBZGRFbGVtZW50U3Vic3RpdHV0aW9uLCAiCgkJImZhaWxlZCB0byBhZGQgYSBuZXcgc3Vic3RpdHV0aW9uIGdyb3VwIGNvbnRhaW5lciBmb3IgIgoJCSInJXMnLlxuIiwgaGVhZC0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICBpZiAoc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXMgPT0gTlVMTCkgewoJc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKAoJICAgIDUgKiBzaXplb2YoeG1sU2NoZW1hRWxlbWVudFB0cikpOwoJaWYgKHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsCgkJImFsbG9jYXRpbmcgbGlzdCBvZiBzdWJzdGl0dXRpb24gZ3JvdXAgbWVtYmVycyIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJc3Vic3RHcm91cC0+bWVtYmVycy0+c2l6ZUl0ZW1zID0gNTsKICAgIH0gZWxzZSBpZiAoc3Vic3RHcm91cC0+bWVtYmVycy0+c2l6ZUl0ZW1zIDw9CgkgICAgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtcykgewoJc3Vic3RHcm91cC0+bWVtYmVycy0+c2l6ZUl0ZW1zICo9IDI7CglzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxSZWFsbG9jKAoJICAgIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zLAoJICAgIHN1YnN0R3JvdXAtPm1lbWJlcnMtPnNpemVJdGVtcyAqIHNpemVvZih4bWxTY2hlbWFFbGVtZW50UHRyKSk7CglpZiAoc3Vic3RHcm91cC0+bWVtYmVycy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwKCQkicmUtYWxsb2NhdGluZyBsaXN0IG9mIHN1YnN0aXR1dGlvbiBncm91cCBtZW1iZXJzIiwgTlVMTCk7CgkgICAgc3Vic3RHcm91cC0+bWVtYmVycy0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgICgoeG1sU2NoZW1hRWxlbWVudFB0ciAqKSBzdWJzdEdyb3VwLT5tZW1iZXJzLT5pdGVtcykKCVtzdWJzdEdyb3VwLT5tZW1iZXJzLT5uYkl0ZW1zKytdID0gKHZvaWQgKikgbWVtYmVyOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEVsZW1lbnRTdWJzdGl0dXRpb25Hcm91cDoKICogQHBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGhlYWQ6ICB0aGUgaGVhZCBvZiB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwCiAqIEBtZW1iZXI6IHRoZSBuZXcgbWVtYmVyIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAKICoKICogQWxsb2NhdGUgYSBuZXcgYW5ub3RhdGlvbiBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hU3Vic3RHcm91cFB0cgp4bWxTY2hlbWFHZXRFbGVtZW50U3Vic3RpdHV0aW9uR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJCSAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkKQp7CiAgICBpZiAocGN0eHQgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CgogICAgaWYgKHBjdHh0LT5zdWJzdEdyb3VwcyA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKCiAgICByZXR1cm4gKCh4bWxTY2hlbWFTdWJzdEdyb3VwUHRyKSB4bWxIYXNoTG9va3VwMihwY3R4dC0+c3Vic3RHcm91cHMsCgloZWFkLT5uYW1lLCBoZWFkLT50YXJnZXROYW1lc3BhY2UpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhbm5vdC0+bmV4dCA9PSBOVUxMKSB7Cgl4bWxGcmVlKGFubm90KTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFBbm5vdFB0ciBwcmV2OwoKCWRvIHsKCSAgICBwcmV2ID0gYW5ub3Q7CgkgICAgYW5ub3QgPSBhbm5vdC0+bmV4dDsKCSAgICB4bWxGcmVlKHByZXYpOwoJfSB3aGlsZSAoYW5ub3QgIT0gTlVMTCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW1wb3J0OgogKiBAaW1wb3J0OiAgYSBzY2hlbWEgaW1wb3J0IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGFuIGltcG9ydCBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJbXBvcnQoeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydCkKewogICAgaWYgKGltcG9ydCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICB4bWxTY2hlbWFGcmVlKGltcG9ydC0+c2NoZW1hKTsKICAgIHhtbEZyZWVEb2MoaW1wb3J0LT5kb2MpOwogICAgeG1sRnJlZShpbXBvcnQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUluY2x1ZGU6CiAqIEBpbmNsdWRlOiAgYSBzY2hlbWEgaW5jbHVkZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhbiBpbmNsdWRlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUluY2x1ZGUoeG1sU2NoZW1hSW5jbHVkZVB0ciBpbmNsdWRlKQp7CiAgICBpZiAoaW5jbHVkZSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICB4bWxGcmVlRG9jKGluY2x1ZGUtPmRvYyk7CiAgICB4bWxGcmVlKGluY2x1ZGUpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUluY2x1ZGVMaXN0OgogKiBAaW5jbHVkZXM6ICBhIHNjaGVtYSBpbmNsdWRlIGxpc3QKICoKICogRGVhbGxvY2F0ZSBhbiBpbmNsdWRlIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUluY2x1ZGVMaXN0KHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZXMpCnsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgbmV4dDsKCiAgICB3aGlsZSAoaW5jbHVkZXMgIT0gTlVMTCkgewogICAgICAgIG5leHQgPSBpbmNsdWRlcy0+bmV4dDsKCXhtbFNjaGVtYUZyZWVJbmNsdWRlKGluY2x1ZGVzKTsKCWluY2x1ZGVzID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVOb3RhdGlvbjoKICogQHNjaGVtYTogIGEgc2NoZW1hIG5vdGF0aW9uIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIE5vdGF0aW9uIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVOb3RhdGlvbih4bWxTY2hlbWFOb3RhdGlvblB0ciBub3RhKQp7CiAgICBpZiAobm90YSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIHhtbEZyZWUobm90YSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0cmlidXRlOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgYXR0cmlidXRlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEF0dHJpYnV0ZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKQp7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChhdHRyLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIGlmIChhdHRyLT5kZWZWYWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShhdHRyLT5kZWZWYWwpOwogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0OgogKiBzZXQ6ICBhIHNjaGVtYSB3aWxkY2FyZCBuYW1lc3BhY2UKICoKICogRGVhbGxvY2F0ZXMgYSBsaXN0IG9mIHdpbGRjYXJkIGNvbnN0cmFpbnQgc3RydWN0dXJlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc2V0KQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5leHQ7CgogICAgd2hpbGUgKHNldCAhPSBOVUxMKSB7CgluZXh0ID0gc2V0LT5uZXh0OwoJeG1sRnJlZShzZXQpOwoJc2V0ID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZDoKICogQHdpbGRjYXJkOiAgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZXMgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZCh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkY2FyZCkKewogICAgaWYgKHdpbGRjYXJkID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHdpbGRjYXJkLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdCh3aWxkY2FyZC0+YW5ub3QpOwogICAgaWYgKHdpbGRjYXJkLT5uc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQod2lsZGNhcmQtPm5zU2V0KTsKICAgIGlmICh3aWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkKCXhtbEZyZWUod2lsZGNhcmQtPm5lZ05zU2V0KTsKICAgIHhtbEZyZWUod2lsZGNhcmQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgYXR0cmlidXRlIGdyb3VwIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0cikKewogICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ci0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0OgogKiBAYXR0clVzZTogIGFuIGF0dHJpYnV0ZSBsaW5rCiAqCiAqIERlYWxsb2NhdGUgYSBsaXN0IG9mIHNjaGVtYSBhdHRyaWJ1dGUgdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0KHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBuZXh0OwoKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKCW5leHQgPSBhdHRyVXNlLT5uZXh0OwoJeG1sRnJlZShhdHRyVXNlKTsKCWF0dHJVc2UgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVFOYW1lUmVmOgogKiBAaXRlbTogYSBRTmFtZSByZWZlcmVuY2Ugc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGVhIGEgUU5hbWUgcmVmZXJlbmNlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVRTmFtZVJlZih4bWxTY2hlbWFRTmFtZVJlZlB0ciBpdGVtKQp7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVFOYW1lUmVmOgogKiBAaXRlbTogYSBRTmFtZSByZWZlcmVuY2Ugc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGVhIGEgUU5hbWUgcmVmZXJlbmNlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVTdWJzdEdyb3VwKHhtbFNjaGVtYVN1YnN0R3JvdXBQdHIgaXRlbSkKewogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybjsKICAgIGlmIChpdGVtLT5tZW1iZXJzICE9IE5VTEwpCgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUoaXRlbS0+bWVtYmVycyk7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZFZvbGF0aWxlKHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSkKewogICAgaWYgKHNjaGVtYS0+dm9sYXRpbGVzID09IE5VTEwpIHsKCXNjaGVtYS0+dm9sYXRpbGVzID0gKHZvaWQgKikgeG1sU2NoZW1hSXRlbUxpc3RDcmVhdGUoKTsKCWlmIChzY2hlbWEtPnZvbGF0aWxlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLAoJCSJhbGxvY2F0aW5nIGxpc3Qgb2Ygdm9sYXRpbGVzIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICByZXR1cm4oeG1sU2NoZW1hSXRlbUxpc3RBZGQoKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSBzY2hlbWEtPnZvbGF0aWxlcywgaXRlbSkpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdDoKICogQGFsaW5rOiBhIHR5cGUgbGluawogKgogKiBEZWFsbG9jYXRlIGEgbGlzdCBvZiB0eXBlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3QoeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaykKewogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbmV4dDsKCiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7CgluZXh0ID0gbGluay0+bmV4dDsKCXhtbEZyZWUobGluayk7CglsaW5rID0gbmV4dDsKICAgIH0KfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdCh4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8pCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIG5leHQ7CiAgICB3aGlsZSAoc3RvICE9IE5VTEwpIHsKCW5leHQgPSBzdG8tPm5leHQ7CglpZiAoc3RvLT5oaXN0b3J5ICE9IE5VTEwpCgkgICAgeG1sRnJlZShzdG8tPmhpc3RvcnkpOwoJaWYgKHN0by0+eHBhdGhDdHh0ICE9IE5VTEwpCgkgICAgeG1sRnJlZVN0cmVhbUN0eHQoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCXhtbEZyZWUoc3RvKTsKCXN0byA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSURDOgogKiBAaWRjOiBhIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKgogKiBEZWFsbG9jYXRlcyBhbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSURDKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYpCnsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBjdXIsIHByZXY7CgogICAgaWYgKGlkY0RlZiA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGlkY0RlZi0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoaWRjRGVmLT5hbm5vdCk7CiAgICAvKiBTZWxlY3RvciAqLwogICAgaWYgKGlkY0RlZi0+c2VsZWN0b3IgIT0gTlVMTCkgewoJaWYgKGlkY0RlZi0+c2VsZWN0b3ItPnhwYXRoQ29tcCAhPSBOVUxMKQoJICAgIHhtbEZyZWVQYXR0ZXJuKCh4bWxQYXR0ZXJuUHRyKSBpZGNEZWYtPnNlbGVjdG9yLT54cGF0aENvbXApOwoJeG1sRnJlZShpZGNEZWYtPnNlbGVjdG9yKTsKICAgIH0KICAgIC8qIEZpZWxkcyAqLwogICAgaWYgKGlkY0RlZi0+ZmllbGRzICE9IE5VTEwpIHsKCWN1ciA9IGlkY0RlZi0+ZmllbGRzOwoJZG8gewoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJICAgIGlmIChwcmV2LT54cGF0aENvbXAgIT0gTlVMTCkKCQl4bWxGcmVlUGF0dGVybigoeG1sUGF0dGVyblB0cikgcHJldi0+eHBhdGhDb21wKTsKCSAgICB4bWxGcmVlKHByZXYpOwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgeG1sRnJlZShpZGNEZWYpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUVsZW1lbnQ6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBlbGVtZW50IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEVsZW1lbnQgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUVsZW1lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChlbGVtLT5hbm5vdCk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cChlbGVtLT5jb250TW9kZWwpOwogICAgaWYgKGVsZW0tPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGVsZW0tPmRlZlZhbCk7CiAgICB4bWxGcmVlKGVsZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUZhY2V0OgogKiBAZmFjZXQ6ICBhIHNjaGVtYSBmYWNldCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBGYWNldCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgaWYgKGZhY2V0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGZhY2V0LT52YWwgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoZmFjZXQtPnZhbCk7CiAgICBpZiAoZmFjZXQtPnJlZ2V4cCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZmFjZXQtPnJlZ2V4cCk7CiAgICBpZiAoZmFjZXQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGZhY2V0LT5hbm5vdCk7CiAgICB4bWxGcmVlKGZhY2V0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlOgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QodHlwZS0+YW5ub3QpOwogICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsIG5leHQ7CgogICAgICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwogICAgICAgIHdoaWxlIChmYWNldCAhPSBOVUxMKSB7CiAgICAgICAgICAgIG5leHQgPSBmYWNldC0+bmV4dDsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICAgICAgZmFjZXQgPSBuZXh0OwogICAgICAgIH0KICAgIH0KICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJLyoKCSogVE9ETzogV2h5IGlzIHRoaXMgcmVzdHJpY3RlZCB0byBub24gYnVpbHQtaW4gdHlwZXM/CgkqLwoJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkKCSAgICB4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdCh0eXBlLT5hdHRyaWJ1dGVVc2VzKTsKICAgIH0KICAgIGlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdCh0eXBlLT5tZW1iZXJUeXBlcyk7CiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIG5leHQsIGxpbms7CgoJbGluayA9IHR5cGUtPmZhY2V0U2V0OwoJZG8gewoJICAgIG5leHQgPSBsaW5rLT5uZXh0OwoJICAgIHhtbEZyZWUobGluayk7CgkgICAgbGluayA9IG5leHQ7Cgl9IHdoaWxlIChsaW5rICE9IE5VTEwpOwogICAgfQogICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAodHlwZS0+Y29udE1vZGVsKTsKICAgIHhtbEZyZWUodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZjoKICogQGl0ZW06ICBhIHNjaGVtYSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqCiAqIERlYWxsb2NhdGVzIGEgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTW9kZWxHcm91cERlZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW0pCnsKICAgIGlmIChpdGVtLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGl0ZW0tPmFubm90KTsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTW9kZWxHcm91cDoKICogQGl0ZW06ICBhIHNjaGVtYSBtb2RlbCBncm91cAogKgogKiBEZWFsbG9jYXRlcyBhIHNjaGVtYSBtb2RlbCBncm91cCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTW9kZWxHcm91cCh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIGl0ZW0pCnsKICAgIGlmIChpdGVtLT5hbm5vdCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUFubm90KGl0ZW0tPmFubm90KTsKICAgIHhtbEZyZWUoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUGFydGljbGU6CiAqIEB0eXBlOiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBUeXBlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVQYXJ0aWNsZSh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBpdGVtKQp7CiAgICBpZiAoaXRlbS0+YW5ub3QgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBbm5vdChpdGVtLT5hbm5vdCk7CiAgICB4bWxGcmVlKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZU1pc2NDb21wb25lbnRzOgogKiBAaXRlbTogIGEgc2NoZW1hIGNvbXBvbmVudAogKgogKiBEZWFsbG9jYXRlcyBtaXNjLiBzY2hlbWEgY29tcG9uZW50IHN0cnVjdHVyZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTWlzY0NvbXBvbmVudHMoeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbSkKewogICAgaWYgKGl0ZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFOgoJICAgIHhtbFNjaGVtYUZyZWVQYXJ0aWNsZSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIGl0ZW0pOwoJICAgIHJldHVybjsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJICAgIHhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwKCh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKSBpdGVtKTsKCSAgICByZXR1cm47CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgoJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZCgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGl0ZW0pOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICAvKiBUT0RPOiBUaGlzIHNob3VsZCBuZXZlciBiZSBoaXQuICovCgkgICAgVE9ETwoJICAgIHJldHVybjsKICAgIH0KfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVZvbGF0aWxlcyh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAoc2NoZW1hLT52b2xhdGlsZXMgPT0gTlVMTCkKCXJldHVybjsKICAgIHsKCXhtbFNjaGVtYUl0ZW1MaXN0UHRyIGxpc3QgPSAoeG1sU2NoZW1hSXRlbUxpc3RQdHIpIHNjaGVtYS0+dm9sYXRpbGVzOwoJeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbTsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBsaXN0LT5uYkl0ZW1zOyBpKyspIHsKCSAgICBpZiAobGlzdC0+aXRlbXNbaV0gIT0gTlVMTCkgewoJCWl0ZW0gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGxpc3QtPml0ZW1zW2ldOwoJCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJCSAgICBjYXNlIFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY6CgkJCXhtbFNjaGVtYUZyZWVRTmFtZVJlZigoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0pOwoJCQlicmVhazsKCQkgICAgZGVmYXVsdDoKCQkJeG1sU2NoZW1hRnJlZU1pc2NDb21wb25lbnRzKGl0ZW0pOwoJCX0KCSAgICB9Cgl9Cgl4bWxTY2hlbWFJdGVtTGlzdEZyZWUobGlzdCk7CiAgICB9Cn0KLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlzdDoKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVR5cGVMaXN0KHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBuZXh0OwoKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKICAgICAgICBuZXh0ID0gdHlwZS0+cmVkZWY7Cgl4bWxTY2hlbWFGcmVlVHlwZSh0eXBlKTsKCXR5cGUgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZToKICogQHNjaGVtYTogIGEgc2NoZW1hIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZSh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChzY2hlbWEtPnZvbGF0aWxlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZvbGF0aWxlcyhzY2hlbWEpOwogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPm5vdGFEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVOb3RhdGlvbik7CiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+YXR0ckRlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZSk7CiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+YXR0cmdycERlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKTsKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlRWxlbWVudCk7CiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZVR5cGVMaXN0KTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+Z3JvdXBEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVNb2RlbEdyb3VwRGVmKTsKICAgIGlmIChzY2hlbWEtPmlkY0RlZiAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+aWRjRGVmLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVJREMpOwogICAgaWYgKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgIT0gTlVMTCkKCXhtbEhhc2hGcmVlKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCgkJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVJbXBvcnQpOwogICAgaWYgKHNjaGVtYS0+aW5jbHVkZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdCgoeG1sU2NoZW1hSW5jbHVkZVB0cikgc2NoZW1hLT5pbmNsdWRlcyk7CiAgICB9CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChzY2hlbWEtPmFubm90KTsKICAgIGlmIChzY2hlbWEtPmRvYyAhPSBOVUxMICYmICFzY2hlbWEtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2Moc2NoZW1hLT5kb2MpOwogICAgeG1sRGljdEZyZWUoc2NoZW1hLT5kaWN0KTsKICAgIHhtbEZyZWUoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURlYnVnIGZ1bmN0aW9ucwkJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWZkZWYgTElCWE1MX09VVFBVVF9FTkFCTEVECgovKioKICogeG1sU2NoZW1hRWxlbWVudER1bXA6CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqCiAqIER1bXAgdGhlIGVsZW1lbnQKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVsZW1lbnREdW1wKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSwgRklMRSAqIG91dHB1dCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKCQkgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIGNvbnRleHQgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9SRUYpIHsKCWZwcmludGYob3V0cHV0LCAiUGFydGljbGU6ICVzIiwgbmFtZSk7CglmcHJpbnRmKG91dHB1dCwgIiwgdGVybSBlbGVtZW50OiAlcyIsIGVsZW0tPnJlZik7CglpZiAoZWxlbS0+cmVmTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIiBucyAlcyIsIGVsZW0tPnJlZk5zKTsKICAgIH0gZWxzZSB7CglmcHJpbnRmKG91dHB1dCwgIkVsZW1lbnQiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKQoJICAgIGZwcmludGYob3V0cHV0LCAiIChnbG9iYWwpIik7CglmcHJpbnRmKG91dHB1dCwgIjogJXMgIiwgZWxlbS0+bmFtZSk7CglpZiAobmFtZXNwYWNlICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJucyAlcyIsIG5hbWVzcGFjZSk7CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoKGVsZW0tPm1pbk9jY3VycyAhPSAxKSB8fCAoZWxlbS0+bWF4T2NjdXJzICE9IDEpKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgbWluICVkICIsIGVsZW0tPm1pbk9jY3Vycyk7CiAgICAgICAgaWYgKGVsZW0tPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiB1bmJvdW5kZWRcbiIpOwogICAgICAgIGVsc2UgaWYgKGVsZW0tPm1heE9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogJWRcbiIsIGVsZW0tPm1heE9jY3Vycyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICAvKgogICAgKiBNaXNjIG90aGVyIHByb3BlcnRpZXMuCiAgICAqLwogICAgaWYgKChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpIHx8CgkoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB8fAoJKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgfHwKCShlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fREVGQVVMVCkgfHwKCShlbGVtLT5pZCAhPSBOVUxMKSkgewoJZnByaW50ZihvdXRwdXQsICIgIHByb3BzOiAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpCgkgICAgZnByaW50ZihvdXRwdXQsICJbZml4ZWRdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9ERUZBVUxUKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2RlZmF1bHRdICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIlthYnN0cmFjdF0gIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKQoJICAgIGZwcmludGYob3V0cHV0LCAiW25pbGxhYmxlXSAiKTsKCWlmIChlbGVtLT5pZCAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2lkOiAnJXMnXSAiLCBlbGVtLT5pZCk7CglmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICAvKgogICAgKiBEZWZhdWx0L2ZpeGVkIHZhbHVlLgogICAgKi8KICAgIGlmIChlbGVtLT52YWx1ZSAhPSBOVUxMKQoJZnByaW50ZihvdXRwdXQsICIgIHZhbHVlOiAnJXMnXG4iLCBlbGVtLT52YWx1ZSk7CiAgICAvKgogICAgKiBUeXBlLgogICAgKi8KICAgIGlmIChlbGVtLT5uYW1lZFR5cGUgIT0gTlVMTCkgewoJZnByaW50ZihvdXRwdXQsICIgIHR5cGU6ICVzICIsIGVsZW0tPm5hbWVkVHlwZSk7CglpZiAoZWxlbS0+bmFtZWRUeXBlTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIm5zICVzXG4iLCBlbGVtLT5uYW1lZFR5cGVOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgLyoKICAgICogU3Vic3RpdHV0aW9uIGdyb3VwLgogICAgKi8KICAgIGlmIChlbGVtLT5zdWJzdEdyb3VwICE9IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiICBzdWJzdGl0dXRpb25Hcm91cDogJXMgIiwgZWxlbS0+c3Vic3RHcm91cCk7CglpZiAoZWxlbS0+c3Vic3RHcm91cE5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJucyAlc1xuIiwgZWxlbS0+c3Vic3RHcm91cE5zKTsKCWVsc2UKCSAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBbm5vdER1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQGFubm90OiAgYSBhbm5vdGF0aW9uCiAqCiAqIER1bXAgdGhlIGFubm90YXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUFubm90RHVtcChGSUxFICogb3V0cHV0LCB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCkKewogICAgeG1sQ2hhciAqY29udGVudDsKCiAgICBpZiAoYW5ub3QgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgY29udGVudCA9IHhtbE5vZGVHZXRDb250ZW50KGFubm90LT5jb250ZW50KTsKICAgIGlmIChjb250ZW50ICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgQW5ub3Q6ICVzXG4iLCBjb250ZW50KTsKICAgICAgICB4bWxGcmVlKGNvbnRlbnQpOwogICAgfSBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIEFubm90OiBlbXB0eVxuIik7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAdHlwZTogIGEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYVR5cGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlLCBGSUxFICogb3V0cHV0LCBpbnQgZGVwdGgpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciB0ZXJtOwogICAgY2hhciBzaGlmdFsxMDBdOwogICAgaW50IGk7CgogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCglyZXR1cm47CiAgICBmb3IgKGkgPSAwOygoaSA8IGRlcHRoKSAmJiAoaSA8IDI1KSk7aSsrKQogICAgICAgIHNoaWZ0WzIgKiBpXSA9IHNoaWZ0WzIgKiBpICsgMV0gPSAnICc7CiAgICBzaGlmdFsyICogaV0gPSBzaGlmdFsyICogaSArIDFdID0gMDsKICAgIGZwcmludGYob3V0cHV0LCBzaGlmdCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHsKCWZwcmludGYob3V0cHV0LCAiTUlTU0lORyBwYXJ0aWNsZSB0ZXJtXG4iKTsKCXJldHVybjsKICAgIH0KICAgIHRlcm0gPSBwYXJ0aWNsZS0+Y2hpbGRyZW47CiAgICBzd2l0Y2ggKHRlcm0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgZnByaW50ZihvdXRwdXQsICJFTEVNICclcyciLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSgoeG1sU2NoZW1hRWxlbWVudFB0cil0ZXJtKS0+dGFyZ2V0TmFtZXNwYWNlLAoJCSgoeG1sU2NoZW1hRWxlbWVudFB0cil0ZXJtKS0+bmFtZSkpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CgkgICAgZnByaW50ZihvdXRwdXQsICJTRVFVRU5DRSIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgoJICAgIGZwcmludGYob3V0cHV0LCAiQ0hPSUNFIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CgkgICAgZnByaW50ZihvdXRwdXQsICJBTEwiKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKCSAgICBmcHJpbnRmKG91dHB1dCwgIkFOWSIpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBmcHJpbnRmKG91dHB1dCwgIlVOS05PV05cbiIpOwoJICAgIHJldHVybjsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzICE9IDEpCglmcHJpbnRmKG91dHB1dCwgIiBtaW46ICVkIiwgcGFydGljbGUtPm1pbk9jY3Vycyk7CiAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpCglmcHJpbnRmKG91dHB1dCwgIiBtYXg6IHVuYm91bmRlZCIpOwogICAgZWxzZSBpZiAocGFydGljbGUtPm1heE9jY3VycyAhPSAxKQoJZnByaW50ZihvdXRwdXQsICIgbWF4OiAlZCIsIHBhcnRpY2xlLT5tYXhPY2N1cnMpOwogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKCgodGVybS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8CgkodGVybS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSB8fAoJKHRlcm0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkpICYmCgkodGVybS0+Y2hpbGRyZW4gIT0gTlVMTCkpIHsKCXhtbFNjaGVtYUNvbnRlbnRNb2RlbER1bXAoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0ZXJtLT5jaGlsZHJlbiwKCSAgICBvdXRwdXQsIGRlcHRoICsxKTsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+bmV4dCAhPSBOVUxMKQoJeG1sU2NoZW1hQ29udGVudE1vZGVsRHVtcCgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5uZXh0LAoJCW91dHB1dCwgZGVwdGgpOwp9Ci8qKgogKiB4bWxTY2hlbWFUeXBlRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAdHlwZTogIGEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYVR5cGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRHVtcCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIEZJTEUgKiBvdXRwdXQpCnsKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlR5cGU6IE5VTExcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiVHlwZTogIik7CiAgICBpZiAodHlwZS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMgIiwgdHlwZS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lICIpOwogICAgaWYgKHR5cGUtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihvdXRwdXQsICJucyAlcyAiLCB0eXBlLT50YXJnZXROYW1lc3BhY2UpOwogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2Jhc2ljXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltzaW1wbGVdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltjb21wbGV4XSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3NlcXVlbmNlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltjaG9pY2VdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2FsbF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VSOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlt1cl0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltyZXN0cmljdGlvbl0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbZXh0ZW5zaW9uXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbdW5rbm93biB0eXBlICVkXSAiLCB0eXBlLT50eXBlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgImNvbnRlbnQ6ICIpOwogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Vua25vd25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbZW1wdHldICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbZWxlbWVudF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlttaXhlZF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgoJLyogbm90IHVzZWQuICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltiYXNpY10gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2ltcGxlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQU5ZOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlthbnldICIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgYmFzZSB0eXBlOiAlcyIsIHR5cGUtPmJhc2UpOwoJaWYgKHR5cGUtPmJhc2VOcyAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAiIG5zICVzXG4iLCB0eXBlLT5iYXNlTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmICh0eXBlLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHR5cGUtPmFubm90KTsKI2lmZGVmIERVTVBfQ09OVEVOVF9NT0RFTAogICAgaWYgKCh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgoJKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFDb250ZW50TW9kZWxEdW1wKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgdHlwZS0+c3VidHlwZXMsCgkgICAgb3V0cHV0LCAxKTsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUR1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKG91dHB1dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiU2NoZW1hczogTlVMTFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiAiKTsKICAgIGlmIChzY2hlbWEtPm5hbWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzLCAiLCBzY2hlbWEtPm5hbWUpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gbmFtZSwgIik7CiAgICBpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzIiwgKGNvbnN0IGNoYXIgKikgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gdGFyZ2V0IG5hbWVzcGFjZSIpOwogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKHNjaGVtYS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFBbm5vdER1bXAob3V0cHV0LCBzY2hlbWEtPmFubm90KTsKCiAgICB4bWxIYXNoU2NhbihzY2hlbWEtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVEdW1wLAogICAgICAgICAgICAgICAgb3V0cHV0KTsKICAgIHhtbEhhc2hTY2FuRnVsbChzY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYUVsZW1lbnREdW1wLCBvdXRwdXQpOwp9CgojaWZkZWYgREVCVUdfSURDCi8qKgogKiB4bWxTY2hlbWFEZWJ1Z0R1bXBJRENUYWJsZToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBEaXNwbGF5cyB0aGUgY3VycmVudCBJREMgdGFibGUgZm9yIGRlYnVnIHB1cnBvc2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRGVidWdEdW1wSURDVGFibGUoRklMRSAqIG91dHB1dCwKCQkJICAgY29uc3QgeG1sQ2hhciAqbmFtZXNwYWNlTmFtZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lLAoJCQkgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqdmFsdWU7CiAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciB0YWI7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleTsKICAgIGludCBpLCBqLCByZXM7CgogICAgZnByaW50ZihvdXRwdXQsICJJREM6IFRBQkxFUyBvbiAlc1xuIiwKCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIG5hbWVzcGFjZU5hbWUsIGxvY2FsTmFtZSkpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpCgogICAgaWYgKGJpbmQgPT0gTlVMTCkKCXJldHVybjsKICAgIGRvIHsKCWZwcmludGYob3V0cHV0LCAiSURDOiAgIEJJTkRJTkcgJXNcbiIsCgkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmluZC0+ZGVmaW5pdGlvbi0+dGFyZ2V0TmFtZXNwYWNlLAoJICAgIGJpbmQtPmRlZmluaXRpb24tPm5hbWUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQoJZm9yIChpID0gMDsgaSA8IGJpbmQtPm5iTm9kZXM7IGkrKykgewoJICAgIHRhYiA9IGJpbmQtPm5vZGVUYWJsZVtpXTsKCSAgICBmcHJpbnRmKG91dHB1dCwgIiAgICAgICAgICggIik7CgkgICAgZm9yIChqID0gMDsgaiA8IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOyBqKyspIHsKCQlrZXkgPSB0YWItPmtleXNbal07CgkJaWYgKChrZXkgIT0gTlVMTCkgJiYgKGtleS0+dmFsICE9IE5VTEwpKSB7CgkJICAgIHJlcyA9IHhtbFNjaGVtYUdldENhbm9uVmFsdWUoa2V5LT52YWwsICZ2YWx1ZSk7CgkJICAgIGlmIChyZXMgPj0gMCkKCQkJZnByaW50ZihvdXRwdXQsICJcIiVzXCIgIiwgdmFsdWUpOwoJCSAgICBlbHNlCgkJCWZwcmludGYob3V0cHV0LCAiQ0FOT04tVkFMVUUtRkFJTEVEICIpOwoJCSAgICBpZiAocmVzID09IDApCgkJCUZSRUVfQU5EX05VTEwodmFsdWUpCgkJfSBlbHNlIGlmIChrZXkgIT0gTlVMTCkKCQkgICAgZnByaW50ZihvdXRwdXQsICIobm8gdmFsKSwgIik7CgkJZWxzZQoJCSAgICBmcHJpbnRmKG91dHB1dCwgIihrZXkgbWlzc2luZyksICIpOwoJICAgIH0KCSAgICBmcHJpbnRmKG91dHB1dCwgIilcbiIpOwoJfQoJYmluZCA9IGJpbmQtPm5leHQ7CiAgICB9IHdoaWxlIChiaW5kICE9IE5VTEwpOwp9CiNlbmRpZiAvKiBERUJVR19JREMgKi8KI2VuZGlmIC8qIExJQlhNTF9PVVRQVVRfRU5BQkxFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJVXRpbGl0aWVzCQkJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3BOb2RlOgogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIG5hbWUgb2YgQG5hbWUgaW4KICogbm8gbmFtZXNwYWNlLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlKHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQXR0clB0ciBwcm9wOwoKICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKCXJldHVybihOVUxMKTsKICAgIHByb3AgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKHByb3AgIT0gTlVMTCkgewogICAgICAgIGlmICgocHJvcC0+bnMgPT0gTlVMTCkgJiYgeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgQkFEX0NBU1QgbmFtZSkpCgkgICAgcmV0dXJuKHByb3ApOwoJcHJvcCA9IHByb3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UHJvcE5vZGVOczoKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUKICogQHVyaTogdGhlIHVyaQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIGxvY2FsIG5hbWUgb2YgQG5hbWUgYW5kCiAqIGEgbmFtZXNwYWNlIFVSSSBvZiBAdXJpLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlTnMoeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICp1cmksIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbEF0dHJQdHIgcHJvcDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCglyZXR1cm4oTlVMTCk7CiAgICBwcm9wID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChwcm9wICE9IE5VTEwpIHsKCWlmICgocHJvcC0+bnMgIT0gTlVMTCkgJiYKCSAgICB4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBCQURfQ0FTVCBuYW1lKSAmJgoJICAgIHhtbFN0ckVxdWFsKHByb3AtPm5zLT5ocmVmLCBCQURfQ0FTVCB1cmkpKQoJICAgIHJldHVybihwcm9wKTsKCXByb3AgPSBwcm9wLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROb2RlQ29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQoJdmFsID0geG1sU3RyZHVwKCh4bWxDaGFyICopIiIpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0UHJvcDoKICogQGN0eHQ6IHRoZSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIG5vZGUKICogQG5hbWU6IHRoZSBwcm9wZXJ0eSBuYW1lCiAqCiAqIFJlYWQgYSBhdHRyaWJ1dGUgdmFsdWUgYW5kIGludGVybmFsaXplIHRoZSBzdHJpbmcKICoKICogUmV0dXJucyB0aGUgc3RyaW5nIG9yIE5VTEwgaWYgbm90IHByZXNlbnQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldFByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbEdldFByb3Aobm9kZSwgQkFEX0NBU1QgbmFtZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUGFyc2luZyBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hR2V0RWxlbToKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICogQG5zOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIGluIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFHZXRFbGVtKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuc05hbWUpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsIG5zTmFtZSk7CiAgICAgICAgaWYgKChyZXQgIT0gTlVMTCkgJiYKCSAgICAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSkgewogICAgICAgICAgICByZXR1cm4gKHJldCk7CiAgICB9IGVsc2UKCXJldCA9IE5VTEw7CgogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0RWxlbShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlLCBsZXZlbCArIDEpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBlbGVtZW50IGRlY2wuICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZWxlbWVudCBkZWNsLiAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRUeXBlOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMgY29udGV4dAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5zOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIHR5cGUgaW4gdGhlIHNjaGVtYXMgb3IgdGhlIHByZWRlZmluZWQgdHlwZXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFR5cGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5zTmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQ7CgogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbnNOYW1lKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkgewkgICAgCgkgICAgaWYgKHJldC0+cmVkZWYgIT0gTlVMTCkgewoJCS8qCgkJKiBSZXR1cm4gdGhlIGxhc3QgcmVkZWZpbml0aW9uLgoJCSovCgkJcmV0dXJuKHJldC0+cmVkZWYpOwoJICAgIH0KICAgICAgICAgICAgcmV0dXJuIChyZXQpOwoJfQogICAgfQogICAgcmV0ID0geG1sU2NoZW1hR2V0UHJlZGVmaW5lZFR5cGUobmFtZSwgbnNOYW1lKTsKICAgIGlmIChyZXQgIT0gTlVMTCkKCXJldHVybiAocmV0KTsKICAgIC8qCiAgICAqIFJlbW92ZWQsIHNpbmNlIHRoZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgZ3JhZnRlZCBvbiB0aGUKICAgICogbWFpbiBzY2hlbWEgb25seS4KICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0VHlwZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5zTmFtZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5zTmFtZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJpYnV0ZURlY2w6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOwogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQsIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOwogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgZ3JvdXAKICoKICogTG9va3VwIGEgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+Z3JvdXBEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0R3JvdXAoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXROYW1lZENvbXBvbmVudDoKICogQHNjaGVtYTogIHRoZSBzY2hlbWEKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwCiAqCiAqIExvb2t1cCBhIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYVRyZWVJdGVtUHRyCnhtbFNjaGVtYUdldE5hbWVkQ29tcG9uZW50KHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgIHhtbFNjaGVtYVR5cGVUeXBlIGl0ZW1UeXBlLAoJCQkgICBjb25zdCB4bWxDaGFyICpuYW1lLAoJCQkgICBjb25zdCB4bWxDaGFyICp0YXJnZXROcykKewogICAgc3dpdGNoIChpdGVtVHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuICgoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHhtbFNjaGVtYUdldEdyb3VwKHNjaGVtYSwKCQluYW1lLCB0YXJnZXROcykpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgeG1sU2NoZW1hR2V0RWxlbShzY2hlbWEsCgkJbmFtZSwgdGFyZ2V0TnMpKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBJU19CTEFOS19OT0RFKG4pCQkJCQkJXAogICAgKCgobiktPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKHhtbFNjaGVtYUlzQmxhbmsoKG4pLT5jb250ZW50LCAtMSkpKQoKLyoqCiAqIHhtbFNjaGVtYUlzQmxhbms6CiAqIEBzdHI6ICBhIHN0cmluZwogKiBAbGVuOiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgb3IgLTEKICoKICogQ2hlY2sgaWYgYSBzdHJpbmcgaXMgaWdub3JhYmxlCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgc3RyaW5nIGlzIE5VTEwgb3IgbWFkZSBvZiBibGFua3MgY2hhcnMsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzQmxhbmsoeG1sQ2hhciAqIHN0ciwgaW50IGxlbikKewogICAgaWYgKHN0ciA9PSBOVUxMKQogICAgICAgIHJldHVybiAoMSk7CiAgICBpZiAobGVuIDwgMCkgewoJd2hpbGUgKCpzdHIgIT0gMCkgewoJICAgIGlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKCQlyZXR1cm4gKDApOwoJICAgIHN0cisrOwoJfQogICAgfSBlbHNlIHdoaWxlICgoKnN0ciAhPSAwKSAmJiAobGVuICE9IDApKSB7CglpZiAoIShJU19CTEFOS19DSCgqc3RyKSkpCgkgICAgcmV0dXJuICgwKTsKCXN0cisrOwoJbGVuLS07CiAgICB9CiAgICAKICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBpdGVtOiAgdGhlIGl0ZW0KICoKICogQWRkIGEgaXRlbSB0byB0aGUgc2NoZW1hJ3MgbGlzdCBvZiBjdXJyZW50IGl0ZW1zLgogKiBUaGlzIGlzIHVzZWQgaWYgdGhlIHNjaGVtYSB3YXMgYWxyZWFkeSBjb25zdHJ1Y3RlZCBhbmQKICogbmV3IHNjaGVtYXRhIG5lZWQgdG8gYmUgYWRkZWQgdG8gaXQuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNlZWRzIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0pCnsKICAgIHN0YXRpYyBpbnQgZ3Jvd1NpemUgPSAxMDA7CiAgICB4bWxTY2hlbWFBc3NlbWJsZVB0ciBhc3M7CgogICAgYXNzID0gY3R4dC0+YXNzZW1ibGU7CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPCAwKSB7CgkvKiBJZiBkaXNhYmxlZC4gKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPD0gMCkgewoJYXNzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoZ3Jvd1NpemUgKiBzaXplb2YoeG1sU2NoZW1hVHlwZVB0cikpOwoJaWYgKGFzcy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCQkiYWxsb2NhdGluZyBuZXcgaXRlbSBidWZmZXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWFzcy0+c2l6ZUl0ZW1zID0gZ3Jvd1NpemU7CiAgICB9IGVsc2UgaWYgKGFzcy0+c2l6ZUl0ZW1zIDw9IGFzcy0+bmJJdGVtcykgewoJYXNzLT5zaXplSXRlbXMgKj0gMjsKCWFzcy0+aXRlbXMgPSAodm9pZCAqKikgeG1sUmVhbGxvYyhhc3MtPml0ZW1zLAoJICAgIGFzcy0+c2l6ZUl0ZW1zICogc2l6ZW9mKHhtbFNjaGVtYVR5cGVQdHIpKTsKCWlmIChhc3MtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsCgkJImdyb3dpbmcgaXRlbSBidWZmZXIiLCBOVUxMKTsKCSAgICBhc3MtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICAvKiBhc3MtPml0ZW1zW2Fzcy0+bmJJdGVtcysrXSA9ICh2b2lkICopIGl0ZW07ICovCiAgICAoKHhtbFNjaGVtYVR5cGVQdHIgKikgYXNzLT5pdGVtcylbYXNzLT5uYkl0ZW1zKytdID0gKHZvaWQgKikgaXRlbTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGROb3RhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgYW5ub3RhdGlvbiBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFBZGROb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUpCnsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPm5vdGFEZWNsID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFOb3RhdGlvblB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFOb3RhdGlvbikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkIGFubm90YXRpb24iLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5ub3RhRGVjbCwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCS8qCgkqIFRPRE86IFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgc2luY2UgYSB1bmlxdWUgbmFtZSB3aWxsIGJlIGNvbXB1dGVkLgoJKiBJZiBpdCBmYWlscywgdGhlbiBhbiBvdGhlciBpbnRlcm5hbCBlcnJvciBtdXN0IGhhdmUgb2NjdXJlZC4KCSovCgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX05PVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgIkFubm90YXRpb24gZGVjbGFyYXRpb24gJyVzJyBpcyBhbHJlYWR5IGRlY2xhcmVkLlxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgYXR0cmlidXRlICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+YXR0ckRlY2wgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuYW1lc3BhY2U7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+YXR0ckRlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CglpZiAodG9wTGV2ZWwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX0FUVFIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiQSBnbG9iYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzICIKCQkiYWxyZWFkeSBleGlzdCIsIG5hbWUpOwoJICAgIHhtbEZyZWUocmV0KTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICBjaGFyIGJ1ZlszMF07CgkgICAgLyoKCSAgICAqIFVzaW5nIHRoZSBjdHh0LT5jb250YWluZXIgZm9yIHhtbEhhc2hBZGRFbnRyeTMgaXMgYW1iaWdpb3VzCgkgICAgKiBpbiB0aGUgc2NlbmFyaW86CgkgICAgKiAxLiBtdWx0aXBsZSB0b3AtbGV2ZWwgY29tcGxleCB0eXBlcyBoYXZlIGRpZmZlcmVudCB0YXJnZXQKCSAgICAqICAgIG5hbWVzcGFjZXMgYnV0IGhhdmUgdGhlIFNBTUUgTkFNRTsgdGhpcyBjYW4gaGFwcGVuIGlmCgkgICAgKgkgc2NoZW1hdGEgYXJlICBpbXBvcnRlZAoJICAgICogMi4gdGhvc2UgY29tcGxleCB0eXBlcyBjb250YWluIGF0dHJpYnV0ZXMgd2l0aCBhbiBlcXVhbCBuYW1lCgkgICAgKiAzLiB0aG9zZSBhdHRyaWJ1dGVzIGFyZSBpbiBubyBuYW1lc3BhY2UKCSAgICAqIFdlIHdpbGwgY29tcHV0ZSBhIG5ldyBjb250ZXh0IHN0cmluZy4KCSAgICAqLwoJICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjYUNvbnQlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwKCQluYW1lc3BhY2UsIHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgYnVmLCAtMSksIHJldCk7CgoJICAgIGlmICh2YWwgIT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkQXR0cmlidXRlLCAiCgkJICAgICJhIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCQkgICAgImNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgaGFzaC4iLCBuYW1lKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5hdHRyZ3JwRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPQogICAgICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikKICAgICAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSBncm91cCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJncnBEZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX0FUVFJHUk9VUCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJBIGdsb2JhbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5IGV4aXN0IiwgbmFtZSk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIHR5cGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEVsZW1lbnQgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFBZGRFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSwKCQkgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgZWxlbWVudCAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmVsZW1EZWNsID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgZWxlbWVudCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CglpZiAodG9wTGV2ZWwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX0VMRU1FTlQsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiQSBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyAiCgkJImFscmVhZHkgZXhpc3QiLCBuYW1lKTsKICAgICAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICBjaGFyIGJ1ZlszMF07CgoJICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjZUNvbnQlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwKCQluYW1lc3BhY2UsICh4bWxDaGFyICopIGJ1ZiwgcmV0KTsKCSAgICBpZiAodmFsICE9IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEVsZW1lbnQsICIKCQkgICAgImEgZHVibGljYXRlIGVsZW1lbnQgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCQkgICAgImNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgaGFzaC4iLCBuYW1lKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9Cgl9CgogICAgfQogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgaXRlbQogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUFkZFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbnNOYW1lLAoJCSB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT50eXBlRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hVHlwZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIHR5cGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcmV0LT5yZWRlZiA9IE5VTEw7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+dHlwZURlY2wsIG5hbWUsIG5zTmFtZSwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJaWYgKCEgY3R4dC0+aXNSZWRlZmluZSkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgaWYgKHRvcExldmVsKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfVFlQRSwKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCQkgICAgIkEgZ2xvYmFsIHR5cGUgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyAiCgkJICAgICJhbHJlYWR5IGV4aXN0IiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgbnNOYW1lLCBuYW1lKSk7CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLCAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZFR5cGUsICIKCQkgICAgImxvY2FsIHR5cGUgJyVzJyBoYXMgYSBkdXBsaWNhdGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBuc05hbWUsIG5hbWUpKTsKCSAgICB9CgkgICAgeG1sRnJlZShyZXQpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIHByZXY7CgoJICAgIC8qCgkgICAgKiBSRURFRklORTogQWRkIGEgcmVkZWZpbml0aW9uLgoJICAgICovCgkgICAgVE9ETwoJICAgIHByZXYgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuc05hbWUpOwoJICAgIGlmIChwcmV2ID09IE5VTEwpIHsKCQlQRVJST1JfSU5UMigieG1sU2NoZW1hQWRkVHlwZSIsICJoYXNoIGxpc3QgZGlkbid0IHJldHVybiAiCgkJICAgICJhIHR5cGUgY29tcG9uZW50LCBidXQgc2hvdWxkIik7CgkJeG1sRnJlZShyZXQpOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIHJldC0+cmVkZWYgPSBwcmV2LT5yZWRlZjsKCSAgICBwcmV2LT5yZWRlZiA9IHJldDsKCX0KICAgIH0KICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CiAgICByZXQtPmF0dHJpYnV0ZVVzZXMgPSBOVUxMOwogICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IE5VTEw7CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCxyZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgeG1sU2NoZW1hUU5hbWVSZWZQdHIKeG1sU2NoZW1hTmV3UU5hbWVSZWYoeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkgICAgIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJICAgICBjb25zdCB4bWxDaGFyICpyZWZOYW1lLAoJCSAgICAgY29uc3QgeG1sQ2hhciAqcmVmTnMpCnsKICAgIHhtbFNjaGVtYVFOYW1lUmVmUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVFOYW1lUmVmKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgUU5hbWUgcmVmZXJlbmNlIGl0ZW0iLAoJICAgIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRVhUUkFfUU5BTUVSRUY7CiAgICByZXQtPm5hbWUgPSByZWZOYW1lOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSByZWZOczsKICAgIHJldC0+aXRlbSA9IE5VTEw7CiAgICByZXQtPml0ZW1UeXBlID0gcmVmVHlwZTsKICAgIC8qCiAgICAqIFN0b3JlIHRoZSByZWZlcmVuY2UgaXRlbSBpbiB0aGUgc2NoZW1hLgogICAgKi8KICAgIHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE1vZGVsR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQHR5cGU6IHRoZSAiY29tcG9zaXRvciIgdHlwZSBvZiB0aGUgbW9kZWwgZ3JvdXAKICogQGNvbnRhaW5lcjogIHRoZSBpbnRlcm5hbCBjb21wb25lbnQgbmFtZQogKiBAbm9kZTogdGhlIG5vZGUgaW4gdGhlIHNjaGVtYSBkb2MKICoKICogQWRkcyBhIHNjaGVtYSBtb2RlbCBncm91cAogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyCnhtbFNjaGVtYUFkZE1vZGVsR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLCBjb25zdCB4bWxDaGFyICoqY29udGFpbmVyLAoJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgcmV0ID0gTlVMTDsKICAgIHhtbENoYXIgYnVmWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBtb2RlbCBncm91cCBjb21wb25lbnRcbiIpOwojZW5kaWYKICAgIHJldCA9ICh4bWxTY2hlbWFNb2RlbEdyb3VwUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgbW9kZWwgZ3JvdXAgY29tcG9uZW50IiwKCSAgICBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5hbm5vdCA9IE5VTEw7CiAgICByZXQtPm5vZGUgPSBub2RlOwogICAgcmV0LT5jaGlsZHJlbiA9IE5VTEw7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB7CglpZiAoY29udGFpbmVyICE9IE5VTEwpCgkgICAgc25wcmludGYoKGNoYXIgKikgYnVmLCAyOSwgIiNzZXElZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgfSBlbHNlIGlmICh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWlmIChjb250YWluZXIgIT0gTlVMTCkKCSAgICBzbnByaW50ZigoY2hhciAqKSBidWYsIDI5LCAiI2NobyVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB9IGVsc2UgewoJaWYgKGNvbnRhaW5lciAhPSBOVUxMKQoJICAgIHNucHJpbnRmKChjaGFyICopIGJ1ZiwgMjksICIjYWxsJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIH0KICAgIGlmIChjb250YWluZXIgIT0gTlVMTCkKCSpjb250YWluZXIgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUIGJ1ZiwgLTEpOwogICAgLyoKICAgICogQWRkIHRvIHZvbGF0aWxlIGl0ZW1zLgogICAgKiBUT0RPOiB0aGlzIHNob3VsZCBiZSBjaGFuZ2VkIHNvbWVkYXkuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KSAhPSAwKSB7Cgl4bWxGcmVlKHJldCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUFkZFBhcnRpY2xlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiB0aGUgY29ycmVzcG9uZGluZyBub2RlIGluIHRoZSBzY2hlbWEgZG9jCiAqIEBtaW46IHRoZSBtaW5PY2N1cnMKICogQG1heDogdGhlIG1heE9jY3VycwogKgogKiBBZGRzIGFuIFhNTCBzY2hlbWEgcGFydGljbGUgY29tcG9uZW50LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJ0aWNsZVB0cgp4bWxTY2hlbWFBZGRQYXJ0aWNsZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCBtaW4sIGludCBtYXgpCnsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHJldCA9IE5VTEw7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBwYXJ0aWNsZSBjb21wb25lbnRcbiIpOwojZW5kaWYKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFydGljbGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBwYXJ0aWNsZSBjb21wb25lbnQiLAoJICAgIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRTsKICAgIHJldC0+YW5ub3QgPSBOVUxMOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIHJldC0+bWluT2NjdXJzID0gbWluOwogICAgcmV0LT5tYXhPY2N1cnMgPSBtYXg7CiAgICByZXQtPm5leHQgPSBOVUxMOwogICAgcmV0LT5jaGlsZHJlbiA9IE5VTEw7CgogICAgaWYgKHhtbFNjaGVtYUFkZFZvbGF0aWxlKHNjaGVtYSwgKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcmV0KSAhPSAwKSB7Cgl4bWxGcmVlKHJldCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGdyb3VwIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cgp4bWxTY2hlbWFBZGRHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUsCgkJICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmdyb3VwRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTW9kZWxHcm91cERlZikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDsKICAgIHJldC0+bm9kZSA9IG5vZGU7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IG5hbWVzcGFjZU5hbWU7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+Z3JvdXBEZWNsLCByZXQtPm5hbWUsIG5hbWVzcGFjZU5hbWUsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfR1JPVVAsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiQSBnbG9iYWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5ICIKCSAgICAiZXhpc3QiLCBuYW1lKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1dpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyCnhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIpCgl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkTnMpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogYSBzY2hlbWEKICoKICogQWRkcyBhIHdpbGRjYXJkLgogKiBJdCBjb3JyZXNwb25kcyB0byBhIHhzZDphbnlBdHRyaWJ1dGUgYW5kIHhzZDphbnkuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFBZGRXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJICAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgd2lsZGNhcmQgY29tcG9uZW50XG4iKTsKI2VuZGlmCgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgd2lsZGNhcmQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVdpbGRjYXJkKSk7CiAgICByZXQtPnR5cGUgPSB0eXBlOwogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwoKICAgIGlmICh4bWxTY2hlbWFBZGRWb2xhdGlsZShzY2hlbWEsICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHJldCkgIT0gMCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiRmFpbGVkIHRvIGFkZCBhIHdpbGRjYXJkIGNvbXBvbmVudCB0byB0aGUgbGlzdCIsIE5VTEwpOwoJeG1sRnJlZShyZXQpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqCQlVdGlsaXRpZXMgZm9yIHBhcnNpbmcJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAKLyoqCiAqIHhtbEdldFFOYW1lUHJvcDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHJlc3VsdCBuYW1lc3BhY2UgaWYgYW55CiAqCiAqIEV4dHJhY3QgYSBRTmFtZSBBdHRyaWJ1dGUgdmFsdWUKICoKICogUmV0dXJucyB0aGUgTkNOYW1lIG9yIE5VTEwgaWYgbm90IGZvdW5kLCBhbmQgYWxzbyB1cGRhdGUgQG5hbWVzcGFjZQogKiAgICB3aXRoIHRoZSBuYW1lc3BhY2UgVVJJCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbEdldFFOYW1lUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICB4bWxOc1B0ciBuczsKICAgIGNvbnN0IHhtbENoYXIgKnJldCwgKnByZWZpeDsKICAgIGludCBsZW47CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWwsICc6JykpIHsKCW5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCAwKTsKCWlmIChucykgewoJICAgICpuYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zLT5ocmVmLCAtMSk7CgkgICAgcmV0dXJuICh2YWwpOwoJfQogICAgfQogICAgcmV0ID0geG1sU3BsaXRRTmFtZTModmFsLCAmbGVuKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAodmFsKTsKICAgIH0KICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgcmV0LCAtMSk7CiAgICBwcmVmaXggPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgbGVuKTsKCiAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKICAgIGlmIChucyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIE5VTEwsIHZhbCwKCSAgICAiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlICIKCSAgICAiZGVjbGFyYXRpb24gaW4gc2NvcGUiLCB2YWwsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgcGFyZW50IGFzIGEgc2NoZW1hIG9iamVjdAogKiBAdmFsdWU6ICB0aGUgUU5hbWUgdmFsdWUKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgdGhlIGxvY2FsIG5hbWUgYW5kIHRoZSBVUkkgb2YgYSBRTmFtZSB2YWx1ZSBhbmQgdmFsaWRhdGVzIGl0LgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9uIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdAogKiBzaG91bGQgcmVzb2x2ZSB0byBzY2hlbWEgY29tcG9uZW50cy4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICAgIHhtbENoYXIgKipvd25lckRlcyBBVFRSSUJVVEVfVU5VU0VELAoJCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKipsb2NhbCkKewogICAgY29uc3QgeG1sQ2hhciAqcHJlZjsKICAgIHhtbE5zUHRyIG5zOwogICAgaW50IGxlbiwgcmV0OwoKICAgICp1cmkgPSBOVUxMOwogICAgKmxvY2FsID0gTlVMTDsKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA+IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCSAgICBOVUxMLCB2YWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkqbG9jYWwgPSB2YWx1ZTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSBpZiAocmV0IDwgMCkKCXJldHVybiAoLTEpOwoKICAgIGlmICghc3RyY2hyKChjaGFyICopIHZhbHVlLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCBOVUxMKTsKCWlmIChucykKCSAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+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+bm9kZSA9IG5vZGU7CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0pOwogICAgLyoKICAgICogVGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHBhcmVudCBlbGVtZW50IGRlY2xhcmF0aW9uLgogICAgKi8KICAgIGl0ZW0tPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sCglub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGlmIChpZGNDYXRlZ29yeSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJLyoKCSogQXR0cmlidXRlICJyZWZlciIgKG1hbmRhdG9yeSkuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWZlciIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJTlVMTCwgbm9kZSwKCQkicmVmZXIiLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIENyZWF0ZSBhIHJlZmVyZW5jZSBpdGVtLgoJICAgICovCgkgICAgaXRlbS0+cmVmID0geG1sU2NoZW1hTmV3UU5hbWVSZWYoc2NoZW1hLCBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSwKCQlOVUxMLCBOVUxMKTsKCSAgICBpZiAoaXRlbS0+cmVmID09IE5VTEwpCgkJcmV0dXJuIChOVUxMKTsKCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkJTlVMTCwgTlVMTCwgYXR0ciwKCQkmKGl0ZW0tPnJlZi0+dGFyZ2V0TmFtZXNwYWNlKSwKCQkmKGl0ZW0tPnJlZi0+bmFtZSkpOwoJICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwKCQkoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBpdGVtLAoJCWl0ZW0tPnJlZi0+dGFyZ2V0TmFtZXNwYWNlKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CglpdGVtLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfRUxFTV9NSVNTSU5HLAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJCSJBIGNoaWxkIGVsZW1lbnQgaXMgbWlzc2luZyIsCgkJIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwogICAgfQogICAgLyoKICAgICogQ2hpbGQgZWxlbWVudCA8c2VsZWN0b3I+LgogICAgKi8KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZWxlY3RvciIpKSB7CglpdGVtLT5zZWxlY3RvciA9IHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZChjdHh0LCBzY2hlbWEsCgkgICAgaXRlbSwgY2hpbGQsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKCS8qCgkqIENoaWxkIGVsZW1lbnRzIDxmaWVsZD4uCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImZpZWxkIikpIHsKCSAgICBkbyB7CgkJZmllbGQgPSB4bWxTY2hlbWFQYXJzZUlEQ1NlbGVjdG9yQW5kRmllbGQoY3R4dCwgc2NoZW1hLAoJCSAgICBpdGVtLCBjaGlsZCwgMSk7CgkJaWYgKGZpZWxkICE9IE5VTEwpIHsKCQkgICAgZmllbGQtPmluZGV4ID0gaXRlbS0+bmJGaWVsZHM7CgkJICAgIGl0ZW0tPm5iRmllbGRzKys7CgkJICAgIGlmIChsYXN0RmllbGQgIT0gTlVMTCkKCQkJbGFzdEZpZWxkLT5uZXh0ID0gZmllbGQ7CgkJICAgIGVsc2UKCQkJaXRlbS0+ZmllbGRzID0gZmllbGQ7CgkJICAgIGxhc3RGaWVsZCA9IGZpZWxkOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIH0gd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImZpZWxkIikpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJCU5VTEwsICIoYW5ub3RhdGlvbj8sIChzZWxlY3RvciwgZmllbGQrKSkiKTsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChzZWxlY3RvciwgZmllbGQrKSkiKTsKICAgIH0KCiAgICByZXR1cm4gKGl0ZW0pOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqIEB0b3BMZXZlbDogaW5kaWNhdGVzIGlmIHRoaXMgaXMgZ2xvYmFsIGRlY2xhcmF0aW9uCiAqCiAqIFBhcnNlcyBhIFhNTCBzY2hlbWEgZWxlbWVudCBkZWNsYXJhdGlvbi4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIG9yIGEgcGFydGljbGU7IE5VTEwgaW4gY2FzZQogKiBvZiBhbiBlcnJvciBvciBpZiB0aGUgcGFydGljbGUgaGFzIG1pbk9jY3Vycz09bWF4T2NjdXJzPT0wLgogKi8Kc3RhdGljIHhtbFNjaGVtYUJhc2ljSXRlbVB0cgp4bWxTY2hlbWFQYXJzZUVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCA9IE5VTEw7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CiAgICBpbnQgbWluLCBtYXgsIGlzUmVmID0gMDsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgLyogMy4zLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBFbGVtZW50IERlY2xhcmF0aW9ucyAqLwogICAgLyogVE9ETzogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgMy4zLjYgKi8KCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogSWYgd2UgZ2V0IGEgInJlZiIgYXR0cmlidXRlIG9uIGEgbG9jYWwgPGVsZW1lbnQ+IHdlIHdpbGwgYXNzdW1lIGl0J3MKICAgICogYSByZWZlcmVuY2UgLSBldmVuIGlmIHRoZXJlJ3MgYSAibmFtZSIgYXR0cmlidXRlOyB0aGlzIHNlZW1zIHRvIGJlIG1vcmUKICAgICogcm9idXN0LgogICAgKi8KICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZQoJaXNSZWYgPSAxOwoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgLyoKICAgICogU2tpcCBwYXJ0aWNsZSBwYXJ0IGlmIGEgZ2xvYmFsIGRlY2xhcmF0aW9uLgogICAgKi8KICAgIGlmICh0b3BMZXZlbCkKCWdvdG8gZGVjbGFyYXRpb25fcGFydDsKICAgIC8qCiAgICAqIFRoZSBwYXJ0aWNsZSBwYXJ0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAqLwogICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAiKHhzOm5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIHhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIE5VTEwsIG5vZGUsIG1pbiwgbWF4KTsKICAgIHBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUoY3R4dCwgc2NoZW1hLCBub2RlLCBtaW4sIG1heCk7CiAgICBpZiAocGFydGljbGUgPT0gTlVMTCkKCWdvdG8gcmV0dXJuX251bGw7CgogICAgLyogcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1JFRjsgKi8KCiAgICBpZiAoaXNSZWYpIHsKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEw7Cgl4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWZlciA9IE5VTEw7CgkvKgoJKiBUaGUgcmVmZXJlbmNlIHBhcnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgkqLwoJeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgIE5VTEwsIE5VTEwsIGF0dHIsICZyZWZOcywgJnJlZik7Cgl4bWxTY2hlbWFDaGVja1JlZmVyZW5jZShjdHh0LCBzY2hlbWEsIG5vZGUsIE5VTEwsIHJlZk5zKTsKCS8qCgkqIFNQRUMgKDMuMy4zIDogMi4xKSAiT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIgoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8xLAoJCU5VTEwsIE5VTEwsIG5hbWVBdHRyLCAicmVmIiwgIm5hbWUiKTsKCX0KCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkKCQl7CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICAvKiBTUEVDICgzLjMuMyA6IDIuMikgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8yLAoJCQlOVUxMLCBOVUxMLCBhdHRyLAoJCQkiT25seSB0aGUgYXR0cmlidXRlcyAnbWluT2NjdXJzJywgJ21heE9jY3VycycgYW5kICIKCQkJIidpZCcgYXJlIGFsbG93ZWQgaW4gYWRkaXRpb24gdG8gJ3JlZiciKTsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQoJLyoKCSogTm8gY2hpbGRyZW4gZXhjZXB0IDxhbm5vdGF0aW9uPiBleHBlY3RlZC4KCSovCglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/KSIpOwoJfQoJaWYgKChtaW4gPT0gMCkgJiYgKG1heCA9PSAwKSkKCSAgICBnb3RvIHJldHVybl9udWxsOwoJLyoKCSogQ3JlYXRlIHRoZSByZWZlcmVuY2UgaXRlbS4KCSovCglyZWZlciA9IHhtbFNjaGVtYU5ld1FOYW1lUmVmKHNjaGVtYSwgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQsCgkgICAgcmVmLCByZWZOcyk7CglpZiAocmVmZXIgPT0gTlVMTCkKCSAgICBnb3RvIHJldHVybl9udWxsOwoJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSByZWZlcjsKCXBhcnRpY2xlLT5hbm5vdCA9IGFubm90OwoJLyoKCSogQWRkIHRvIGFzc2VtYmxlZCBpdGVtczsgdGhlIHJlZmVyZW5jZSBuZWVkIHRvIGJlIHJlc29sdmVkLgoJKi8KCWlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHBhcnRpY2xlKTsKCglyZXR1cm4gKCh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHBhcnRpY2xlKTsKICAgIH0KICAgIC8qCiAgICAqIFRoZSBkZWNsYXJhdGlvbiBwYXJ0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAqLwpkZWNsYXJhdGlvbl9wYXJ0OgogICAgewoJY29uc3QgeG1sQ2hhciAqbnMgPSBOVUxMLCAqZml4ZWQsICpuYW1lLCAqb2xkY29udGFpbmVyLCAqYXR0clZhbHVlOwoJeG1sU2NoZW1hSURDUHRyIGN1cklEQyA9IE5VTEwsIGxhc3RJREMgPSBOVUxMOwoKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgTlVMTCwgbmFtZUF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApCgkgICAgZ290byByZXR1cm5fbnVsbDsKCS8qCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KCWlmICh0b3BMZXZlbCkgewoJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgewoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZm9ybSIpOwoJICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAidW5xdWFsaWZpZWQiKSkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkJTlVMTCwgIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfQoJZGVjbCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgc2NoZW1hLCBuYW1lLCBucywgbm9kZSwgdG9wTGV2ZWwpOwoJaWYgKGRlY2wgPT0gTlVMTCkgewoJICAgIGdvdG8gcmV0dXJuX251bGw7Cgl9CglkZWNsLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ7CglkZWNsLT5ub2RlID0gbm9kZTsKCWRlY2wtPnRhcmdldE5hbWVzcGFjZSA9IG5zOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWxsYWJsZSIpKSkKCQl7CgkJICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CgkJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSkKCQkJewoJCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBhdHRyKTsKCQkJfQoJCSAgICB9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpICYmCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpICYmCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInN1YnN0aXR1dGlvbkdyb3VwIikpKSB7CgoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIGF0dHIpOwoJCSAgICB9CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgkvKgoJKiBFeHRyYWN0L3ZhbGlkYXRlIGF0dHJpYnV0ZXMuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgdG9wIGF0dHJpYnV0ZXMgb2YgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGhlcmUuCgkgICAgKi8KCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTDsKCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1RPUExFVkVMOwoJICAgIHhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCBOVUxMLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBub2RlLCAic3Vic3RpdHV0aW9uR3JvdXAiLAoJCSYoZGVjbC0+c3Vic3RHcm91cE5zKSwgJihkZWNsLT5zdWJzdEdyb3VwKSk7CgkgICAgaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLAoJCW5vZGUsICJhYnN0cmFjdCIsIDApKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1Q7CgkgICAgLyoKCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJICAgICovCgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbCIpOwoJICAgIGlmIChhdHRyID09IE5VTEwpIHsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OKQoJCSAgICBkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTjsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT047CgkgICAgfSBlbHNlIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYoZGVjbC0+ZmxhZ3MpLAoJCSAgICAtMSwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9FWFRFTlNJT04sCgkJICAgIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04sIC0xLCAtMSwgLTEpICE9IDApIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQlOVUxMLCAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpIiwKCQkJYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9CgkgICAgfQoJfQoJLyoKCSogQXR0cmlidXRlICJibG9jayIuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJibG9jayIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBBcHBseSBkZWZhdWx0ICJibG9jayIgdmFsdWVzLgoJICAgICovCgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1JFU1RSSUNUSU9OKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT047CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTikKCQlkZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTjsKCSAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OKQoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OOwoJfSBlbHNlIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYoZGVjbC0+ZmxhZ3MpLAoJCS0xLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04sCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT04sIC0xLCAtMSkgIT0gMCkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJICAgICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgIgoJCSAgICAicmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSIsIGF0dHJWYWx1ZSwKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQoJaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLAoJICAgIG5vZGUsICJuaWxsYWJsZSIsIDApKQoJICAgIGRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEU7CgoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ0eXBlIik7CglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBkZWNsLCBhdHRyLAoJCSYoZGVjbC0+bmFtZWRUeXBlTnMpLCAmKGRlY2wtPm5hbWVkVHlwZSkpOwoJICAgIHhtbFNjaGVtYUNoZWNrUmVmZXJlbmNlKGN0eHQsIHNjaGVtYSwgbm9kZSwKCSAgICAoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBkZWNsLCBkZWNsLT5uYW1lZFR5cGVOcyk7Cgl9CglkZWNsLT52YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImRlZmF1bHQiKTsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZml4ZWQiKTsKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICBmaXhlZCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAoZGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJCS8qCgkJKiAzLjMuMyA6IDEKCQkqIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4KCQkqLwoJCXhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8xLAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgYXR0ciwKCQkgICAgImRlZmF1bHQiLCAiZml4ZWQiKTsKCSAgICB9IGVsc2UgewoJCWRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQ7CgkJZGVjbC0+dmFsdWUgPSBmaXhlZDsKCSAgICB9Cgl9CgkvKgoJKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KCSovCglvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CgljdHh0LT5jb250YWluZXIgPSBkZWNsLT5uYW1lOwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhUeXBlIikpIHsKCSAgICAvKgoJICAgICogMy4zLjMgOiAzCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkKCSAgICAqIGV4Y2x1c2l2ZQoJICAgICovCgkgICAgaWYgKGRlY2wtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIG5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8Y29tcGxleFR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCSAgICB9IGVsc2UKCQlFTEVNX1RZUEUoZGVjbCkgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIC8qCgkgICAgKiAzLjMuMyA6IDMKCSAgICAqICJ0eXBlIiBhbmQgZWl0aGVyIDxzaW1wbGVUeXBlPiBvciA8Y29tcGxleFR5cGU+IGFyZQoJICAgICogbXV0dWFsbHkgZXhjbHVzaXZlCgkgICAgKi8KCSAgICBpZiAoZGVjbC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8zLAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZGVjbCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlCgkJRUxFTV9UWVBFKGRlY2wpID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9Cgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgfHwgKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSkgewoJICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJ1bmlxdWUiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFLCBkZWNsLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHsKCQljdXJJREMgPSB4bWxTY2hlbWFQYXJzZUlEQyhjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSwgZGVjbC0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSB7CgkJY3VySURDID0geG1sU2NoZW1hUGFyc2VJREMoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYsIGRlY2wtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfQoJICAgIGlmIChsYXN0SURDICE9IE5VTEwpCgkJbGFzdElEQy0+bmV4dCA9IGN1cklEQzsKCSAgICBlbHNlCgkJZGVjbC0+aWRjcyA9ICh2b2lkICopIGN1cklEQzsKCSAgICBsYXN0SURDID0gY3VySURDOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wsIG5vZGUsIGNoaWxkLAoJCU5VTEwsICIoYW5ub3RhdGlvbj8sICgoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlKT8sICIKCQkiKHVuaXF1ZSB8IGtleSB8IGtleXJlZikqKSkiKTsKCX0KCWN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKCWRlY2wtPmFubm90ID0gYW5ub3Q7CiAgICB9CiAgICAvKgogICAgKiBOT1RFOiBFbGVtZW50IERlY2xhcmF0aW9uIFJlcHJlc2VudGF0aW9uIE9LIDQuIHdpbGwgYmUgY2hlY2tlZCBhdCBhCiAgICAqIGRpZmZlcmVudCBsYXllci4KICAgICovCiAgICBGUkVFX0FORF9OVUxMKGRlcykKICAgIGlmICh0b3BMZXZlbCkKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgZGVjbCk7CiAgICBlbHNlIHsKCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgZGVjbDsKCXJldHVybiAoKHhtbFNjaGVtYUJhc2ljSXRlbVB0cikgcGFydGljbGUpOwogICAgfQoKcmV0dXJuX251bGw6CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBpZiAoYW5ub3QgIT0gTlVMTCkgewoJaWYgKHBhcnRpY2xlICE9IE5VTEwpCgkgICAgcGFydGljbGUtPmFubm90ID0gTlVMTDsKCWlmIChkZWNsICE9IE5VTEwpCgkgICAgZGVjbC0+YW5ub3QgPSBOVUxMOwoJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVVuaW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBVbmlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGludGVybmFsIGVycm9yLCAwIGluIGNhc2Ugb2Ygc3VjY2VzcyBhbmQgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VVbmlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciA9IE5VTEw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIC8qCiAgICAqIE1hcmsgdGhlIHNpbXBsZSB0eXBlIGFzIGJlaW5nIG9mIHZhcmlldHkgInVuaW9uIi4KICAgICovCiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CiAgICAvKgogICAgKiBTUEVDIChCYXNlIHR5cGUpICgyKSAiSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKICAgICogdGhlbiB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LiIKICAgICovCiAgICB0eXBlLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWVtYmVyVHlwZXMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlICJtZW1iZXJUeXBlcyIuIFRoaXMgaXMgYSBsaXN0IG9mIFFOYW1lcy4KICAgICogVE9ETzogQ2hlY2sgdGhlIHZhbHVlIHRvIGNvbnRhaW4gYW55dGhpbmcuCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtZW1iZXJUeXBlcyIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJY29uc3QgeG1sQ2hhciAqZW5kOwoJeG1sQ2hhciAqdG1wOwoJY29uc3QgeG1sQ2hhciAqbG9jYWxOYW1lLCAqbnNOYW1lOwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaywgbGFzdExpbmsgPSBOVUxMOwoJeG1sU2NoZW1hUU5hbWVSZWZQdHIgcmVmOwoKCWN1ciA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCXR5cGUtPnJlZiA9IGN1cjsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKGN0eHQsIHNjaGVtYSwgTlVMTCwKCQlOVUxMLCBhdHRyLCBCQURfQ0FTVCB0bXAsICZuc05hbWUsICZsb2NhbE5hbWUpID09IDApIHsKCQkvKgoJCSogQ3JlYXRlIHRoZSBtZW1iZXIgdHlwZSBsaW5rLgoJCSovCgkJbGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJCWlmIChsaW5rID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAieG1sU2NoZW1hUGFyc2VVbmlvbiwgIgoJCQkiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJbGluay0+dHlwZSA9IE5VTEw7CgkJbGluay0+bmV4dCA9IE5VTEw7CgkJaWYgKGxhc3RMaW5rID09IE5VTEwpCgkJICAgIHR5cGUtPm1lbWJlclR5cGVzID0gbGluazsKCQllbHNlCgkJICAgIGxhc3RMaW5rLT5uZXh0ID0gbGluazsKCQlsYXN0TGluayA9IGxpbms7CgkJLyoKCQkqIENyZWF0ZSBhIHJlZmVyZW5jZSBpdGVtLgoJCSovCgkJcmVmID0geG1sU2NoZW1hTmV3UU5hbWVSZWYoc2NoZW1hLCBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLAoJCSAgICBsb2NhbE5hbWUsIG5zTmFtZSk7CgkJaWYgKHJlZiA9PSBOVUxMKSB7CgkJICAgIEZSRUVfQU5EX05VTEwodG1wKQoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJLyoKCQkqIEFzc2lnbiB0aGUgcmVmZXJlbmNlIHRvIHRoZSBsaW5rLCBpdCB3aWxsIGJlIHJlc29sdmVkCgkJKiBsYXRlciBkdXJpbmcgZml4dXAgb2YgdGhlIHVuaW9uIHNpbXBsZSB0eXBlLgoJCSovCgkJbGluay0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSByZWY7CgkgICAgfQoJICAgIEZSRUVfQU5EX05VTEwodG1wKQoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CgogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCS8qCgkqIEFkZCB0aGUgYW5ub3RhdGlvbiB0byB0aGUgc2ltcGxlIHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCXhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZSwgbGFzdCA9IE5VTEw7CgoJLyoKCSogQW5jaG9yIHRoZSBtZW1iZXIgdHlwZXMgaW4gdGhlICJzdWJ0eXBlcyIgZmllbGQgb2YgdGhlCgkqIHNpbXBsZSB0eXBlLgoJKi8KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKCQlpZiAobGFzdCA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCQkgICAgbGFzdCA9IHN1YnR5cGU7CgkJfSBlbHNlIHsKCQkgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CgkJICAgIGxhc3QgPSBzdWJ0eXBlOwoJCX0KCQlsYXN0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlKikiKTsKICAgIH0KICAgIGlmICgoYXR0ciA9PSBOVUxMKSAmJiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkpIHsKCSAvKgoJKiBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMKCSogRWl0aGVyIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBvZiB0aGUgPHVuaW9uPiBlbGVtZW50IG11c3QKCSogYmUgbm9uLWVtcHR5IG9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIHNpbXBsZVR5cGUgW2NoaWxkXS4KCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1VOSU9OX01FTUJFUlRZUEVTX09SX1NJTVBMRVRZUEVTLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdtZW1iZXJUeXBlcycgb3IgIgoJICAgICJhdCBsZWFzdCBvbmUgPHNpbXBsZVR5cGU+IGNoaWxkIG11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTGlzdDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgTGlzdCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIC8qCiAgICAqIE1hcmsgdGhlIHR5cGUgYXMgYmVpbmcgb2YgdmFyaWV0eSAibGlzdCIuCiAgICAqLwogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CiAgICAvKgogICAgKiBTUEVDIChCYXNlIHR5cGUpICgyKSAiSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwKICAgICogdGhlbiB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LiIKICAgICovCiAgICB0eXBlLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaXRlbVR5cGUiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgIml0ZW1UeXBlIi4gTk9URSB0aGF0IHdlIHdpbGwgdXNlIHRoZSAicmVmIiBhbmQgInJlZk5zIgogICAgKiBmaWVsZHMgZm9yIGhvbGRpbmcgdGhlIHJlZmVyZW5jZSB0byB0aGUgaXRlbVR5cGUuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIE5VTEwsCglub2RlLCAiaXRlbVR5cGUiLCAmKHR5cGUtPnJlZk5zKSwgJih0eXBlLT5yZWYpKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7Cgl4bWxTY2hlbWFBZGRBbm5vdGF0aW9uKCh4bWxTY2hlbWFBbm5vdEl0ZW1QdHIpIHR5cGUsCgkgICAgeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJLyoKCSogc3JjLWxpc3QtaXRlbVR5cGUtb3Itc2ltcGxlVHlwZQoJKiBFaXRoZXIgdGhlIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIHRoZSA8c2ltcGxlVHlwZT4gW2NoaWxkXSBvZgoJKiB0aGUgPGxpc3Q+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguCgkqLwoJaWYgKHR5cGUtPnJlZiAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJImFyZSBtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7Cgl9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAodHlwZS0+cmVmID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJFaXRoZXIgdGhlIGF0dHJpYnV0ZSAnaXRlbVR5cGUnIG9yIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJICAgICJtdXN0IGJlIHByZXNlbnQiLCBOVUxMKTsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlPykiKTsKICAgIH0KICAgIGlmICgodHlwZS0+cmVmID09IE5VTEwpICYmCgkodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCSh4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiaXRlbVR5cGUiKSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdpdGVtVHlwZScgb3IgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgIm11c3QgYmUgcHJlc2VudCIsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlIFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIG9sZEN0eHRUeXBlLCBvbGRQYXJlbnRJdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICphdHRyVmFsdWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IGhhc1Jlc3RyaWN0aW9uID0gMDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmICh0b3BMZXZlbCkgewoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LAoJCU5VTEwsIE5VTEwsIGF0dHIsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJmF0dHJWYWx1ZSkgIT0gMCkKCQlyZXR1cm4gKE5VTEwpOwoJICAgIC8qCgkgICAgKiBTa2lwIGJ1aWx0LWluIHR5cGVzLgoJICAgICovCgkgICAgaWYgKGN0eHQtPmlzUzRTKSB7CgkJeG1sU2NoZW1hVHlwZVB0ciBiaVR5cGU7CgoJCWlmIChjdHh0LT5pc1JlZGVmaW5lKSB7CgkJICAgIC8qCgkJICAgICogUkVERUZJTkU6IERpc2FsbG93IHJlZGVmaW5pdGlvbiBvZiBidWlsdC1pbi10eXBlcy4KCQkgICAgKiBUT0RPOiBJdCBzZWVtcyB0aGF0IHRoZSBzcGVjIGRvZXMgbm90IHNheSBhbnl0aGluZwoJCSAgICAqIGFib3V0IHRoaXMgY2FzZS4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVERUZJTkUsCgkJCU5VTEwsIE5VTEwsIG5vZGUsCgkJCSJSZWRlZmluaXRpb24gb2YgYnVpbHQtaW4gc2ltcGxlIHR5cGVzIGlzIG5vdCAiCgkJCSJzdXBwb3J0ZWQiLCBOVUxMKTsKCQkgICAgcmV0dXJuKE5VTEwpOwoJCX0KCQliaVR5cGUgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShhdHRyVmFsdWUsIHhtbFNjaGVtYU5zKTsKCQlpZiAoYmlUeXBlICE9IE5VTEwpCgkJICAgIHJldHVybiAoYmlUeXBlKTsKCSAgICB9Cgl9CiAgICB9CgogICAgaWYgKHRvcExldmVsID09IDApIHsKICAgICAgICBjaGFyIGJ1Zls0MF07CgoJLyoKCSogUGFyc2UgYXMgbG9jYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSovCiAgICAgICAgc25wcmludGYoYnVmLCAzOSwgIiNTVCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7Cgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIChjb25zdCB4bWxDaGFyICopYnVmLCBOVUxMLAoJICAgIG5vZGUsIDApOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRTsKCXR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJTlVMTCwgdHlwZSwgYXR0cik7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIHR5cGUsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSoKCSogTm90ZSB0aGF0IGF0dHJWYWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAibmFtZSIgaGVyZS4KCSovCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIGF0dHJWYWx1ZSwKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSwgMSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUw7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQlOVUxMLCB0eXBlLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgkvKgoJKiBBdHRyaWJ1dGUgImZpbmFsIi4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpbmFsIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT047CgkgICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1QpCgkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNUOwoJICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTikKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OOwoJfSBlbHNlIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaW5hbCIpOwoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwKCQktMSwgLTEsIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04sIC0xLAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVCwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSAhPSAwKSB7CgoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJICAgIHR5cGUsICh4bWxOb2RlUHRyKSBhdHRyLAoJCSAgICBOVUxMLCAiKCNhbGwgfCBMaXN0IG9mIChsaXN0IHwgdW5pb24gfCByZXN0cmljdGlvbikiLAoJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0KCX0KICAgIH0KICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCB0eXBlLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZEN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICBvbGRQYXJlbnRJdGVtID0gY3R4dC0+cGFyZW50SXRlbTsKICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiKTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewkKICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSk7CQoJaGFzUmVzdHJpY3Rpb24gPSAxOwkKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJsaXN0IikpIHsKICAgICAgICB4bWxTY2hlbWFQYXJzZUxpc3QoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAidW5pb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlVW5pb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIpOwogICAgfQogICAgLyoKICAgICogUkVERUZJTkU6IFNQRUMgc3JjLXJlZGVmaW5lICg1KQogICAgKiAiV2l0aGluIHRoZSBbY2hpbGRyZW5dLCBlYWNoIDxzaW1wbGVUeXBlPiBtdXN0IGhhdmUgYQogICAgKiA8cmVzdHJpY3Rpb24+IGFtb25nIGl0cyBbY2hpbGRyZW5dIC4uLiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2Ygd2hvc2UKICAgICogYmFzZSBbYXR0cmlidXRlXSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSC3YWN0dWFsIHZhbHVltyBvZiBpdHMgb3duCiAgICAqIG5hbWUgYXR0cmlidXRlIHBsdXMgdGFyZ2V0IG5hbWVzcGFjZTsiCiAgICAqLwogICAgaWYgKHRvcExldmVsICYmIGN0eHQtPmlzUmVkZWZpbmUgJiYgKCEgaGFzUmVzdHJpY3Rpb24pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCAiVGhpcyBpcyBhIHJlZGVmaW5pdGlvbiwgdGh1cyB0aGUgIgoJICAgICI8c2ltcGxlVHlwZT4gbXVzdCBoYXZlIGEgPHJlc3RyaWN0aW9uPiBjaGlsZCIsIE5VTEwpOwogICAgfQoKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBvbGRQYXJlbnRJdGVtOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBvbGRDdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWY6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2VzIGEgWE1MIHNjaGVtYSBwYXJ0aWNsZSAocmVmZXJlbmNlIHRvIGEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbikuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqcmVmID0gTlVMTCwgKnJlZk5zID0gTlVMTDsKICAgIGludCBtaW4sIG1heDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgInJlZiIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLCBOVUxMLCBOVUxMLAoJYXR0ciwgJnJlZk5zLCAmcmVmKSAhPSAwKSB7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWluID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAieHM6bm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLAoJIih4czpub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaXRlbSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKGN0eHQsIHNjaGVtYSwgbm9kZSwgbWluLCBtYXgpOwogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBDcmVhdGUgYSByZWZlcmVuY2UgaXRlbSBhcyB0aGUgdGVybTsgaXQgd2lsbCBiZSBzdWJzdGl0dXRlZCBmb3IKICAgICogdGhlIG1vZGVsIGdyb3VwIGFmdGVyIHRoZSByZWZlcmVuY2UgaGFzIGJlZW4gcmVzb2x2ZWQuCiAgICAqLwogICAgaXRlbS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgl4bWxTY2hlbWFOZXdRTmFtZVJlZihzY2hlbWEsIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCwgcmVmLCByZWZOcyk7CiAgICB4bWxTY2hlbWFDaGVja1JlZmVyZW5jZShjdHh0LCBzY2hlbWEsIG5vZGUsICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIGl0ZW0sIHJlZk5zKTsKICAgIHhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIGl0ZW0sIG5vZGUsIG1pbiwgbWF4KTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICAvKiBUT0RPOiBJcyBhbm5vdGF0aW9uIGV2ZW4gYWxsb3dlZCBmb3IgYSBtb2RlbCBncm91cCByZWZlcmVuY2U/ICovCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBUT0RPOiBXaGF0IHRvIGRvIGV4YWN0bHkgd2l0aCB0aGUgYW5ub3RhdGlvbj8KCSovCglpdGVtLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgLyoKICAgICogQ29ycmVzcG9uZHMgdG8gbm8gY29tcG9uZW50IGF0IGFsbCBpZiBtaW5PY2N1cnM9PW1heE9jY3Vycz09MC4KICAgICovCiAgICBpZiAoKG1pbiA9PSAwKSAmJiAobWF4ID09IDApKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSk7CiAgICByZXR1cm4gKCh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyBhIFhNTCBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIKeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwRGVmaW5pdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwKCSAgICAibmFtZSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsCglOVUxMLCBOVUxMLCBhdHRyLAoJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpdGVtID0geG1sU2NoZW1hQWRkR3JvdXAoY3R4dCwgc2NoZW1hLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCWl0ZW0tPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewoJaXRlbS0+Y2hpbGRyZW4gPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CglpdGVtLT5jaGlsZHJlbiA9IHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJaXRlbS0+Y2hpbGRyZW4gPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIDApOwoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8sIChhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSk/KSIpOwogICAgfQoKICAgIHJldHVybiAoaXRlbSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhbnVwRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSByb290IG9mIHRoZSBkb2N1bWVudC4KICoKICogcmVtb3ZlcyB1bndhbnRlZCBub2RlcyBpbiBhIHNjaGVtYXMgZG9jdW1lbnQgdHJlZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYW51cERvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgcm9vdCkKewogICAgeG1sTm9kZVB0ciBkZWxldGUsIGN1cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHJvb3QgPT0gTlVMTCkpIHJldHVybjsKCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICBkZWxldGUgPSBOVUxMOwogICAgY3VyID0gcm9vdDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgewogICAgICAgICAgICBpZiAoSVNfQkxBTktfTk9ERShjdXIpKSB7CiAgICAgICAgICAgICAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIGRlbGV0ZSA9IGN1cjsKICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBTa2lwIHRvIG5leHQgbm9kZQogICAgICAgICAqLwogICAgICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfUkVGX05PREUpICYmCiAgICAgICAgICAgICAgICAoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX05PREUpKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIHNraXBfY2hpbGRyZW46CiAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBkbyB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+cGFyZW50OwogICAgICAgICAgICBpZiAoY3VyID09IE5VTEwpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgaWYgKGN1ciA9PSByb290KSB7CiAgICAgICAgICAgICAgICBjdXIgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICB4bWxGcmVlTm9kZShkZWxldGUpOwogICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICB9Cn0KCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1QpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVDsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsKCiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqdmFsOwoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICBpZiAoc2NoZW1hLT52ZXJzaW9uID09IE5VTEwpCgl4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAidmVyc2lvbiIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfVE9LRU4pLCAmKHNjaGVtYS0+dmVyc2lvbikpOwogICAgZWxzZQoJeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgInZlcnNpb24iLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1RPS0VOKSwgTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJlbGVtZW50Rm9ybURlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0KHZhbCwgJnNjaGVtYS0+ZmxhZ3MsCgkgICAgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pICE9IDApIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0VMRU1GT1JNREVGQVVMVF9WQUxVRSwKCQlOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJhdHRyaWJ1dGVGb3JtRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQodmFsLCAmc2NoZW1hLT5mbGFncywKCSAgICBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQVRUUkZPUk1ERUZBVUxUX1ZBTFVFLAoJCU5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCSIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpbmFsRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbCh2YWwsICYoc2NoZW1hLT5mbGFncyksIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04sCgkgICAgLTEsCgkgICAgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNULAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT04pICE9IDApIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIsCgkJdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImJsb2NrRGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbCh2YWwsICYoc2NoZW1hLT5mbGFncyksIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04sCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04sIC0xLCAtMSkgIT0gMCkgewoJICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSIsCgkJdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcwogKiBAbm9kZXM6ICB0aGUgbGlzdCBvZiB0b3AgbGV2ZWwgbm9kZXMKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZXMpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZXMgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuOwoKICAgIGNoaWxkID0gbm9kZXM7CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJpbXBvcnQiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJyZWRlZmluZSIpKSB8fAoJICAgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUltcG9ydChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiaW5jbHVkZSIpKSB7CgkgICAgY3R4dC0+aW5jbHVkZXMrKzsKCSAgICB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY3R4dC0+aW5jbHVkZXMtLTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVkZWZpbmUiKSkgewojaWZkZWYgRU5BQkxFX1JFREVGSU5FCgkgICAgeG1sU2NoZW1hUGFyc2VSZWRlZmluZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKI2Vsc2UKCSAgICBUT0RPCiNlbmRpZgoJfQoJY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleFR5cGUiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZpbml0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgIm5vdGF0aW9uIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZU5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIE5VTEwsIGNoaWxkLAoJCQkgICBYTUxfU0NIRU1BUF9VTktOT1dOX1NDSEVNQVNfQ0hJTEQsCgkJCSAgICJVbmV4cGVjdGVkIGVsZW1lbnQgXCIlc1wiIGFzIGNoaWxkIG9mIDxzY2hlbWE+LlxuIiwKCQkJICAgY2hpbGQtPm5hbWUsIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9Cgl3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwp9CgpzdGF0aWMgeG1sU2NoZW1hSW1wb3J0UHRyCnhtbFNjaGVtYUFkZEltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgeG1sSGFzaFRhYmxlUHRyICppbXBvcnRzLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hSW1wb3J0UHRyIHJldDsKCiAgICBpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJKmltcG9ydHMgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CglpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9GQUlMRURfQlVJTERfSU1QT1JULAoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJIkludGVybmFsIGVycm9yOiBmYWlsZWQgdG8gYnVpbGQgdGhlIGltcG9ydCB0YWJsZSIsCgkJTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KICAgIHJldCA9ICh4bWxTY2hlbWFJbXBvcnQqKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGltcG9ydCBzdHJ1Y3QiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAobnNOYW1lID09IE5VTEwpCgluc05hbWUgPSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0U7CiAgICB4bWxIYXNoQWRkRW50cnkoKmltcG9ydHMsIG5zTmFtZSwgcmV0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCiNpZmRlZiBFTkFCTEVfUkVERUZJTkUKc3RhdGljIHhtbFNjaGVtYVNjaGVtYVJlZlB0cgp4bWxTY2hlbWFTY2hlbWFSZWZDcmVhdGUodm9pZCkKewogICAgeG1sU2NoZW1hU2NoZW1hUmVmUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hU2NoZW1hUmVmUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVNjaGVtYVJlZikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSByZWZlcmVuY2UiLCBOVUxMKTsKCXJldHVybihOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFTY2hlbWFSZWYpKTsKICAgIHJldHVybihyZXQpOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTY2hlbWFSZWZGcmVlKHhtbFNjaGVtYVNjaGVtYVJlZlB0ciByZWYpCnsKICAgIHhtbEZyZWUocmVmKTsKfQojZW5kaWYKCnN0YXRpYyB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYVBhcnNlckN0eHRDcmVhdGUodm9pZCkKewogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0NUWFRfUEFSU0VSOwogICAgcmV0LT5jb21wQ29udGFpbmVyID0geG1sU2NoZW1hQ29udGFpbmVyQ3JlYXRlKCk7CiAgICBpZiAocmV0LT5jb21wQ29udGFpbmVyID09IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHJldCk7CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICByZXR1cm4ocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoY29uc3QgY2hhciAqVVJMLCB4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlckN0eHRDcmVhdGUoKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgICAgICAgIAogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXQtPmRpY3QgPSBkaWN0OwogICAgeG1sRGljdFJlZmVyZW5jZShkaWN0KTsgICAgCiAgICBpZiAoVVJMICE9IE5VTEwpCglyZXQtPlVSTCA9IHhtbERpY3RMb29rdXAoZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKICAgICAgICBpZiAodmN0eHQtPnNjaGVtYSAhPSBOVUxMKQoJICAgIHZjdHh0LT5wY3R4dCA9IHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KCIqIiwgdmN0eHQtPnNjaGVtYS0+ZGljdCk7CgllbHNlCgkgICAgdmN0eHQtPnBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOwoJaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0IiwKCQkiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHBhcnNlciBjb250ZXh0Iik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh2Y3R4dC0+cGN0eHQsIHZjdHh0LT5lcnJvciwgdmN0eHQtPndhcm5pbmcsIE5VTEwpOwkKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYyh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIgYWN0eHQsCgkJCSAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCQkgIGNvbnN0IHhtbENoYXIgKmxvY2F0aW9uLAoJCQkgIHhtbERvY1B0ciAqZG9jLAoJCQkgIGNvbnN0IHhtbENoYXIgKip0YXJnZXROYW1lc3BhY2UsCgkJCSAgaW50IGFic29sdXRlKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgeG1sUGFyc2VyQ3R4dFB0ciBwYXJzZXJDdHh0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydDsKICAgIGNvbnN0IHhtbENoYXIgKm5zOwogICAgeG1sTm9kZVB0ciByb290OwoKICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgd2lsbCBiZSB1c2VkIGZvciA8aW1wb3J0PiwgPHhzaTpzY2hlbWFMb2NhdGlvbj4gYW5kCiAgICAqIDx4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj4uCiAgICAqLwogICAgKmRvYyA9IE5VTEw7CiAgICAvKgogICAgKiBHaXZlbiB0aGF0IHRoZSBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSBpcyBvbmx5IGEgaGludCwgaXQgaXMgb3BlbgogICAgKiB0byBhcHBsaWNhdGlvbnMgdG8gaWdub3JlIGFsbCBidXQgdGhlIGZpcnN0IDxpbXBvcnQ+IGZvciBhIGdpdmVuCiAgICAqIG5hbWVzcGFjZSwgcmVnYXJkbGVzcyBvZiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2Ygc2NoZW1hTG9jYXRpb24sIGJ1dAogICAgKiBzdWNoIGEgc3RyYXRlZ3kgcmlza3MgbWlzc2luZyB1c2VmdWwgaW5mb3JtYXRpb24gd2hlbiBuZXcKICAgICogc2NoZW1hTG9jYXRpb25zIGFyZSBvZmZlcmVkLgogICAgKgogICAgKiBYU1YgKHZlciAyLjUtMikgZG9lcyB1c2UgdGhlIGZpcnN0IDxpbXBvcnQ+IHdoaWNoIHJlc29sdmVzIHRvIGEgdmFsaWQgc2NoZW1hLgogICAgKiBYZXJjZXMtSiAodmVyIDIuNS4xKSBpZ25vcmVzIGFsbCBidXQgdGhlIGZpcnN0IGdpdmVuIDxpbXBvcnQ+IC0gcmVnYXJkbGVzcyBpZgogICAgKiB2YWxpZCBvciBub3QuCiAgICAqIFdlIHdpbGwgZm9sbG93IFhTViBoZXJlLgogICAgKi8KICAgIGlmIChsb2NhdGlvbiA9PSBOVUxMKSB7CgkvKgoJKiBTY2hlbWEgRG9jdW1lbnQgTG9jYXRpb24gU3RyYXRlZ3k6CgkqCgkqIDMgQmFzZWQgb24gdGhlIG5hbWVzcGFjZSBuYW1lLCBpZGVudGlmeSBhbiBleGlzdGluZyBzY2hlbWEgZG9jdW1lbnQsCgkqIGVpdGhlciBhcyBhIHJlc291cmNlIHdoaWNoIGlzIGFuIFhNTCBkb2N1bWVudCBvciBhIDxzY2hlbWE+IGVsZW1lbnQKCSogaW5mb3JtYXRpb24gaXRlbSwgaW4gc29tZSBsb2NhbCBzY2hlbWEgcmVwb3NpdG9yeTsKCSoKCSogNSBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIG5hbWVzcGFjZSBuYW1lIHRvIGxvY2F0ZSBzdWNoIGEgcmVzb3VyY2UuCgkqCgkqIE5PVEU6IFRob3NlIHN0YXRlZ2llcyBhcmUgbm90IHN1cHBvcnRlZCwgc28gd2Ugd2lsbCBza2lwLgoJKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAobnNOYW1lID09IE5VTEwpCglucyA9IFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRTsKICAgIGVsc2UKCW5zID0gbnNOYW1lOwoKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbnMpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CgkvKgoJKiBUaGVyZSB3YXMgYSB2YWxpZCByZXNvdXJjZSBmb3IgdGhlIHNwZWNpZmllZCBuYW1lc3BhY2UgYWxyZWFkeQoJKiBkZWZpbmVkLCBzbyBza2lwLgoJKiBUT0RPOiBUaGlzIG1pZ2h0IGJlIGNoYW5nZWQgc29tZWRheSB0byBhbGxvdyBpbXBvcnQgb2YKCSogY29tcG9uZW50cyBmcm9tIG11bHRpcGxlIGRvY3VtZW50cyBmb3IgYSBzaW5nbGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCglyZXR1cm4gKDApOwogICAgfQogICAgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpCglwY3R4dCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSBhY3R4dDsKICAgIGVsc2UgewoJeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0KTsKCXBjdHh0ID0gKCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGFjdHh0KS0+cGN0eHQ7CiAgICB9CiAgICAvKgogICAgKiBTY2hlbWEgRG9jdW1lbnQgTG9jYXRpb24gU3RyYXRlZ3k6CiAgICAqCiAgICAqIDIgQmFzZWQgb24gdGhlIGxvY2F0aW9uIFVSSSwgaWRlbnRpZnkgYW4gZXhpc3Rpbmcgc2NoZW1hIGRvY3VtZW50LAogICAgKiBlaXRoZXIgYXMgYSByZXNvdXJjZSB3aGljaCBpcyBhbiBYTUwgZG9jdW1lbnQgb3IgYSA8c2NoZW1hPiBlbGVtZW50CiAgICAqIGluZm9ybWF0aW9uIGl0ZW0sIGluIHNvbWUgbG9jYWwgc2NoZW1hIHJlcG9zaXRvcnk7CiAgICAqCiAgICAqIDQgQXR0ZW1wdCB0byByZXNvbHZlIHRoZSBsb2NhdGlvbiBVUkksIHRvIGxvY2F0ZSBhIHJlc291cmNlIG9uIHRoZQogICAgKiB3ZWIgd2hpY2ggaXMgb3IgY29udGFpbnMgb3IgcmVmZXJlbmNlcyBhIDxzY2hlbWE+IGVsZW1lbnQ7CiAgICAqIFRPRE86IEhtbSwgSSBkb24ndCBrbm93IGlmIHRoZSByZWZlcmVuY2Ugc3R1ZmYgaW4gNC4gd2lsbCB3b3JrLgogICAgKgogICAgKi8KICAgIGlmICgoYWJzb2x1dGUgPT0gMCkgJiYgKG5vZGUgIT0gTlVMTCkpIHsKCXhtbENoYXIgKmJhc2UsICpVUkk7CgoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIG5vZGUtPmRvYy0+VVJMKTsKCX0gZWxzZSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIGJhc2UpOwoJICAgIHhtbEZyZWUoYmFzZSk7Cgl9CglpZiAoVVJJICE9IE5VTEwpIHsKCSAgICBsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAocGN0eHQtPmRpY3QsIFVSSSwgLTEpOwoJICAgIHhtbEZyZWUoVVJJKTsKCX0KICAgIH0KICAgIHBhcnNlckN0eHQgPSB4bWxOZXdQYXJzZXJDdHh0KCk7CiAgICBpZiAocGFyc2VyQ3R4dCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJ4bWxTY2hlbWFQYXJzZUltcG9ydDogIgoJICAgICJhbGxvY2F0aW5nIGEgcGFyc2VyIGNvbnRleHQiLCBOVUxMKTsKCXJldHVybigtMSk7CiAgICB9CiAgICBpZiAoKHBjdHh0LT5kaWN0ICE9IE5VTEwpICYmIChwYXJzZXJDdHh0LT5kaWN0ICE9IE5VTEwpKSB7Cgl4bWxEaWN0RnJlZShwYXJzZXJDdHh0LT5kaWN0KTsKCXBhcnNlckN0eHQtPmRpY3QgPSBwY3R4dC0+ZGljdDsKCXhtbERpY3RSZWZlcmVuY2UocGFyc2VyQ3R4dC0+ZGljdCk7CiAgICB9CiAgICAqZG9jID0geG1sQ3R4dFJlYWRGaWxlKHBhcnNlckN0eHQsIChjb25zdCBjaGFyICopIGxvY2F0aW9uLAoJICAgIE5VTEwsIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAvKgogICAgKiAyLjEgVGhlIHJlZmVyZW50IGlzIChhIGZyYWdtZW50IG9mKSBhIHJlc291cmNlIHdoaWNoIGlzIGFuCiAgICAqIFhNTCBkb2N1bWVudCAoc2VlIGNsYXVzZSAxLjEpLCB3aGljaCBpbiB0dXJuIGNvcnJlc3BvbmRzIHRvCiAgICAqIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluIGEgd2VsbC1mb3JtZWQgaW5mb3JtYXRpb24KICAgICogc2V0LCB3aGljaCBpbiB0dXJuIGNvcnJlc3BvbmRzIHRvIGEgdmFsaWQgc2NoZW1hLgogICAgKiBUT0RPOiBXaGF0IHRvIGRvIHdpdGggdGhlICJmcmFnbWVudCIgc3R1ZmY/CiAgICAqCiAgICAqIDIuMiBUaGUgcmVmZXJlbnQgaXMgYSA8c2NoZW1hPiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaW4KICAgICogYSB3ZWxsLWZvcm1lZCBpbmZvcm1hdGlvbiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMKICAgICogdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIE5PVEU6IDIuMiB3b24ndCBhcHBseSwgc2luY2Ugb25seSBYTUwgZG9jdW1lbnRzIHdpbGwgYmUgcHJvY2Vzc2VkCiAgICAqIGhlcmUuCiAgICAqLwogICAgaWYgKCpkb2MgPT0gTlVMTCkgewoJeG1sRXJyb3JQdHIgbGVycjsKCS8qCgkqIEl0IGlzICpub3QqIGFuIGVycm9yIGZvciB0aGUgYXBwbGljYXRpb24gc2NoZW1hIHJlZmVyZW5jZQoJKiBzdHJhdGVneSB0byBmYWlsLgoJKgoJKiBJZiB0aGUgZG9jIGlzIE5VTEwgYW5kIHRoZSBwYXJzZXIgZXJyb3IgaXMgYW4gSU8gZXJyb3Igd2UKCSogd2lsbCBhc3N1bWUgdGhhdCB0aGUgcmVzb3VyY2UgY291bGQgbm90IGJlIGxvY2F0ZWQgb3IgYWNjZXNzZWQuCgkqCgkqIFRPRE86IFRyeSB0byBmaW5kIHNwZWNpZmljIGVycm9yIGNvZGVzIHRvIHJlYWN0IG9ubHkgb24KCSogbG9jYWxpc2F0aW9uIGZhaWx1cmVzLgoJKgoJKiBUT0RPLCBGSVhNRTogQ2hlY2sgdGhlIHNwZWM6IGlzIGEgbmFtZXNwYWNlIGFkZGVkIHRvIHRoZSBpbXBvcnRlZAoJKiBuYW1lc3BhY2VzLCBldmVuIGlmIHRoZSBzY2hlbWFMb2NhdGlvbiBkaWQgbm90IHByb3ZpZGUKCSogYSByZXNvdXJjZT8gSSBndWVzcyBzbywgc2luY2Ugb21pdHRpbmcgdGhlICJzY2hlbWFMb2NhdGlvbiIKCSogYXR0cmlidXRlLCBpbXBvcnRzIGEgbmFtZXNwYWNlIGFzIHdlbGwuCgkqLwoJbGVyciA9IHhtbEdldExhc3RFcnJvcigpOwoJaWYgKChsZXJyICE9IE5VTEwpICYmIChsZXJyLT5kb21haW4gPT0gWE1MX0ZST01fSU8pKSB7CgkgICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CgkgICAgcmV0dXJuKDApOwoJfQoJeG1sU2NoZW1hQ3VzdG9tRXJyKGFjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xLAoJICAgIG5vZGUsIE5VTEwsCgkgICAgIkZhaWxlZCB0byBwYXJzZSB0aGUgcmVzb3VyY2UgJyVzJyBmb3IgaW1wb3J0IiwKCSAgICBsb2NhdGlvbiwgTlVMTCk7Cgl4bWxGcmVlUGFyc2VyQ3R4dChwYXJzZXJDdHh0KTsKCXJldHVybihYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSk7CiAgICB9CiAgICB4bWxGcmVlUGFyc2VyQ3R4dChwYXJzZXJDdHh0KTsKCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoKmRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFDdXN0b21FcnIoYWN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEsCgkgICAgbm9kZSwgTlVMTCwKCSAgICAiVGhlIFhNTCBkb2N1bWVudCAnJXMnIHRvIGJlIGltcG9ydGVkIGhhcyBubyBkb2N1bWVudCAiCgkgICAgImVsZW1lbnQiLCBsb2NhdGlvbiwgTlVMTCk7Cgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0KCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKHBjdHh0LCByb290KTsKCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYUN1c3RvbUVycihhY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBub2RlLCBOVUxMLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGEgWE1MIHNjaGVtYSBkb2N1bWVudCIsCgkgICAgbG9jYXRpb24sIE5VTEwpOwoJeG1sRnJlZURvYygqZG9jKTsKCSpkb2MgPSBOVUxMOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSk7CiAgICB9CiAgICAqdGFyZ2V0TmFtZXNwYWNlID0geG1sU2NoZW1hR2V0UHJvcChwY3R4dCwgcm9vdCwgInRhcmdldE5hbWVzcGFjZSIpOwogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IEltcG9ydCBDb25zdHJhaW50cyBhbmQgU2VtYW50aWNzCiAgICAqLwogICAgaWYgKG5zTmFtZSA9PSBOVUxMKSB7CglpZiAoKnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKGFjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18yLAoJCW5vZGUsIE5VTEwsCgkJIlRoZSBYTUwgc2NoZW1hIHRvIGJlIGltcG9ydGVkIGlzIG5vdCBleHBlY3RlZCAiCgkJInRvIGhhdmUgYSB0YXJnZXQgbmFtZXNwYWNlOyB0aGlzIGRpZmZlcnMgZnJvbSAiCgkJIml0cyB0YXJnZXQgbmFtZXNwYWNlIG9mICclcyciLCAqdGFyZ2V0TmFtZXNwYWNlLCBOVUxMKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIpOwoJfQogICAgfSBlbHNlIHsKCWlmICgqdGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoYWN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEsCgkJbm9kZSwgTlVMTCwKCQkiVGhlIFhNTCBzY2hlbWEgdG8gYmUgaW1wb3J0ZWQgaXMgZXhwZWN0ZWQgdG8gaGF2ZSBhIHRhcmdldCAiCgkJIm5hbWVzcGFjZSBvZiAnJXMnIiwgbnNOYW1lLCBOVUxMKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEpOwoJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoKnRhcmdldE5hbWVzcGFjZSwgbnNOYW1lKSkgewoJICAgIHhtbFNjaGVtYUN1c3RvbUVycihhY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQlub2RlLCBOVUxMLAoJCSJUaGUgWE1MIHNjaGVtYSB0byBiZSBpbXBvcnRlZCBpcyBleHBlY3RlZCB0byBoYXZlIGEgIgoJCSJ0YXJnZXQgbmFtZXNwYWNlIG9mICclcyc7IHRoaXMgZGlmZmVycyBmcm9tICIKCQkiaXRzIHRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJyIsCgkJbnNOYW1lLCAqdGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEpOwoJfQogICAgfQogICAgaW1wb3J0ID0geG1sU2NoZW1hQWRkSW1wb3J0KHBjdHh0LCAmKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMpLCBuc05hbWUpOwogICAgaWYgKGltcG9ydCA9PSBOVUxMKSB7CglBRVJST1JfSU5UKCJ4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jIiwKCSAgICAiZmFpbGVkIHRvIGJ1aWxkIGltcG9ydCB0YWJsZSIpOwoJeG1sRnJlZURvYygqZG9jKTsKCSpkb2MgPSBOVUxMOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpbXBvcnQtPnNjaGVtYUxvY2F0aW9uID0gbG9jYXRpb247CiAgICBpbXBvcnQtPmRvYyA9ICpkb2M7CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZUZvckltcEluYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQl4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQljb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UsCgkJCXhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqb2xkVVJMLCAqKm9sZExvY0ltcHMsICpvbGRUTlM7CiAgICBpbnQgb2xkRmxhZ3MsIG9sZE51bUxvY0ltcHMsIG9sZFNpemVMb2NJbXBzLCBvbGRJc1M0UzsKCiAgICAvKgogICAgKiBTYXZlIGFuZCByZXNldCB0aGUgY29udGV4dCAmIHNjaGVtYS4KICAgICovCiAgICBvbGRVUkwgPSBwY3R4dC0+VVJMOwogICAgLyogVE9ETzogSXMgdXNpbmcgdGhlIGRvYy0+VVJMIGhlcmUgY29ycmVjdD8gKi8KICAgIHBjdHh0LT5VUkwgPSBub2RlLT5kb2MtPlVSTDsKCiAgICBvbGRMb2NJbXBzID0gcGN0eHQtPmxvY2FsSW1wb3J0czsKICAgIHBjdHh0LT5sb2NhbEltcG9ydHMgPSBOVUxMOwogICAgb2xkTnVtTG9jSW1wcyA9IHBjdHh0LT5uYkxvY2FsSW1wb3J0czsKICAgIHBjdHh0LT5uYkxvY2FsSW1wb3J0cyA9IDA7CiAgICBvbGRTaXplTG9jSW1wcyA9IHBjdHh0LT5zaXplTG9jYWxJbXBvcnRzOwogICAgcGN0eHQtPnNpemVMb2NhbEltcG9ydHMgPSAwOwoKICAgIG9sZEZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIG9sZElzUzRTID0gcGN0eHQtPmlzUzRTOwoKICAgIHhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKICAgIG9sZFROUyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROYW1lc3BhY2U7CiAgICBpZiAoKHRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSAmJgoJeG1sU3RyRXF1YWwodGFyZ2V0TmFtZXNwYWNlLCB4bWxTY2hlbWFOcykpIHsKCS8qCgkqIFdlIGFyZSBwYXJzaW5nIHRoZSBzY2hlbWEgZm9yIHNjaGVtYSEKCSovCglwY3R4dC0+aXNTNFMgPSAxOwogICAgfQogICAgLyoKICAgICogUGFyc2UgdGhlIHNjaGVtYS4KICAgICovCiAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKHBjdHh0LCBzY2hlbWEsIG5vZGUpOwogICAgeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgc2NoZW1hLCBub2RlLT5jaGlsZHJlbik7CiAgICAvKgogICAgKiBSZXN0b3JlIHRoZSBjb250ZXh0ICYgc2NoZW1hLgogICAgKi8KICAgIHNjaGVtYS0+ZmxhZ3MgPSBvbGRGbGFnczsKICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gb2xkVE5TOwogICAgaWYgKHBjdHh0LT5sb2NhbEltcG9ydHMgIT0gTlVMTCkKCXhtbEZyZWUoKHhtbENoYXIgKikgcGN0eHQtPmxvY2FsSW1wb3J0cyk7CiAgICBwY3R4dC0+bG9jYWxJbXBvcnRzID0gb2xkTG9jSW1wczsKICAgIHBjdHh0LT5uYkxvY2FsSW1wb3J0cyA9IG9sZE51bUxvY0ltcHM7CiAgICBwY3R4dC0+c2l6ZUxvY2FsSW1wb3J0cyA9IG9sZFNpemVMb2NJbXBzOwogICAgcGN0eHQtPlVSTCA9IG9sZFVSTDsKICAgIHBjdHh0LT5pc1M0UyA9IG9sZElzUzRTOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbXBvcnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEltcG9ydCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGlmCiAqIG5vdCB2YWxpZCBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbXBvcnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZXNwYWNlTmFtZSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHJldCA9IDA7CgogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWVzcGFjZSIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0cihwY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwKCSJuYW1lc3BhY2UiLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLAoJJm5hbWVzcGFjZU5hbWUpICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgTlVMTCwgbm9kZSwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLAoJICAgIE5VTEwsIG5hbWVzcGFjZU5hbWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChwY3R4dC0+ZXJyKTsKICAgIH0KCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHIocGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsCgkic2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLAoJJnNjaGVtYUxvY2F0aW9uKSAhPSAwKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIE5VTEwsIG5vZGUsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICBOVUxMLCBuYW1lc3BhY2VOYW1lLCBOVUxMLCBOVUxMLCBOVUxMKTsKCXJldHVybiAocGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlIGFubm90YXRpb24gaGVyZSBpcyBzaW1wbHkgZGlzY2FyZGVkIC4uLgoJICogVE9ETzogcmVhbGx5PwogICAgICAgICAqLwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIC8qCiAgICAqIEFwcGx5IGFkZGl0aW9uYWwgY29uc3RyYWludHMuCiAgICAqLwogICAgaWYgKG5hbWVzcGFjZU5hbWUgIT0gTlVMTCkgewoJLyoKCSogMS4xIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgcHJlc2VudCwgdGhlbiBpdHMgt2FjdHVhbCB2YWx1ZbcKCSogbXVzdCBub3QgbWF0Y2ggdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBlbmNsb3NpbmcgPHNjaGVtYT4ncwoJKiB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHhtbFN0ckVxdWFsKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBuYW1lc3BhY2VOYW1lKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBub3QgbWF0Y2ggIgoJCSJ0aGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbXBvcnRpbmcgc2NoZW1hIiwKCQlzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgcmV0dXJuIChwY3R4dC0+ZXJyKTsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiAxLjIgSWYgdGhlIG5hbWVzcGFjZSBbYXR0cmlidXRlXSBpcyBub3QgcHJlc2VudCwgdGhlbiB0aGUgZW5jbG9zaW5nCgkqIDxzY2hlbWE+IG11c3QgaGF2ZSBhIHRhcmdldE5hbWVzcGFjZSBbYXR0cmlidXRlXS4KCSovCglpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IGJlIGV4aXN0ZW50IGlmICIKCQkidGhlIGltcG9ydGluZyBzY2hlbWEgaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCU5VTEwpOwoJICAgIHJldHVybiAocGN0eHQtPmVycik7Cgl9CiAgICB9CiAgICAvKgogICAgKiBBZGQgdGhlIG5hbWVzcGFjZSB0byB0aGUgbGlzdCBvZiBsb2NhbGx5IGltcG9ydGVkIG5hbWVzcGFjZS4KICAgICogVE9ETzogVGhpcyBjb3VsZCBiZSByZW1vdmVkIGlmIHRoZSBzY2hlbWEtZ3JhcGggaXMgcmVhZHkuIEkuZS4KICAgICogICAgICAgdXNlIHRoZSBncmFwaCBmb3IgdGhpcyBpbmZvIGluc3RlYWQuCiAgICAqLwogICAgaWYgKHBjdHh0LT5sb2NhbEltcG9ydHMgPT0gTlVMTCkgewoJcGN0eHQtPmxvY2FsSW1wb3J0cyA9IChjb25zdCB4bWxDaGFyICoqKSB4bWxNYWxsb2MoMTAgKgoJICAgIHNpemVvZihjb25zdCB4bWxDaGFyKikpOwoJcGN0eHQtPnNpemVMb2NhbEltcG9ydHMgPSAxMDsKCXBjdHh0LT5uYkxvY2FsSW1wb3J0cyA9IDA7CiAgICB9IGVsc2UgaWYgKHBjdHh0LT5zaXplTG9jYWxJbXBvcnRzIDw9IHBjdHh0LT5uYkxvY2FsSW1wb3J0cykgewoJcGN0eHQtPnNpemVMb2NhbEltcG9ydHMgKj0gMjsKCXBjdHh0LT5sb2NhbEltcG9ydHMgPSAoY29uc3QgeG1sQ2hhciAqKikgeG1sUmVhbGxvYygKCSAgICAoeG1sQ2hhciAqKikgcGN0eHQtPmxvY2FsSW1wb3J0cywKCSAgICBwY3R4dC0+c2l6ZUxvY2FsSW1wb3J0cyAqIHNpemVvZihjb25zdCB4bWxDaGFyKikpOwogICAgfQogICAgcGN0eHQtPmxvY2FsSW1wb3J0c1twY3R4dC0+bmJMb2NhbEltcG9ydHMrK10gPSBuYW1lc3BhY2VOYW1lOwogICAgLyoKICAgICogTG9jYXRlIGFuZCBhcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHBjdHh0LAoJc2NoZW1hLCBub2RlLCBuYW1lc3BhY2VOYW1lLAoJc2NoZW1hTG9jYXRpb24sICZkb2MsICZ0YXJnZXROYW1lc3BhY2UsIDApOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAoZG9jICE9IE5VTEwpCgkgICAgeG1sRnJlZURvYyhkb2MpOwoJcmV0dXJuIChyZXQpOwogICAgfSBlbHNlIGlmIChkb2MgIT0gTlVMTCkgewogICAgICAgCXhtbFNjaGVtYVBhcnNlRm9ySW1wSW5jKHBjdHh0LCBzY2hlbWEsIHRhcmdldE5hbWVzcGFjZSwKCSAgICB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpKTsKICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbmNsdWRlZERvYzoKICogQHBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogUGFyc2UgYW4gaW5jbHVkZWQgKGFuZCB0by1iZS1yZWRlZmluZWQpIFhNTCBzY2hlbWEgZG9jdW1lbnQuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZXJyb3JzIGFuZAogKiAgICAgICAgIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUluY2x1ZGVkRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgeG1sTm9kZVB0ciBub2RlLCBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiwKCQkJICBpbnQgKmxvY2F0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbERvY1B0ciBkb2MgPSBOVUxMOwogICAgeG1sTm9kZVB0ciByb290ID0gTlVMTDsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZSA9IE5VTEw7CiAgICBpbnQgd2FzQ29udmVydGluZ05zID0gMDsKICAgIHhtbFBhcnNlckN0eHRQdHIgcGFyc2VyQ3R4dDsKCiAgICBpZiAobG9jYXRlZCA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKICAgICgqbG9jYXRlZCkgPSAwOwogICAgLyoKICAgICogQ2hlY2sgaWYgdGhpcyBvbmUgd2FzIGFscmVhZHkgcHJvY2Vzc2VkIHRvIGF2b2lkIGluY29ycmVjdAogICAgKiBkdXBsaWNhdGUgY29tcG9uZW50IGVycm9ycyBhbmQgaW5maW5pdGUgY2lyY3VsYXIgaW5jbHVzaW9uLgogICAgKi8KICAgIGluY2x1ZGUgPSBzY2hlbWEtPmluY2x1ZGVzOwogICAgd2hpbGUgKGluY2x1ZGUgIT0gTlVMTCkgewoJaWYgKHhtbFN0ckVxdWFsKGluY2x1ZGUtPnNjaGVtYUxvY2F0aW9uLCBzY2hlbWFMb2NhdGlvbikpIHsKCSAgICAoKmxvY2F0ZWQpID0gMTsKCSAgICB0YXJnZXROYW1lc3BhY2UgPSBpbmNsdWRlLT5vcmlnVGFyZ2V0TmFtZXNwYWNlOwoJICAgIGlmICh0YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJCS8qCgkJKiBDaGFtZWxlb24gaW5jbHVkZTogc2tpcCBvbmx5IGlmIGl0IHdhcyBidWlsZCBmb3IKCQkqIHRoZSB0YXJnZXROYW1lc3BhY2Ugb2YgdGhlIGluY2x1ZGluZyBzY2hlbWEuCgkJKi8KCQlpZiAoeG1sU3RyRXF1YWwoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCgkJICAgIGluY2x1ZGUtPnRhcmdldE5hbWVzcGFjZSkpIHsKCQkgICAgZ290byBjaGVja190YXJnZXROYW1lc3BhY2U7CgkJfQoJICAgIH0gZWxzZSB7CQkKCQlnb3RvIGNoZWNrX3RhcmdldE5hbWVzcGFjZTsKCSAgICB9Cgl9CglpbmNsdWRlID0gaW5jbHVkZS0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICogVE9ETzogVXNlIHhtbEN0eHRSZWFkRmlsZSB0byBzaGFyZSB0aGUgZGljdGlvbmFyeT8KICAgICovCiAgICBwYXJzZXJDdHh0ID0geG1sTmV3UGFyc2VyQ3R4dCgpOwogICAgaWYgKHBhcnNlckN0eHQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAieG1sU2NoZW1hUGFyc2VJbmNsdWRlOiAiCgkgICAgImFsbG9jYXRpbmcgYSBwYXJzZXIgY29udGV4dCIsIE5VTEwpOwoJZ290byBleGl0X2ZhaWx1cmU7CiAgICB9CgogICAgaWYgKChwY3R4dC0+ZGljdCAhPSBOVUxMKSAmJiAocGFyc2VyQ3R4dC0+ZGljdCAhPSBOVUxMKSkgewoJeG1sRGljdEZyZWUocGFyc2VyQ3R4dC0+ZGljdCk7CglwYXJzZXJDdHh0LT5kaWN0ID0gcGN0eHQtPmRpY3Q7Cgl4bWxEaWN0UmVmZXJlbmNlKHBhcnNlckN0eHQtPmRpY3QpOwogICAgfQoKICAgIGRvYyA9IHhtbEN0eHRSZWFkRmlsZShwYXJzZXJDdHh0LCAoY29uc3QgY2hhciAqKSBzY2hlbWFMb2NhdGlvbiwKCSAgICBOVUxMLCBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CiAgICBpZiAoZG9jID09IE5VTEwpIHsJCQkKCWdvdG8gZXhpdF9ub3RfbG9jYXRlZDsKICAgIH0KICAgICgqbG9jYXRlZCkgPSAxOwogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBvZiB0aGUgc2NoZW1hCiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGluY2x1ZGVkIGRvY3VtZW50ICclcycgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIHNjaGVtYUxvY2F0aW9uKTsKCWdvdG8gZXhpdF9lcnJvcjsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKHBjdHh0LCByb290KTsKCiAgICAvKgogICAgICogQ2hlY2sgdGhlIHNjaGVtYXMgdG9wIGxldmVsIGVsZW1lbnQKICAgICAqLwogICAgaWYgKCFJU19TQ0hFTUEocm9vdCwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGRvY3VtZW50ICclcycgdG8gYmUgaW5jbHVkZWQgaXMgbm90IGEgc2NoZW1hIGRvY3VtZW50IiwKCSAgICBzY2hlbWFMb2NhdGlvbik7Cglnb3RvIGV4aXRfZXJyb3I7CiAgICB9CgogICAgdGFyZ2V0TmFtZXNwYWNlID0geG1sU2NoZW1hR2V0UHJvcChwY3R4dCwgcm9vdCwgInRhcmdldE5hbWVzcGFjZSIpOwogICAgLyoKICAgICogMi4xIFNJSSBoYXMgYSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0sIGFuZCBpdHMgt2FjdHVhbAogICAgKiB2YWx1ZbcgaXMgaWRlbnRpY2FsIHRvIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdGFyZ2V0TmFtZXNwYWNlCiAgICAqIFthdHRyaWJ1dGVdIG9mIFNJSZIgKHdoaWNoIG11c3QgaGF2ZSBzdWNoIGFuIFthdHRyaWJ1dGVdKS4KICAgICovCmNoZWNrX3RhcmdldE5hbWVzcGFjZToKICAgIGlmICh0YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewoJaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRlZCBzY2hlbWEgIgoJCSInJXMnIGhhcyB0byBiZSBhYnNlbnQsIHNpbmNlIHRoZSBpbmNsdWRpbmcgc2NoZW1hICIKCQkiaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCXNjaGVtYUxvY2F0aW9uKTsKCSAgICBnb3RvIGV4aXRfZXJyb3I7Cgl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCh0YXJnZXROYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREUsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgJyVzJyBvZiB0aGUgaW5jbHVkZWQgc2NoZW1hICclcycgIgoJCSJkaWZmZXJzIGZyb20gJyVzJyBvZiB0aGUgaW5jbHVkaW5nIHNjaGVtYSIsCgkJdGFyZ2V0TmFtZXNwYWNlLCBzY2hlbWFMb2NhdGlvbiwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIGdvdG8gZXhpdF9lcnJvcjsKCX0KICAgIH0gZWxzZSBpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewoJaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpID09IDApIHsKCSAgICBzY2hlbWEtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TOwoJfSBlbHNlCgkgICAgd2FzQ29udmVydGluZ05zID0gMTsKICAgIH0KCiAgICBpZiAoaW5jbHVkZSAhPSBOVUxMKQoJZ290byBleGl0OwoKICAgIC8qCiAgICAqIFVSR0VOVCBUT0RPOiBJZiB0aGUgc2NoZW1hIGlzIGEgY2hhbWVsZW9uLWluY2x1ZGUgdGhlbiBjb3B5IHRoZQogICAgKiBjb21wb25lbnRzIGludG8gdGhlIGluY2x1ZGluZyBzY2hlbWEgYW5kIG1vZGlmeSB0aGUgdGFyZ2V0TmFtZXNwYWNlCiAgICAqIG9mIHRob3NlIGNvbXBvbmVudHMsIGRvIG5vdGhpbmcgb3RoZXJ3aXNlLgogICAgKiBOT1RFOiBUaGlzIGlzIGN1cnJlbnRseSB3b3JrZWQtYXJvdW5kIGJ5IGNvbXBpbGluZyB0aGUgY2hhbWVsZW9uCiAgICAqIGZvciBldmVyeSBkZXN0aW5jdCBpbmNsdWRpbmcgdGFyZ2V0TmFtZXNwYWNlOyB0aHVzIG5vdCBwZXJmb3JtYW50IGF0CiAgICAqIHRoZSBtb21lbnQuCiAgICAqIFRPRE86IENoZWNrIHdoZW4gdGhlIG5hbWVzcGFjZSBpbiB3aWxkY2FyZHMgZm9yIGNoYW1lbGVvbnMgbmVlZHMKICAgICogdG8gYmUgY29udmVydGVkOiBiZWZvcmUgd2UgYnVpbHQgd2lsZGNhcmQgaW50ZXJzZWN0aW9ucyBvciBhZnRlci4KICAgICogICBBbnN3ZXI6IGFmdGVyIQogICAgKi8KICAgIC8qCiAgICAqIFJlZ2lzdGVyIHRoZSBpbmNsdWRlLgogICAgKi8KICAgIGluY2x1ZGUgPSAoeG1sU2NoZW1hSW5jbHVkZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJbmNsdWRlKSk7CiAgICBpZiAoaW5jbHVkZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShwY3R4dCwgImFsbG9jYXRpbmcgaW5jbHVkZSBlbnRyeSIsIE5VTEwpOwoJZ290byBleGl0X2ZhaWx1cmU7CiAgICB9CiAgICBtZW1zZXQoaW5jbHVkZSwgMCwgc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpKTsKICAgIGluY2x1ZGUtPm5leHQgPSBzY2hlbWEtPmluY2x1ZGVzOwogICAgc2NoZW1hLT5pbmNsdWRlcyA9IGluY2x1ZGU7CiAgICAvKgogICAgKiBUT0RPOiBVc2UgdGhlIHJlc29sdmVkIFVSSSBmb3IgdGhlIHRoaXMgbG9jYXRpb24sIHNpbmNlIGl0IG1pZ2h0CiAgICAqIGRpZmZlciBpZiB1c2luZyBmaWxlbmFtZXMvVVJJcyBzaW11bHRhbmVvc2x5LgogICAgKi8KICAgIGluY2x1ZGUtPnNjaGVtYUxvY2F0aW9uID0gc2NoZW1hTG9jYXRpb247CiAgICBpbmNsdWRlLT5kb2MgPSBkb2M7CiAgICAvKgogICAgKiBJbiBjYXNlIG9mIGNoYW1lbGVvbnMsIHRoZSBvcmlnaW5hbCB0YXJnZXQgbmFtZXNwYWNlIHdpbGwgZGlmZmVyCiAgICAqIGZyb20gdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UuCiAgICAqLwogICAgaW5jbHVkZS0+b3JpZ1RhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKICAgIGluY2x1ZGUtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwojaWZkZWYgREVCVUdfSU5DTFVERVMKICAgIGlmICh0YXJnZXROYW1lc3BhY2UgIT0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCSAgICAiSU5DTFVESU5HIENIQU1FTEVPTiAnJXMnXG4gIG9yaWcgVE5TICclcydcbiIKCSAgICAiICBpbnRvIFROUyAnJXMnXG4iLCBzY2hlbWFMb2NhdGlvbiwKCSAgICB0YXJnZXROYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIGVsc2UKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICJJTkNMVURJTkcgJyVzJ1xuICBvcmlnLVROUyAnJXMnXG4iLCBzY2hlbWFMb2NhdGlvbiwKCSAgICB0YXJnZXROYW1lc3BhY2UpOwojZW5kaWYKICAgIC8qCiAgICAqIENvbXBpbGUgdGhlIGluY2x1ZGVkIHNjaGVtYS4KICAgICovCiAgICB4bWxTY2hlbWFQYXJzZUZvckltcEluYyhwY3R4dCwgc2NoZW1hLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgcm9vdCk7CgpleGl0OgogICAgLyoKICAgICogUmVtb3ZlIHRoZSBjb252ZXJ0aW5nIGZsYWcuCiAgICAqLwogICAgaWYgKCh3YXNDb252ZXJ0aW5nTnMgPT0gMCkgJiYKCShzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsKICAgIHJldHVybiAoMCk7CgpleGl0X2Vycm9yOgogICAgaWYgKGRvYyAhPSBOVUxMKSB7CglpZiAoaW5jbHVkZSAhPSBOVUxMKQoJICAgIGluY2x1ZGUtPmRvYyA9IE5VTEw7Cgl4bWxGcmVlRG9jKGRvYyk7CiAgICB9CiAgICByZXR1cm4gKHBjdHh0LT5lcnIpOwoKZXhpdF9ub3RfbG9jYXRlZDoKICAgIHJldHVybigwKTsKCmV4aXRfZmFpbHVyZToKICAgIGlmIChkb2MgIT0gTlVMTCkgewoJaWYgKGluY2x1ZGUgIT0gTlVMTCkKCSAgICBpbmNsdWRlLT5kb2MgPSBOVUxMOwoJeG1sRnJlZURvYyhkb2MpOwogICAgfQogICAgcmV0dXJuICgtMSk7Cn0KCgpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmVBdHRycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkgICAgIHhtbENoYXIgKipzY2hlbWFMb2NhdGlvbiwKCQkJCSAgICAgaW50IGlzUmVkZWZpbmUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwKCShzY2hlbWFMb2NhdGlvbiA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAqc2NoZW1hTG9jYXRpb24gPSBOVUxMOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICogQXBwbGllcyBmb3IgYm90aCA8aW5jbHVkZT4gYW5kIDxyZWRlZmluZT4uCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKHBjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIFByZWxpbWluYXJ5IHN0ZXAsIGV4dHJhY3QgdGhlIFVSSS1SZWZlcmVuY2UgYW5kIG1ha2UgYW4gVVJJCiAgICAqIGZyb20gdGhlIGJhc2UuCiAgICAqLwogICAgLyoKICAgICogQXR0cmlidXRlICJzY2hlbWFMb2NhdGlvbiIgaXMgbWFuZGF0b3J5LgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKICAgICAgICB4bWxDaGFyICp1cmkgPSBOVUxMOwoKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUocGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwKCSAgICAoY29uc3QgeG1sQ2hhciAqKikgc2NoZW1hTG9jYXRpb24pICE9IDApCgkgICAgZ290byBleGl0X2Vycm9yOwoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgdXJpID0geG1sQnVpbGRVUkkoKnNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKCpzY2hlbWFMb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmICh1cmkgPT0gTlVMTCkgewoJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUiLAoJCSJjb3VsZCBub3QgYnVpbGQgYW4gVVJJIGZyb20gdGhlIHNjaGVtYUxvY2F0aW9uIikKCSAgICBnb3RvIGV4aXRfZmFpbHVyZTsKCX0KCSgqc2NoZW1hTG9jYXRpb24pID0gKHhtbENoYXIgKikgeG1sRGljdExvb2t1cChwY3R4dC0+ZGljdCwgdXJpLCAtMSk7Cgl4bWxGcmVlKHVyaSk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkgICAgTlVMTCwgbm9kZSwgInNjaGVtYUxvY2F0aW9uIiwgTlVMTCk7Cglnb3RvIGV4aXRfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBSZXBvcnQgc2VsZi1pbmNsdXNpb24gYW5kIHNlbGYtcmVkZWZpbml0aW9uLgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbCgqc2NoZW1hTG9jYXRpb24sIHBjdHh0LT5VUkwpKSB7CglpZiAoaXNSZWRlZmluZSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFREVGSU5FLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgcmVkZWZpbmUgaXRzZWxmLiIsCgkJKnNjaGVtYUxvY2F0aW9uKTsJICAgIAoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBzY2hlbWEgZG9jdW1lbnQgJyVzJyBjYW5ub3QgaW5jbHVkZSBpdHNlbGYuIiwKCQkqc2NoZW1hTG9jYXRpb24pOwoJfQoJZ290byBleGl0X2Vycm9yOwogICAgfQogICAgCiAgICByZXR1cm4oMCk7CmV4aXRfZXJyb3I6CiAgICByZXR1cm4ocGN0eHQtPmVycik7CmV4aXRfZmFpbHVyZToKICAgIHJldHVybigtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJCWludCBpc1JlZGVmaW5lKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uID0gTlVMTDsKICAgIGludCByZXMgPSAwLCBsb2NhdGVkID0gMCwgaGFzUmVkZWZpbml0aW9ucyA9IDA7CgogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIFBhcnNlIGF0dHJpYnV0ZXMuIE5vdGUgdGhhdCB0aGUgcmV0dXJuZWQgc2NoZW1hTG9jYXRpb24gd2lsbAogICAgKiBiZSBhbHJlYWR5IGNvbnZlcnRlZCB0byBhbiBhYnNvbHV0ZSBVUkkuCiAgICAqLwogICAgcmVzID0geG1sU2NoZW1hUGFyc2VJbmNsdWRlT3JSZWRlZmluZUF0dHJzKHBjdHh0LCBzY2hlbWEsCglub2RlLCAoeG1sQ2hhciAqKikgKCZzY2hlbWFMb2NhdGlvbiksIGlzUmVkZWZpbmUpOwogICAgaWYgKHJlcyAhPSAwKQoJcmV0dXJuKHJlcyk7CgogICAgLyoKICAgICogSW5jbHVkZSB0aGUgc2NoZW1hLgogICAgKi8KICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZWREb2MocGN0eHQsIHNjaGVtYSwgbm9kZSwKCXNjaGVtYUxvY2F0aW9uLCAmbG9jYXRlZCk7CiAgICBpZiAocmVzICE9IDApCglyZXR1cm4ocmVzKTsKICAgICAgICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICAKICAgIGlmIChpc1JlZGVmaW5lKSB7CgkvKgoJKiBQYXJzZSAoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlIHwgZ3JvdXAgfCBhdHRyaWJ1dGVHcm91cCkpKgoJKi8KCXBjdHh0LT5pc1JlZGVmaW5lID0gMTsKCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikgfHwKCSAgICBJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikgfHwKCSAgICBJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpIHx8CgkgICAgSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSB8fAoJICAgIElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpIHsKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkJLyoKCQkqIFRPRE86IGRpc2NhcmQgb3Igbm90PwoJCSovCgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsJCQoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShwY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkJeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShwY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkJaGFzUmVkZWZpbml0aW9ucyA9IDE7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CgkJVE9ETwoJCWhhc1JlZGVmaW5pdGlvbnMgPSAxOwoJCS8qIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cERlZmluaXRpb24ocGN0eHQsIHNjaGVtYSwgY2hpbGQpOyAqLwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJCVRPRE8KCQloYXNSZWRlZmluaXRpb25zID0gMTsKCQkvKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKHBjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsgKi8KCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXBjdHh0LT5pc1JlZGVmaW5lID0gMDsKICAgIH0gZWxzZSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IGRpc2NhcmQgb3Igbm90PwoJICAgICovCgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0gICAgCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJcmVzID0gWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQ7CglpZiAoaXNSZWRlZmluZSkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKHBjdHh0LAoJCXJlcywKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24gfCAoc2ltcGxlVHlwZSB8IGNvbXBsZXhUeXBlIHwgZ3JvdXAgfCBhdHRyaWJ1dGVHcm91cCkpKiIpOwoJfSBlbHNlIHsKCSAgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIocGN0eHQsCgkJcmVzLAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8pIik7Cgl9CQogICAgfQogICAgaWYgKCFsb2NhdGVkKSB7CgkvKgoJKiBUT0RPOiBUaGlzIGlzIGFsbCAqbm90KiB5ZXQgT0ssIHNpbmNlIHdlIGdldCBhICFsb2NhdGVkIGlmIHRoZQoJKiBkb2N1bWVudCB3YXMgbm90IGFuIFhNTCBkb2N1bWVudCBhcyB3ZWxsIDotKAoJKi8KCWlmICghaXNSZWRlZmluZSkgewkKCSAgICAvKgoJICAgICogV0FSTklORyBmb3IgPGluY2x1ZGU+OgoJICAgICogV2Ugd2lsbCByYWlzZSBhbiBlcnJvciBpZiB0aGUgc2NoZW1hIGNhbm5vdCBiZSBsb2NhdGVkCgkgICAgKiBmb3IgaW5jbHVzaW9ucywgc2luY2UgdGhlIHRoYXQgd2FzIHRoZSBmZWVkYmFjayBmcm9tIHRoZQoJICAgICogc2NoZW1hIHBlb3BsZS4gSS5lLiB0aGUgZm9sbG93aW5nIHNwZWMgcGllY2Ugd2lsbCAqbm90KiBiZQoJICAgICogc2F0aXNmaWVkOgoJICAgICogU1BFQyBzcmMtaW5jbHVkZTogIkl0IGlzIG5vdCBhbiBlcnJvciBmb3IgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZQoJICAgICogc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gdG8gZmFpbCB0byByZXNvbHZlIGl0IGFsbCwgaW4gd2hpY2gKCSAgICAqIGNhc2Ugbm8gY29ycmVzcG9uZGluZyBpbmNsdXNpb24gaXMgcGVyZm9ybWVkLgoJICAgICogU28gZG8gd2UgbmVlZCBhIHdhcm5pbmcgcmVwb3J0IGhlcmU/IgoJICAgICovCgkgICAgcmVzID0gWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREU7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwgcmVzLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkZhaWxlZCB0byBsb2FkIHRoZSBkb2N1bWVudCAnJXMnIGZvciBpbmNsdXNpb24iLAoJCXNjaGVtYUxvY2F0aW9uKTsKCX0gZWxzZSBpZiAoaGFzUmVkZWZpbml0aW9ucykgewoJICAgIC8qCgkgICAgKiBTUEVDIHNyYy1yZWRlZmluZSAoMSkKCSAgICAqICJJZiB0aGVyZSBhcmUgYW55IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbXMgYW1vbmcgdGhlIFtjaGlsZHJlbl0KCSAgICAqIG90aGVyIHRoYW4gPGFubm90YXRpb24+IHRoZW4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZQoJICAgICogc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gbXVzdCBzdWNjZXNzZnVsbHkgcmVzb2x2ZS4iCgkgICAgKiBUT0RPOiBBc2sgdGhlIFdHIGlmIGEgdGhlIGxvY2F0aW9uIGhhcyB0byByZXNvbHZlIGhlcmUgYXMgd2VsbCEKCSAgICAqLwoJICAgIHJlcyA9IFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORTsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LCByZXMsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiRmFpbGVkIHRvIGxvYWQgdGhlIGRvY3VtZW50ICclcycgZm9yIHJlZGVmaW5pdGlvbiIsCgkJc2NoZW1hTG9jYXRpb24pOwoJfQogICAgfQogICAgcmV0dXJuKHJlcyk7Cn0KCiNpZmRlZiBFTkFCTEVfUkVERUZJTkUKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVJlZGVmaW5lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmVzOwoKICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUocGN0eHQsIHNjaGVtYSwgbm9kZSwgMSk7CiAgICBpZiAocmVzICE9IDApCglyZXR1cm4ocmVzKTsKICAgIHJldHVybigwKTsKfQojZW5kaWYKCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmVzOwoKICAgIHJlcyA9IHhtbFNjaGVtYVBhcnNlSW5jbHVkZU9yUmVkZWZpbmUocGN0eHQsIHNjaGVtYSwgbm9kZSwgMCk7CiAgICBpZiAocmVzICE9IDApCglyZXR1cm4ocmVzKTsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAdHlwZTogdGhlICJjb21wb3NpdG9yIiB0eXBlCiAqIEBwYXJ0aWNsZU5lZWRlZDogaWYgYSBhIG1vZGVsIGdyb3VwIHdpdGggYSBwYXJ0aWNsZQogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2VxdWVuY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHJlZUl0ZW1QdHIKeG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJIHhtbE5vZGVQdHIgbm9kZSwgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSwKCQkJIGludCB3aXRoUGFydGljbGUpCnsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgaXRlbTsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyLCAqY29udGFpbmVyOwogICAgaW50IG1pbiA9IDAsIG1heCA9IDA7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIENyZWF0ZSBhIG1vZGVsIGdyb3VwIHdpdGggdGhlIGdpdmVuIGNvbXBvc2l0b3IuCiAgICAqLwogICAgaXRlbSA9IHhtbFNjaGVtYUFkZE1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCB0eXBlLCAmY29udGFpbmVyLCBub2RlKTsKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKE5VTEwpOwoKICAgIGlmICh3aXRoUGFydGljbGUpIHsKCWlmICh0eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpIHsKCSAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgMSwgMSwgIigwIHwgMSkiKTsKCSAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMSwgMSwgMSwgIjEiKTsKCX0gZWxzZSB7CgkgICAgLyogY2hvaWNlICsgc2VxdWVuY2UgKi8KCSAgICBtaW4gPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJ4czpub25OZWdhdGl2ZUludGVnZXIiKTsKCSAgICBtYXggPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLAoJCSIoeHM6bm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwoJfQoJeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgTlVMTCwgbm9kZSwgbWluLCBtYXgpOwoJLyoKCSogQ3JlYXRlIGEgcGFydGljbGUKCSovCglwYXJ0aWNsZSA9IHhtbFNjaGVtYUFkZFBhcnRpY2xlKGN0eHQsIHNjaGVtYSwgbm9kZSwgbWluLCBtYXgpOwoJaWYgKHBhcnRpY2xlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgaXRlbTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIE5VTEwsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIE5VTEwsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCiAgICB9CgogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICBpdGVtLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgY3R4dC0+Y29udGFpbmVyID0gY29udGFpbmVyOwogICAgaWYgKHR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgewoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCwgbGFzdCA9IE5VTEw7CgoJd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LAoJCXNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGlmIChwYXJ0ICE9IE5VTEwpIHsKCQlpZiAocGFydC0+bWluT2NjdXJzID4gMSkKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywKCQkJTlVMTCwgTlVMTCwgY2hpbGQsCgkJCSJJbnZhbGlkIHZhbHVlIGZvciBtaW5PY2N1cnMgKG11c3QgYmUgMCBvciAxKSIsIE5VTEwpOwoJCWlmIChwYXJ0LT5tYXhPY2N1cnMgPiAxKQoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUFYT0NDVVJTLAoJCQlOVUxMLCBOVUxMLCBjaGlsZCwKCQkJIkludmFsaWQgdmFsdWUgZm9yIG1heE9jY3VycyAobXVzdCBiZSAwIG9yIDEpIiwKCQkJTlVMTCk7CgkJaWYgKGxhc3QgPT0gTlVMTCkKCQkgICAgaXRlbS0+Y2hpbGRyZW4gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIHBhcnQ7CgkJZWxzZQoJCSAgICBsYXN0LT5uZXh0ID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0OwoJCWxhc3QgPSBwYXJ0OwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChhbm5vdGF0aW9uPywgZWxlbWVudCopIik7Cgl9CiAgICB9IGVsc2UgewoJLyogY2hvaWNlICsgc2VxdWVuY2UgKi8KCXhtbFNjaGVtYVRyZWVJdGVtUHRyIHBhcnQgPSBOVUxMLCBsYXN0ID0gTlVMTDsKCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSkgewoKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkJcGFydCA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCQkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJCXBhcnQgPQoJCSAgICB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgewoJCXBhcnQgPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlQW55KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKCQlwYXJ0ID0geG1sU2NoZW1hUGFyc2VNb2RlbEdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UsIDEpOwoJICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJCXBhcnQgPSB4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAxKTsKCSAgICB9CgkgICAgaWYgKHBhcnQgIT0gTlVMTCkgewoJCWlmIChsYXN0ID09IE5VTEwpCgkJICAgIGl0ZW0tPmNoaWxkcmVuID0gcGFydDsKCQllbHNlCgkJICAgIGxhc3QtPm5leHQgPSBwYXJ0OwoJCWxhc3QgPSBwYXJ0OwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChlbGVtZW50IHwgZ3JvdXAgfCBjaG9pY2UgfCBzZXF1ZW5jZSB8IGFueSkqKSIpOwoJfQogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgaWYgKHdpdGhQYXJ0aWNsZSkgewoJaWYgKChtaW4gPT0gMCkgJiYgKG1heCA9PSAwKSkKCSAgICByZXR1cm4gKE5VTEwpOwoJZWxzZQoJICAgIHJldHVybiAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0aWNsZSk7CiAgICB9IGVsc2UKCXJldHVybiAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFJlc3RyaWN0aW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIHhtbFNjaGVtYVR5cGVUeXBlIHBhcmVudFR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY2hhciBidWZbMzBdOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyLCAqY29udGFpbmVyOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKiBOb3QgYSBjb21wb25lbnQsIGRvbid0IGNyZWF0ZSBpdC4gKi8KICAgIHR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgogICAgLyoKICAgICogVE9ETzogSXMgdGhlIGNvbnRhaW5lciBuZWVkZWQgYXQgYWxsPyB0aGUgYW5vbnltb3VzCiAgICAqIGl0ZW1zIGluc2lkZSBzaG91bGQgZ2VuZXJhdGUgdW5pcXVlIG5hbWVzIGFscmVhZHkuCiAgICAqLwogICAgc25wcmludGYoYnVmLCAyOSwgIiNyZXN0ciVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICBjb250YWluZXIgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUIGJ1ZiwgLTEpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmFzZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAKICAgICovCiAgICAvKgogICAgKiBFeHRyYWN0IHRoZSBiYXNlIHR5cGUuIFRoZSAiYmFzZSIgYXR0cmlidXRlIGlzIG1hbmRhdG9yeSBpZiBpbnNpZGUKICAgICogYSBjb21wbGV4IHR5cGUgb3IgaWYgcmVkZWZpbmluZy4KICAgICoKICAgICogU1BFQyAoMS4yKSAiLi4ub3RoZXJ3aXNlICg8cmVzdHJpY3Rpb24+IGhhcyBubyA8c2ltcGxlVHlwZT4gIgogICAgKiBhbW9uZyBpdHMgW2NoaWxkcmVuXSksIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHdoaWNoIGlzCiAgICAqIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkKICAgICogdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwKCU5VTEwsIE5VTEwsIG5vZGUsICJiYXNlIiwKCSYodHlwZS0+YmFzZU5zKSwgJih0eXBlLT5iYXNlKSkgPT0gMCkKICAgIHsKCWlmICgodHlwZS0+YmFzZSA9PSBOVUxMKSAmJiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCXR5cGUsIG5vZGUsICJiYXNlIiwgTlVMTCk7Cgl9IGVsc2UgaWYgKChjdHh0LT5pc1JlZGVmaW5lKSAmJgoJICAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCXsKCSAgICBpZiAodHlwZS0+YmFzZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJICAgIHR5cGUsIG5vZGUsICJiYXNlIiwgTlVMTCk7CgkgICAgfSBlbHNlIGlmICgoISB4bWxTdHJFcXVhbCh0eXBlLT5iYXNlLCB0eXBlLT5uYW1lKSkgfHwKCQkoISB4bWxTdHJFcXVhbCh0eXBlLT5iYXNlTnMsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSkpKQoJICAgIHsKCQl4bWxDaGFyICpzdHIxID0gTlVMTCwgKnN0cjIgPSBOVUxMOwoJCS8qCgkJKiBSRURFRklORTogU1BFQyBzcmMtcmVkZWZpbmUgKDUpCgkJKiAiV2l0aGluIHRoZSBbY2hpbGRyZW5dLCBlYWNoIDxzaW1wbGVUeXBlPiBtdXN0IGhhdmUgYQoJCSogPHJlc3RyaWN0aW9uPiBhbW9uZyBpdHMgW2NoaWxkcmVuXSAuLi4gdGhlILdhY3R1YWwgdmFsdWW3IG9mCgkJKiB3aG9zZSBiYXNlIFthdHRyaWJ1dGVdIG11c3QgYmUgdGhlIHNhbWUgYXMgdGhlILdhY3R1YWwgdmFsdWW3CgkJKiBvZiBpdHMgb3duIG5hbWUgYXR0cmlidXRlIHBsdXMgdGFyZ2V0IG5hbWVzcGFjZTsiCgkJKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwgIlRoaXMgaXMgYSByZWRlZmluaXRpb24sIGJ1dCB0aGUgUU5hbWUgIgoJCSAgICAidmFsdWUgJyVzJyBvZiB0aGUgJ2Jhc2UnIGF0dHJpYnV0ZSBkb2VzIG5vdCBtYXRjaCB0aGUgIgoJCSAgICAidHlwZSdzIGRlc2lnbmF0aW9uICclcyciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyMSwgdHlwZS0+YmFzZU5zLCB0eXBlLT5iYXNlKSwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0cjEsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSwKCQkJdHlwZS0+bmFtZSksIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyMSk7CgkJRlJFRV9BTkRfTlVMTChzdHIyKTsKCSAgICB9Cgl9CQkKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+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/KSkiKTsKCX0KICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZUNvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgIGludCAqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkgfHwKCShoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24gPSAwOwogICAgLyogTm90IGEgY29tcG9uZW50LCBkb24ndCBjcmVhdGUgaXQuICovCiAgICB0eXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgTlVMTCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwkKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgTlVMTCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwkKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZXN0cmljdGlvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCk7CgkoKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pID0gMTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENvbXBsZXhDb250ZW50IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgKmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpIHx8CgkoaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbiA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgICpoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uID0gMDsKICAgIC8qIE5vdCBhIGNvbXBvbmVudCwgZG9uJ3QgY3JlYXRlIGl0LiAqLwogICAgdHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkpCgkgICAgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwoKICAgIC8qCiAgICAqIFNldCB0aGUgJ21peGVkJyBvbiB0aGUgY29tcGxleCB0eXBlIGFuY2VzdG9yLgogICAgKi8KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAibWl4ZWQiLCAwKSkgIHsKCWlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSA9PSAwKQoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJLyoKCSogQWRkIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBjb21wbGV4IHR5cGUgYW5jZXN0b3IuCgkqLwoJeG1sU2NoZW1hQWRkQW5ub3RhdGlvbigoeG1sU2NoZW1hQW5ub3RJdGVtUHRyKSB0eXBlLAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKSk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgTlVMTCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBOVUxMLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImV4dGVuc2lvbiIpKSB7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCwKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKTsKCSgqaGFzUmVzdHJpY3Rpb25PckV4dGVuc2lvbikgPSAxOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwKCSAgICBOVUxMLCAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBleHRlbnNpb24pKSIpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENvbXBsZXggVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lciwgKm5hbWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlOwogICAgY2hhciBidWZbNDBdOwogICAgaW50IGZpbmFsID0gMCwgYmxvY2sgPSAwLCBoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uID0gMDsKCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoKICAgIGlmICh0b3BMZXZlbCkgewoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgTlVMTCwgbm9kZSwgIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCSAgICBOVUxMLCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCiAgICB9CgogICAgaWYgKHRvcExldmVsID09IDApIHsKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgoJKi8KICAgICAgICBzbnByaW50ZihidWYsIDM5LCAiI0NUJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgKGNvbnN0IHhtbENoYXIgKilidWYsIE5VTEwsCgkgICAgbm9kZSwgMCk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CgluYW1lID0gdHlwZS0+bmFtZTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOwoJLyoKCSogVE9ETzogV2UgbmVlZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCiAgICB9IGVsc2UgewoJLyoKCSogUGFyc2UgYXMgZ2xvYmFsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgoJKi8KCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCgkgICAgbm9kZSwgMSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgfQogICAgdHlwZS0+dGFyZ2V0TmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZSAiaWQiLgoJCSovCgkJeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCB0eXBlLCBub2RlLAoJCSAgICBCQURfQ0FTVCAiaWQiKTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaXhlZCIpKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZSAibWl4ZWQiLgoJCSovCgkJaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsIE5VTEwsIHR5cGUsCgkJICAgICh4bWxOb2RlUHRyKSBhdHRyKSkKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKCSAgICB9IGVsc2UgaWYgKHRvcExldmVsKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZXMgb2YgZ2xvYmFsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9ucy4KCQkqLwoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSB7CgkJICAgIC8qIFBhc3MuICovCgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYWJzdHJhY3QiKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiYWJzdHJhY3QiLgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoY3R4dCwgTlVMTCwgdHlwZSwKCQkJKHhtbE5vZGVQdHIpIGF0dHIpKQoJCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImZpbmFsIi4KCQkgICAgKi8KCQkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwKCQkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwKCQkJJih0eXBlLT5mbGFncyksCgkJCS0xLAoJCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTiwKCQkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTiwKCQkJLTEsIC0xLCAtMSkgIT0gMCkKCQkgICAgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJICAgIHR5cGUsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLAoJCQkgICAgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKSIsCgkJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCSAgICB9IGVsc2UgCgkJCWZpbmFsID0gMTsKCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJibG9jayIuCgkJICAgICovCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsCgkJCSh4bWxOb2RlUHRyKSBhdHRyKTsKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYodHlwZS0+ZmxhZ3MpLAoJCQktMSwKCQkJWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT04sCgkJCVhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04sCgkJCS0xLCAtMSwgLTEpICE9IDApIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkJICAgICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkgIiwKCQkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIH0gZWxzZSAKCQkJYmxvY2sgPSAxOwoJCX0gZWxzZSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIHR5cGUsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICBpZiAoISBibG9jaykgewoJLyoKCSogQXBwbHkgZGVmYXVsdCAiYmxvY2siIHZhbHVlcy4KCSovCglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19FWFRFTlNJT047CiAgICB9CiAgICBpZiAoISBmaW5hbCkgewoJLyoKCSogQXBwbHkgZGVmYXVsdCAiYmxvY2siIHZhbHVlcy4KCSovCglpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjsKCWlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT047CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZUNvbnRlbnQiKSkgewoJLyoKCSogPGNvbXBsZXhUeXBlPjxzaW1wbGVDb250ZW50Pi4uLgoJKiAzLjQuMyA6IDIuMgoJKiBTcGVjaWZ5aW5nIG1peGVkPSd0cnVlJyB3aGVuIHRoZSA8c2ltcGxlQ29udGVudD4KCSogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuIGhhcyBubyBlZmZlY3QKCSovCglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJICAgIHR5cGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkgICAgJmhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhDb250ZW50IikpIHsKCS8qCgkqIDxjb21wbGV4VHlwZT48Y29tcGxleENvbnRlbnQ+Li4uCgkqLwoJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJICAgICZoYXNSZXN0cmljdGlvbk9yRXh0ZW5zaW9uKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIHsKCS8qCgkqIEUuZyA8Y29tcGxleFR5cGU+PHNlcXVlbmNlPi4uLiBvciA8Y29tcGxleFR5cGU+PGF0dHJpYnV0ZT4uLi4gZXRjLgoJKgoJKiBTUEVDCgkqICIuLi50aGUgdGhpcmQgYWx0ZXJuYXRpdmUgKG5laXRoZXIgPHNpbXBsZUNvbnRlbnQ+IG5vcgoJKiA8Y29tcGxleENvbnRlbnQ+KSBpcyBjaG9zZW4uIFRoaXMgY2FzZSBpcyB1bmRlcnN0b29kIGFzIHNob3J0aGFuZAoJKiBmb3IgY29tcGxleCBjb250ZW50IHJlc3RyaWN0aW5nIHRoZSC3dXItdHlwZSBkZWZpbml0aW9utywgYW5kIHRoZQoJKiBkZXRhaWxzIG9mIHRoZSBtYXBwaW5ncyBzaG91bGQgYmUgbW9kaWZpZWQgYXMgbmVjZXNzYXJ5LgoJKi8KCXR5cGUtPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoJLyoKCSogUGFyc2UgbW9kZWwgZ3JvdXBzLgoJKi8KICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCwgMSk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlTW9kZWxHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwKCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFLCAxKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZU1vZGVsR3JvdXBEZWZSZWYoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfQoJLyoKCSogUGFyc2UgYXR0cmlidXRlIGRlY2xzL3JlZnMuCgkqLwogICAgICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNpbXBsZUNvbnRlbnQgfCBjb21wbGV4Q29udGVudCB8ICIKCSAgICAiKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICgoYXR0cmlidXRlIHwgIgoJICAgICJhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpKSIpOwogICAgfQogICAgLyoKICAgICogUkVERUZJTkU6IFNQRUMgc3JjLXJlZGVmaW5lICg1KQogICAgKi8KICAgIGlmICh0b3BMZXZlbCAmJiBjdHh0LT5pc1JlZGVmaW5lICYmICghIGhhc1Jlc3RyaWN0aW9uT3JFeHRlbnNpb24pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19SRURFRklORSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCAiVGhpcyBpcyBhIHJlZGVmaW5pdGlvbiwgdGh1cyB0aGUgIgoJICAgICI8Y29tcGxleFR5cGU+IG11c3QgaGF2ZSBhIDxyZXN0cmljdGlvbj4gb3IgPGV4dGVuc2lvbj4gIgoJICAgICJncmFuZC1jaGlsZCIsIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIGEgbm9kZSBzZXQKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZVNjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUHRyIHNjaGVtYSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVBhcnNlIG9ubHkgYW5kIGlzIHVzZWQgaWYKICAgICogdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgdGhlIEFQSTsgaS5lLiBub3QKICAgICogYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGN0eHQtPmlzUzRTID0gMDsKICAgIGlmIChJU19TQ0hFTUEobm9kZSwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwojaWZkZWYgRU5BQkxFX1JFREVGSU5FCgl4bWxTY2hlbWFTY2hlbWFSZWZQdHIgcmVmOwojZW5kaWYKCiAgICAgICAgc2NoZW1hID0geG1sU2NoZW1hTmV3U2NoZW1hKGN0eHQpOwogICAgICAgIGlmIChzY2hlbWEgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidGFyZ2V0TmFtZXNwYWNlIik7CglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgJnZhbCk7CgkgICAgLyoKCSAgICAqIFRPRE86IFNob3VsZCB3ZSBwcm9jZWVkIHdpdGggYW4gaW52YWxpZCB0YXJnZXQgbmFtZXNwYWNlPwoJICAgICovCgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwoJICAgIGlmICh4bWxTdHJFcXVhbChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgeG1sU2NoZW1hTnMpKSB7CgkJLyoKCQkqIFdlIGFyZSBwYXJzaW5nIHRoZSBzY2hlbWEgZm9yIHNjaGVtYSEKCQkqLwoJCWN0eHQtPmlzUzRTID0gMTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gTlVMTDsKCX0KCS8qCgkqIEFkZCB0aGUgY3VycmVudCBucyBuYW1lIGFuZCBsb2NhdGlvbiB0byB0aGUgaW1wb3J0IHRhYmxlOwoJKiB0aGlzIGlzIG5lZWRlZCB0byBoYXZlIGEgY29uc2lzdGVudCBtZWNoYW5pc20sIHJlZ2FyZGxlc3MKCSogaWYgYWxsIHNjaGVtYXRhIGFyZSBjb25zdHJ1Y3RlZCBkeW5hbWljYWxseSBmaXJlZCBieSB0aGUKCSogaW5zdGFuY2Ugb3IgaWYgdGhlIHNjaGVtYSB0byBiZSB1c2VkIHdhcyBzcGVjaWZpZWQgdmlhCgkqIHRoZSBBUEkuCgkqIFRPRE8KCSovCiNpZmRlZiBFTkFCTEVfUkVERUZJTkUKCXJlZiA9IHhtbFNjaGVtYVNjaGVtYVJlZkNyZWF0ZSgpOwoJaWYgKHJlZiA9PSBOVUxMKSB7CSAgICAKCSAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CgkgICAgc2NoZW1hID0gTlVMTDsKCSAgICByZXR1cm4gTlVMTDsKCX0KCXJlZi0+c2NoZW1hID0gc2NoZW1hOwojZW5kaWYKCglpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQoY3R4dCwgJihzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSwKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CglpZiAoaW1wb3J0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQSW50ZXJuYWxFcnIoY3R4dCwgInhtbFNjaGVtYVBhcnNlU2NoZW1hIiwKCQkiZmFpbGVkIHRvIGFkZCBhbiBpbXBvcnQgZW50cnkiLCBOVUxMLCBOVUxMKTsJCQoJICAgIHhtbFNjaGVtYUZyZWUoc2NoZW1hKTsKCSAgICBzY2hlbWEgPSBOVUxMOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglpbXBvcnQtPnNjaGVtYUxvY2F0aW9uID0gY3R4dC0+VVJMOwoJLyoKCSogTk9URTogV2Ugd29uJ3Qgc2V0IHRoZSBkb2MgaGVyZSwgb3RoZXJ3aXNlIGl0IHdpbGwgYmUgZnJlZWQKCSogaWYgdGhlIGltcG9ydCBzdHJ1Y3QgaXMgZnJlZWQuCgkqIGltcG9ydC0+ZG9jID0gY3R4dC0+ZG9jOwoJKi8KCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMoY3R4dCwgc2NoZW1hLCBub2RlKTsKICAgICAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgbm9kZS0+Y2hpbGRyZW4pOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxEb2NQdHIgZG9jOwoKCWRvYyA9IG5vZGUtPmRvYzsKCiAgICAgICAgaWYgKChkb2MgIT0gTlVMTCkgJiYgKGRvYy0+VVJMICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIlRoZSBmaWxlIFwiJXNcIiBpcyBub3QgYSBYTUwgc2NoZW1hLlxuIiwgZG9jLT5VUkwsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiVGhlIGZpbGUgaXMgbm90IGEgWE1MIHNjaGVtYS5cbiIsIE5VTEwsIE5VTEwpOwoJfQoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwogICAgICAgICAgICBzY2hlbWEgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIGlmIChzY2hlbWEgIT0gTlVMTCkKCXNjaGVtYS0+Y291bnRlciA9IGN0eHQtPmNvdW50ZXI7CiAgICBjdHh0LT5uYmVycm9ycyA9IG5iZXJyb3JzOwojaWZkZWYgREVCVUcKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlKCkgZmFpbGVkXG4iKTsKI2VuZGlmCiAgICByZXR1cm4gKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW5nIHVzaW5nIFNjaGVtYXMJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlSZWFkaW5nL1dyaXRpbmcgU2NoZW1hcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZiAwIC8qIFdpbGwgYmUgZW5hYmxlZCBpZiBpdCBpcyBjbGVhciB3aGF0IG9wdGlvbnMgYXJlIG5lZWRlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVBhcnNlckN0eHRTZXRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG9wdGlvbnM6IGEgY29tYmluYXRpb24gb2YgeG1sU2NoZW1hUGFyc2VyT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHBhcnNlLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICBpbnQgb3B0aW9ucykKCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFQYXJzZU9wdGlvbi4KICAgICovCiAgICBmb3IgKGkgPSAxOyBpIDwgKGludCkgc2l6ZW9mKGludCkgKiA4OyBpKyspIHsKICAgICAgICBpZiAob3B0aW9ucyAmIDE8PGkpIHsKCSAgICByZXR1cm4gKC0xKTsKICAgICAgICB9CiAgICB9CiAgICBjdHh0LT5vcHRpb25zID0gb3B0aW9uczsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHRHZXRPcHRpb25zOgogKiBAY3R4dDogYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9mIHRoZSBwYXJzZXIgY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQoKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZQoJcmV0dXJuIChjdHh0LT5vcHRpb25zKTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KGNvbnN0IGNoYXIgKlVSTCkKewogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciByZXQ7CgogICAgaWYgKFVSTCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VyQ3R4dENyZWF0ZSgpOwogICAgaWYgKHJldCA9PSBOVUxMKQoJcmV0dXJuKE5VTEwpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dDoKICogQGRvYzogIGEgcHJlcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZG9jdW1lbnQuCiAqIE5CLiBUaGUgZG9jdW1lbnQgbWF5IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgcGFyc2luZyBwcm9jZXNzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dCh4bWxEb2NQdHIgZG9jKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoZG9jID09IE5VTEwpCiAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZXJDdHh0Q3JlYXRlKCk7CiAgICBpZiAocmV0ID09IE5VTEwpCglyZXR1cm4oTlVMTCk7CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIC8qIFRoZSBhcHBsaWNhdGlvbiBoYXMgcmVzcG9uc2liaWxpdHkgZm9yIHRoZSBkb2N1bWVudCAqLwogICAgcmV0LT5wcmVzZXJ2ZSA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+ZG9jICE9IE5VTEwgJiYgIWN0eHQtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2MoY3R4dC0+ZG9jKTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKSB7Cgl4bWxGcmVlKCh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtcyk7Cgl4bWxGcmVlKGN0eHQtPmFzc2VtYmxlKTsKICAgIH0KICAgIGlmIChjdHh0LT52Y3R4dCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KGN0eHQtPnZjdHh0KTsKICAgIH0KICAgIGlmIChjdHh0LT5sb2NhbEltcG9ydHMgIT0gTlVMTCkKCXhtbEZyZWUoKHhtbENoYXIgKikgY3R4dC0+bG9jYWxJbXBvcnRzKTsKICAgIGlmIChjdHh0LT5zdWJzdEdyb3VwcyAhPSBOVUxMKQoJeG1sSGFzaEZyZWUoY3R4dC0+c3Vic3RHcm91cHMsCgkgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZVN1YnN0R3JvdXApOwogICAgeG1sU2NoZW1hQ29udGFpbmVyRnJlZShjdHh0LT5jb21wQ29udGFpbmVyKTsgICAgCiAgICB4bWxEaWN0RnJlZShjdHh0LT5kaWN0KTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqCQkJQnVpbGRpbmcgdGhlIGNvbnRlbnQgbW9kZWxzCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUsIGludCBjb3VudGVyLCB4bWxBdXRvbWF0YVN0YXRlUHRyIGVuZCkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgdG1wOwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwgbWVtYmVyOwogICAgeG1sU2NoZW1hU3Vic3RHcm91cFB0ciBzdWJzdEdyb3VwOwogICAgaW50IGk7CgogICAgZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwogICAgLyoKICAgICogV3JhcCB0aGUgc3Vic3RpdHV0aW9uIGdyb3VwIHdpdGggYSBDSE9JQ0UuCiAgICAqLwogICAgc3RhcnQgPSBwY3R4dC0+c3RhdGU7CiAgICBpZiAoZW5kID09IE5VTEwpCgllbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CiAgICBzdWJzdEdyb3VwID0geG1sU2NoZW1hR2V0RWxlbWVudFN1YnN0aXR1dGlvbkdyb3VwKHBjdHh0LCBlbGVtRGVjbCk7CiAgICBpZiAoc3Vic3RHcm91cCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBHRVRfTk9ERShwYXJ0aWNsZSksCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvclN1YnN0R3JvdXAsICIKCSAgICAiZGVjbGFyYXRpb24gaXMgbWFya2VkIGhhdmluZyBhIHN1YnN0LiBncm91cCBidXQgbm9uZSAiCgkgICAgImF2YWlsYWJsZS5cbiIsIGVsZW1EZWNsLT5uYW1lLCBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIGlmIChjb3VudGVyID49IDApIHsKCS8qCgkqIE5PVEUgdGhhdCB3ZSBwdXQgdGhlIGRlY2xhcmF0aW9uIGluLCBldmVuIGlmIGl0J3MgYWJzdHJhY3QsCgkqLwoJdG1wID0geG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLCBzdGFydCwgTlVMTCwgY291bnRlcik7CiAgICAgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sIHRtcCwgZW5kLAoJICAgICAgICAgICAgZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKTsKCS8qCgkqIEFkZCBzdWJzdC4gZ3JvdXAgbWVtYmVycy4KCSovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwogICAgICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwgdG1wLCBlbmQsCgkJICAgICAgICAgICAgICAgbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwgbWVtYmVyKTsKCX0KICAgIH0gZWxzZSBpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkvKgoJKiBOT1RFIHRoYXQgd2UgcHV0IHRoZSBkZWNsYXJhdGlvbiBpbiwgZXZlbiBpZiBpdCdzIGFic3RyYWN0LAoJKi8KCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkgICAgc3RhcnQsIE5VTEwsCgkgICAgZWxlbURlY2wtPm5hbWUsIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsIGVsZW1EZWNsKSwgZW5kKTsKCS8qCgkqIEFkZCBzdWJzdC4gZ3JvdXAgbWVtYmVycy4KCSovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwoJICAgIHRtcCA9IHhtbEF1dG9tYXRhTmV3T25jZVRyYW5zMihwY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCSAgICAgICAgICAgICAgIG1lbWJlci0+bmFtZSwgbWVtYmVyLT50YXJnZXROYW1lc3BhY2UsCgkJCSAgICAgICAxLCAxLCBtZW1iZXIpOwoJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHRtcCwgZW5kKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKCWludCBtYXhPY2N1cnMgPSBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CgkgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CglpbnQgbWluT2NjdXJzID0gcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgoJY291bnRlciA9CgkgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwgbWluT2NjdXJzLAoJICAgIG1heE9jY3Vycyk7Cglob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCSAgICBzdGFydCwgTlVMTCwKCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpLAoJICAgIGhvcCk7CgkvKgoJICogQWRkIHN1YnN0LiBncm91cCBtZW1iZXJzLgoJICovCglmb3IgKGkgPSAwOyBpIDwgc3Vic3RHcm91cC0+bWVtYmVycy0+bmJJdGVtczsgaSsrKSB7CgkgICAgbWVtYmVyID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnN0R3JvdXAtPm1lbWJlcnMtPml0ZW1zW2ldOwoJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihwY3R4dC0+YW0sCgkJc3RhcnQsIE5VTEwsCgkJbWVtYmVyLT5uYW1lLCBtZW1iZXItPnRhcmdldE5hbWVzcGFjZSwgbWVtYmVyKSwKCQlob3ApOwoJfQoJeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLCBob3AsIHN0YXJ0LCBjb3VudGVyKTsKCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKHBjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwogICAgfQogICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkKCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgcGN0eHQtPnN0YXRlID0gZW5kOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvckVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgaWYgKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgcGFydGljbGUtPmNoaWxkcmVuKS0+ZmxhZ3MgJgoJWE1MX1NDSEVNQVNfRUxFTV9TVUJTVF9HUk9VUF9IRUFEKSB7CgkvKgoJKiBTdWJzdGl0dXRpb24gZ3JvdXBzLgoJKi8KCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cChjdHh0LCBwYXJ0aWNsZSwgLTEsIE5VTEwpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7Cgl4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwoKCWVsZW1EZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbjsKCglpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKCSAgICByZXR1cm47CglpZiAocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSB7CgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCSAgICBlbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwoJfSBlbHNlIGlmICgocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpICYmCgkgICAgICAgICAgIChwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMikpIHsKCSAgICAvKiBTcGVjaWFsIGNhc2UuICovCgkgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sIHN0YXJ0LCBOVUxMLAoJCWVsZW1EZWNsLT5uYW1lLCBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLCBlbGVtRGVjbCk7CgkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgc3RhcnQpOwoJfSBlbHNlIHsKCSAgICBpbnQgY291bnRlcjsKCSAgICBpbnQgbWF4T2NjdXJzID0gcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwoJCQkgICAgVU5CT1VOREVEIDogcGFydGljbGUtPm1heE9jY3VycyAtIDE7CgkgICAgaW50IG1pbk9jY3VycyA9IHBhcnRpY2xlLT5taW5PY2N1cnMgPCAxID8KCQkJICAgIDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCgkgICAgc3RhcnQgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMKTsKCSAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CgkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLCBzdGFydCwgTlVMTCwKCQllbGVtRGVjbC0+bmFtZSwgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwgZWxlbURlY2wpOwoJICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgc3RhcnQsIGNvdW50ZXIpOwoJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAoJCU5VTEwsIGNvdW50ZXIpOwoJfQoJaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkKCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBjdHh0LT5zdGF0ZSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWw6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcGFydGljbGU6ICB0aGUgcGFydGljbGUgY29tcG9uZW50CiAqIEBuYW1lOiAgdGhlIGNvbXBsZXggdHlwZSdzIG5hbWUgd2hvc2UgY29udGVudCBpcyBiZWluZyBidWlsdAogKgogKiBHZW5lcmF0ZSB0aGUgYXV0b21hdGEgc2VxdWVuY2UgbmVlZGVkIGZvciB0aGF0IHR5cGUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHBhcnRpY2xlID09IE5VTEwpIHsKCVBFUlJPUl9JTlQoInhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCIsICJwYXJ0aWNsZSBpcyBOVUxMIik7CSAgICAKCXJldHVybjsKICAgIH0KICAgIGlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsIiwgIm5vIHRlcm0gb24gcGFydGljbGUiKTsKCXJldHVybjsKICAgIH0KCiAgICBzd2l0Y2ggKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOiB7CgkgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQ7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsKCgkgICAgd2lsZCA9ICh4bWxTY2hlbWFXaWxkY2FyZFB0cikgcGFydGljbGUtPmNoaWxkcmVuOwoKCSAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKCSAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCQlpZiAod2lsZC0+YW55ID09IDEpIHsKCQkgICAgLyoKCQkgICAgKiBXZSBuZWVkIHRvIGFkZCBib3RoIHRyYW5zaXRpb25zOgoJCSAgICAqCgkJICAgICogMS4gdGhlIHsiKiIsICIqIn0gZm9yIGVsZW1lbnRzIGluIGEgbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBlbmQpOwoJCSAgICAvKgoJCSAgICAqIDIuIHRoZSB7IioifSBmb3IgZWxlbWVudHMgaW4gbm8gbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBwY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgTlVMTCwgd2lsZCk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIG5zID0gd2lsZC0+bnNTZXQ7CgkJICAgIGRvIHsKCQkJcGN0eHQtPnN0YXRlID0gc3RhcnQ7CgkJCXBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQkgICAgcGN0eHQtPnN0YXRlLCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgd2lsZCk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld05lZ1RyYW5zKHBjdHh0LT5hbSwKCQkJc3RhcnQsIGVuZCwgQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsCgkJCXdpbGQpOwoJCX0KCSAgICB9IGVsc2UgewoJCWludCBjb3VudGVyOwoJCXhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwoJCWludCBtYXhPY2N1cnMgPQoJCSAgICBwYXJ0aWNsZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/IFVOQk9VTkRFRCA6IHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxOwoJCWludCBtaW5PY2N1cnMgPQoJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIDwgMSA/IDAgOiBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMTsKCgkJY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCQlob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgkJaWYgKHdpbGQtPmFueSA9PSAxKSB7CgkJICAgIHBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHdpbGQpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBwY3R4dC0+c3RhdGUsIGhvcCk7CgkJICAgIHBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIocGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB3aWxkKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBob3ApOwoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCXBjdHh0LT5zdGF0ZSA9CgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKHBjdHh0LT5hbSwKCQkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgd2lsZCk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgaG9wKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld05lZ1RyYW5zKHBjdHh0LT5hbSwKCQkJc3RhcnQsIGhvcCwgQkFEX0NBU1QgIioiLCB3aWxkLT5uZWdOc1NldC0+dmFsdWUsCgkJCXdpbGQpOwoJCX0KCQl4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhwY3R4dC0+YW0sIGhvcCwgc3RhcnQsIGNvdW50ZXIpOwoJCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKHBjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwoJICAgIH0KCSAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CgkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CgkgICAgfQoJICAgIHBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgYnJlYWs7Cgl9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbEZvckVsZW1lbnQocGN0eHQsIHBhcnRpY2xlKTsKCSAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBzdWI7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIG1heCBhbmQgbWluIG9jY3VyYW5jZXMgYXJlIGRlZmF1bHQgKDEpIHRoZW4KICAgICAgICAgICAgICAgICAqIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlIHBhcnRpY2xlcyBvZiB0aGUgPHNlcXVlbmNlPi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDEpICYmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlID0gcGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJCQlvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IHBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwKCQkJCXBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLCBVTkJPVU5ERUQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBjb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBwY3R4dC0+c3RhdGU7CgoJCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKCQkJICAgIC8qCgkJCSAgICAgKiBlcHNpbG9uIG5lZWRlZCB0byBibG9jayBwcmV2aW91cyB0cmFucyBmcm9tCgkJCSAgICAgKiBiZWluZyBhbGxvd2VkIHRvIGVudGVyIGJhY2sgZnJvbSBhbm90aGVyCgkJCSAgICAgKiBjb25zdHJ1Y3QKCQkJICAgICAqLwoJCQkgICAgcGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwKCQkJCQkJcGN0eHQtPnN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJICAgIG9sZHN0YXRlLCBwY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocGFydGljbGUtPm1heE9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAocGFydGljbGUtPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sCgkJCSAgICBvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gcGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihwY3R4dC0+YW0sCgkJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwKCQkJICAgIHBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHBjdHh0LAoJCQkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBzdWIsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMocGN0eHQtPmFtLAoJCQkgICAgdG1wLCBvbGRzdGF0ZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIHRtcCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLAoJCQkJb2xkc3RhdGUsIHBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJCSh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgc3ViOwogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gcGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzIGFuZCByZW1lcmdlIHRoZSBlbmQgd2l0aCBhbgogICAgICAgICAgICAgICAgICogZXBzaWxvbiB0cmFuc2l0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID09IDEpIHsKCQkgICAgc3ViID0gcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChwY3R4dCwKCQkJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgc3ViLCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLCBlbmQpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcCwgYmFzZTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4T2NjdXJzID0gcGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwogICAgICAgICAgICAgICAgICAgICAgICBVTkJPVU5ERUQgOiBwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWluT2NjdXJzID0KICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljbGUtPm1pbk9jY3VycyA8IDEgPyAwIDogcGFydGljbGUtPm1pbk9jY3VycyAtIDE7CgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogdXNlIGEgY291bnRlciB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgdHJhbnN0aW9ucwogICAgICAgICAgICAgICAgICAgICAqIHdoaWNoIHdlbnQgdGhyb3VnaCB0aGUgY2hvaWNlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPQogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXIocGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CiAgICAgICAgICAgICAgICAgICAgaG9wID0geG1sQXV0b21hdGFOZXdTdGF0ZShwY3R4dC0+YW0pOwogICAgICAgICAgICAgICAgICAgIGJhc2UgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKHBjdHh0LT5hbSk7CgoJCSAgICBzdWIgPSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBwY3R4dC0+c3RhdGUgPSBiYXNlOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocGN0eHQsCgkJCSAgICAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1YiwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgaG9wKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBzdGFydCwgYmFzZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKHBjdHh0LT5hbSwgaG9wLCBiYXNlLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhwY3R4dC0+YW0sIGhvcCwgZW5kLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24ocGN0eHQtPmFtLCBzdGFydCwgZW5kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOnsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgkJeG1sU2NoZW1hUGFydGljbGVQdHIgc3ViOwoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CiAgICAgICAgICAgICAgICBpbnQgbGF4OwoKCQlzdWIgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICAgICAgICAgICAgICBpZiAoc3ViID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBzdGFydCA9IHBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoKCQkgICAgZWxlbURlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3ViLT5jaGlsZHJlbjsKCQkgICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCQkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsIiwKCQkJICAgICI8ZWxlbWVudD4gcGFydGljbGUgaGFzIG5vIHRlcm0iKTsKCQkJcmV0dXJuOwoJCSAgICB9OwoJCSAgICAvKgoJCSAgICAqIE5PVEU6IFRoZSB7bWF4IG9jY3Vyc30gb2YgYWxsIHRoZSBwYXJ0aWNsZXMgaW4gdGhlCgkJICAgICoge3BhcnRpY2xlc30gb2YgdGhlIGdyb3VwIG11c3QgYmUgMCBvciAxOyB0aGlzIGlzCgkJICAgICogYWxyZWFkeSBlbnN1cmVkIGR1cmluZyB0aGUgcGFyc2Ugb2YgdGhlIGNvbnRlbnQgb2YKCQkgICAgKiA8YWxsPi4KCQkgICAgKi8KCQkgICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fU1VCU1RfR1JPVVBfSEVBRCkgewoJCQlpbnQgY291bnRlcjsKCgkJICAgICAgICAvKgoJCQkgKiBUaGlzIGlzIGFuIGFic3RyYWN0IGdyb3VwLCB3ZSBuZWVkIHRvIHNoYXJlCgkJCSAqIHRoZSBzYW1lIGNvdW50ZXIgZm9yIGFsbCB0aGUgZWxlbWVudCB0cmFuc2l0aW9ucwoJCQkgKiBkZXJpdmVkIGZyb20gdGhlIGdyb3VwCgkJCSAqLwoJCQljb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKHBjdHh0LT5hbSwKCQkJICAgICAgICAgICAgICAgICAgIHN1Yi0+bWluT2NjdXJzLCBzdWItPm1heE9jY3Vycyk7CgkJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsRm9yU3Vic3RHcm91cChwY3R4dCwKCQkJCQkgICBzdWIsIGNvdW50ZXIsIHBjdHh0LT5zdGF0ZSk7CgkJICAgIH0gZWxzZSB7CgkJCWlmICgoc3ViLT5taW5PY2N1cnMgPT0gMSkgJiYKCQkJICAgIChzdWItPm1heE9jY3VycyA9PSAxKSkgewoJCQkgICAgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKHBjdHh0LT5hbSwgcGN0eHQtPnN0YXRlLAoJCQkJCQkgICAgcGN0eHQtPnN0YXRlLAoJCQkJCQkgICAgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSAgICBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkJCQkgICAgMSwgMSwgZWxlbURlY2wpOwoJCQl9IGVsc2UgaWYgKChzdWItPm1pbk9jY3VycyA9PSAwKSAmJgoJCQkgICAgKHN1Yi0+bWF4T2NjdXJzID09IDEpKSB7CgoJCQkgICAgeG1sQXV0b21hdGFOZXdDb3VudFRyYW5zMihwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwKCQkJCQkJICAgICBwY3R4dC0+c3RhdGUsCgkJCQkJCSAgICAgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSAgICAgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJCQkJICAgICAwLAoJCQkJCQkgICAgIDEsCgkJCQkJCSAgICAgZWxlbURlY2wpOwoJCQl9CgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBzdWIgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHN1Yi0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxheCA9IHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMDsKICAgICAgICAgICAgICAgIHBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdBbGxUcmFucyhwY3R4dC0+YW0sIHBjdHh0LT5zdGF0ZSwgTlVMTCwgbGF4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICAvKgoJICAgICogSWYgd2UgaGl0IGEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiwgdGhlbiB0aGlzIG1lYW5zIHRoYXQKCSAgICAqIGl0IHdhcyBlbXB0eSwgdGh1cyB3YXMgbm90IHN1YnN0aXR1dGVkIGZvciB0aGUgY29udGFpbmluZwoJICAgICogbW9kZWwgZ3JvdXAuIEp1c3QgZG8gbm90aGluZyBpbiB0aGlzIGNhc2UuCgkgICAgKi8KCSAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgoJICAgIHhtbFNjaGVtYVBJbnRlcm5hbEVycihwY3R4dCwgInhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCIsCgkJImZvdW5kIHVuZXhwZWN0ZWQgdGVybSBvZiB0eXBlICclcycgaW4gY29udGVudCBtb2RlbCBvZiBjb21wbGV4ICIKCQkidHlwZSAnJXMnIiwKCQl4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nKHBhcnRpY2xlLT5jaGlsZHJlbi0+dHlwZSksIG5hbWUpOwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICJVbmV4cGVjdGVkIHR5cGU6ICVkXG4iLCBwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUpOwogICAgICAgICAgICByZXR1cm47CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKgogKiBCdWlsZHMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIGNvbXBsZXggdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKCiAgICBpZiAoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8CgkodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpIHx8CgkoKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgJiYKCSh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKSkKCXJldHVybjsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAiQnVpbGRpbmcgY29udGVudCBtb2RlbCBmb3IgJXNcbiIsIG5hbWUpOwojZW5kaWYKCiAgICBjdHh0LT5hbSA9IHhtbE5ld0F1dG9tYXRhKCk7CiAgICBpZiAoY3R4dC0+YW0gPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICJDYW5ub3QgY3JlYXRlIGF1dG9tYXRhIGZvciBjb21wbGV4IHR5cGUgJXNcbiIsIG5hbWUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YUdldEluaXRTdGF0ZShjdHh0LT5hbSk7CiAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoY3R4dCwgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0eXBlLT5zdWJ0eXBlcywgbmFtZSk7CiAgICB4bWxBdXRvbWF0YVNldEZpbmFsU3RhdGUoY3R4dC0+YW0sIGN0eHQtPnN0YXRlKTsKICAgIHR5cGUtPmNvbnRNb2RlbCA9IHhtbEF1dG9tYXRhQ29tcGlsZShjdHh0LT5hbSk7CiAgICBpZiAodHlwZS0+Y29udE1vZGVsID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwKCSAgICAiRmFpbGVkIHRvIGNvbXBpbGUgdGhlIGNvbnRlbnQgbW9kZWwiLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sUmVnZXhwSXNEZXRlcm1pbmlzdCh0eXBlLT5jb250TW9kZWwpICE9IDEpIHsKICAgICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfTk9UX0RFVEVSTUlOSVNUSUMsCgkgICAgLyogWE1MX1NDSEVNQVNfRVJSX05PVERFVEVSTUlOSVNULCAqLwoJICAgIE5VTEwsIHR5cGUsIHR5cGUtPm5vZGUsCgkgICAgIlRoZSBjb250ZW50IG1vZGVsIGlzIG5vdCBkZXRlcm1pbmlzdCIsIE5VTEwpOwogICAgfSBlbHNlIHsKI2lmZGVmIERFQlVHX0NPTlRFTlRfUkVHRVhQCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJDb250ZW50IG1vZGVsIG9mICVzOlxuIiwgdHlwZS0+bmFtZSk7CiAgICAgICAgeG1sUmVnZXhwUHJpbnQoc3RkZXJyLCB0eXBlLT5jb250TW9kZWwpOwojZW5kaWYKICAgIH0KICAgIGN0eHQtPnN0YXRlID0gTlVMTDsKICAgIHhtbEZyZWVBdXRvbWF0YShjdHh0LT5hbSk7CiAgICBjdHh0LT5hbSA9IE5VTEw7Cn0KCi8qKgogKiB4bWxTY2hlbWFFbGVtZW50Rml4dXA6CiAqIEBlbGVtOiAgdGhlIHNjaGVtYSBlbGVtZW50IGNvbnRleHQKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIFJlc29sdmVzIHRoZSByZWZlcmVuY2VzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24KICogb3IgcGFydGljbGUsIHdoaWNoIGhhcyBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGFzIGl0J3MKICogdGVybS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUVsZW1lbnRGaXh1cCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW1EZWNsID09IE5VTEwpIHx8CgkoKGVsZW1EZWNsICE9IE5VTEwpICYmCgkoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9SRVNPTFZFRCkpKQogICAgICAgIHJldHVybjsKICAgIGVsZW1EZWNsLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX1JFU09MVkVEOwoKICAgIGlmICgoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpICYmIChlbGVtRGVjbC0+bmFtZWRUeXBlICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJLyogKHR5cGUgZGVmaW5pdGlvbikgLi4uIG90aGVyd2lzZSB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcKCSogdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlIFthdHRyaWJ1dGVdIC4uLgoJKi8KCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgZWxlbURlY2wtPm5hbWVkVHlwZSwKCSAgICBlbGVtRGVjbC0+bmFtZWRUeXBlTnMpOwoJaWYgKHR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgZWxlbURlY2wtPm5vZGUsCgkJInR5cGUiLCBlbGVtRGVjbC0+bmFtZWRUeXBlLCBlbGVtRGVjbC0+bmFtZWRUeXBlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7Cgl9IGVsc2UKCSAgICBlbGVtRGVjbC0+c3VidHlwZXMgPSB0eXBlOwogICAgfQogICAgaWYgKGVsZW1EZWNsLT5zdWJzdEdyb3VwICE9IE5VTEwpIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgc3Vic3RIZWFkOwoKCS8qCgkqIEZJWE1FIFRPRE86IERvIHdlIG5lZWQgYSBuZXcgZmllbGQgaW4gX3htbFNjaGVtYUVsZW1lbnQgZm9yCgkqIHN1YnN0aXR1dGlvbkdyb3VwPwoJKi8KCXN1YnN0SGVhZCA9IHhtbFNjaGVtYUdldEVsZW0oY3R4dC0+c2NoZW1hLCBlbGVtRGVjbC0+c3Vic3RHcm91cCwKCSAgICBlbGVtRGVjbC0+c3Vic3RHcm91cE5zKTsKCWlmIChzdWJzdEhlYWQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgTlVMTCwKCQkic3Vic3RpdHV0aW9uR3JvdXAiLCBlbGVtRGVjbC0+c3Vic3RHcm91cCwKCQllbGVtRGVjbC0+c3Vic3RHcm91cE5zLCBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYUVsZW1lbnRGaXh1cChzdWJzdEhlYWQsIGN0eHQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIC8qCgkgICAgKiBTZXQgdGhlICJzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb24iLgoJICAgICogTk9URSB0aGF0IG5vdyB3ZSB1c2UgdGhlICJyZWZEZWNsIiBmaWVsZCBmb3IgdGhpcy4KCSAgICAqLwoJICAgIGVsZW1EZWNsLT5yZWZEZWNsID0gc3Vic3RIZWFkOwoJICAgIC8qCgkgICAgKiAodHlwZSBkZWZpbml0aW9uKS4uLm90aGVyd2lzZSB0aGUge3R5cGUgZGVmaW5pdGlvbn0gb2YgdGhlCgkgICAgKiBlbGVtZW50IGRlY2xhcmF0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mCgkgICAgKiB0aGUgc3Vic3RpdHV0aW9uR3JvdXAgW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQKCSAgICAqLwoJICAgIGlmIChlbGVtRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkKCQllbGVtRGVjbC0+c3VidHlwZXMgPSBzdWJzdEhlYWQtPnN1YnR5cGVzOwoJfQogICAgfQogICAgaWYgKChlbGVtRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgJiYgKGVsZW1EZWNsLT5uYW1lZFR5cGUgPT0gTlVMTCkgJiYKCShlbGVtRGVjbC0+c3Vic3RHcm91cCA9PSBOVUxMKSkKCWVsZW1EZWNsLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZVVuaW9uTWVtYmVyVHlwZXM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzY2hlbWEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgYW5kIGJ1aWxkcyB0aGUgIm1lbWJlciB0eXBlIGRlZmluaXRpb25zIiBwcm9wZXJ0eSBvZiB0aGUgdW5pb24KICogc2ltcGxlIHR5cGUuIFRoaXMgaGFuZGxlcyBwYXJ0ICgxKSwgcGFydCAoMikgaXMgZG9uZSBpbgogKiB4bWxTY2hlbWFGaW5pc2hNZW1iZXJUeXBlRGVmaW5pdGlvbnNQcm9wZXJ0eSgpCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlc29sdmVVbmlvbk1lbWJlclR5cGVzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKCiAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBsaW5rLCBsYXN0TGluaywgbmV3TGluazsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbWVtYmVyVHlwZTsKCiAgICAvKgogICAgKiBTUEVDICgxKSAiSWYgdGhlIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIFtEZWZpbml0aW9uOl0KICAgICogZGVmaW5lIHRoZSBleHBsaWNpdCBtZW1iZXJzIGFzIHRoZSB0eXBlIGRlZmluaXRpb25zILdyZXNvbHZlZLcKICAgICogdG8gYnkgdGhlIGl0ZW1zIGluIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0sCiAgICAqIGlmIGFueSwgZm9sbG93ZWQgYnkgdGhlIHR5cGUgZGVmaW5pdGlvbnMgY29ycmVzcG9uZGluZyB0byB0aGUKICAgICogPHNpbXBsZVR5cGU+cyBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8dW5pb24+LCBpZiBhbnkuIgogICAgKi8KICAgIC8qCiAgICAqIFJlc29sdmUgcmVmZXJlbmNlcy4KICAgICovCiAgICBsaW5rID0gdHlwZS0+bWVtYmVyVHlwZXM7CiAgICBsYXN0TGluayA9IE5VTEw7CiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7Cgljb25zdCB4bWxDaGFyICpuYW1lLCAqbnNOYW1lOwoKCW5hbWUgPSAoKHhtbFNjaGVtYVFOYW1lUmVmUHRyKSBsaW5rLT50eXBlKS0+bmFtZTsKCW5zTmFtZSA9ICgoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGxpbmstPnR5cGUpLT50YXJnZXROYW1lc3BhY2U7CgoJbWVtYmVyVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBuYW1lLCBuc05hbWUpOwoJaWYgKChtZW1iZXJUeXBlID09IE5VTEwpIHx8ICghIElTX1NJTVBMRV9UWVBFKG1lbWJlclR5cGUpKSkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQl0eXBlLCB0eXBlLT5ub2RlLCAibWVtYmVyVHlwZXMiLAoJCW5hbWUsIG5zTmFtZSwgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7CgkgICAgLyoKCSAgICAqIFJlbW92ZSB0aGUgbWVtYmVyIHR5cGUgbGluay4KCSAgICAqLwoJICAgIGlmIChsYXN0TGluayA9PSBOVUxMKQoJCXR5cGUtPm1lbWJlclR5cGVzID0gbGluay0+bmV4dDsKCSAgICBlbHNlCgkJbGFzdExpbmstPm5leHQgPSBsaW5rLT5uZXh0OwoJICAgIG5ld0xpbmsgPSBsaW5rOwoJICAgIGxpbmsgPSBsaW5rLT5uZXh0OwoJICAgIHhtbEZyZWUobmV3TGluayk7Cgl9IGVsc2UgewoJICAgIGxpbmstPnR5cGUgPSBtZW1iZXJUeXBlOwoJICAgIGxhc3RMaW5rID0gbGluazsKCSAgICBsaW5rID0gbGluay0+bmV4dDsKCX0KICAgIH0KICAgIC8qCiAgICAqIEFkZCBsb2NhbCBzaW1wbGUgdHlwZXMsCiAgICAqLwogICAgbWVtYmVyVHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgd2hpbGUgKG1lbWJlclR5cGUgIT0gTlVMTCkgewoJbGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJaWYgKGxpbmsgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWxpbmstPnR5cGUgPSBtZW1iZXJUeXBlOwoJbGluay0+bmV4dCA9IE5VTEw7CglpZiAobGFzdExpbmsgPT0gTlVMTCkKCSAgICB0eXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CgllbHNlCgkgICAgbGFzdExpbmstPm5leHQgPSBsaW5rOwoJbGFzdExpbmsgPSBsaW5rOwoJbWVtYmVyVHlwZSA9IG1lbWJlclR5cGUtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWxUeXBlOiB0aGUgdmFsdWUgdHlwZQogKgogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgaGFzIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLCBvcgogKiBpcyBkZXJpdmVkIGZyb20gc3VjaCBhIHR5cGUuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCB2YWxUeXBlKQp7CiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGlmIChJU19DT01QTEVYX1RZUEUodHlwZSkpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gdmFsVHlwZSkKCSAgICByZXR1cm4oMSk7CglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHx8CgkgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoJICAgIHJldHVybiAoMCk7CglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGUtPnN1YnR5cGVzLCB2YWxUeXBlKSk7CiAgICB9IGVsc2UKCXJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUodHlwZS0+c3VidHlwZXMsIHZhbFR5cGUpKTsKCiAgICByZXR1cm4gKDApOwp9CgojaWYgMAovKioKICogeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWxUeXBlOiB0aGUgdmFsdWUgdHlwZQogKgogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgaGFzIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLCBvcgogKiBpcyBkZXJpdmVkIGZyb20gc3VjaCBhIHR5cGUuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzVXNlckRlcml2ZWRGcm9tQnVpbHRJblR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgdmFsVHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAoSVNfQ09NUExFWF9UWVBFKHR5cGUpKQoJcmV0dXJuICgwKTsKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IHZhbFR5cGUpCgkgICAgcmV0dXJuKDEpOwoJcmV0dXJuICgwKTsKICAgIH0gZWxzZQoJcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcywgdmFsVHlwZSkpOwoKICAgIHJldHVybiAoMCk7Cn0KI2VuZGlmCgpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFRdWVyeUJ1aWx0SW5UeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICBpZiAoSVNfQ09NUExFWF9UWVBFKHR5cGUpKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCSAgICByZXR1cm4odHlwZSk7CiAgICBlbHNlCglyZXR1cm4oeG1sU2NoZW1hUXVlcnlCdWlsdEluVHlwZSh0eXBlLT5zdWJ0eXBlcykpOwoKICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKCiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CgkvKgoJKiBOb3RlIHRoYXQgYW55U2ltcGxlVHlwZSBpcyBhY3R1YWxseSBub3QgYSBwcmltaXRpdmUgdHlwZQoJKiBidXQgd2UgbmVlZCB0aGF0IGhlcmUuCgkqLwoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSB8fAoJICAgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkpCgkgICAgcmV0dXJuICh0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CgojaWYgMAovKioKICogeG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3RvcjoKICogQHR5cGU6ICB0aGUgc2ltcGxlVHlwZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIHByaW1pdGl2ZSB0eXBlIG9mIHRoZSBnaXZlbiB0eXBlIG9yCiAqIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlQW5jZXN0b3IoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpIHx8IFZBUklFVFlfVU5JT04odHlwZSkpCglyZXR1cm4gKDApOwogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKQoJICAgIHJldHVybiAodHlwZSk7Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CgogICAgcmV0dXJuIChOVUxMKTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIEBjdXI6IHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbGlzdAogKiBAbGFzdFVzZTogdGhlIHRvcCBvZiB0aGUgYXR0cmlidXRlIHVzZSBsaXN0CiAqCiAqIEJ1aWxkcyB0aGUgYXR0cmlidXRlIHVzZXMgbGlzdCBvbiB0aGUgZ2l2ZW4gY29tcGxleCB0eXBlLgogKiBUaGlzIG9uZSBpcyBzdXBwb3NlZCB0byBiZSBjYWxsZWQgYnkKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uIG9ubHkuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgY3VyLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKnVzZXMsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqbGFzdFVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciB0bXA7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCWlmIChjdXItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgLyoKCSAgICAgKiBXM0M6ICIyIFRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXBzILdyZXNvbHZlZLcKCSAgICAgKiB0byBieSB0aGUgt2FjdHVhbCB2YWx1ZbdzIG9mIHRoZSByZWYgW2F0dHJpYnV0ZV0gb2YgdGhlCgkgICAgICogPGF0dHJpYnV0ZUdyb3VwPiBbY2hpbGRyZW5dLCBpZiBhbnkuIgoJICAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LAoJCSgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGN1ciktPmF0dHJpYnV0ZXMsIHVzZXMsCgkJbGFzdFVzZSkgPT0gLTEpIHsKCQlyZXR1cm4gKC0xKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qIFczQzogIjEgVGhlIHNldCBvZiBhdHRyaWJ1dGUgdXNlcyBjb3JyZXNwb25kaW5nIHRvIHRoZQoJICAgICAqIDxhdHRyaWJ1dGU+IFtjaGlsZHJlbl0sIGlmIGFueS4iCgkgICAgICovCgkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpCgkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYnVpbGRpbmcgYXR0cmlidXRlIHVzZXMiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgdG1wLT5hdHRyID0gY3VyOwoJICAgIHRtcC0+bmV4dCA9IE5VTEw7CgkgICAgaWYgKCp1c2VzID09IE5VTEwpCgkJKnVzZXMgPSB0bXA7CgkgICAgZWxzZQoJCSgqbGFzdFVzZSktPm5leHQgPSB0bXA7CgkgICAgKmxhc3RVc2UgPSB0bXA7Cgl9CgljdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVzdDogIHRoZSBkZXN0aW5hdGlvbiB3aWxkY2FyZAogKiBAc291cmNlOiB0aGUgc291cmNlIHdpbGRjYXJkCiAqCiAqIENsb25lcyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHNvdXJjZQogKiBhbmQgYXNzaWduZXMgdGhlbSB0byBkZXN0LgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpkZXN0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHNvdXJjZSkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIHRtcCwgbGFzdDsKCiAgICBpZiAoKHNvdXJjZSA9PSBOVUxMKSB8fCAoKmRlc3QgPT0gTlVMTCkpCglyZXR1cm4oLTEpOwogICAgKCpkZXN0KS0+YW55ID0gc291cmNlLT5hbnk7CiAgICBjdXIgPSBzb3VyY2UtPm5zU2V0OwogICAgbGFzdCA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHRtcCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7Cgl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCWlmIChsYXN0ID09IE5VTEwpCgkgICAgKCpkZXN0KS0+bnNTZXQgPSB0bXA7CgllbHNlCgkgICAgbGFzdC0+bmV4dCA9IHRtcDsKCWxhc3QgPSB0bXA7CgljdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBpZiAoKCpkZXN0KS0+bmVnTnNTZXQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KCgqZGVzdCktPm5lZ05zU2V0KTsKICAgIGlmIChzb3VyY2UtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSgqZGVzdCktPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAoKCpkZXN0KS0+bmVnTnNTZXQgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJKCpkZXN0KS0+bmVnTnNTZXQtPnZhbHVlID0gc291cmNlLT5uZWdOc1NldC0+dmFsdWU7CiAgICB9IGVsc2UKCSgqZGVzdCktPm5lZ05zU2V0ID0gTlVMTDsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGNvbXBsZXRlV2lsZDogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAY3VyV2lsZDogdGhlIHNlY29uZCB3aWxkY2FyZAogKgogKiBVbmlvbnMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIHVuaW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY29tcGxldGVXaWxkLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY3VyV2lsZCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckIsIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZQogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoKCQkvKgoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4KCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gYW55IG11c3QgYmUgdGhlIHZhbHVlCiAgICAqLwogICAgaWYgKGNvbXBsZXRlV2lsZC0+YW55ICE9IGN1cldpbGQtPmFueSkgewoJaWYgKGNvbXBsZXRlV2lsZC0+YW55ID09IDApIHsKCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogMyBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3KSwKICAgICogdGhlbiB0aGUgdW5pb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CglpbnQgZm91bmQ7Cgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHN0YXJ0OwoKCWN1ciA9IGN1cldpbGQtPm5zU2V0OwoJc3RhcnQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBzdGFydDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAodG1wID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJCXRtcC0+bmV4dCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IHRtcDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoKCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAqIDQgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCB2YWx1ZXMgKG5hbWVzcGFjZSBuYW1lcwogICAgKiBvciC3YWJzZW50tyksIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7Cgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7CgoJcmV0dXJuKDApOwogICAgfQogICAgLyoKICAgICAqIDUuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7CgoJaW50IG5zRm91bmQsIGFic2VudEZvdW5kID0gMDsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCSAgICBjdXJCID0gY3VyV2lsZC0+bmVnTnNTZXQ7Cgl9IGVsc2UgewoJICAgIGN1ciA9IGN1cldpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0OwoJfQoJbnNGb3VuZCA9IDA7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKQoJCWFic2VudEZvdW5kID0gMTsKCSAgICBlbHNlIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKQoJCW5zRm91bmQgPSAxOwoJICAgIGlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKQoJCWJyZWFrOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCglpZiAobnNGb3VuZCAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzIGJvdGggdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlCgkgICAgKiBuYW1lIGFuZCC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9IGVsc2UgaWYgKG5zRm91bmQgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKgoJICAgICogNS4yIElmIHRoZSBzZXQgUyBpbmNsdWRlcyB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgbmFtZQoJICAgICogYnV0IG5vdCC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0CgkgICAgKiBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjMgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3IGJ1dCBub3QgdGhlIG5lZ2F0ZWQKCSAgICAqIG5hbWVzcGFjZSBuYW1lLCB0aGVuIHRoZSB1bmlvbiBpcyBub3QgZXhwcmVzc2libGUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwKCQlYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUsCgkJIlRoZSB1bmlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGUuXG4iLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybihYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUpOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyoKCSAgICAqIDUuNCBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSBlaXRoZXIgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlCgkgICAgKiBuYW1lIG9yILdhYnNlbnS3LCB0aGVuIHdoaWNoZXZlciBvZiBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90CgkgICAgKiBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgICogNi4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7Cgl9Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJLyoKCQkqIDYuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcsIHRoZW4gYW55IG11c3QgYmUgdGhlCgkJKiB2YWx1ZS4KCQkqLwoJCWNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCQl9CgkJcmV0dXJuICgwKTsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA2LjIgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgt2Fic2VudLcsIHRoZW4gYSBwYWlyIG9mIG5vdAoJICAgICogYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICgwKTsKCn0KCi8qKgogKiB4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkCiAqCiAqIEludGVyc2VjdHMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIGludGVyc2VjdGlvbi4KICogUmV0dXJucyBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZSwgLTEgaW4gY2FzZSBvZiBhbgogKiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgcHJldiwgIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZQogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoKCQkvKgoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4KCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gdGhlIG90aGVyIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSAmJiAoY29tcGxldGVXaWxkLT5hbnkpKSB7CglpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAqIDMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgdmFsdWUgKGEgbmFtZXNwYWNlCiAgICAqIG5hbWUgb3Igt2Fic2VudLcpIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YgKG5hbWVzcGFjZSBuYW1lcyBvcgogICAgKiC3YWJzZW50tyksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkIHZhbHVlIGlmIGl0IHdhcyBpbgogICAgKiB0aGUgc2V0LCBtaW51cyC3YWJzZW50tyBpZiBpdCB3YXMgaW4gdGhlIHNldCwgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoJY29uc3QgeG1sQ2hhciAqbmVnOwoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpIHsKCSAgICBuZWcgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIG5lZyA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCS8qCgkqIFJlbW92ZSBhYnNlbnQgYW5kIG5lZ2F0ZWQuCgkqLwoJcHJldiA9IE5VTEw7CgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQlicmVhazsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAobmVnICE9IE5VTEwpIHsKCSAgICBwcmV2ID0gTlVMTDsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IG5lZykgewoJCSAgICBpZiAocHJldiA9PSBOVUxMKQoJCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCSAgICBlbHNlCgkJCXByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJICAgIHhtbEZyZWUoY3VyKTsKCQkgICAgYnJlYWs7CgkJfQoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0KCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKgogICAgKiA0IElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CglpbnQgZm91bmQ7CgoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQlpZiAocHJldiA9PSBOVUxMKQoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl0bXAgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWN1ciA9IHRtcDsKCQljb250aW51ZTsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CgoJcmV0dXJuKDApOwogICAgfQogICAgLyogNSBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IG5hbWVzcGFjZSBuYW1lcywKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIGlzIG5vdCBleHByZXNzaWJsZQogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpKSB7CgoJeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUsCgkgICAgIlRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybihYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFKTsKICAgIH0KICAgIC8qCiAgICAqIDYgSWYgdGhlIG9uZSBpcyBhIG5lZ2F0aW9uIG9mIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlcgogICAgKiBpcyBhIG5lZ2F0aW9uIG9mILdhYnNlbnS3LCB0aGVuIHRoZSBvbmUgd2hpY2ggaXMgdGhlIG5lZ2F0aW9uCiAgICAqIG9mIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSAgY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzdWI6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQHN1cGVyOiB0aGUgc2Vjb25kIHdpbGRjYXJkCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogV2lsZGNhcmQgU3Vic2V0IChjb3MtbnMtc3Vic2V0KQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50IG9mIEBzdWIgaXMgYW4gaW50ZW5zaW9uYWwKICogc3Vic2V0IG9mIEBzdXBlciwgMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TTlNTdWJzZXQoeG1sU2NoZW1hV2lsZGNhcmRQdHIgc3ViLAoJCQkgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHN1cGVyKQp7CiAgICAvKgogICAgKiAxIHN1cGVyIG11c3QgYmUgYW55LgogICAgKi8KICAgIGlmIChzdXBlci0+YW55KQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIDIuMSBzdWIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yILdhYnNlbnS3LgogICAgKiAyLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCB0aGUgc2FtZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKHN1Yi0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShzdXBlci0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShzdWItPm5lZ05zU2V0LT52YWx1ZSA9PSBzdWItPm5lZ05zU2V0LT52YWx1ZSkpCglyZXR1cm4gKDApOwogICAgLyoKICAgICogMy4xIHN1YiBtdXN0IGJlIGEgc2V0IHdob3NlIG1lbWJlcnMgYXJlIGVpdGhlciBuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcuCiAgICAqLwogICAgaWYgKHN1Yi0+bnNTZXQgIT0gTlVMTCkgewoJLyoKCSogMy4yLjEgc3VwZXIgbXVzdCBiZSB0aGUgc2FtZSBzZXQgb3IgYSBzdXBlcnNldCB0aGVyZW9mLgoJKi8KCWlmIChzdXBlci0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCOwoJICAgIGludCBmb3VuZCA9IDA7CgoJICAgIGN1ciA9IHN1Yi0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWN1ckIgPSBzdXBlci0+bnNTZXQ7CgkJd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQlmb3VuZCA9IDE7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGN1ckIgPSBjdXJCLT5uZXh0OwoJCX0KCQlpZiAoIWZvdW5kKQoJCSAgICByZXR1cm4gKDEpOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGZvdW5kKQoJCXJldHVybiAoMCk7Cgl9IGVsc2UgaWYgKHN1cGVyLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgkgICAgLyoKCSAgICAqIDMuMi4yIHN1cGVyIG11c3QgYmUgYSBwYWlyIG9mIG5vdCBhbmQgYSBuYW1lc3BhY2UgbmFtZSBvcgoJICAgICogt2Fic2VudLcgYW5kIHRoYXQgdmFsdWUgbXVzdCBub3QgYmUgaW4gc3ViJ3Mgc2V0LgoJICAgICovCgkgICAgY3VyID0gc3ViLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBzdXBlci0+bmVnTnNTZXQtPnZhbHVlKQoJCSAgICByZXR1cm4gKDEpOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAYXR0cnM6IHRoZSBhdHRyaWJ1dGUgbGlzdAogKiBAY29tcGxldGVXaWxkOiB0aGUgcmVzdWx0aW5nIGNvbXBsZXRlIHdpbGRjYXJkCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cnMsCgkJCQkgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciAqY29tcGxldGVXaWxkKQp7CiAgICB3aGlsZSAoYXR0cnMgIT0gTlVMTCkgewoJaWYgKGF0dHJzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgewoJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGdyb3VwOwoKCSAgICBncm91cCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgYXR0cnM7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcy4KCSAgICAqLwoJICAgIGlmIChncm91cC0+cmVmICE9IE5VTEwpIHsKCQlpZiAoZ3JvdXAtPnJlZkl0ZW0gPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIFRPRE86IFNob3VsZCB3ZSByYWlzZSBhIHdhcm5pbmcgaGVyZT8KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBUaGUgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBjb3VsZCBub3QKCQkgICAgKiBiZSByZXNvbHZlZCBiZWZvcmVoYW5kLCBzbyBza2lwLgoJCSAgICAqLwoJCSAgICBhdHRycyA9IGF0dHJzLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UKCQkgICAgZ3JvdXAgPSBncm91cC0+cmVmSXRlbTsKCSAgICB9CgkgICAgLyoKCSAgICAqIEZvciBldmVyeSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiwgYW4gaW50ZXJzZWN0ZWQgd2lsZGNhcmQKCSAgICAqIHdpbGwgYmUgY3JlYXRlZCAoYXNzdW1lZCB0aGF0IGEgd2lsZGNhcmQgZXhpc3RzIG9uIHRoZQoJICAgICogcGFydGljdWxhciBhdHRyLiBnci4gZGVmLiBvciBvbiBhbnkgY29udGFpbmVkIGF0dHIuIGdyLiBkZWYKCSAgICAqIGF0IGFsbCkuCgkgICAgKiBUaGUgZmxhZyBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCBlbnN1cmVzCgkgICAgKiB0aGF0IHRoZSBpbnRlcnNlY3Rpb24gd2lsbCBiZSBwZXJmb3JtZWQgb25seSBvbmNlLgoJICAgICovCgkgICAgaWYgKChncm91cC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCkgPT0gMCkgewoJCWlmIChncm91cC0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwKCQkJZ3JvdXAtPmF0dHJpYnV0ZXMsICZncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4gKC0xKTsKCQl9CgkJZ3JvdXAtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEOwoJICAgIH0KCSAgICBpZiAoZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCQlpZiAoKmNvbXBsZXRlV2lsZCA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogQ29weSB0aGUgZmlyc3QgZW5jb3VudGVyZWQgd2lsZGNhcmQgYXMgY29udGV4dCwgZXhjZXB0IGZvciB0aGUgYW5ub3RhdGlvbi4KCQkgICAgKgoJCSAgICAqIEFsdGhvdWdoIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCBtaWdodCBub3QgY29ycmVzcG9uZCB0byBhbnkKCQkgICAgKiBub2RlIGluIHRoZSBzY2hlbWEsIHdlIHdpbGwgc2F2ZSB0aGlzIGNvbnRleHQgbm9kZS4KCQkgICAgKi8KCQkgICAgKmNvbXBsZXRlV2lsZCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQsIGN0eHQtPnNjaGVtYSwKCQkJWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEUsCgkJCWdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bm9kZSk7CgkJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LAoJCQljb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPnByb2Nlc3NDb250ZW50cyA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPm5vZGUgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPm5vZGU7CgkJfSBlbHNlIGlmICh4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoY3R4dCwgKmNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJCSAgICAgaW50ICpmaXhlZCwKCQkJCSAgICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlLAoJCQkJICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKewogICAgKmZpeGVkID0gMDsKICAgICp2YWx1ZSA9IE5VTEw7CiAgICBpZiAodmFsICE9IDApCgkqdmFsID0gTlVMTDsKCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgPT0gTlVMTCkKCWl0ZW0gPSBpdGVtLT5yZWZEZWNsOwoKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGlmIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSB7CgkqdmFsdWUgPSBpdGVtLT5kZWZWYWx1ZTsKCWlmICh2YWwgIT0gMCkKCSAgICAqdmFsID0gaXRlbS0+ZGVmVmFsOwoJaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkKCSAgICAqZml4ZWQgPSAxOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ1ZDV2lsZGNhcmROYW1lc3BhY2U6CiAqIEB3aWxkOiAgdGhlIHdpbGRjYXJkCiAqIEBuczogIHRoZSBuYW1lc3BhY2UKICoKICogVmFsaWRhdGlvbiBSdWxlOiBXaWxkY2FyZCBhbGxvd3MgTmFtZXNwYWNlIE5hbWUKICogKGN2Yy13aWxkY2FyZC1uYW1lc3BhY2UpCiAqCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIG1hdGNoZXMgdGhlIHdpbGRjYXJkLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZSh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLAoJCQkJICAgY29uc3QgeG1sQ2hhciogbnMpCnsKICAgIGlmICh3aWxkID09IE5VTEwpCglyZXR1cm4oLTEpOwoKICAgIGlmICh3aWxkLT5hbnkpCglyZXR1cm4oMSk7CiAgICBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCgljdXIgPSB3aWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChjdXItPnZhbHVlLCBucykpCgkJcmV0dXJuKDEpOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0gZWxzZSBpZiAoKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChucyAhPSBOVUxMKSAmJgoJKCF4bWxTdHJFcXVhbCh3aWxkLT5uZWdOc1NldC0+dmFsdWUsIG5zKSkpCglyZXR1cm4oMSk7CgogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICoKICogQnVpbGRzIHRoZSB3aWxkY2FyZCBhbmQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFJldHVybnMgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGN1ciwgYmFzZSwgdG1wLCBpZCA9IE5VTEwsCglwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIGxhc3RVc2UgPSBOVUxMLCBsYXN0QmFzZVVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cnM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFueVR5cGU7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgaW50IGVyciA9IDA7CgogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgLyoKICAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIHdpdGggY29tcGxleCBjb250ZW50IFNjaGVtYSBDb21wb25lbnQuCiAgICAgKgogICAgICogQXR0cmlidXRlIHVzZXMuCiAgICAgKiBUT0RPOiBBZGQgY2hlY2tzIGZvciBhYnNlbnQgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGFuZAogICAgICogc2ltcGxlIHR5cGVzLgogICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyAhPSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24iLAoJICAgICJhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJ1aWxkZWQiKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmICh0eXBlLT5iYXNlVHlwZSA9PSBOVUxMKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24iLAoJICAgICJubyBiYXNlIHR5cGUiKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICAvKgogICAgICogSW5oZXJpdCB0aGUgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZS4KICAgICAqLwogICAgLyoKICAgICAqIE5PVEU6IEl0IGlzIGFsbG93ZWQgdG8gImV4dGVuZCIgdGhlIGFueVR5cGUgY29tcGxleCB0eXBlLgogICAgICovCiAgICBpZiAoISBJU19BTllUWVBFKGJhc2VUeXBlKSkgewoJaWYgKGJhc2VUeXBlICE9IE5VTEwpIHsKCSAgICBmb3IgKGN1ciA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVVc2VzOyBjdXIgIT0gTlVMTDsKCQljdXIgPSBjdXItPm5leHQpIHsKCQl0bXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0cikKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkocGN0eHQsCgkJCSJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyBvZiBjb21wbGV4VHlwZSIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdG1wOwoJCX0gZWxzZQoJCSAgICBsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQlsYXN0QmFzZVVzZSA9IHRtcDsKCSAgICB9Cgl9CiAgICB9CiAgICBhdHRycyA9IHR5cGUtPmF0dHJpYnV0ZXM7ICAgIAogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZSB3aWxkY2FyZHMuCiAgICAqLwogICAgZXJyID0geG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKHBjdHh0LAoJYXR0cnMsICZ0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCk7CiAgICAvKgogICAgKiBOT1RFOiBEdXJpbmcgdGhlIHBhcnNlIHRpbWUsIHRoZSB3aWxkY2FyZCBpcyBjcmVhdGVkIG9uIHRoZSBjb21wbGV4VHlwZQogICAgKiBkaXJlY3RseSwgaWYgZW5jb3VudGVyZWQgaW4gYSA8cmVzdHJpY3Rpb24+IG9yIDxleHRlbnNpb24+IGVsZW1lbnQuCiAgICAqLwogICAgaWYgKGVyciA9PSAtMSkgewoJUEVSUk9SX0lOVCgieG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uIiwKCSAgICAiZmFpbGVkIHRvIGJ1aWxkIGFuIGludGVyc2VjdGVkIGF0dHJpYnV0ZSB3aWxkY2FyZCIpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSAmJgoJKChJU19BTllUWVBFKGJhc2VUeXBlKSkgfHwKCSAoKGJhc2VUeXBlICE9IE5VTEwpICYmCgkgIChiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCSAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkpKSB7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBVbmlvbiB0aGUgY29tcGxldGUgd2lsZGNhcmQgd2l0aCB0aGUgYmFzZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyhwY3R4dCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQlyZXR1cm4gKC0xKTsKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIEp1c3QgaW5oZXJpdCB0aGUgd2lsZGNhcmQuCgkgICAgKi8KCSAgICAvKgoJICAgICogTk9URTogVGhpcyBpcyB0aGUgb25seSBjYXNlIHdoZXJlIGFuIGF0dHJpYnV0ZQogICAgICAgICAgICAqIHdpbGRjYXJkIGlzIHNoYXJlZC4KICAgICAgICAgICAgKi8KCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZDsKCX0KICAgIH0KCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkKCSAgICAqIDQuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGFsc28gaGF2ZSBvbmUuCgkgICAgKi8KCSAgICBpZiAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGhhcyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQsICIKCQkgICAgImJ1dCB0aGUgYmFzZSB0eXBlICVzIGRvZXMgbm90IGhhdmUgb25lIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfSBlbHNlIGlmICh4bWxTY2hlbWFDaGVja0NPU05TU3Vic2V0KAoJCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCBiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpKSB7CgkJLyogNC4yICovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIKCQkgICAgInN1YnNldCBvZiB0aGUgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICAvKiA0LjMgVW5sZXNzIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3dXItdHlwZQoJICAgICogZGVmaW5pdGlvbrcsIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUKCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSBtdXN0IGJlIGlkZW50aWNhbCB0byBvcgoJICAgICogc3Ryb25nZXIgdGhhbiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUKCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSwgd2hlcmUgc3RyaWN0IGlzIHN0cm9uZ2VyCgkgICAgKiB0aGFuIGxheCBpcyBzdHJvbmdlciB0aGFuIHNraXAuCgkgICAgKi8KCSAgICBpZiAoKCEgSVNfQU5ZVFlQRShiYXNlVHlwZSkpICYmCgkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8zLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlICdwcm9jZXNzIGNvbnRlbnRzJyBvZiB0aGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzICIKCQkgICAgIndlYWtlciB0aGFuIHRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0KCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJLyoKCSogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKQoJKiBBdCB0aGlzIHBvaW50IHRoZSB0eXBlIGFuZCB0aGUgYmFzZSBoYXZlIGJvdGgsIGVpdGhlcgoJKiBubyB3aWxkY2FyZCBvciBhIHdpbGRjYXJkLgoJKi8KCWlmICgoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkgICAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkpIHsKCSAgICAvKiAxLjMgKi8KCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NOU1N1YnNldCgKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIgoJCSAgICAic3VwZXJzZXQgb2YgdGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfQoJfQogICAgfQoKICAgIC8qCiAgICAgKiBHYXRoZXIgYXR0cmlidXRlIHVzZXMgZGVmaW5lZCBieSB0aGlzIHR5cGUuCiAgICAgKi8KICAgIGlmIChhdHRycyAhPSBOVUxMKSB7CglpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQocGN0eHQsIGF0dHJzLAoJICAgICZ1c2VzLCAmbGFzdFVzZSkgPT0gLTEpIHsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCA0LgogICAgICogIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QKICAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLiIKICAgICAqCiAgICAgKiBGb3IgImV4dGVuc2lvbiIgdGhpcyBpcyBkb25lIGZ1cnRoZXIgZG93bi4KICAgICAqLwogICAgaWYgKCh1c2VzICE9IE5VTEwpICYmICgodHlwZS0+ZmxhZ3MgJgoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSA9PSAwKSkgewoJY3VyID0gdXNlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIHRtcCA9IGN1ci0+bmV4dDsKCSAgICB3aGlsZSAodG1wICE9IE5VTEwpIHsKCQlpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksCgkJICAgIHhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCSAgICAoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciksCgkJICAgIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKHBjdHh0LAoJCQlYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsCgkJCXR5cGUsIGN1ci0+YXR0ciwKCQkJIkR1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlICVzIHNwZWNpZmllZCIsCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJCSAgICB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSwKCQkJICAgIHhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGJyZWFrOwoJCX0KCQl0bXAgPSB0bXAtPm5leHQ7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0KICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCS8qCgkgKiBEZXJpdmUgYnkgcmVzdHJpY3Rpb24uCgkgKi8KCWlmIChJU19BTllUWVBFKGJhc2VUeXBlKSkgewoJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwoJfSBlbHNlIHsKCSAgICBpbnQgZm91bmQsIHZhbGlkOwoJICAgIGNvbnN0IHhtbENoYXIgKmJFZmZWYWx1ZTsKCSAgICBpbnQgZWZmRml4ZWQ7CgoJICAgIGN1ciA9IHVzZXM7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCXZhbGlkID0gMTsKCQliYXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCQl3aGlsZSAoYmFzZSAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkgJiYKCQkJeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciksCgkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShiYXNlLT5hdHRyKSkpIHsKCgkJCWZvdW5kID0gMTsKCQkJCgkJCWlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0KCQkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09CgkJCSAgICBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIE5PT1AuCgkJCSAgICAqLwoJCQl9IGVsc2UgaWYgKChjdXItPmF0dHItPm9jY3VycyA9PQoJCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09CgkJCSAgICBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMi4xLjEKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihwY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCQl0eXBlLCBjdXItPmF0dHIsCgkJCQkiVGhlICdvcHRpb25hbCcgdXNlIGlzIGluY29uc2lzdGVudCB3aXRoIGEgIgoJCQkJIm1hdGNoaW5nICdyZXF1aXJlZCcgdXNlIG9mIHRoZSBiYXNlIHR5cGUiLAoJCQkJTlVMTCk7CgkJCX0gZWxzZSBpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09CgkJCSAgICBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSAmJgoJCQkgICAgKGJhc2UtPmF0dHItPm9jY3VycyA9PQoJCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDMKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8zLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJCSJBIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgZm9yIHRoZSAncmVxdWlyZWQnICIKCQkJCSJhdHRyaWJ1dGUgdXNlICclcycgb2YgdGhlIGJhc2UgdHlwZSBpcyAiCgkJCQkibWlzc2luZyIsCgkJCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGJhc2UtPmF0dHIpLAoJCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUoYmFzZS0+YXR0cikpKTsKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQl9IGVsc2UgaWYgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soCgkJCSAgICBjdXItPmF0dHItPnN1YnR5cGVzLCBiYXNlLT5hdHRyLT5zdWJ0eXBlcywgMCkgIT0gMCkgewoJCQkgICAgCQkJICAgIAoJCQkgICAgLyoKCQkJICAgICogU1BFQyAoMi4xLjIpICJSJ3Mge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0ncwoJCQkgICAgKiB7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tCgkJCSAgICAqIEIncyB7dHlwZSBkZWZpbml0aW9ufSBnaXZlbiB0aGUgZW1wdHkgc2V0IGFzCgkJCSAgICAqIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4iCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIocGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8yLAoJCQkJdHlwZSwgY3VyLT5hdHRyLAoJCQkJIlRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24ncyB0eXBlICIKCQkJCSJkZWZpbml0aW9uIGlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSAiCgkJCQkidGhlIGNvcnJlc3BvbmRpbmcgZGVmaW5pdGlvbiBpbiB0aGUgIgoJCQkJImJhc2UgdHlwZSIsIE5VTEwpOwkJCSAgICAKCQkJfSBlbHNlIHsKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zIFtEZWZpbml0aW9uOl0gIExldCB0aGUgZWZmZWN0aXZlIHZhbHVlCgkJCSAgICAqIGNvbnN0cmFpbnQgb2YgYW4gYXR0cmlidXRlIHVzZSBiZSBpdHMge3ZhbHVlCgkJCSAgICAqIGNvbnN0cmFpbnR9LCBpZiBwcmVzZW50LCBvdGhlcndpc2UgaXRzIHthdHRyaWJ1dGUKCQkJICAgICogZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9IC4KCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYmFzZS0+YXR0ciwKCQkJCSZlZmZGaXhlZCwgJmJFZmZWYWx1ZSwgTlVMTCk7CgkJCSAgICAvKgoJCQkgICAgKiAyLjEuMyAuLi4gb25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlCgkJCSAgICAqCgkJCSAgICAqIDIuMS4zLjEgQidzILdlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludLcgaXMKCQkJICAgICogt2Fic2VudLcgb3IgZGVmYXVsdC4KCQkJICAgICovCgkJCSAgICBpZiAoKGJFZmZWYWx1ZSAhPSBOVUxMKSAmJgoJCQkJKGVmZkZpeGVkID09IDEpKSB7CgkJCQljb25zdCB4bWxDaGFyICpyRWZmVmFsdWUgPSBOVUxMOwoJCQkJCgkJCQl4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYmFzZS0+YXR0ciwKCQkJCSAgICAmZWZmRml4ZWQsICZyRWZmVmFsdWUsIE5VTEwpOwoJCQkJICAgIC8qCgkJCQkgICAgKiAyLjEuMy4yIFIncyC3ZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnS3IGlzCgkJCQkgICAgKiBmaXhlZCB3aXRoIHRoZSBzYW1lIHN0cmluZyBhcyBCJ3MuCgkJCQkgICAgKiBUT0RPOiBDb21wYXJlIHRoZSBjb21wdXRlZCB2YWx1ZXMuCgkJCQkqLwoJCQkJaWYgKChlZmZGaXhlZCA9PSAwKSB8fAoJCQkJICAgICghIHhtbFN0ckVxdWFsKHJFZmZWYWx1ZSwgYkVmZlZhbHVlKSkpIHsKCQkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihwY3R4dCwKCQkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8zLAoJCQkJCXR5cGUsIGN1ci0+YXR0ciwKCQkJCQkiVGhlIGVmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJCQkJImF0dHJpYnV0ZSB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggIgoJCQkJCSJpdHMgY29ycmVzcG9uZGVudCBvZiB0aGUgYmFzZSB0eXBlIiwKCQkJCQlOVUxMKTsKCQkJCX0gZWxzZSB7CgkJCQkgICAgLyoKCQkJCSAgICAqIE92ZXJyaWRlIHRoZSBhdHRyaWJ1dGUgdXNlLgoJCQkJICAgICovCgkJCQkgICAgYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJCX0KCQkJICAgIH0gZWxzZQkJCQkKCQkJCWJhc2UtPmF0dHIgPSBjdXItPmF0dHI7CgkJCX0KCgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGJhc2UgPSBiYXNlLT5uZXh0OwoJCX0KCgkJaWYgKCghZm91bmQpICYmIChjdXItPmF0dHItPm9jY3VycyAhPQoJCQlYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSkgewoJCSAgICAvKgoJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMgoJCSAgICAqLwoJCSAgICBpZiAoKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB8fAoJCQkoeG1sU2NoZW1hQ2hlY2tDVkNXaWxkY2FyZE5hbWVzcGFjZSgKCQkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCQljdXItPmF0dHItPnRhcmdldE5hbWVzcGFjZSkgIT0gMSkpIHsKCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnIocGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMiwKCQkJICAgIHR5cGUsIGN1ci0+YXR0ciwKCQkJICAgICJOZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkgICAgIm5vciBhIG1hdGNoaW5nIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgZG9lcyBleGlzdCIsCgkJCSAgICBOVUxMKTsKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBBZGQgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSoKCQkJKiBOb3RlIHRoYXQgdGhpcyBtYXkgbGVhZCB0byBmdW5ueSBkZXJpdmF0aW9uIGVycm9yIHJlcG9ydHMsIGlmCgkJCSogbXVsdGlwbGUgZXF1YWwgYXR0cmlidXRlIHVzZXMgZXhpc3Q7IGJ1dCB0aGlzIGlzIG5vdAoJCQkqIGFsbG93ZWQgYW55d2F5LCBhbmQgaXQgd2lsbCBiZSByZXBvcnRlZCBiZWZvcmVoYW5kLgoJCQkqLwoJCQl0bXAgPSBjdXI7CgkJCWlmIChwcmV2ICE9IE5VTEwpCgkJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCQllbHNlCgkJCSAgICB1c2VzID0gY3VyLT5uZXh0OwoJCQljdXIgPSBjdXItPm5leHQ7CgkJCXRtcC0+bmV4dCA9IE5VTEw7CgkJCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJCX0gZWxzZQoJCQkgICAgbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJCWxhc3RCYXNlVXNlID0gdG1wOwoJCQkKCQkJY29udGludWU7CgkJICAgIH0KCQl9CgkJcHJldiA9IGN1cjsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodXNlcyk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsKCS8qCgkgKiBUaGUgc3BlYyBhbGxvd3Mgb25seSBhcHBlbmRpbmcsIGFuZCBub3Qgb3RoZXIga2luZHMgb2YgZXh0ZW5zaW9ucy4KCSAqCgkgKiBUaGlzIGVuc3VyZXM6IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKSA6IDEuMgoJICovCglpZiAodXNlcyAhPSBOVUxMKSB7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwoJICAgIH0gZWxzZQoJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdXNlczsKCX0KICAgIH0gZWxzZSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24iLAoJICAgICJubyBkZXJpdmF0aW9uIG1ldGhvZCIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0CgkgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4KCSAgICAqCgkgICAgKiBOb3RlIHRoYXQgdGhpcyB3YXMgYWxyZWFkeSBkb25lIGZvciAicmVzdHJpY3Rpb24iIGFuZCB0eXBlcyBkZXJpdmVkIGZyb20KCSAgICAqIHRoZSB1ci10eXBlLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsKCQl0bXAgPSBjdXItPm5leHQ7CgkJd2hpbGUgKHRtcCAhPSBOVUxMKSB7CgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwKCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJCSh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyICksCgkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpKSkpIHsKCgkJCXhtbFNjaGVtYVBBdHRyVXNlRXJyKHBjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF80LAoJCQkgICAgdHlwZSwgdG1wLT5hdHRyLAoJCQkgICAgIkR1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlIHNwZWNpZmllZCIsIE5VTEwpOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogNS4gVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdAoJICAgICogbm90IGhhdmUge3R5cGUgZGVmaW5pdGlvbn1zIHdoaWNoIGFyZSBvciBhcmUgZGVyaXZlZCBmcm9tIElELgoJICAgICovCgkgICAgaWYgKChjdXItPmF0dHItPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdXItPmF0dHItPnN1YnR5cGVzLAoJCSAgICBYTUxfU0NIRU1BU19JRCkpKSB7CgkJaWYgKGlkICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNSwKCQkJdHlwZSwgY3VyLT5hdHRyLAoJCQkiVGhlcmUgbXVzdCBub3QgZXhpc3QgbW9yZSB0aGFuIG9uZSBhdHRyaWJ1dGUgdXNlLCAiCgkJCSJkZWNsYXJlZCBvZiB0eXBlICdJRCcgb3IgZGVyaXZlZCBmcm9tIGl0IiwKCQkJTlVMTCk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCX0KCQlpZCA9IGN1cjsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJlbW92ZSAicHJvaGliaXRlZCIgYXR0cmlidXRlIHVzZXMuIFRoZSByZWFzb24gdGhpcyBpcyBkb25lIGF0IHRoaXMgbGF0ZQoJICAgICogc3RhZ2UgaXMgdG8gYmUgYWJsZSB0byBjYXRjaCBkdWJsaWNhdGUgYXR0cmlidXRlIHVzZXMuIFNvIHdlIGhhZCB0byBrZWVwCgkgICAgKiBwcm9oaWJpdGVkIHVzZXMgaW4gdGhlIGxpc3QgYXMgd2VsbC4KCSAgICAqLwoJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJdG1wID0gY3VyOwoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCWN1ciA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKHRtcCk7CgkgICAgfSBlbHNlIHsKCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgICogVE9ETzogVGhpcyBjaGVjayBzaG91bGQgYmUgcmVtb3ZlZCBpZiB3ZSBhcmUgMTAwJSBzdXJlIG9mCiAgICAgKiB0aGUgYmFzZSB0eXBlIGF0dHJpYnV0ZSB1c2VzIGFscmVhZHkgYmVpbmcgYnVpbHQuCiAgICAgKi8KICAgIGlmICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgKCEgSVNfQU5ZVFlQRShiYXNlVHlwZSkpICYmCgkoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkoSVNfTk9UX1RZUEVGSVhFRChiYXNlVHlwZSkpKSB7CglQRVJST1JfSU5UKCJ4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24iLAoJICAgICJhdHRyaWJ1dGUgdXNlcyBub3QgYnVpbGRlZCBvbiBiYXNlIHR5cGUiKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRmluYWxDb250YWluczoKICogQHNjaGVtYTogIHRoZSBzY2hlbWEKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBmaW5hbDogdGhlIGZpbmFsCiAqCiAqIEV2YWx1YXRlcyBpZiBhIHR5cGUgZGVmaW5pdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gImZpbmFsIi4KICogVGhpcyBkb2VzIHRha2UgImZpbmFsRGVmYXVsdCIgaW50byBhY2NvdW50IGFzIHdlbGwuCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBkb2VzIGNvbnRhaW50IHRoZSBnaXZlbiAiZmluYWwiLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgZmluYWwpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgaWYgKHR5cGUtPmZsYWdzICYgZmluYWwpCglyZXR1cm4gKDEpOwogICAgZWxzZQoJcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzOgogKiBAdHlwZTogIHRoZSBVbmlvbiBTaW1wbGUgVHlwZQogKgogKiBSZXR1cm5zIGEgbGlzdCBvZiBtZW1iZXIgdHlwZXMgb2YgQHR5cGUgaWYgZXhpc3RpbmcsCiAqIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZUxpbmtQdHIKeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB3aGlsZSAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkpIHsKCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJICAgIHJldHVybiAodHlwZS0+bWVtYmVyVHlwZXMpOwoJZWxzZQoJICAgIHR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW46CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWZmZWN0aXZlIFRvdGFsIFJhbmdlCiAqIChhbGwgYW5kIHNlcXVlbmNlKSArIChjaG9pY2UpCiAqCiAqIFJldHVybnMgdGhlIG1pbmltdW4gRWZmZWN0aXZlIFRvdGFsIFJhbmdlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW4oeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmICgocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHx8CgkocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSkKCXJldHVybiAoMCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWludCBtaW4gPSAtMSwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWlmIChwYXJ0ID09IE5VTEwpCgkgICAgcmV0dXJuICgwKTsKCXdoaWxlIChwYXJ0ICE9IE5VTEwpIHsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5taW5PY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihwYXJ0KTsKCSAgICBpZiAoY3VyID09IDApCgkJcmV0dXJuICgwKTsKCSAgICBpZiAoKG1pbiA+IGN1cikgfHwgKG1pbiA9PSAtMSkpCgkJbWluID0gY3VyOwoJICAgIHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQ7Cgl9CglyZXR1cm4gKHBhcnRpY2xlLT5taW5PY2N1cnMgKiBtaW4pOwogICAgfSBlbHNlIHsKCS8qIDxhbGw+IGFuZCA8c2VxdWVuY2U+ICovCglpbnQgc3VtID0gMDsKCXhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnQgPQoJICAgICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgcGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbjsKCglpZiAocGFydCA9PSBOVUxMKQoJICAgIHJldHVybiAoMCk7CglkbyB7CgkgICAgaWYgKChwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgfHwKCQkocGFydC0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkpCgkJc3VtICs9IHBhcnQtPm1pbk9jY3VyczsKCSAgICBlbHNlCgkJc3VtICs9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihwYXJ0KTsKCSAgICBwYXJ0ID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0LT5uZXh0OwoJfSB3aGlsZSAocGFydCAhPSBOVUxMKTsKCXJldHVybiAocGFydGljbGUtPm1pbk9jY3VycyAqIHN1bSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNYXg6CiAqIEBwYXJ0aWNsZTogdGhlIHBhcnRpY2xlCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWZmZWN0aXZlIFRvdGFsIFJhbmdlCiAqIChhbGwgYW5kIHNlcXVlbmNlKSArIChjaG9pY2UpCiAqCiAqIFJldHVybnMgdGhlIG1heGltdW0gRWZmZWN0aXZlIFRvdGFsIFJhbmdlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNYXgoeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGUpCnsKICAgIGlmICgocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpIHx8CgkocGFydGljbGUtPmNoaWxkcmVuLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybiAoMCk7CiAgICBpZiAocGFydGljbGUtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpIHsKCWludCBtYXggPSAtMSwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWZvciAoOyBwYXJ0ICE9IE5VTEw7IHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQpIHsKCSAgICBpZiAocGFydC0+Y2hpbGRyZW4gPT0gTlVMTCkKCQljb250aW51ZTsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5tYXhPY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heChwYXJ0KTsKCSAgICBpZiAoY3VyID09IFVOQk9VTkRFRCkKCQlyZXR1cm4gKFVOQk9VTkRFRCk7CgkgICAgaWYgKChtYXggPCBjdXIpIHx8IChtYXggPT0gLTEpKQoJCW1heCA9IGN1cjsKCX0KCS8qIFRPRE86IEhhbmRsZSBvdmVyZmxvd3M/ICovCglyZXR1cm4gKHBhcnRpY2xlLT5tYXhPY2N1cnMgKiBtYXgpOwogICAgfSBlbHNlIHsKCS8qIDxhbGw+IGFuZCA8c2VxdWVuY2U+ICovCglpbnQgc3VtID0gMCwgY3VyOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydCA9CgkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoKCWZvciAoOyBwYXJ0ICE9IE5VTEw7IHBhcnQgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpIHBhcnQtPm5leHQpIHsKCSAgICBpZiAocGFydC0+Y2hpbGRyZW4gPT0gTlVMTCkKCQljb250aW51ZTsKCSAgICBpZiAoKHBhcnQtPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB8fAoJCShwYXJ0LT5jaGlsZHJlbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSkKCQljdXIgPSBwYXJ0LT5tYXhPY2N1cnM7CgkgICAgZWxzZQoJCWN1ciA9IHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1heChwYXJ0KTsKCSAgICBpZiAoY3VyID09IFVOQk9VTkRFRCkKCQlyZXR1cm4gKFVOQk9VTkRFRCk7CgkgICAgaWYgKChjdXIgPiAwKSAmJiAocGFydGljbGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQpKQoJCXJldHVybiAoVU5CT1VOREVEKTsKCSAgICBzdW0gKz0gY3VyOwoJfQoJLyogVE9ETzogSGFuZGxlIG92ZXJmbG93cz8gKi8KCXJldHVybiAocGFydGljbGUtPm1heE9jY3VycyAqIHN1bSk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1BhcnRpY2xlRW1wdGlhYmxlOgogKiBAcGFydGljbGU6IHRoZSBwYXJ0aWNsZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFBhcnRpY2xlIEVtcHRpYWJsZQogKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gcGFydGljbGUgaXMgZW1wdGlhYmxlLgogKgogKiBSZXR1cm5zIDEgaWYgZW1wdGlhYmxlLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSh4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSkKewogICAgLyoKICAgICogU1BFQyAoMSkgIkl0cyB7bWluIG9jY3Vyc30gaXMgMC4iCiAgICAqLwogICAgaWYgKChwYXJ0aWNsZSA9PSBOVUxMKSB8fCAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB8fAoJKHBhcnRpY2xlLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiSXRzIHt0ZXJtfSBpcyBhIGdyb3VwIGFuZCB0aGUgbWluaW11bSBwYXJ0IG9mIHRoZQogICAgKiBlZmZlY3RpdmUgdG90YWwgcmFuZ2Ugb2YgdGhhdCBncm91cCwgWy4uLl0gaXMgMC4iCiAgICAqLwogICAgaWYgKElTX01PREVMX0dST1VQKHBhcnRpY2xlLT5jaGlsZHJlbikpIHsKCWlmICh4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNaW4ocGFydGljbGUpID09IDApCgkgICAgcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LOgogKiBAdHlwZTogIHRoZSBkZXJpdmVkIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGJhc2VUeXBlOiAgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpIChjb3Mtc3QtZGVyaXZlZC1PSykKICoKICogQ2hlY2tzIHdoZXRlciBAdHlwZSBjYW4gYmUgdmFsaWRseQogKiBkZXJpdmVkIGZyb20gQGJhc2VUeXBlLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYW4gcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCSAgICAgaW50IHN1YnNldCkKewogICAgLyoKICAgICogMSBUaGV5IGFyZSB0aGUgc2FtZSB0eXBlIGRlZmluaXRpb24uCiAgICAqIFRPRE86IFRoZSBpZGVudHkgY2hlY2sgbWlnaHQgaGF2ZSB0byBiZSBtb3JlIGNvbXBsZXggdGhhbiB0aGlzLgogICAgKi8KICAgIGlmICh0eXBlID09IGJhc2VUeXBlKQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIDIuMSByZXN0cmljdGlvbiBpcyBub3QgaW4gdGhlIHN1YnNldCwgb3IgaW4gdGhlIHtmaW5hbH0KICAgICogb2YgaXRzIG93biB7YmFzZSB0eXBlIGRlZmluaXRpb259OwogICAgKi8KICAgIGlmICgoc3Vic2V0ICYgU1VCU0VUX1JFU1RSSUNUSU9OKSB8fAoJKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHR5cGUtPmJhc2VUeXBlLAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSkgewoJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzEpOwogICAgfQogICAgLyogMi4yICovCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gYmFzZVR5cGUpIHsKCS8qCgkqIDIuMi4xIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIEIuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDIuMi4yIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIG5vdCB0aGUgt3VyLXR5cGUgZGVmaW5pdGlvbrcKICAgICogYW5kIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEIgZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzCiAgICAqIGNvbnN0cmFpbnQuCiAgICAqLwogICAgaWYgKCghIElTX0FOWVRZUEUodHlwZS0+YmFzZVR5cGUpKSAmJgoJKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0sodHlwZS0+YmFzZVR5cGUsCgkgICAgYmFzZVR5cGUsIHN1YnNldCkgPT0gMCkpIHsKCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAyLjIuMyBEJ3Mge3ZhcmlldHl9IGlzIGxpc3Qgb3IgdW5pb24gYW5kIEIgaXMgdGhlILdzaW1wbGUgdXItdHlwZQogICAgKiBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoSVNfQU5ZX1NJTVBMRV9UWVBFKGJhc2VUeXBlKSAmJgoJKFZBUklFVFlfTElTVCh0eXBlKSB8fCBWQVJJRVRZX1VOSU9OKHR5cGUpKSkgewoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDIuMi40IEIncyB7dmFyaWV0eX0gaXMgdW5pb24gYW5kIEQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gYSB0eXBlCiAgICAqIGRlZmluaXRpb24gaW4gQidzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIHN1YnNldCwgYXMKICAgICogZGVmaW5lZCBieSB0aGlzIGNvbnN0cmFpbnQuCiAgICAqCiAgICAqIE5PVEU6IFRoaXMgc2VlbXMgbm90IHRvIGludm9sdmUgYnVpbHQtaW4gdHlwZXMsIHNpbmNlIHRoZXJlIGlzIG5vCiAgICAqIGJ1aWx0LWluIFVuaW9uIFNpbXBsZSBUeXBlLgogICAgKi8KICAgIGlmIChWQVJJRVRZX1VOSU9OKGJhc2VUeXBlKSkgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgY3VyOwoKCWN1ciA9IGJhc2VUeXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHR5cGUsIGN1ci0+dHlwZSwgc3Vic2V0KSA9PSAwKQoJCXJldHVybiAoMCk7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8yKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWw6CiAqIEBwY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGN0eHRUeXBlOiAgdGhlIHR5cGUgZGVmaW5pdGlvbgogKiBAYW5jZXN0b3I6IGFuIGFuY2VzdG9yIG9mIEBjdHh0VHlwZQogKgogKiBDaGVja3Mgc3QtcHJvcHMtY29ycmVjdCAoMikgKyBjdC1wcm9wcy1jb3JyZWN0ICgzKS4KICogQ2lyY3VsYXIgdHlwZSBkZWZpbml0aW9ucyBhcmUgbm90IGFsbG93ZWQuCiAqCiAqIFJldHVybnMgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yIGlmIHRoZSBnaXZlbiB0eXBlIGlzCiAqIGNpcmN1bGFyLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tUeXBlRGVmQ2lyY3VsYXJJbnRlcm5hbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGN0eHRUeXBlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGFuY2VzdG9yKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICgoYW5jZXN0b3IgPT0gTlVMTCkgfHwgKGFuY2VzdG9yLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpCglyZXR1cm4gKDApOwoKICAgIGlmIChjdHh0VHlwZSA9PSBhbmNlc3RvcikgewoJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIsCgkgICAgTlVMTCwgY3R4dFR5cGUsIEdFVF9OT0RFKGN0eHRUeXBlKSwKCSAgICAiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yKTsKICAgIH0KICAgIGlmIChhbmNlc3Rvci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01BUktFRCkgewoJLyoKCSogQXZvaWQgaW5pZmluaXRlIHJlY3Vyc2lvbiBvbiBjaXJjdWxhciB0eXBlcyBub3QgeWV0IGNoZWNrZWQuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGFuY2VzdG9yLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWwocGN0eHQsIGN0eHRUeXBlLAoJYW5jZXN0b3ItPmJhc2VUeXBlKTsKICAgIGFuY2VzdG9yLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFyOgogKiBAaXRlbTogIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHR5cGUgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhcih4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJCSAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKChpdGVtID09IE5VTEwpIHx8CgkoKGl0ZW0tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkoaXRlbS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkpCglyZXR1cm47CiAgICBpZiAoaXRlbS0+cmVkZWYgIT0gTlVMTCkgewoJeG1sU2NoZW1hVHlwZVB0ciBjdXIgPSBpdGVtOwoJZG8gewoJICAgIHhtbFNjaGVtYUNoZWNrVHlwZURlZkNpcmN1bGFySW50ZXJuYWwoY3R4dCwgY3VyLCBjdXItPmJhc2VUeXBlKTsKCSAgICBjdXIgPSBjdXItPnJlZGVmOwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfSBlbHNlCgl4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhckludGVybmFsKGN0eHQsIGl0ZW0sIGl0ZW0tPmJhc2VUeXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVUeXBlRGVmczoKICogQGl0ZW06ICB0aGUgY29tcGxleC9zaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciB0eXBlIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZVR5cGVEZWZzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZiwKCQkJIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmICh0eXBlRGVmID09IE5VTEwpCglyZXR1cm47CgogICAgLyoKICAgICogUmVzb2x2ZSB0aGUgYmFzZSB0eXBlLgogICAgKi8KICAgIGlmICh0eXBlRGVmLT5iYXNlVHlwZSA9PSBOVUxMKSB7Cgl0eXBlRGVmLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+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+YmFzZVR5cGUsCgkgICAgYmFzZVR5cGUsIHNldCkpOwogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMgKDIuMy4yLjIpICJJZiBEJ3Mge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBzaW1wbGUsIHRoZW4gaXQKCSogbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQgYXMgZGVmaW5lZCBpbiBUeXBlCgkqIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJKi8KCXJldHVybiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh0eXBlLT5iYXNlVHlwZSwgYmFzZVR5cGUsIHNldCkpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0s6CiAqIEB0eXBlOiAgdGhlIGRlcml2ZWQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2FsbHM6CiAqIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSBBTkQgVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KQogKgogKiBDaGVja3Mgd2hldGVyIEB0eXBlIGNhbiBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSBAYmFzZVR5cGUuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhbiBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0soeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkgICBpbnQgc2V0KQp7CiAgICBpZiAoSVNfU0lNUExFX1RZUEUodHlwZSkpCglyZXR1cm4gKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0sodHlwZSwgYmFzZVR5cGUsIHNldCkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFDaGVja0NPU0NURGVyaXZlZE9LKHR5cGUsIGJhc2VUeXBlLCBzZXQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgKGNvcy1jdC1leHRlbmRzKQogKgogKiBTVEFUVVM6CiAqICAgbWlzc2luZzoKICogICAgICgxLjUpCiAqICAgICAoMS40LjMuMi4yLjIpICJQYXJ0aWNsZSBWYWxpZCAoRXh0ZW5zaW9uKSIsIHdoaWNoIGlzIG5vdCByZWFsbHkgbmVlZGVkLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIC8qCiAgICAqIFRPRE86IENvcnJlY3QgdGhlIGVycm9yIGNvZGU7IFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSBpcyB1c2VkCiAgICAqIHRlbXBvcmFyaWx5IG9ubHkuCiAgICAqLwogICAgLyoKICAgICogU1BFQyAoMSkgIklmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24sCiAgICAqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICovCiAgICBpZiAoSVNfQ09NUExFWF9UWVBFKGJhc2UpKSB7CgkvKgoJKiBTUEVDICgxLjEpICJUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJKiBjb250YWluIGV4dGVuc2lvbi4iCgkqLwoJaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04pIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImNvbnRhaW5zICdleHRlbnNpb24nIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQoJLyoKCSogU1BFQyAoMS4yKSAiSXRzIHthdHRyaWJ1dGUgdXNlc30gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUge2F0dHJpYnV0ZQoJKiB1c2VzfQoJKiBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmLCB0aGF0IGlzLCBmb3IgZXZlcnkgYXR0cmlidXRlCgkqIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSwgdGhlcmUKCSogbXVzdCBiZSBhbiBhdHRyaWJ1dGUgdXNlIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSBjb21wbGV4CgkqIHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIHRoZSBzYW1lCgkqIHtuYW1lfSwge3RhcmdldCBuYW1lc3BhY2V9IGFuZCB7dHlwZSBkZWZpbml0aW9ufSBhcyBpdHMgYXR0cmlidXRlCgkqIGRlY2xhcmF0aW9uIgoJKgoJKiBOT1RFICgxLjIpOiBUaGlzIHdpbGwgYmUgYWxyZWFkeSBzYXRpc2ZpZWQgYnkgdGhlIHdheSB0aGUgYXR0cmlidXRlCgkqIHVzZXMgYXJlIGV4dGVuZGVkIGluIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbigpOyB0aHVzIHRoaXMKCSogY2hlY2sgaXMgbm90IG5lZWRlZC4KCSovCgoJLyoKCSogU1BFQyAoMS4zKSAiSWYgaXQgaGFzIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LCB0aGUgY29tcGxleCB0eXBlCgkqIGRlZmluaXRpb24gbXVzdCBhbHNvIGhhdmUgb25lLCBhbmQgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uJ3MKCSoge2F0dHJpYnV0ZSAgd2lsZGNhcmR9J3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSBtdXN0IGJlIGEgc3Vic2V0CgkqIG9mIHRoZSBjb21wbGV4ICB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UKCSogY29uc3RyYWludH0sIGFzIGRlZmluZWQgYnkgV2lsZGNhcmQgU3Vic2V0ICinMy4xMC42KS4iCgkqCgkqIE5PVEUgKDEuMykgVGhpcyBpcyBhbHJlYWR5IGNoZWNrZWQgaW4KCSogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOyB0aHVzIHRoaXMgY2hlY2sgaXMgbm90IG5lZWRlZC4KCSoKCSogU1BFQyAoMS40KSAiT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKCSovCglpZiAoKHR5cGUtPmNvbnRlbnRUeXBlRGVmICE9IE5VTEwpICYmCgkgICAgKHR5cGUtPmNvbnRlbnRUeXBlRGVmID09IGJhc2UtPmNvbnRlbnRUeXBlRGVmKSkgewoJICAgIC8qCgkgICAgKiBTUEVDICgxLjQuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufQoJICAgICogYW5kIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmCgkgICAgKiBtdXN0IGJlIHRoZSBzYW1lIHNpbXBsZSB0eXBlIGRlZmluaXRpb24iCgkgICAgKiBQQVNTCgkgICAgKi8KCX0gZWxzZSBpZiAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgJiYKCSAgICAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSApIHsKCSAgICAvKgoJICAgICogU1BFQyAoMS40LjIpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgYm90aCB0aGUge2Jhc2UgdHlwZQoJICAgICogZGVmaW5pdGlvbn0gYW5kIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgbXVzdAoJICAgICogYmUgZW1wdHkuIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBTUEVDICgxLjQuMykgIkFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkgICAgKi8KCSAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJCS8qCgkJKiBTUEVDIDEuNC4zLjEgVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUKCQkqIGRlZmluaXRpb24gaXRzZWxmIG11c3Qgc3BlY2lmeSBhIHBhcnRpY2xlLgoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgY29udGVudCB0eXBlIG11c3Qgc3BlY2lmeSBhIHBhcnRpY2xlIiwgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogU1BFQyAoMS40LjMuMikgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkgICAgKi8KCSAgICBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJLyoKCQkqIFNQRUMgKDEuNC4zLjIuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZQoJCSogZGVmaW5pdGlvbn0gbXVzdCBiZSBlbXB0eS4KCQkqIFBBU1MKCQkqLwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIFNQRUMgKDEuNC4zLjIuMikgIkFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkJKi8KCQlpZiAoKHR5cGUtPmNvbnRlbnRUeXBlICE9IGJhc2UtPmNvbnRlbnRUeXBlKSB8fAoJCSAgICAoKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCQkgICAgKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykpKSB7CgkJICAgIC8qCgkJICAgICogU1BFQyAoMS40LjMuMi4yLjEpICJCb3RoIHtjb250ZW50IHR5cGV9cyBtdXN0IGJlIG1peGVkCgkJICAgICogb3IgYm90aCBtdXN0IGJlIGVsZW1lbnQtb25seS4iCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlIGNvbnRlbnQgdHlwZSBvZiBib3RoLCB0aGUgdHlwZSBhbmQgaXRzIGJhc2UgIgoJCQkidHlwZSwgbXVzdCBlaXRoZXIgJ21peGVkJyBvciAnZWxlbWVudC1vbmx5JyIsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7CgkJfQoJCS8qCgkJKiBGVVRVUkUgVE9ETyBTUEVDICgxLjQuMy4yLjIuMikgIlRoZSBwYXJ0aWNsZSBvZiB0aGUKCQkqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIG11c3QgYmUgYSC3dmFsaWQgZXh0ZW5zaW9utwoJCSogb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0ncyBwYXJ0aWNsZSwgYXMgZGVmaW5lZAoJCSogaW4gUGFydGljbGUgVmFsaWQgKEV4dGVuc2lvbikgKKczLjkuNikuIgoJCSoKCQkqIE5PVEUgdGhhdCB3ZSB3b24ndCBjaGVjayAiUGFydGljbGUgVmFsaWQgKEV4dGVuc2lvbikiLAoJCSogc2luY2UgaXQgaXMgZW5zdXJlZCBieSB0aGUgZGVyaXZhdGlvbiBwcm9jZXNzIGluCgkJKiB4bWxTY2hlbWFUeXBlRml4dXAoKS4gV2UgbmVlZCB0byBpbXBsZW1lbnQgdGhpcyB3aGVuIGhlYWRpbmcKCQkqIGZvciBhIGNvbnN0cnVjdGlvbiBBUEkKCQkqLwoJICAgIH0KCSAgICAvKgoJICAgICogVE9ETyAoMS41KQoJICAgICovCgl9CiAgICB9IGVsc2UgewoJLyoKCSogU1BFQyAoMikgIklmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwKCSogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgoJKi8KCWlmICh0eXBlLT5jb250ZW50VHlwZURlZiAhPSBiYXNlKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDIuMSkgIlRoZSB7Y29udGVudCB0eXBlfSBtdXN0IGJlIHRoZSBzYW1lIHNpbXBsZSB0eXBlCgkgICAgKiBkZWZpbml0aW9uLiIKCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiVGhlIGNvbnRlbnQgdHlwZSBtdXN0IGJlIHRoZSBzaW1wbGUgYmFzZSB0eXBlIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQoJaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04pIHsKCSAgICAvKgoJICAgICogU1BFQyAoMi4yKSAiVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QKCSAgICAqIGNvbnRhaW4gZXh0ZW5zaW9uIgoJICAgICogTk9URSB0aGF0IHRoaXMgaXMgdGhlIHNhbWUgYXMgKDEuMSkuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImNvbnRhaW5zICdleHRlbnNpb24nIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvbk9LUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy40LjYpIENvbnN0cmFpbnRzIG9uIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpIChkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uKQogKgogKiBTVEFUVVM6CiAqICAgbWlzc2luZzoKICogICAgICg1LjQuMiksICg1LjIuMi4xKQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvbk9LUmVzdHJpY3Rpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CgogICAgLyoKICAgICogVE9ETzogQ29ycmVjdCB0aGUgZXJyb3IgY29kZTsgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xIGlzIHVzZWQKICAgICogdGVtcG9yYXJpbHkgb25seS4KICAgICovCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSB7CgkvKgoJKiBTUEVDICgxKSAiVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhIGNvbXBsZXggdHlwZQoJKiBkZWZpbml0aW9uIHdob3NlIHtmaW5hbH0gZG9lcyBub3QgY29udGFpbiByZXN0cmljdGlvbi4iCgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJUaGUgJ2ZpbmFsJyBvZiB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gIgoJICAgICJjb250YWlucyAncmVzdHJpY3Rpb24nIiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7CiAgICB9CiAgICAvKgogICAgKiBOT1RFICgzKSBhbmQgKDQpIGFyZSBkb25lIGluIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbigpLgogICAgKgogICAgKiBTUEVDICg1KSAiT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOiIKICAgICovCiAgICBpZiAoYmFzZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkgewoJLyoKCSogU1BFQyAoNS4xKSAiVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB0aGUKCSogt3VyLXR5cGUgZGVmaW5pdGlvbrcuIgoJKiBQQVNTCgkqLwogICAgfSBlbHNlIGlmICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwKCSAgICAodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgewoJLyoKCSogU1BFQyAoNS4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCgkqIG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIgoJKgoJKiBTUEVDICg1LjIuMikgIk9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToiCgkqLwoJaWYgKChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fAoJICAgIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuMi4yLjEpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUKCSAgICAqIGRlZmluaXRpb259IG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGZyb20gd2hpY2gKCSAgICAqIHRoZSB7Y29udGVudCB0eXBlfSBpcyB2YWxpZGx5IGRlcml2ZWQgZ2l2ZW4gdGhlIGVtcHR5CgkgICAgKiBzZXQgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLiIKCSAgICAqIFVSR0VOVCBUT0RPCgkgICAgKi8KCX0gZWxzZSBpZiAoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgJiYKCSAgICAoeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSgKCQkoeG1sU2NoZW1hUGFydGljbGVQdHIpIGJhc2UtPnN1YnR5cGVzKSkpIHsKCSAgICAvKgoJICAgICogU1BFQyAoNS4yLjIuMikgIlRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgbWl4ZWQKCSAgICAqIGFuZCBoYXZlIGEgcGFydGljbGUgd2hpY2ggaXMgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBpbgoJICAgICogUGFydGljbGUgRW1wdGlhYmxlICinMy45LjYpLiIKCSAgICAqIFBBU1MKCSAgICAqLwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSBjb250ZW50IHR5cGUgb2YgdGhlIGJhc2UgdHlwZSBtdXN0IGJlIGVpdGhlciAiCgkJImEgc2ltcGxlIHR5cGUgb3IgJ21peGVkJyBhbmQgYW4gZW1wdGlhYmxlIHBhcnRpY2xlIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCS8qCgkqIFNQRUMgKDUuMy4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUgaXRzZWxmIG11c3QKCSogYmUgZW1wdHkiCgkqLwoJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJICAgIC8qCgkgICAgKiBTUEVDICg1LjMuMi4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB7YmFzZSB0eXBlCgkgICAgKiBkZWZpbml0aW9ufSBtdXN0IGFsc28gYmUgZW1wdHkuIgoJICAgICogUEFTUwoJICAgICovCgl9IGVsc2UgaWYgKCgoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSB8fAoJICAgIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKSAmJgoJICAgIHhtbFNjaGVtYUlzUGFydGljbGVFbXB0aWFibGUoCgkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlLT5zdWJ0eXBlcykpIHsKCSAgICAvKgoJICAgICogU1BFQyAoNS4zLjIuMikgIlRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZQoJICAgICogZGVmaW5pdGlvbn0gbXVzdCBiZSBlbGVtZW50T25seSBvciBtaXhlZCBhbmQgaGF2ZSBhIHBhcnRpY2xlCgkgICAgKiB3aGljaCBpcyC3ZW1wdGlhYmxltyBhcyBkZWZpbmVkIGluIFBhcnRpY2xlIEVtcHRpYWJsZSAopzMuOS42KS4iCgkgICAgKiBQQVNTCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJUaGUgY29udGVudCB0eXBlIG9mIHRoZSBiYXNlIHR5cGUgbXVzdCBiZSBlaXRoZXIgIgoJCSJlbXB0eSBvciAnbWl4ZWQnIChvciAnZWxlbWVudHMtb25seScpIGFuZCBhbiBlbXB0aWFibGUgIgoJCSJwYXJ0aWNsZSIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KICAgIH0gZWxzZSBpZiAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgfHwKCUhBU19NSVhFRF9DT05URU5UKHR5cGUpKSB7CgkvKgoJKiBTUEVDICg1LjQuMS4xKSAiVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgoJKiBpdHNlbGYgbXVzdCBiZSBlbGVtZW50LW9ubHkiCgkqLwkgCglpZiAoSEFTX01JWEVEX0NPTlRFTlQodHlwZSkgJiYgKCEgSEFTX01JWEVEX0NPTlRFTlQoYmFzZSkpKSB7CgkgICAgLyoKCSAgICAqIFNQRUMgKDUuNC4xLjIpICJUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZQoJICAgICogZGVmaW5pdGlvbiBpdHNlbGYgYW5kIG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUKCSAgICAqIG1peGVkIgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJJZiB0aGUgY29udGVudCB0eXBlIGlzICdtaXhlZCcsIHRoZW4gdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgIgoJCSJiYXNlIHR5cGUgbXVzdCBhbHNvIGJlICdtaXhlZCciLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CgkvKgoJKiBTUEVDICg1LjQuMikgIlRoZSBwYXJ0aWNsZSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmCgkqIG11c3QgYmUgYSC3dmFsaWQgcmVzdHJpY3Rpb263IG9mIHRoZSBwYXJ0aWNsZSBvZiB0aGUge2NvbnRlbnQKCSogdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBQYXJ0aWNsZSBWYWxpZAoJKiAoUmVzdHJpY3Rpb24pICinMy45LjYpLgoJKgoJKiBVUkdFTlQgVE9ETzogKDUuNC4yKQoJKi8KICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkgICAgIlRoZSB0eXBlIGlzIG5vdCBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIGl0cyBiYXNlIHR5cGUiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NUQ29tcG9uZW50OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuNC42KSBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1RDb21wb25lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJldDsKICAgIC8qCiAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ1RQcm9wc0NvcnJlY3QoY3R4dCwgdHlwZSk7CiAgICBpZiAocmV0ICE9IDApCglyZXR1cm4gKHJldCk7CiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikKCXJldCA9IHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzKGN0eHQsIHR5cGUpOwogICAgZWxzZQoJcmV0ID0geG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uT0tSZXN0cmljdGlvbihjdHh0LCB0eXBlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDQ1Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiAoMy40LjMpIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgQ29tcGxleCBUeXBlIERlZmluaXRpb25zOgogKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sgKHNyYy1jdCkKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NSQ0NUKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBUT0RPOiBBZGp1c3QgdGhlIGVycm9yIGNvZGVzIGhlcmUsIGFzIEkgdXNlZAogICAgKiBYTUxfU0NIRU1BUF9TUkNfQ1RfMSBvbmx5IHlldC4KICAgICovCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoISBIQVNfU0lNUExFX0NPTlRFTlQodHlwZSkpIHsKCS8qCgkqIDEgSWYgdGhlIDxjb21wbGV4Q29udGVudD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGUgdHlwZSBkZWZpbml0aW9uCgkqILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdCgkqIG11c3QgYmUgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbjsKCSovCglpZiAoISBJU19DT01QTEVYX1RZUEUoYmFzZSkpIHsKCSAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQlOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLAoJCSJJZiB1c2luZyA8Y29tcGxleENvbnRlbnQ+LCB0aGUgYmFzZSB0eXBlIGlzIGV4cGVjdGVkIHRvIGJlICIKCQkiYSBjb21wbGV4IHR5cGUuIFRoZSBiYXNlIHR5cGUgJyVzJyBpcyBhIHNpbXBsZSB0eXBlIiwKCQl4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBiYXNlLT50YXJnZXROYW1lc3BhY2UsCgkJYmFzZS0+bmFtZSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIFNQRUMKCSogMiBJZiB0aGUgPHNpbXBsZUNvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgYWxsIG9mIHRoZQoJKiBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKiAyLjEgVGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUKCSogYmFzZSBbYXR0cmlidXRlXSBtdXN0IGJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOgoJKi8KCWlmIChJU19TSU1QTEVfVFlQRShiYXNlKSkgewoJICAgIGlmICgodHlwZS0+ZmxhZ3MgJgoJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSA9PSAwKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkvKgoJCSogMi4xLjMgb25seSBpZiB0aGUgPGV4dGVuc2lvbj4gYWx0ZXJuYXRpdmUgaXMgYWxzbwoJCSogY2hvc2VuLCBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkJKi8KCQkvKiBUT0RPOiBDaGFuZ2UgZXJyb3IgY29kZSB0byAuLi5fU1JDX0NUXzJfMV8zLiAqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJJZiB1c2luZyA8c2ltcGxlQ29udGVudD4gYW5kIDxyZXN0cmljdGlvbj4sIHRoZSBiYXNlICIKCQkgICAgInR5cGUgbXVzdCBiZSBhIGNvbXBsZXggdHlwZS4gVGhlIGJhc2UgdHlwZSAnJXMnIGlzICIKCQkgICAgImEgc2ltcGxlIHR5cGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLCBiYXNlLT50YXJnZXROYW1lc3BhY2UsCgkJCWJhc2UtPm5hbWUpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qIEJhc2UgdHlwZSBpcyBhIGNvbXBsZXggdHlwZS4gKi8KCSAgICBpZiAoKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8CgkJKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpIHsKCQkvKgoJCSogMi4xLjEgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfSBpcyBhCgkJKiBzaW1wbGUgdHlwZSBkZWZpbml0aW9uOwoJCSogUEFTUwoJCSovCgkJaWYgKGJhc2UtPmNvbnRlbnRUeXBlRGVmID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja1NSQ0NULCAiCgkJCSInJXMnLCBiYXNlIHR5cGUgaGFzIG5vIGNvbnRlbnQgdHlwZSIsCgkJCXR5cGUtPm5hbWUpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfSBlbHNlIGlmICgoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSAmJgoJCSh0eXBlLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pKSB7CgoJCS8qCgkJKiAyLjEuMiBvbmx5IGlmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGFsc28KCQkqIGNob3NlbiwgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfQoJCSogaXMgbWl4ZWQgYW5kIGEgcGFydGljbGUgZW1wdGlhYmxlLgoJCSovCgkJaWYgKCEgeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSgKCQkgICAgKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBiYXNlLT5zdWJ0eXBlcykpIHsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVBfU1JDX0NUXzE7CgkJfSBlbHNlIAoJCSAgICAvKgoJCSAgICAqIEF0dGVudGlvbjogYXQgdGhpcyBwb2ludCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkIGlzIGluCgkJICAgICogLT5jb250ZW50VHlwZURlZiAocHV0IHRoZXJlIGR1cmluZyBwYXJzaW5nKS4KCQkgICAgKi8JCSAgICAKCQkgICAgaWYgKHR5cGUtPmNvbnRlbnRUeXBlRGVmID09IE5VTEwpIHsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkgICAgLyoKCQkgICAgKiAyLjIgSWYgY2xhdXNlIDIuMS4yIGFib3ZlIGlzIHNhdGlzZmllZCwgdGhlbiB0aGVyZQoJCSAgICAqIG11c3QgYmUgYSA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YKCQkgICAgKiA8cmVzdHJpY3Rpb24+LgoJCSAgICAqLwoJCSAgICAvKiBUT0RPOiBDaGFuZ2UgZXJyb3IgY29kZSB0byAuLi5fU1JDX0NUXzJfMi4gKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkEgPHNpbXBsZVR5cGU+IGlzIGV4cGVjdGVkIGFtb25nIHRoZSBjaGlsZHJlbiAiCgkJCSJvZiA8cmVzdHJpY3Rpb24+LCBpZiA8c2ltcGxlQ29udGVudD4gaXMgdXNlZCBhbmQgIgoJCQkidGhlIGJhc2UgdHlwZSAnJXMnIGlzIGEgY29tcGxleCB0eXBlIiwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCQliYXNlLT5uYW1lKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQl9CgkgICAgfSBlbHNlIHsKCQlyZXQgPSBYTUxfU0NIRU1BUF9TUkNfQ1RfMTsKCSAgICB9Cgl9CglpZiAocmV0ID4gMCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJJZiA8c2ltcGxlQ29udGVudD4gYW5kIDxyZXN0cmljdGlvbj4gaXMgdXNlZCwgdGhlICIKCQkgICAgImJhc2UgdHlwZSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgb3IgYSBjb21wbGV4IHR5cGUgd2l0aCAiCgkJICAgICJtaXhlZCBjb250ZW50IGFuZCBwYXJ0aWNsZSBlbXB0aWFibGUuIFRoZSBiYXNlIHR5cGUgIgoJCSAgICAiJyVzJyBpcyBub25lIG9mIHRob3NlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICBiYXNlLT5uYW1lKSk7CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiSWYgPHNpbXBsZUNvbnRlbnQ+IGFuZCA8ZXh0ZW5zaW9uPiBpcyB1c2VkLCB0aGUgIgoJCSAgICAiYmFzZSB0eXBlIG11c3QgYmUgYSBzaW1wbGUgdHlwZS4gVGhlIGJhc2UgdHlwZSAnJXMnICIKCQkgICAgImlzIGEgY29tcGxleCB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICBiYXNlLT5uYW1lKSk7CgkgICAgfQoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJfQogICAgfQogICAgLyoKICAgICogU1BFQyAoMykgIlRoZSBjb3JyZXNwb25kaW5nIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGNvbXBvbmVudCBtdXN0CiAgICAqIHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUKICAgICogRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cyAopzMuNC42KTsiCiAgICAqIE5PVEUgKDMpIHdpbGwgYmUgZG9uZSBpbiB4bWxTY2hlbWFUeXBlRml4dXAoKS4KICAgICovCiAgICAvKgogICAgKiBTUEVDICg0KSBJZiBjbGF1c2UgMi4yLjEgb3IgY2xhdXNlIDIuMi4yIGluIHRoZSBjb3JyZXNwb25kZW5jZSBzcGVjaWZpY2F0aW9uCiAgICAqIGFib3ZlIGZvciB7YXR0cmlidXRlIHdpbGRjYXJkfSBpcyBzYXRpc2ZpZWQsIHRoZSBpbnRlbnNpb25hbAogICAgKiBpbnRlcnNlY3Rpb24gbXVzdCBiZSBleHByZXNzaWJsZSwgYXMgZGVmaW5lZCBpbiBBdHRyaWJ1dGUgV2lsZGNhcmQKICAgICogSW50ZXJzZWN0aW9uICinMy4xMC42KS4KICAgICogTk9URSAoNCkgaXMgZG9uZSBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oKS4KICAgICovCiAgICByZXR1cm4gKHJldCk7Cn0KCiNpZmRlZiBFTkFCTEVfUEFSVElDTEVfUkVTVFJJQ1RJT04KLyoqCiAqIHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIE9jY3VycmVuY2UgUmFuZ2UgT0sgKHJhbmdlLW9rKQogKgogKiBTVEFUVVM6IGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tQYXJ0aWNsZVJhbmdlT0soaW50IHJtaW4sIGludCBybWF4LAoJCQkgICAgICBpbnQgYm1pbiwgaW50IGJtYXgpCnsKICAgIGlmIChybWluIDwgYm1pbikKCXJldHVybiAoMSk7CiAgICBpZiAoKGJtYXggIT0gVU5CT1VOREVEKSAmJgoJKHJtYXggPiBibWF4KSkKCXJldHVybiAoMSk7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tSQ2FzZU5hbWVBbmRUeXBlT0s6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIHJlc3RyaWN0aW5nIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGUKICogQGI6IHRoZSBiYXNlIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGUKICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFBhcnRpY2xlIFJlc3RyaWN0aW9uIE9LIChFbHQ6RWx0IC0tIE5hbWVBbmRUeXBlT0spCiAqIChyY2FzZS1OYW1lQW5kVHlwZU9LKQogKgogKiBTVEFUVVM6CiAqICAgTUlTU0lORyAoMy4yLjMpCiAqICAgQ0xBUklGWTogKDMuMi4yKQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VOYW1lQW5kVHlwZU9LKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSB4bWxTY2hlbWFQYXJ0aWNsZVB0ciByLAoJCQkJIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbVIsIGVsZW1COwoKICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1OYW1lQW5kVHlwZU9LKS4gKi8KICAgIGVsZW1SID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHItPmNoaWxkcmVuOwogICAgZWxlbUIgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgYi0+Y2hpbGRyZW47CiAgICAvKgogICAgKiBTUEVDICgxKSAiVGhlIGRlY2xhcmF0aW9ucycge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cyBhcmUKICAgICogdGhlIHNhbWUuIgogICAgKi8KICAgIGlmICgoZWxlbVIgIT0gZWxlbUIpICYmCgkoKCEgeG1sU3RyRXF1YWwoZWxlbVItPm5hbWUsIGVsZW1CLT5uYW1lKSkgfHwKCSghIHhtbFN0ckVxdWFsKGVsZW1SLT50YXJnZXROYW1lc3BhY2UsIGVsZW1CLT50YXJnZXROYW1lc3BhY2UpKSkpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMikgIlIncyBvY2N1cnJlbmNlIHJhbmdlIGlzIGEgdmFsaWQgcmVzdHJpY3Rpb24gb2YgQidzCiAgICAqIG9jY3VycmVuY2UgcmFuZ2UgYXMgZGVmaW5lZCBieSBPY2N1cnJlbmNlIFJhbmdlIE9LICinMy45LjYpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tQYXJ0aWNsZVJhbmdlT0soci0+bWluT2NjdXJzLCByLT5tYXhPY2N1cnMsCgkgICAgYi0+bWluT2NjdXJzLCBiLT5tYXhPY2N1cnMpICE9IDApCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMy4xKSAiQm90aCBCJ3MgZGVjbGFyYXRpb24ncyB7c2NvcGV9IGFuZCBSJ3MgZGVjbGFyYXRpb24ncwogICAgKiB7c2NvcGV9IGFyZSBnbG9iYWwuIgogICAgKi8KICAgIGlmIChlbGVtUiA9PSBlbGVtQikKCXJldHVybiAoMCk7CiAgICAvKgogICAgKiBTUEVDICgzLjIuMSkgIkVpdGhlciBCJ3Mge25pbGxhYmxlfSBpcyB0cnVlIG9yIFIncyB7bmlsbGFibGV9IGlzIGZhbHNlLiIKICAgICovCiAgICBpZiAoKChlbGVtQi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSAmJgoJKGVsZW1SLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpKQoJIHJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgzLjIuMikgImVpdGhlciBCJ3MgZGVjbGFyYXRpb24ncyB7dmFsdWUgY29uc3RyYWludH0gaXMgYWJzZW50LAogICAgKiBvciBpcyBub3QgZml4ZWQsIG9yIFIncyBkZWNsYXJhdGlvbidzIHt2YWx1ZSBjb25zdHJhaW50fSBpcyBmaXhlZAogICAgKiB3aXRoIHRoZSBzYW1lIHZhbHVlLiIKICAgICovCiAgICBpZiAoKGVsZW1CLT52YWx1ZSAhPSBOVUxMKSAmJiAoZWxlbUItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCSgoZWxlbVItPnZhbHVlID09IE5VTEwpIHx8CgkgKChlbGVtUi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSA9PSAwKSB8fAoJIC8qIFRPRE86IEVxdWFsaXR5IG9mIHRoZSBpbml0aWFsIHZhbHVlIG9yIG5vcm1hbGl6ZWQgb3IgY2Fub25pY2FsPyAqLwoJICghIHhtbFN0ckVxdWFsKGVsZW1SLT52YWx1ZSwgZWxlbUItPnZhbHVlKSkpKQoJIHJldHVybiAoMSk7CiAgICAvKgogICAgKiBUT0RPOiBTUEVDICgzLjIuMykgIlIncyBkZWNsYXJhdGlvbidzIHtpZGVudGl0eS1jb25zdHJhaW50CiAgICAqIGRlZmluaXRpb25zfSBpcyBhIHN1YnNldCBvZiBCJ3MgZGVjbGFyYXRpb24ncyB7aWRlbnRpdHktY29uc3RyYWludAogICAgKiBkZWZpbml0aW9uc30sIGlmIGFueS4iCiAgICAqLwogICAgaWYgKGVsZW1CLT5pZGNzICE9IE5VTEwpIHsKCS8qIFRPRE8gKi8KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgKDMuMi40KSAiUidzIGRlY2xhcmF0aW9uJ3Mge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gaXMgYQogICAgKiBzdXBlcnNldCBvZiBCJ3MgZGVjbGFyYXRpb24ncyB7ZGlzYWxsb3dlZCBzdWJzdGl0dXRpb25zfS4iCiAgICAqLwogICAgaWYgKCgoZWxlbUItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pICYmCgkgKChlbGVtUi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0VYVEVOU0lPTikgPT0gMCkpIHx8CgkoKGVsZW1CLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04pICYmCgkgKChlbGVtUi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1JFU1RSSUNUSU9OKSA9PSAwKSkgfHwKCSgoZWxlbUItPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT04pICYmCgkgKChlbGVtUi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTikgPT0gMCkpKQoJIHJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgzLjIuNSkgIlIncyB7dHlwZSBkZWZpbml0aW9ufSBpcyB2YWxpZGx5IGRlcml2ZWQgZ2l2ZW4KICAgICoge2V4dGVuc2lvbiwgbGlzdCwgdW5pb259IGZyb20gQidzIHt0eXBlIGRlZmluaXRpb259IgogICAgKgogICAgKiBCQURTUEVDIFRPRE86IFdoYXQncyB0aGUgcG9pbnQgb2YgYWRkaW5nICJsaXN0IiBhbmQgInVuaW9uIiB0byB0aGUKICAgICogc2V0LCBpZiB0aGUgY29ycmVzcG9uZGluZyBjb25zdHJhaW50cyBoYW5kbGUgInJlc3RyaWN0aW9uIiBhbmQKICAgICogImV4dGVuc2lvbiIgb25seT8KICAgICoKICAgICovCiAgICB7CglpbnQgc2V0ID0gMDsKCglzZXQgfD0gU1VCU0VUX0VYVEVOU0lPTjsKCXNldCB8PSBTVUJTRVRfTElTVDsKCXNldCB8PSBTVUJTRVRfVU5JT047CglpZiAoeG1sU2NoZW1hQ2hlY2tDT1NEZXJpdmVkT0soZWxlbVItPnN1YnR5cGVzLAoJICAgIGVsZW1CLT5zdWJ0eXBlcywgc2V0KSAhPSAwKQoJICAgIHJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TQ29tcGF0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSByZXN0cmljdGluZyBlbGVtZW50IGRlY2xhcmF0aW9uIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSB3aWxkY2FyZCBwYXJ0aWNsZQogKgogKiAoMy45LjYpIENvbnN0cmFpbnRzIG9uIFBhcnRpY2xlIFNjaGVtYSBDb21wb25lbnRzCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDoKICogUGFydGljbGUgRGVyaXZhdGlvbiBPSyAoRWx0OkFueSAtLSBOU0NvbXBhdCkKICogKHJjYXNlLU5TQ29tcGF0KQogKgogKiBTVEFUVVM6IGNvbXBsZXRlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZU5TQ29tcGF0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICAvKiBUT0RPOkVycm9yIGNvZGVzIChyY2FzZS1OU0NvbXBhdCkuICovCiAgICAvKgogICAgKiBTUEVDICJGb3IgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBwYXJ0aWNsZSB0byBiZSBhILd2YWxpZCByZXN0cmljdGlvbrcKICAgICogb2YgYSB3aWxkY2FyZCBwYXJ0aWNsZSBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6IgogICAgKgogICAgKiBTUEVDICgxKSAiVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24ncyB7dGFyZ2V0IG5hbWVzcGFjZX0gaXMgt3ZhbGlktwogICAgKiB3aXRoIHJlc3BlY3QgdG8gdGhlIHdpbGRjYXJkJ3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSBhcyBkZWZpbmVkIGJ5CiAgICAqIFdpbGRjYXJkIGFsbG93cyBOYW1lc3BhY2UgTmFtZSAopzMuMTAuNCkuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKCh4bWxTY2hlbWFXaWxkY2FyZFB0cikgYi0+Y2hpbGRyZW4sCgkoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHItPmNoaWxkcmVuKS0+dGFyZ2V0TmFtZXNwYWNlKSAhPSAwKQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIFNQRUMgKDIpICJSJ3Mgb2NjdXJyZW5jZSByYW5nZSBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEIncwogICAgKiBvY2N1cnJlbmNlIHJhbmdlIGFzIGRlZmluZWQgYnkgT2NjdXJyZW5jZSBSYW5nZSBPSyAopzMuOS42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKHItPm1pbk9jY3Vycywgci0+bWF4T2NjdXJzLAoJICAgIGItPm1pbk9jY3VycywgYi0+bWF4T2NjdXJzKSAhPSAwKQoJcmV0dXJuICgxKTsKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tSQ2FzZVJlY3Vyc2VBc0lmR3JvdXA6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAcjogdGhlIHJlc3RyaWN0aW5nIGVsZW1lbnQgZGVjbGFyYXRpb24gcGFydGljbGUKICogQGI6IHRoZSBiYXNlIG1vZGVsIGdyb3VwIHBhcnRpY2xlCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBEZXJpdmF0aW9uIE9LIChFbHQ6QWxsL0Nob2ljZS9TZXF1ZW5jZSAtLSBSZWN1cnNlQXNJZkdyb3VwKQogKiAocmNhc2UtUmVjdXJzZUFzSWZHcm91cCkKICoKICogU1RBVFVTOiBUT0RPCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tSQ2FzZVJlY3Vyc2VBc0lmR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgLyogVE9ETzogRXJyb3IgY29kZXMgKHJjYXNlLVJlY3Vyc2VBc0lmR3JvdXApLiAqLwogICAgVE9ETwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VOU1N1YnNldDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEByOiB0aGUgcmVzdHJpY3Rpbmcgd2lsZGNhcmQgcGFydGljbGUKICogQGI6IHRoZSBiYXNlIHdpbGRjYXJkIHBhcnRpY2xlCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBEZXJpdmF0aW9uIE9LIChBbnk6QW55IC0tIE5TU3Vic2V0KQogKiAocmNhc2UtTlNTdWJzZXQpCiAqCiAqIFNUQVRVUzogY29tcGxldGUKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1JDYXNlTlNTdWJzZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCQkgICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYiwKCQkJCSAgICBpbnQgaXNBbnlUeXBlQmFzZSkKewogICAgLyogVE9ETzogRXJyb3IgY29kZXMgKHJjYXNlLU5TU3Vic2V0KS4gKi8KICAgIC8qCiAgICAqIFNQRUMgKDEpICJSJ3Mgb2NjdXJyZW5jZSByYW5nZSBpcyBhIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEIncwogICAgKiBvY2N1cnJlbmNlIHJhbmdlIGFzIGRlZmluZWQgYnkgT2NjdXJyZW5jZSBSYW5nZSBPSyAopzMuOS42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKHItPm1pbk9jY3Vycywgci0+bWF4T2NjdXJzLAoJICAgIGItPm1pbk9jY3VycywgYi0+bWF4T2NjdXJzKSkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiBTUEVDICgyKSAiUidzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhbiBpbnRlbnNpb25hbCBzdWJzZXQKICAgICogb2YgQidzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gYXMgZGVmaW5lZCBieSBXaWxkY2FyZCBTdWJzZXQgKKczLjEwLjYpLiIKICAgICovCiAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NOU1N1YnNldCgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHItPmNoaWxkcmVuLAoJKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBiLT5jaGlsZHJlbikpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogU1BFQyAoMykgIlVubGVzcyBCIGlzIHRoZSBjb250ZW50IG1vZGVsIHdpbGRjYXJkIG9mIHRoZSC3dXItdHlwZQogICAgKiBkZWZpbml0aW9utywgUidzIHtwcm9jZXNzIGNvbnRlbnRzfSBtdXN0IGJlIGlkZW50aWNhbCB0byBvciBzdHJvbmdlcgogICAgKiB0aGFuIEIncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlciB0aGFuIGxheCBpcwogICAgKiBzdHJvbmdlciB0aGFuIHNraXAuIgogICAgKi8KICAgIGlmICghIGlzQW55VHlwZUJhc2UpIHsKCWlmICggKCh4bWxTY2hlbWFXaWxkY2FyZFB0cikgci0+Y2hpbGRyZW4pLT5wcm9jZXNzQ29udGVudHMgPAoJICAgICgoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIGItPmNoaWxkcmVuKS0+cHJvY2Vzc0NvbnRlbnRzKQoJICAgIHJldHVybiAoMSk7CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TUGFydGljbGVSZXN0cmljdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBWYWxpZCAoUmVzdHJpY3Rpb24pIChjb3MtcGFydGljbGUtcmVzdHJpY3QpCiAqCiAqIFNUQVRVUzogVE9ETwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TUGFydGljbGVSZXN0cmljdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCQkgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIGIpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qcGFydCA9IEdFVF9QQVJUSUNMRSh0eXBlKTsKICAgIGJhc2VQYXJ0ID0gR0VUX1BBUlRJQ0xFKGJhc2UpOwogICAgKi8KCiAgICBUT0RPCgogICAgLyoKICAgICogU1BFQyAoMSkgIlRoZXkgYXJlIHRoZSBzYW1lIHBhcnRpY2xlLiIKICAgICovCiAgICBpZiAociA9PSBiKQoJcmV0dXJuICgwKTsKCgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VOU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSBtb2RlbCBncm91cCBwYXJ0aWNsZQogKiBAYjogdGhlIGJhc2Ugd2lsZGNhcmQgcGFydGljbGUKICoKICogKDMuOS42KSBDb25zdHJhaW50cyBvbiBQYXJ0aWNsZSBTY2hlbWEgQ29tcG9uZW50cwogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFBhcnRpY2xlIERlcml2YXRpb24gT0sgKEFsbC9DaG9pY2UvU2VxdWVuY2U6QW55IC0tCiAqICAgICAgICAgICAgICAgICAgICAgICAgIE5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkpCiAqIChyY2FzZS1OU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5KQogKgogKiBTVEFUVVM6IFRPRE86IHN1YnN0LWdyb3VwcwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VOU1JlY3Vyc2VDaGVja0NhcmRpbmFsaXR5KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCQkgICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHIsCgkJCQkJICAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBiKQp7CiAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0OwogICAgLyogVE9ETzogRXJyb3IgY29kZXMgKHJjYXNlLU5TUmVjdXJzZUNoZWNrQ2FyZGluYWxpdHkpLiAqLwogICAgaWYgKChyLT5jaGlsZHJlbiA9PSBOVUxMKSB8fCAoci0+Y2hpbGRyZW4tPmNoaWxkcmVuID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBTUEVDICJGb3IgYSBncm91cCBwYXJ0aWNsZSB0byBiZSBhILd2YWxpZCByZXN0cmljdGlvbrcgb2YgYQogICAgKiB3aWxkY2FyZCBwYXJ0aWNsZS4uLiIKICAgICoKICAgICogU1BFQyAoMSkgIkV2ZXJ5IG1lbWJlciBvZiB0aGUge3BhcnRpY2xlc30gb2YgdGhlIGdyb3VwIGlzIGEgt3ZhbGlkCiAgICAqIHJlc3RyaWN0aW9utyBvZiB0aGUgd2lsZGNhcmQgYXMgZGVmaW5lZCBieQogICAgKiBQYXJ0aWNsZSBWYWxpZCAoUmVzdHJpY3Rpb24pICinMy45LjYpLiIKICAgICovCiAgICBwYXJ0ID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSByLT5jaGlsZHJlbi0+Y2hpbGRyZW47CiAgICBkbyB7CglpZiAoeG1sU2NoZW1hQ2hlY2tDT1NQYXJ0aWNsZVJlc3RyaWN0KGN0eHQsIHBhcnQsIGIpKQoJICAgIHJldHVybiAoMSk7CglwYXJ0ID0gKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBwYXJ0LT5uZXh0OwogICAgfSB3aGlsZSAocGFydCAhPSBOVUxMKTsKICAgIC8qCiAgICAqIFNQRUMgKDIpICJUaGUgZWZmZWN0aXZlIHRvdGFsIHJhbmdlIG9mIHRoZSBncm91cCBbLi4uXSBpcyBhCiAgICAqIHZhbGlkIHJlc3RyaWN0aW9uIG9mIEIncyBvY2N1cnJlbmNlIHJhbmdlIGFzIGRlZmluZWQgYnkKICAgICogT2NjdXJyZW5jZSBSYW5nZSBPSyAopzMuOS42KS4iCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrUGFydGljbGVSYW5nZU9LKAoJICAgIHhtbFNjaGVtYUdldFBhcnRpY2xlVG90YWxSYW5nZU1pbihyKSwKCSAgICB4bWxTY2hlbWFHZXRQYXJ0aWNsZVRvdGFsUmFuZ2VNYXgociksCgkgICAgYi0+bWluT2NjdXJzLCBiLT5tYXhPY2N1cnMpICE9IDApCglyZXR1cm4gKDEpOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHI6IHRoZSA8YWxsPiBvciA8c2VxdWVuY2U+IG1vZGVsIGdyb3VwIHBhcnRpY2xlCiAqIEBiOiB0aGUgYmFzZSA8YWxsPiBvciA8c2VxdWVuY2U+IG1vZGVsIGdyb3VwIHBhcnRpY2xlCiAqCiAqICgzLjkuNikgQ29uc3RyYWludHMgb24gUGFydGljbGUgU2NoZW1hIENvbXBvbmVudHMKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBQYXJ0aWNsZSBEZXJpdmF0aW9uIE9LIChBbGw6QWxsLFNlcXVlbmNlOlNlcXVlbmNlIC0tCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlY3Vyc2UpCiAqIChyY2FzZS1SZWN1cnNlKQogKgogKiBTVEFUVVM6ICA/CiAqIFRPRE86IHN1YnN0LWdyb3VwcwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrUkNhc2VSZWN1cnNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hUGFydGljbGVQdHIgciwKCQkJICAgeG1sU2NoZW1hUGFydGljbGVQdHIgYikKewogICAgLyogeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydDsgKi8KICAgIC8qIFRPRE86IEVycm9yIGNvZGVzIChyY2FzZS1SZWN1cnNlKS4gKi8KICAgIGlmICgoci0+Y2hpbGRyZW4gPT0gTlVMTCkgfHwgKGItPmNoaWxkcmVuID09IE5VTEwpIHx8Cgkoci0+Y2hpbGRyZW4tPnR5cGUgIT0gYi0+Y2hpbGRyZW4tPnR5cGUpKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBTUEVDICJGb3IgYW4gYWxsIG9yIHNlcXVlbmNlIGdyb3VwIHBhcnRpY2xlIHRvIGJlIGEgt3ZhbGlkCiAgICAqIHJlc3RyaWN0aW9utyBvZiBhbm90aGVyIGdyb3VwIHBhcnRpY2xlIHdpdGggdGhlIHNhbWUge2NvbXBvc2l0b3J9Li4uIgogICAgKgogICAgKiBTUEVDICgxKSAiUidzIG9jY3VycmVuY2UgcmFuZ2UgaXMgYSB2YWxpZCByZXN0cmljdGlvbiBvZiBCJ3MKICAgICogb2NjdXJyZW5jZSByYW5nZSBhcyBkZWZpbmVkIGJ5IE9jY3VycmVuY2UgUmFuZ2UgT0sgKKczLjkuNikuIgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFDaGVja1BhcnRpY2xlUmFuZ2VPSyhyLT5taW5PY2N1cnMsIHItPm1heE9jY3VycywKCSAgICBiLT5taW5PY2N1cnMsIGItPm1heE9jY3VycykpCglyZXR1cm4gKDEpOwoKCiAgICByZXR1cm4gKDApOwp9CgojZW5kaWYKCiNkZWZpbmUgRkFDRVRfUkVTVFJfTVVUVUFMX0VSUihmYWMxLCBmYWMyKSBcCiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LCAgICAgIFwKCVhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsIFwKCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBmYWMxLCBmYWMxLT5ub2RlLCBcCgkiSXQgaXMgYW4gZXJyb3IgZm9yIGJvdGggJyVzJyBhbmQgJyVzJyB0byBiZSBzcGVjaWZpZWQgb24gdGhlICJcCgkic2FtZSB0eXBlIGRlZmluaXRpb24iLCBcCglCQURfQ0FTVCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWMxLT50eXBlKSwgXAoJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjMi0+dHlwZSksIE5VTEwpOwoKI2RlZmluZSBGQUNFVF9SRVNUUl9FUlIoZmFjMSwgbXNnKSBcCiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LCAgICAgIFwKCVhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsIFwKCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBmYWMxLCBmYWMxLT5ub2RlLCBcCgltc2csIE5VTEwpOwoKI2RlZmluZSBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZmFjKSBcCiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LCBcCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLCBcCglOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZmFjLCBmYWMtPm5vZGUsIFwKCSJUaGUgYmFzZSB0eXBlJ3MgZmFjZXQgaXMgJ2ZpeGVkJywgdGh1cyB0aGUgdmFsdWUgbXVzdCBub3QgIiBcCgkiZGlmZmVyIiwgTlVMTCk7CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFEZXJpdmVGYWNldEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDEsCgkJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0MiwKCQkJaW50IGxlc3NHcmVhdGVyLAoJCQlpbnQgb3JFcXVhbCwKCQkJaW50IG9mQmFzZSkKewogICAgeG1sQ2hhciAqbXNnID0gTlVMTDsKCiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiciKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0MS0+dHlwZSkpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIicgaGFzIHRvIGJlIik7CiAgICBpZiAobGVzc0dyZWF0ZXIgPT0gMCkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgZXF1YWwgdG8iKTsKICAgIGlmIChsZXNzR3JlYXRlciA9PSAxKQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBncmVhdGVyIHRoYW4iKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgbGVzcyB0aGFuIik7CgogICAgaWYgKG9yRXF1YWwpCgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIG9yIGVxdWFsIHRvIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiICciKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0Mi0+dHlwZSkpOwogICAgaWYgKG9mQmFzZSkKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInIG9mIHRoZSBiYXNlIHR5cGUiKTsKICAgIGVsc2UKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInIik7CgogICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCVhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsCglOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZmFjZXQxLCBmYWNldDEtPm5vZGUsCgkoY29uc3QgY2hhciAqKSBtc2csIE5VTEwpOwoKICAgIGlmIChtc2cgIT0gTlVMTCkKCXhtbEZyZWUobXNnKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFEZXJpdmVBbmRWYWxpZGF0ZUZhY2V0cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgbGluaywgY3VyLCBsYXN0ID0gTlVMTDsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBiZmFjZXQsCglmbGVuZ3RoID0gTlVMTCwgZnRvdGRpZyA9IE5VTEwsIGZmcmFjZGlnID0gTlVMTCwKCWZtYXhsZW4gPSBOVUxMLCBmbWlubGVuID0gTlVMTCwgLyogZmFjZXRzIG9mIHRoZSBjdXJyZW50IHR5cGUgKi8KCWZtaW5pbmMgPSBOVUxMLCBmbWF4aW5jID0gTlVMTCwKCWZtaW5leGMgPSBOVUxMLCBmbWF4ZXhjID0gTlVMTCwKCWJmbGVuZ3RoID0gTlVMTCwgYmZ0b3RkaWcgPSBOVUxMLCBiZmZyYWNkaWcgPSBOVUxMLAoJYmZtYXhsZW4gPSBOVUxMLCBiZm1pbmxlbiA9IE5VTEwsIC8qIGZhY2V0cyBvZiB0aGUgYmFzZSB0eXBlICovCgliZm1pbmluYyA9IE5VTEwsIGJmbWF4aW5jID0gTlVMTCwKCWJmbWluZXhjID0gTlVMTCwgYmZtYXhleGMgPSBOVUxMOwogICAgaW50IHJlcywgZXJyID0gMCwgZml4ZWRFcnI7CiAgICAvKgogICAgKiAzIFRoZSB7ZmFjZXRzfSBvZiBSIGFyZSB0aGUgdW5pb24gb2YgUyBhbmQgdGhlIHtmYWNldHN9CiAgICAqIG9mIEIsIGVsaW1pbmF0aW5nIGR1cGxpY2F0ZXMuIFRvIGVsaW1pbmF0ZSBkdXBsaWNhdGVzLAogICAgKiB3aGVuIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBvY2N1cnMgaW4gYm90aCBTIGFuZCB0aGUKICAgICoge2ZhY2V0c30gb2YgQiwgdGhlIG9uZSBpbiB0aGUge2ZhY2V0c30gb2YgQiBpcyBub3QKICAgICogaW5jbHVkZWQsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBlbnVtZXJhdGlvbiBhbmQgcGF0dGVybgogICAgKiBmYWNldHMsIGZvciB3aGljaCBtdWx0aXBsZSBvY2N1cnJlbmNlcyB3aXRoIGRpc3RpbmN0IHZhbHVlcwogICAgKiBhcmUgYWxsb3dlZC4KICAgICovCgogICAgaWYgKCh0eXBlLT5mYWNldFNldCA9PSBOVUxMKSAmJiAoYmFzZS0+ZmFjZXRTZXQgPT0gTlVMTCkpCglyZXR1cm4gKDApOwoKICAgIGxhc3QgPSB0eXBlLT5mYWNldFNldDsKICAgIGlmIChsYXN0ICE9IE5VTEwpCgl3aGlsZSAobGFzdC0+bmV4dCAhPSBOVUxMKQoJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwoKICAgIGZvciAoY3VyID0gdHlwZS0+ZmFjZXRTZXQ7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCWZhY2V0ID0gY3VyLT5mYWNldDsKCXN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCWZsZW5ndGggPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQlmbWlubGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CgkJZm1pbmluYyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgoJCWZtaW5leGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQlmbWF4bGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgkJZm1heGluYyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJCWZtYXhleGMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJCWZ0b3RkaWcgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJCWZmcmFjZGlnID0gZmFjZXQ7IGJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBmb3IgKGN1ciA9IGJhc2UtPmZhY2V0U2V0OyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CglmYWNldCA9IGN1ci0+ZmFjZXQ7Cglzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQliZmxlbmd0aCA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCWJmbWlubGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CgkJYmZtaW5pbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCQliZm1pbmV4YyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJCWJmbWF4bGVuID0gZmFjZXQ7IGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgkJYmZtYXhpbmMgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCQliZm1heGV4YyA9IGZhY2V0OyBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CgkJYmZ0b3RkaWcgPSBmYWNldDsgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJCWJmZnJhY2RpZyA9IGZhY2V0OyBicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgZXJyID0gMDsKICAgIC8qCiAgICAqIGxlbmd0aCBhbmQgbWluTGVuZ3RoIG9yIG1heExlbmd0aCAoMi4yKSArICgzLjIpCiAgICAqLwogICAgaWYgKGZsZW5ndGggJiYgKGZtaW5sZW4gfHwgZm1heGxlbikpIHsKCUZBQ0VUX1JFU1RSX0VSUihmbGVuZ3RoLCAiSXQgaXMgYW4gZXJyb3IgZm9yIGJvdGggJ2xlbmd0aCcgYW5kICIKCSAgICAiZWl0aGVyIG9mICdtaW5MZW5ndGgnIG9yICdtYXhMZW5ndGgnIHRvIGJlIHNwZWNpZmllZCBvbiAiCgkgICAgInRoZSBzYW1lIHR5cGUgZGVmaW5pdGlvbiIpCiAgICB9CiAgICAvKgogICAgKiBNdXR1YWwgZXhjbHVzaW9ucyBpbiB0aGUgc2FtZSBkZXJpdmF0aW9uIHN0ZXAuCiAgICAqLwogICAgaWYgKChmbWF4aW5jKSAmJiAoZm1heGV4YykpIHsKCS8qCgkqIFNDQyAibWF4SW5jbHVzaXZlIGFuZCBtYXhFeGNsdXNpdmUiCgkqLwoJRkFDRVRfUkVTVFJfTVVUVUFMX0VSUihmbWF4aW5jLCBmbWF4ZXhjKQogICAgfQogICAgaWYgKChmbWluaW5jKSAmJiAoZm1pbmV4YykpIHsKCS8qCgkqIFNDQyAibWluSW5jbHVzaXZlIGFuZCBtaW5FeGNsdXNpdmUiCgkqLwoJRkFDRVRfUkVTVFJfTVVUVUFMX0VSUihmbWluaW5jLCBmbWluZXhjKQogICAgfQoKICAgIGlmIChmbGVuZ3RoICYmIGJmbGVuZ3RoKSB7CgkvKgoJKiBTQ0MgImxlbmd0aCB2YWxpZCByZXN0cmljdGlvbiIKCSogVGhlIHZhbHVlcyBoYXZlIHRvIGJlIGVxdWFsLgoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZmxlbmd0aC0+dmFsLCBiZmxlbmd0aC0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgIT0gMCkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZmxlbmd0aCwgYmZsZW5ndGgsIDAsIDAsIDEpOwoJaWYgKChyZXMgIT0gMCkgJiYgKGJmbGVuZ3RoLT5maXhlZCkpIHsKCSAgICBGQUNFVF9SRVNUUl9GSVhFRF9FUlIoZmxlbmd0aCkKCX0KCiAgICB9CiAgICBpZiAoZm1pbmxlbiAmJiBiZm1pbmxlbikgewoJLyoKCSogU0NDICJtaW5MZW5ndGggdmFsaWQgcmVzdHJpY3Rpb24iCgkqIG1pbkxlbmd0aCA+PSBCQVNFIG1pbkxlbmd0aAoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmxlbi0+dmFsLCBiZm1pbmxlbi0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgPT0gLTEpCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5sZW4sIGJmbWlubGVuLCAxLCAxLCAxKTsKCWlmICgocmVzICE9IDApICYmIChiZm1pbmxlbi0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtaW5sZW4pCgl9CiAgICB9CiAgICBpZiAoZm1heGxlbiAmJiBiZm1heGxlbikgewoJLyoKCSogU0NDICJtYXhMZW5ndGggdmFsaWQgcmVzdHJpY3Rpb24iCgkqIG1heExlbmd0aCA8PSBCQVNFIG1pbkxlbmd0aAoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGxlbi0+dmFsLCBiZm1heGxlbi0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgPT0gMSkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGxlbiwgYmZtYXhsZW4sIC0xLCAxLCAxKTsKCWlmICgocmVzICE9IDApICYmIChiZm1heGxlbi0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtYXhsZW4pCgl9CiAgICB9CiAgICAvKgogICAgKiBTQ0MgImxlbmd0aCBhbmQgbWluTGVuZ3RoIG9yIG1heExlbmd0aCIKICAgICovCiAgICBpZiAoISBmbGVuZ3RoKQoJZmxlbmd0aCA9IGJmbGVuZ3RoOwogICAgaWYgKGZsZW5ndGgpIHsKCWlmICghIGZtaW5sZW4pCgkgICAgZmxlbmd0aCA9IGJmbGVuZ3RoOwoJaWYgKGZtaW5sZW4pIHsKCSAgICAvKiAoMS4xKSBsZW5ndGggPj0gbWluTGVuZ3RoICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbGVuZ3RoLT52YWwsIGZtaW5sZW4tPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpCgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZsZW5ndGgsIGZtaW5sZW4sIDEsIDEsIDApOwoJfQoJaWYgKCEgZm1heGxlbikKCSAgICBmbWF4bGVuID0gYmZtYXhsZW47CglpZiAoZm1heGxlbikgewoJICAgIC8qICgyLjEpIGxlbmd0aCA8PSBtYXhMZW5ndGggKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZsZW5ndGgtPnZhbCwgZm1heGxlbi0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKQoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbGVuZ3RoLCBmbWF4bGVuLCAtMSwgMSwgMCk7Cgl9CiAgICB9CiAgICBpZiAoZm1heGluYykgewoJLyoKCSogIm1heEluY2x1c2l2ZSIKCSovCglpZiAoZm1pbmluYykgewoJICAgIC8qIFNDQyAibWF4SW5jbHVzaXZlID49IG1pbkluY2x1c2l2ZSIgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhpbmMtPnZhbCwgZm1pbmluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4aW5jLCBmbWluaW5jLCAxLCAxLCAwKTsKCSAgICB9Cgl9CgkvKgoJKiBTQ0MgIm1heEluY2x1c2l2ZSB2YWxpZCByZXN0cmljdGlvbiIKCSovCglpZiAoYmZtYXhpbmMpIHsKCSAgICAvKiBtYXhJbmNsdXNpdmUgPD0gQkFTRSBtYXhJbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhpbmMtPnZhbCwgYmZtYXhpbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGluYywgYmZtYXhpbmMsIC0xLCAxLCAxKTsKCSAgICBpZiAoKHJlcyAhPSAwKSAmJiAoYmZtYXhpbmMtPmZpeGVkKSkgewoJCUZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWF4aW5jKQoJICAgIH0KCX0KCWlmIChiZm1heGV4YykgewoJICAgIC8qIG1heEluY2x1c2l2ZSA8IEJBU0UgbWF4RXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4aW5jLT52YWwsIGJmbWF4ZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhpbmMsIGJmbWF4ZXhjLCAtMSwgMCwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluaW5jKSB7CgkgICAgLyogbWF4SW5jbHVzaXZlID49IEJBU0UgbWluSW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4aW5jLT52YWwsIGJmbWluaW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhpbmMsIGJmbWluaW5jLCAxLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5leGMpIHsKCSAgICAvKiBtYXhJbmNsdXNpdmUgPiBCQVNFIG1pbkV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGluYy0+dmFsLCBiZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhpbmMsIGJmbWluZXhjLCAxLCAwLCAxKTsKCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoZm1heGV4YykgewoJLyoKCSogIm1heEV4Y2x1c2l2ZSA+PSBtaW5FeGNsdXNpdmUiCgkqLwoJaWYgKGZtaW5leGMpIHsKCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtYXhleGMtPnZhbCwgZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWF4ZXhjLCBmbWluZXhjLCAxLCAxLCAwKTsKCSAgICB9Cgl9CgkvKgoJKiAibWF4RXhjbHVzaXZlIHZhbGlkIHJlc3RyaWN0aW9uIgoJKi8KCWlmIChiZm1heGV4YykgewoJICAgIC8qIG1heEV4Y2x1c2l2ZSA8PSBCQVNFIG1heEV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGV4Yy0+dmFsLCBiZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhleGMsIGJmbWF4ZXhjLCAtMSwgMSwgMSk7CgkgICAgfQoJICAgIGlmICgocmVzICE9IDApICYmIChiZm1heGV4Yy0+Zml4ZWQpKSB7CgkJRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtYXhleGMpCgkgICAgfQoJfQoJaWYgKGJmbWF4aW5jKSB7CgkgICAgLyogbWF4RXhjbHVzaXZlIDw9IEJBU0UgbWF4SW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWF4ZXhjLT52YWwsIGJmbWF4aW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1heGV4YywgYmZtYXhpbmMsIC0xLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5pbmMpIHsKCSAgICAvKiBtYXhFeGNsdXNpdmUgPiBCQVNFIG1pbkluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGV4Yy0+dmFsLCBiZm1pbmluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhleGMsIGJmbWluaW5jLCAxLCAwLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5leGMpIHsKCSAgICAvKiBtYXhFeGNsdXNpdmUgPiBCQVNFIG1pbkV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1heGV4Yy0+dmFsLCBiZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtYXhleGMsIGJmbWluZXhjLCAxLCAwLCAxKTsKCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoZm1pbmV4YykgewoJLyoKCSogIm1pbkV4Y2x1c2l2ZSA8IG1heEluY2x1c2l2ZSIKCSovCglpZiAoZm1heGluYykgewoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmV4Yy0+dmFsLCBmbWF4aW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5leGMsIGZtYXhpbmMsIC0xLCAwLCAwKTsKCSAgICB9Cgl9CgkvKgoJKiAibWluRXhjbHVzaXZlIHZhbGlkIHJlc3RyaWN0aW9uIgoJKi8KCWlmIChiZm1pbmV4YykgewoJICAgIC8qIG1pbkV4Y2x1c2l2ZSA+PSBCQVNFIG1pbkV4Y2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmV4Yy0+dmFsLCBiZm1pbmV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluZXhjLCBiZm1pbmV4YywgMSwgMSwgMSk7CgkgICAgfQoJICAgIGlmICgocmVzICE9IDApICYmIChiZm1pbmV4Yy0+Zml4ZWQpKSB7CgkJRkFDRVRfUkVTVFJfRklYRURfRVJSKGZtaW5leGMpCgkgICAgfQoJfQoJaWYgKGJmbWF4aW5jKSB7CgkgICAgLyogbWluRXhjbHVzaXZlIDw9IEJBU0UgbWF4SW5jbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluZXhjLT52YWwsIGJmbWF4aW5jLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzID09IDEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmV4YywgYmZtYXhpbmMsIC0xLCAxLCAxKTsKCSAgICB9Cgl9CglpZiAoYmZtaW5pbmMpIHsKCSAgICAvKiBtaW5FeGNsdXNpdmUgPj0gQkFTRSBtaW5JbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5leGMtPnZhbCwgYmZtaW5pbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmV4YywgYmZtaW5pbmMsIDEsIDEsIDEpOwoJICAgIH0KCX0KCWlmIChiZm1heGV4YykgewoJICAgIC8qIG1pbkV4Y2x1c2l2ZSA8IEJBU0UgbWF4RXhjbHVzaXZlICovCgkgICAgcmVzID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlcyhmbWluZXhjLT52YWwsIGJmbWF4ZXhjLT52YWwpOwoJICAgIGlmIChyZXMgPT0gLTIpCgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICBpZiAocmVzICE9IC0xKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5leGMsIGJmbWF4ZXhjLCAtMSwgMCwgMSk7CgkgICAgfQoJfQogICAgfQogICAgaWYgKGZtaW5pbmMpIHsKCS8qCgkqICJtaW5JbmNsdXNpdmUgPCBtYXhFeGNsdXNpdmUiCgkqLwoJaWYgKGZtYXhleGMpIHsKCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5pbmMtPnZhbCwgZm1heGV4Yy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyAhPSAtMSkgewoJCXhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmbWluaW5jLCBmbWF4ZXhjLCAtMSwgMCwgMCk7CgkgICAgfQoJfQoJLyoKCSogIm1pbkV4Y2x1c2l2ZSB2YWxpZCByZXN0cmljdGlvbiIKCSovCglpZiAoYmZtaW5pbmMpIHsKCSAgICAvKiBtaW5JbmNsdXNpdmUgPj0gQkFTRSBtaW5JbmNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5pbmMtPnZhbCwgYmZtaW5pbmMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtaW5pbmMsIDEsIDEsIDEpOwoJICAgIH0KCSAgICBpZiAoKHJlcyAhPSAwKSAmJiAoYmZtaW5pbmMtPmZpeGVkKSkgewoJCUZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmbWluaW5jKQoJICAgIH0KCX0KCWlmIChiZm1heGluYykgewoJICAgIC8qIG1pbkluY2x1c2l2ZSA8PSBCQVNFIG1heEluY2x1c2l2ZSAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZm1pbmluYy0+dmFsLCBiZm1heGluYy0+dmFsKTsKCSAgICBpZiAocmVzID09IC0yKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWYgKHJlcyA9PSAxKSB7CgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5pbmMsIGJmbWF4aW5jLCAtMSwgMSwgMSk7CgkgICAgfQoJfQoJaWYgKGJmbWluZXhjKSB7CgkgICAgLyogbWluSW5jbHVzaXZlID4gQkFTRSBtaW5FeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5pbmMtPnZhbCwgYmZtaW5leGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gMSkKCQl4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZm1pbmluYywgYmZtaW5leGMsIDEsIDAsIDEpOwoJfQoJaWYgKGJmbWF4ZXhjKSB7CgkgICAgLyogbWluSW5jbHVzaXZlIDwgQkFTRSBtYXhFeGNsdXNpdmUgKi8KCSAgICByZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZtaW5pbmMtPnZhbCwgYmZtYXhleGMtPnZhbCk7CgkgICAgaWYgKHJlcyA9PSAtMikKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIGlmIChyZXMgIT0gLTEpCgkJeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZtaW5pbmMsIGJmbWF4ZXhjLCAtMSwgMCwgMSk7Cgl9CiAgICB9CiAgICBpZiAoZnRvdGRpZyAmJiBiZnRvdGRpZykgewoJLyoKCSogU0NDICIgdG90YWxEaWdpdHMgdmFsaWQgcmVzdHJpY3Rpb24iCgkqIHRvdGFsRGlnaXRzIDw9IEJBU0UgdG90YWxEaWdpdHMKCSovCglyZXMgPSB4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGZ0b3RkaWctPnZhbCwgYmZ0b3RkaWctPnZhbCk7CglpZiAocmVzID09IC0yKQoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CglpZiAocmVzID09IDEpCgkgICAgeG1sU2NoZW1hRGVyaXZlRmFjZXRFcnIocGN0eHQsIGZ0b3RkaWcsIGJmdG90ZGlnLAoJICAgIC0xLCAxLCAxKTsKCWlmICgocmVzICE9IDApICYmIChiZnRvdGRpZy0+Zml4ZWQpKSB7CgkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZ0b3RkaWcpCgl9CiAgICB9CiAgICBpZiAoZmZyYWNkaWcgJiYgYmZmcmFjZGlnKSB7CgkvKgoJKiBTQ0MgICJmcmFjdGlvbkRpZ2l0cyB2YWxpZCByZXN0cmljdGlvbiIKCSogZnJhY3Rpb25EaWdpdHMgPD0gQkFTRSBmcmFjdGlvbkRpZ2l0cwoJKi8KCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZmZyYWNkaWctPnZhbCwgYmZmcmFjZGlnLT52YWwpOwoJaWYgKHJlcyA9PSAtMikKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJaWYgKHJlcyA9PSAxKQoJICAgIHhtbFNjaGVtYURlcml2ZUZhY2V0RXJyKHBjdHh0LCBmZnJhY2RpZywgYmZmcmFjZGlnLAoJICAgIC0xLCAxLCAxKTsKCWlmICgocmVzICE9IDApICYmIChiZmZyYWNkaWctPmZpeGVkKSkgewoJICAgIEZBQ0VUX1JFU1RSX0ZJWEVEX0VSUihmZnJhY2RpZykKCX0KICAgIH0KICAgIC8qCiAgICAqIFNDQyAiZnJhY3Rpb25EaWdpdHMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRvdGFsRGlnaXRzIgogICAgKi8KICAgIGlmICghIGZ0b3RkaWcpCglmdG90ZGlnID0gYmZ0b3RkaWc7CiAgICBpZiAoISBmZnJhY2RpZykKCWZmcmFjZGlnID0gYmZmcmFjZGlnOwogICAgaWYgKGZ0b3RkaWcgJiYgZmZyYWNkaWcpIHsKCXJlcyA9IHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoZmZyYWNkaWctPnZhbCwgZnRvdGRpZy0+dmFsKTsKCWlmIChyZXMgPT0gLTIpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCWlmIChyZXMgPT0gMSkKCSAgICB4bWxTY2hlbWFEZXJpdmVGYWNldEVycihwY3R4dCwgZmZyYWNkaWcsIGZ0b3RkaWcsCgkJLTEsIDEsIDApOwogICAgfQogICAgLyoKICAgICogKkVudW1lcmF0aW9ucyogd29uJyBiZSBhZGRlZCBoZXJlLCBzaW5jZSBvbmx5IHRoZSBmaXJzdCBzZXQKICAgICogb2YgZW51bWVyYXRpb25zIGluIHRoZSBhbmNlc3Rvci1vci1zZWxmIGF4aXMgaXMgdXNlZAogICAgKiBmb3IgdmFsaWRhdGlvbiwgcGx1cyB3ZSBuZWVkIHRvIHVzZSB0aGUgYmFzZSB0eXBlIG9mIHRob3NlCiAgICAqIGVudW1lcmF0aW9ucyBmb3Igd2hpdGVzcGFjZS4KICAgICoKICAgICogKlBhdHRlcm5zKjogd29uJ3QgYmUgYWRkIGhlcmUsIHNpbmNlIHRoZXkgYXJlIE9SZWQgYXQKICAgICogdHlwZSBsZXZlbCBhbmQgQU5EZWQgYXQgYW5jZXN0b3IgbGV2ZWwuIFRoaXMgd2lsbAogICAgKiBoYXBwZWQgZHVyaW5nIHZhbGlkYXRpb24gYnkgd2Fsa2luZyB0aGUgYmFzZSBheGlzCiAgICAqIG9mIHRoZSB0eXBlLgogICAgKi8KICAgIGZvciAoY3VyID0gYmFzZS0+ZmFjZXRTZXQ7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCWJmYWNldCA9IGN1ci0+ZmFjZXQ7CgkvKgoJKiBTcGVjaWFsIGhhbmRsaW5nIG9mIGVudW1lcmF0aW9ucyBhbmQgcGF0dGVybnMuCgkqIFRPRE86IGhtbSwgdGhleSBzaG91bGQgbm90IGFwcGVhciBpbiB0aGUgc2V0LCBzbyByZW1vdmUgdGhpcy4KCSovCglpZiAoKGJmYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHx8CgkgICAgKGJmYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkKCSAgICBjb250aW51ZTsKCS8qCgkqIFNlYXJjaCBmb3IgYSBkdXBsaWNhdGUgZmFjZXQgaW4gdGhlIGN1cnJlbnQgdHlwZS4KCSovCglsaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CgllcnIgPSAwOwoJZml4ZWRFcnIgPSAwOwoJd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJICAgIGZhY2V0ID0gbGluay0+ZmFjZXQ7CgkgICAgaWYgKGZhY2V0LT50eXBlID09IGJmYWNldC0+dHlwZSkgewoJCXN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCQkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJCS8qCgkJCSogVGhlIHdoaXRlc3BhY2UgbXVzdCBiZSBzdHJvbmdlci4KCQkJKi8KCQkJaWYgKGZhY2V0LT53aGl0ZXNwYWNlIDwgYmZhY2V0LT53aGl0ZXNwYWNlKSB7CgkJCSAgICBGQUNFVF9SRVNUUl9FUlIoZmxlbmd0aCwKCQkJCSJUaGUgJ3doaXRlc3BhY2UnIHZhbHVlIGhhcyB0byBiZSBlcXVhbCB0byAiCgkJCQkib3Igc3Ryb25nZXIgdGhhbiB0aGUgJ3doaXRlc3BhY2UnIHZhbHVlIG9mICIKCQkJCSJ0aGUgYmFzZSB0eXBlIikKCQkJfQoJCQlpZiAoKGJmYWNldC0+Zml4ZWQpICYmCgkJCSAgICAoZmFjZXQtPndoaXRlc3BhY2UgIT0gYmZhY2V0LT53aGl0ZXNwYWNlKSkgewoJCQkgICAgRkFDRVRfUkVTVFJfRklYRURfRVJSKGZhY2V0KQoJCQl9CgkJCWJyZWFrOwoJCSAgICBkZWZhdWx0OgoJCQlicmVhazsKCQl9CgkJLyogRHVwbGljYXRlIGZvdW5kLiAqLwoJCWJyZWFrOwoJICAgIH0KCSAgICBsaW5rID0gbGluay0+bmV4dDsKCX0KCS8qCgkqIElmIG5vIGR1cGxpY2F0ZSB3YXMgZm91bmQ6IGFkZCB0aGUgYmFzZSB0eXBlcydzIGZhY2V0CgkqIHRvIHRoZSBzZXQuCgkqLwoJaWYgKGxpbmsgPT0gTlVMTCkgewoJICAgIGxpbmsgPSAoeG1sU2NoZW1hRmFjZXRMaW5rUHRyKQoJCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkgICAgaWYgKGxpbmsgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnJNZW1vcnkocGN0eHQsCgkJICAgICJkZXJpdmluZyBmYWNldHMsIGNyZWF0aW5nIGEgZmFjZXQgbGluayIsIE5VTEwpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICBsaW5rLT5mYWNldCA9IGN1ci0+ZmFjZXQ7CgkgICAgbGluay0+bmV4dCA9IE5VTEw7CgkgICAgaWYgKGxhc3QgPT0gTlVMTCkKCQl0eXBlLT5mYWNldFNldCA9IGxpbms7CgkgICAgZWxzZQoJCWxhc3QtPm5leHQgPSBsaW5rOwoJICAgIGxhc3QgPSBsaW5rOwoJfQoKICAgIH0KCiAgICByZXR1cm4gKDApOwppbnRlcm5hbF9lcnJvcjoKICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCglYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLAoJTlVMTCwgdHlwZSwgTlVMTCwKCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hRGVyaXZlQW5kVmFsaWRhdGVGYWNldHMiLCBOVUxMKTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rLCBwcmV2TGluaywgc3ViTGluaywgbmV3TGluazsKICAgIC8qCiAgICAqIFRoZSBhY3R1YWwgdmFsdWUgaXMgdGhlbiBmb3JtZWQgYnkgcmVwbGFjaW5nIGFueSB1bmlvbiB0eXBlCiAgICAqIGRlZmluaXRpb24gaW4gdGhlILdleHBsaWNpdCBtZW1iZXJztyB3aXRoIHRoZSBtZW1iZXJzIG9mIHRoZWlyCiAgICAqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLgogICAgKi8KICAgIGxpbmsgPSB0eXBlLT5tZW1iZXJUeXBlczsKICAgIHdoaWxlIChsaW5rICE9IE5VTEwpIHsKCglpZiAoSVNfTk9UX1RZUEVGSVhFRChsaW5rLT50eXBlKSkKCSAgICB4bWxTY2hlbWFUeXBlRml4dXAobGluay0+dHlwZSwgcGN0eHQsIE5VTEwpOwoKCWlmIChWQVJJRVRZX1VOSU9OKGxpbmstPnR5cGUpKSB7CgkgICAgc3ViTGluayA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKGxpbmstPnR5cGUpOwoJICAgIGlmIChzdWJMaW5rICE9IE5VTEwpIHsKCQlsaW5rLT50eXBlID0gc3ViTGluay0+dHlwZTsKCQlpZiAoc3ViTGluay0+bmV4dCAhPSBOVUxMKSB7CgkJICAgIGxhc3RMaW5rID0gbGluay0+bmV4dDsKCQkgICAgc3ViTGluayA9IHN1YkxpbmstPm5leHQ7CgkJICAgIHByZXZMaW5rID0gbGluazsKCQkgICAgd2hpbGUgKHN1YkxpbmsgIT0gTlVMTCkgewoJCQluZXdMaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKQoJCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJCQlpZiAobmV3TGluayA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KHBjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsCgkJCQlOVUxMKTsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9CgkJCW5ld0xpbmstPnR5cGUgPSBzdWJMaW5rLT50eXBlOwoJCQlwcmV2TGluay0+bmV4dCA9IG5ld0xpbms7CgkJCXByZXZMaW5rID0gbmV3TGluazsKCQkJbmV3TGluay0+bmV4dCA9IGxhc3RMaW5rOwoKCQkJc3ViTGluayA9IHN1YkxpbmstPm5leHQ7CgkJICAgIH0KCQl9CgkgICAgfQoJfQoJbGluayA9IGxpbmstPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXBPcHRpbUZhY2V0cyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgICAgCiAgICBpbnQgaGFzID0gMCwgbmVlZFZhbCA9IDAsIG5vcm1WYWwgPSAwOwoKICAgIGhhcwk9ICh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFMpID8gMSA6IDA7CiAgICBpZiAoaGFzKSB7CgluZWVkVmFsID0gKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUUpID8gMSA6IDA7Cglub3JtVmFsID0gKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9OT1JNVkFMVUVORUVERUQpID8gMSA6IDA7CiAgICB9CiAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhYzsKCQoJZm9yIChmYWMgPSB0eXBlLT5mYWNldHM7IGZhYyAhPSBOVUxMOyBmYWMgPSBmYWMtPm5leHQpIHsKCSAgICBzd2l0Y2ggKGZhYy0+dHlwZSkgewoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCQkgICAgbm9ybVZhbCA9IDE7CgkJICAgIGhhcyA9IDE7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQkgICAgbmVlZFZhbCA9IDE7CgkJICAgIG5vcm1WYWwgPSAxOwoJCSAgICBoYXMgPSAxOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICBoYXMgPSAxOwoJCSAgICBicmVhazsKCSAgICB9Cgl9CQogICAgfQogICAgaWYgKG5vcm1WYWwpCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRDsKICAgIGlmIChuZWVkVmFsKQoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7CiAgICBpZiAoaGFzKQoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTOwoKICAgIGlmIChoYXMgJiYgKCEgbmVlZFZhbCkgJiYgVkFSSUVUWV9BVE9NSUModHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgcHJpbSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHlwZSk7CgkvKgoJKiBPUFRJTUlaRSBWQUwgVE9ETzogU29tZSBmYWNldHMgbmVlZCBhIGNvbXB1dGVkIHZhbHVlLgoJKi8KCWlmICgocHJpbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkgJiYKCSAgICAocHJpbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfU1RSSU5HKSkgewoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFOwoJfSAJCiAgICB9ICAgICAgIAp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVR5cGVGaXh1cFdoaXRlc3BhY2UoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICAKICAgIAogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIHdoaXRlc3BhY2UtZmFjZXQgdmFsdWUuCiAgICAqLyAgICAKICAgIGlmIChWQVJJRVRZX0xJU1QodHlwZSkpIHsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9DT0xMQVBTRTsKCXJldHVybiAoMCk7CiAgICB9IGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpCglyZXR1cm4gKDApOwogICAgCiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbjsKCglmb3IgKGxpbiA9IHR5cGUtPmZhY2V0U2V0OyBsaW4gIT0gTlVMTDsgbGluID0gbGluLT5uZXh0KSB7CgkgICAgaWYgKGxpbi0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJc3dpdGNoIChsaW4tPmZhY2V0LT53aGl0ZXNwYWNlKSB7CgkJY2FzZSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRToKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1BSRVNFUlZFOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0U6CgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9SRVBMQUNFOwoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFOgoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1dISVRFU1BBQ0VfQ09MTEFQU0U7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3IAogICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvIAogICAgKiBjb2xsYXBzZQogICAgKi8KICAgIHsKCXhtbFNjaGVtYVR5cGVQdHIgYW5jOwoKCWZvciAoYW5jID0gdHlwZS0+YmFzZVR5cGU7IGFuYyAhPSBOVUxMICYmIAoJCWFuYy0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRTsKCQlhbmMgPSBhbmMtPmJhc2VUeXBlKSB7CgoJICAgIGlmIChhbmMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkJaWYgKGFuYy0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfTk9STVNUUklORykgewkgICAgCgkJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9SRVBMQUNFOwoKCQl9IGVsc2UgaWYgKChhbmMtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgfHwKCQkgICAgKGFuYy0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpIHsJCSAgICAKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX1BSRVNFUlZFOwoKCQl9IGVsc2UKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9XSElURVNQQUNFX0NPTExBUFNFOwoJCWJyZWFrOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVHlwZUZpeHVwOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4ZXMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIHR5cGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgoJKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkpCglyZXR1cm47CiAgICBpZiAoISBJU19OT1RfVFlQRUZJWEVEKHR5cGUpKQoJcmV0dXJuOwogICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9JTlRFUk5BTF9SRVNPTFZFRDsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGUtPm5hbWU7CgogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVR5cGVGaXh1cCwgIgoJICAgICJiYXNlVHlwZSBpcyBtaXNzaW5nIG9uICclcyciLCB0eXBlLT5uYW1lKTsKCXJldHVybjsKICAgIH0KCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoKCS8qCgkqIFR5cGUtZml4IHRoZSBiYXNlIHR5cGUuCgkqLwoJaWYgKElTX05PVF9UWVBFRklYRUQoYmFzZVR5cGUpKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgcGN0eHQsIE5VTEwpOwoJaWYgKGJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfSU5WQUxJRCkgewoJICAgIC8qCgkgICAgKiBTa2lwIGZpeHVwIGlmIHRoZSBiYXNlIHR5cGUgaXMgaW52YWxpZC4KCSAgICAqIFRPRE86IEdlbmVyYXRlIGEgd2FybmluZyEKCSAgICAqLwoJICAgIHJldHVybjsKCX0JCgkvKgoJKiBUaGlzIGJhc2ljYWxseSBjaGVja3MgaWYgdGhlIGJhc2UgdHlwZSBjYW4gYmUgZGVyaXZlZC4KCSovCglpZiAoeG1sU2NoZW1hQ2hlY2tTUkNDVChwY3R4dCwgdHlwZSkgIT0gMCkgewoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfSU5URVJOQUxfSU5WQUxJRDsKCSAgICByZXR1cm47Cgl9CgkvKgoJKiBGaXh1cCB0aGUgY29udGVudCB0eXBlLgoJKi8KCWlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB7CgkgICAgLyoKCSAgICAqIENvcnJlc3BvbmRzIHRvIDxjb21wbGV4VHlwZT48c2ltcGxlQ29udGVudD4uLi4KCSAgICAqLwoJICAgIGlmICgoSVNfQ09NUExFWF9UWVBFKGJhc2VUeXBlKSkgJiYKCQkoYmFzZVR5cGUtPmNvbnRlbnRUeXBlRGVmICE9IE5VTEwpICYmCgkJKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikpIHsKCQl4bWxTY2hlbWFUeXBlUHRyIGNvbnRlbnRCYXNlLCBjb250ZW50OwoJCWNoYXIgYnVmWzMwXTsKCQljb25zdCB4bWxDaGFyICp0bXBuYW1lOwoJCS8qCgkJKiBTUEVDICgxKSBJZiA8cmVzdHJpY3Rpb24+ICsgYmFzZSB0eXBlIGlzIDxjb21wbGV4VHlwZT4sCgkJKiAid2hvc2Ugb3duIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUuLi4iCgkJKi8KCQlpZiAodHlwZS0+Y29udGVudFR5cGVEZWYgIT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDEuMSkgInRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlCgkJICAgICogPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDxyZXN0cmljdGlvbj4gaWYgdGhlcmUKCQkgICAgKiBpcyBvbmU7IgoJCSAgICAqIE5vdGUgdGhhdCB0aGlzICI8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0iIHdhcyBwdXQKCQkgICAgKiBpbnRvIC0+Y29udGVudFR5cGVEZWYgZHVyaW5nIHBhcnNpbmcuCgkJICAgICovCgkJICAgIGNvbnRlbnRCYXNlID0gdHlwZS0+Y29udGVudFR5cGVEZWY7CgkJICAgIHR5cGUtPmNvbnRlbnRUeXBlRGVmID0gTlVMTDsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqICgxLjIpICIuLi5vdGhlcndpc2UgKDxyZXN0cmljdGlvbj4gaGFzIG5vIDxzaW1wbGVUeXBlPgoJCSAgICAqIGFtb25nIGl0cyBbY2hpbGRyZW5dKSwgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gd2hpY2gKCQkgICAgKiBpcyB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIC4uLiBiYXNlIHR5cGUuIgoJCSAgICAqLwoJCSAgICBjb250ZW50QmFzZSA9IGJhc2VUeXBlLT5jb250ZW50VHlwZURlZjsKCQl9CgkJLyoKCQkqIFNQRUMKCQkqICIuLi4gYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHdoaWNoIHJlc3RyaWN0cyB0aGUgc2ltcGxlCgkJKiB0eXBlIGRlZmluaXRpb24gaWRlbnRpZmllZCBpbiBjbGF1c2UgMS4xIG9yIGNsYXVzZSAxLjIKCQkqIHdpdGggYSBzZXQgb2YgZmFjZXQgY29tcG9uZW50cyIKCQkqCgkJKiBDcmVhdGUgdGhlIGFub255bW91cyBzaW1wbGUgdHlwZSwgd2hpY2ggd2lsbCBiZSB0aGUgY29udGVudAoJCSogdHlwZSBvZiB0aGUgY29tcGxleCB0eXBlLgoJCSovCQkKCQlzbnByaW50ZihidWYsIDI5LCAiI3NjU1QlZCIsICsrKHBjdHh0LT5jb3VudGVyKSk7CgkJdG1wbmFtZSA9IHhtbERpY3RMb29rdXAocGN0eHQtPmRpY3QsIEJBRF9DQVNUIGJ1ZiwgLTEpOwoJCWNvbnRlbnQgPSB4bWxTY2hlbWFBZGRUeXBlKHBjdHh0LAoJCSAgICBwY3R4dC0+c2NoZW1hLCB0bXBuYW1lLCB0bXBuYW1lLCB0eXBlLT5ub2RlLCAwKTsKCQlpZiAoY29udGVudCA9PSBOVUxMKQoJCSAgICByZXR1cm47CgkJLyoKCQkqIFdlIHdpbGwgdXNlIHRoZSBzYW1lIG5vZGUgYXMgZm9yIHRoZSA8Y29tcGxleFR5cGU+CgkJKiB0byBoYXZlIGl0IHNvbWVob3cgYW5jaG9yZWQgaW4gdGhlIHNjaGVtYSBkb2MuCgkJKi8KCQljb250ZW50LT5ub2RlID0gdHlwZS0+bm9kZTsKCQljb250ZW50LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRTsKCQljb250ZW50LT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJY29udGVudC0+YmFzZVR5cGUgPSBjb250ZW50QmFzZTsKCQkvKgoJCSogTW92ZSB0aGUgZmFjZXRzLCBwcmV2aW91c2x5IGFuY2hvcmVkIG9uIHRoZSBjb21wbGV4VHlwZS4KCQkqLwoJCWNvbnRlbnQtPmZhY2V0cyA9IHR5cGUtPmZhY2V0czsKCQl0eXBlLT5mYWNldHMgPSBOVUxMOwoJCWNvbnRlbnQtPmZhY2V0U2V0ID0gdHlwZS0+ZmFjZXRTZXQ7CgkJdHlwZS0+ZmFjZXRTZXQgPSBOVUxMOwoKCQl0eXBlLT5jb250ZW50VHlwZURlZiA9IGNvbnRlbnQ7CgkJaWYgKElTX05PVF9UWVBFRklYRUQoY29udGVudEJhc2UpKQoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoY29udGVudEJhc2UsIHBjdHh0LCBOVUxMKTsKCQl4bWxTY2hlbWFUeXBlRml4dXAoY29udGVudCwgcGN0eHQsIE5VTEwpOwoKCSAgICB9IGVsc2UgaWYgKChJU19DT01QTEVYX1RZUEUoYmFzZVR5cGUpKSAmJgoJCShiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSAmJgoJCSh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pKSB7CgkJLyoKCQkqIFNQRUMgKDIpIElmIDxyZXN0cmljdGlvbj4gKyBiYXNlIGlzIGEgbWl4ZWQgPGNvbXBsZXhUeXBlPiB3aXRoCgkJKiBhbiBlbXB0aWFibGUgcGFydGljbGUsIHRoZW4gYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIHdoaWNoCgkJKiByZXN0cmljdHMgdGhlIDxyZXN0cmljdGlvbj4ncyA8c2ltcGxlVHlwZT4gY2hpbGQuCgkJKi8KCQlpZiAoKHR5cGUtPmNvbnRlbnRUeXBlRGVmID09IE5VTEwpIHx8CgkJICAgICh0eXBlLT5jb250ZW50VHlwZURlZi0+YmFzZVR5cGUgPT0gTlVMTCkpIHsKCQkgICAgLyoKCQkgICAgKiBUT0RPOiBDaGVjayBpZiB0aGlzIGV2ZXIgaGFwcGVucy4KCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVHlwZUZpeHVwLCAiCgkJCSJjb21wbGV4IHR5cGUgJyVzJzogdGhlIDxzaW1wbGVDb250ZW50PjxyZXN0cmljdGlvbj4gIgoJCQkiaXMgbWlzc2luZyBhIDxzaW1wbGVUeXBlPiBjaGlsZCwgYnV0IHdhcyBub3QgY2F0Y2hlZCAiCgkJCSJieSB4bWxTY2hlbWFDaGVja1NSQ0NUKCkiLCB0eXBlLT5uYW1lKTsKCQl9CgkgICAgfSBlbHNlIGlmICgoSVNfQ09NUExFWF9UWVBFKGJhc2VUeXBlKSkgJiYKCQkodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikpIHsKCQkvKgoJCSogU1BFQyAoMykgSWYgPGV4dGVuc2lvbj4gKyBiYXNlIGlzIDxjb21wbGV4VHlwZT4gd2l0aAoJCSogPHNpbXBsZVR5cGU+IGNvbnRlbnQsICIuLi50aGVuIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGF0CgkJKiBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiIKCQkqLwoJCWlmIChiYXNlVHlwZS0+Y29udGVudFR5cGVEZWYgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIFRPRE86IENoZWNrIGlmIHRoaXMgZXZlciBoYXBwZW5zLiB4bWxTY2hlbWFDaGVja1NSQ0NUCgkJICAgICogc2hvdWxkIGhhdmUgY2F0Y2hlZCB0aGlzIGFscmVhZHkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVR5cGVGaXh1cCwgIgoJCQkiY29tcGxleCB0eXBlICclcyc6IHRoZSA8ZXh0ZW5zaW9uPmVkIGJhc2UgdHlwZSBpcyAiCgkJCSJhIGNvbXBsZXggdHlwZSB3aXRoIG5vIHNpbXBsZSBjb250ZW50IHR5cGUiLAoJCQl0eXBlLT5uYW1lKTsKCQl9CgkJdHlwZS0+Y29udGVudFR5cGVEZWYgPSBiYXNlVHlwZS0+Y29udGVudFR5cGVEZWY7CgkgICAgfSBlbHNlIGlmICgoSVNfU0lNUExFX1RZUEUoYmFzZVR5cGUpKSAmJgoJCSh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSkgewoJCS8qCgkJKiBTUEVDICg0KSA8ZXh0ZW5zaW9uPiArIGJhc2UgaXMgPHNpbXBsZVR5cGU+CgkJKiAiLi4uIHRoZW4gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIgoJCSovCgkJdHlwZS0+Y29udGVudFR5cGVEZWYgPSBiYXNlVHlwZTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiBUT0RPOiBDaGVjayBpZiB0aGlzIGV2ZXIgaGFwcGVucy4KCQkqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVR5cGVGaXh1cCwgIgoJCSAgICAiY29tcGxleCB0eXBlICclcycgd2l0aCA8c2ltcGxlQ29udGVudD46IHVuaGFuZGxlZCAiCgkJICAgICJkZXJpdmF0aW9uIGNhc2UiLCB0eXBlLT5uYW1lKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIGludCBkdW1teVNlcXVlbmNlID0gMDsKCSAgICB4bWxTY2hlbWFQYXJ0aWNsZVB0ciBwYXJ0aWNsZSA9CgkJKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0eXBlLT5zdWJ0eXBlczsKCSAgICAvKgoJICAgICogQ29ycmVzcG9uZHMgdG8gPGNvbXBsZXhUeXBlPjxjb21wbGV4Q29udGVudD4uLi4KCSAgICAqCgkgICAgKiBOT1RFIHRoYXQgdGhlIGVmZmVjdGl2ZSBtaXhlZCB3YXMgYWxyZWFkeSBzZXQgZHVyaW5nIHBhcnNpbmcgb2YKCSAgICAqIDxjb21wbGV4VHlwZT4gYW5kIDxjb21wbGV4Q29udGVudD47IGl0cyBmbGFnIHZhbHVlIGlzCgkgICAgKiBYTUxfU0NIRU1BU19UWVBFX01JWEVELgoJICAgICoKCSAgICAqIENvbXB1dGUgdGhlICJlZmZlY3RpdmUgY29udGVudCI6CgkgICAgKiAoMi4xLjEpICsgKDIuMS4yKSArICgyLjEuMykKCSAgICAqLwoJICAgIGlmICgocGFydGljbGUgPT0gTlVMTCkgfHwKCQkoKHBhcnRpY2xlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkgJiYKCQkgKChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgfHwKCQkgIChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSB8fAoJCSAgKChwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkgJiYKCQkgICAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSkpICYmCgkJICAgKCAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBwYXJ0aWNsZS0+Y2hpbGRyZW4pLT5jaGlsZHJlbiA9PSBOVUxMKSkpIHsKCQlpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CgkJICAgIC8qCgkJICAgICogU1BFQyAoMi4xLjQpICJJZiB0aGUgt2VmZmVjdGl2ZSBtaXhlZLcgaXMgdHJ1ZSwgdGhlbgoJCSAgICAqIGEgcGFydGljbGUgd2hvc2UgcHJvcGVydGllcyBhcmUgYXMgZm9sbG93czouLi4iCgkJICAgICoKCQkgICAgKiBFbXB0eSBzZXF1ZW5jZSBtb2RlbCBncm91cCB3aXRoCgkJICAgICogbWluT2NjdXJzL21heE9jY3VycyA9IDEgKGkuZS4gYSAicGFydGljbGUgZW1wdGlhYmxlIikuCgkJICAgICogTk9URSB0aGF0IHdlIHNpbGwgYXNzaWduIGl0IHRoZSA8Y29tcGxleFR5cGU+IG5vZGUgdG8KCQkgICAgKiBzb21laG93IGFuY2hvciBpdCBpbiB0aGUgZG9jLgoJCSAgICAqLwoJCSAgICBpZiAoKHBhcnRpY2xlID09IE5VTEwpIHx8CgkJCShwYXJ0aWNsZS0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkgewoJCQkvKgoJCQkqIENyZWF0ZSB0aGUgcGFydGljbGUuCgkJCSovCgkJCXBhcnRpY2xlID0geG1sU2NoZW1hQWRkUGFydGljbGUocGN0eHQsIHBjdHh0LT5zY2hlbWEsCgkJCSAgICB0eXBlLT5ub2RlLCAxLCAxKTsKCQkJaWYgKHBhcnRpY2xlID09IE5VTEwpCgkJCSAgICByZXR1cm47CgkJCS8qCgkJCSogQ3JlYXRlIHRoZSBtb2RlbCBncm91cC4KCQkJKi8KCQkJcGFydGljbGUtPmNoaWxkcmVuID0gKHhtbFNjaGVtYVRyZWVJdGVtUHRyKQoJCQkgICAgeG1sU2NoZW1hQWRkTW9kZWxHcm91cChwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJCVhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSwgTlVMTCwgdHlwZS0+bm9kZSk7CgkJCWlmIChwYXJ0aWNsZS0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkJICAgIHJldHVybjsKCgkJCXR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpIHBhcnRpY2xlOwoJCSAgICB9CgkJICAgIGR1bW15U2VxdWVuY2UgPSAxOwoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqIFNQRUMgKDIuMS41KSAib3RoZXJ3aXNlIGVtcHR5IgoJCSAgICAqLwoJCSAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQl9CgkgICAgfSBlbHNlIHsKCQkvKgoJIAkqIFNQRUMgKDIuMikgIm90aGVyd2lzZSB0aGUgcGFydGljbGUgY29ycmVzcG9uZGluZyB0byB0aGUKCQkqIDxhbGw+LCA8Y2hvaWNlPiwgPGdyb3VwPiBvciA8c2VxdWVuY2U+IGFtb25nIHRoZQoJCSogW2NoaWxkcmVuXS4iCgkJKi8KCQl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCSAgICB9CgkgICAgLyoKCSAgICAqIENvbXB1dGUgdGhlICJjb250ZW50IHR5cGUiLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewoJCS8qCgkJKiBTUEVDICgzLjEpICJJZiA8cmVzdHJpY3Rpb24+Li4uIgoJCSogKDMuMS4xKSArICgzLjEuMikgKi8KCQlpZiAodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkJCXR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwoJCX0KCSAgICB9IGVsc2UgewoJCS8qCgkJKiBTUEVDICgzLjIpICJJZiA8ZXh0ZW5zaW9uPi4uLiIKCQkqLwoJCWlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkgICAgLyoKCQkgICAgKiBTUEVDICgzLjIuMSkKCQkgICAgKi8KCQkgICAgdHlwZS0+Y29udGVudFR5cGUgPSBiYXNlVHlwZS0+Y29udGVudFR5cGU7CgkJICAgIHR5cGUtPnN1YnR5cGVzID0gYmFzZVR5cGUtPnN1YnR5cGVzOwoJCSAgICAvKgoJCSAgICAqIE5PVEUgdGhhdCB0aGUgZWZmZWN0aXZlIG1peGVkIGlzIGlnbm9yZWQgaGVyZS4KCQkgICAgKi8KCQl9IGVsc2UgaWYgKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkgICAgLyoKCQkgICAgKiBTUEVDICgzLjIuMikKCQkgICAgKi8KCQkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCQkJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBTUEVDICgzLjIuMykKCQkgICAgKi8KCQkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCQkJdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CgkJICAgIC8qCgkJICAgICogIkEgbW9kZWwgZ3JvdXAgd2hvc2Uge2NvbXBvc2l0b3J9IGlzIHNlcXVlbmNlIGFuZCB3aG9zZQoJCSAgICAqIHtwYXJ0aWNsZXN9IGFyZS4uLiIKCQkgICAgKi8KCQkgICAgaWYgKCEgZHVtbXlTZXF1ZW5jZSkgewoJCQl4bWxTY2hlbWFUcmVlSXRlbVB0ciBlZmZlY3RpdmVDb250ZW50ID0KCQkJICAgICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgdHlwZS0+c3VidHlwZXM7CgkJCS8qCgkJCSogQ3JlYXRlIHRoZSBwYXJ0aWNsZS4KCQkJKi8KCQkJcGFydGljbGUgPSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShwY3R4dCwgcGN0eHQtPnNjaGVtYSwKCQkJICAgIHR5cGUtPm5vZGUsIDEsIDEpOwoJCQlpZiAocGFydGljbGUgPT0gTlVMTCkKCQkJICAgIHJldHVybjsKCQkJLyoKCQkJKiBDcmVhdGUgdGhlICJzZXF1ZW5jZSIgbW9kZWwgZ3JvdXAuCgkJCSovCgkJCXBhcnRpY2xlLT5jaGlsZHJlbiA9ICh4bWxTY2hlbWFUcmVlSXRlbVB0cikKCQkJICAgIHhtbFNjaGVtYUFkZE1vZGVsR3JvdXAocGN0eHQsIHBjdHh0LT5zY2hlbWEsCgkJCQlYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UsIE5VTEwsIHR5cGUtPm5vZGUpOwoJCQlpZiAocGFydGljbGUtPmNoaWxkcmVuID09IE5VTEwpCgkJCSAgICByZXR1cm47CgkJCXR5cGUtPnN1YnR5cGVzID0gKHhtbFNjaGVtYVR5cGVQdHIpIHBhcnRpY2xlOwoJCQkvKgoJCQkqIFNQRUMgInRoZSBwYXJ0aWNsZSBvZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YKCQkJKiB0aGUgLi4uIGJhc2UgLi4uIgoJCQkqIENyZWF0ZSBhIGR1cGxpY2F0ZSBvZiB0aGUgYmFzZSB0eXBlJ3MgcGFydGljbGUKCQkJKiBhbmQgYXNzaWduIGl0cyAidGVybSIgdG8gaXQuCgkJCSovCgkJCXBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPQoJCQkgICAgKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSB4bWxTY2hlbWFBZGRQYXJ0aWNsZShwY3R4dCwKCQkJCXBjdHh0LT5zY2hlbWEsIHR5cGUtPm5vZGUsCgkJCQkoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSB0eXBlLT5zdWJ0eXBlcyktPm1pbk9jY3VycywKCQkJCSgoeG1sU2NoZW1hUGFydGljbGVQdHIpIHR5cGUtPnN1YnR5cGVzKS0+bWF4T2NjdXJzKTsKCQkJaWYgKHBhcnRpY2xlLT5jaGlsZHJlbi0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkJICAgIHJldHVybjsKCQkJcGFydGljbGUgPSAoeG1sU2NoZW1hUGFydGljbGVQdHIpCgkJCSAgICBwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwoJCQlwYXJ0aWNsZS0+Y2hpbGRyZW4gPQoJCQkJKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgYmFzZVR5cGUtPnN1YnR5cGVzKS0+Y2hpbGRyZW47CgkJCS8qCgkJCSogU1BFQyAiZm9sbG93ZWQgYnkgdGhlILdlZmZlY3RpdmUgY29udGVudLcuIgoJCQkqLwoJCQlwYXJ0aWNsZS0+bmV4dCA9IGVmZmVjdGl2ZUNvbnRlbnQ7CgkJICAgIH0gZWxzZSB7CgkJCS8qCgkJCSogVGhpcyBpcyB0aGUgY2FzZSB3aGVuIHRoZXJlIGlzIGFscmVhZHkgYW4gZW1wdHkKCQkJKiA8c2VxdWVuY2U+IHdpdGggbWluT2NjdXJzPT1tYXhPY2N1cnM9PTEuCgkJCSogSnVzdCBhZGQgdGhlIGJhc2UgdHlwZXMncyBjb250ZW50IHR5cGUuCgkJCSogTk9URSB0aGF0LCBhbHRob3VnaCB3ZSBtaXNzIHRvIGFkZCBhbiBpbnRlcm1lZGlhdGUKCQkJKiA8c2VxdWVuY2U+LCB0aGlzIHNob3VsZCBwcm9kdWNlIG5vIGRpZmZlcmVuY2UgdG8KCQkJKiBuZWl0aGVyIHRoZSByZWdleCBjb21waWxhdGlvbiBvZiB0aGUgY29udGVudCBtb2RlbCwKCQkJKiBub3IgdG8gdGhlIGNvbXBsZXggdHlwZSBjb250cmFpbnRzLgoJCQkqLwoJCQlwYXJ0aWNsZS0+Y2hpbGRyZW4tPmNoaWxkcmVuID0KCQkJICAgICh4bWxTY2hlbWFUcmVlSXRlbVB0cikgYmFzZVR5cGUtPnN1YnR5cGVzOwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCS8qCgkqIEFwcGx5IHRoZSBjb21wbGV4IHR5cGUgY29tcG9uZW50IGNvbnN0cmFpbnRzOyB0aGlzIHdpbGwgbm90CgkqIGNoZWNrIGF0dHJpYnV0ZXMsIHNpbmNlIHRoaXMgaXMgZG9uZSBpbgoJKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oKS4KCSovCglpZiAoeG1sU2NoZW1hQ2hlY2tDVENvbXBvbmVudChwY3R4dCwgdHlwZSkgIT0gMCkKCSAgICByZXR1cm47CgkvKgoJKiBJbmhlcml0ICYgY2hlY2sgY29uc3RyYWludHMgZm9yIGF0dHJpYnV0ZXMuCgkqLwoJeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKHBjdHh0LCB0eXBlKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkvKgoJKiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnQKCSovCgl0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CglpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKSB7CgkgICAgLyoKCSAgICAqIENvcnJlc3BvbmRzIHRvIDxzaW1wbGVUeXBlPjxsaXN0Pi4uLgoJICAgICovCgkgICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCQkvKgoJCSogVGhpcyBvbmUgaXMgcmVhbGx5IG5lZWRlZCwgc28gZ2V0IG91dC4KCQkqLwoJCVBFUlJPUl9JTlQoInhtbFNjaGVtYVR5cGVGaXh1cCIsCgkJImxpc3QgdHlwZSBoYXMgbm8gaXRlbS10eXBlIGFzc2lnbmVkIik7CgkJcmV0dXJuOwoJICAgIH0KCSAgICBpZiAoSVNfTk9UX1RZUEVGSVhFRCh0eXBlLT5zdWJ0eXBlcykpCgkJeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGUtPnN1YnR5cGVzLCBwY3R4dCwgTlVMTCk7Cgl9IGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpIHsKCSAgICAvKgoJICAgICogQ29ycmVzcG9uZHMgdG8gPHNpbXBsZVR5cGU+PHVuaW9uPi4uLgoJICAgICovCgkgICAgaWYgKHR5cGUtPm1lbWJlclR5cGVzID09IE5VTEwpIHsKCQkvKgoJCSogVGhpcyBvbmUgaXMgcmVhbGx5IG5lZWRlZCwgc28gZ2V0IG91dC4KCQkqLwoJCXJldHVybjsKCSAgICB9CgkgICAgaWYgKHhtbFNjaGVtYUZpbmlzaE1lbWJlclR5cGVEZWZpbml0aW9uc1Byb3BlcnR5KHBjdHh0LCB0eXBlKSA9PSAtMSkKCQlyZXR1cm47Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKCSAgICAvKgoJICAgICogQ29ycmVzcG9uZHMgdG8gPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uPi4uLgoJICAgICovCgkgICAgaWYgKElTX05PVF9UWVBFRklYRUQoYmFzZVR5cGUpKQoJCXhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgcGN0eHQsIE5VTEwpOwoJICAgIC8qCgkgICAgKiBWYXJpZXR5CgkgICAgKiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlCgkgICAgKiB7dmFyaWV0eX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkgICAgKi8KCSAgICBpZiAoVkFSSUVUWV9BVE9NSUMoYmFzZVR5cGUpKQoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUM7CgkgICAgZWxzZSBpZiAoVkFSSUVUWV9MSVNUKGJhc2VUeXBlKSkgewoJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUOwoJCS8qCgkJKiBJbmhlcml0IHRoZSBpdGVtVHlwZS4KCQkqLwoJCXR5cGUtPnN1YnR5cGVzID0gYmFzZVR5cGUtPnN1YnR5cGVzOwoJICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9VTklPTihiYXNlVHlwZSkpIHsKCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CgkJLyoKCQkqIE5PVEUgdGhhdCB3ZSB3b24ndCBhc3NpZ24gdGhlIG1lbWJlclR5cGVzIG9mIHRoZSBiYXNlLAoJCSogc2luY2UgdGhpcyB3aWxsIG1ha2UgdHJvdWJsZSB3aGVuIGZyZWVpbmcgdGhlbTsgd2Ugd2lsbAoJCSogdXNlIGEgbG9va3VwIGZ1bmN0aW9uIHRvIGFjY2VzcyB0aGVtIGluc3RlYWQuCgkJKi8KCSAgICB9Cgl9CgkvKgoJKiBDaGVjayBjb25zdHJhaW50cy4KCSoKCSogVE9ETzogU3BsaXQgdGhpcyBzb21laG93LCB3ZSBuZWVkIHRvIGtub3cgZmlyc3QgaWYgd2UgY2FuIGRlcml2ZQoJKiBmcm9tIHRoZSBiYXNlIHR5cGUgYXQgYWxsIQoJKi8KCWlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgUmVzdHJpY3Rpb24KCSAgICAqIChGYWNldHMpCgkgICAgKiBOT1RFOiBTYXRpc2ZhY3Rpb24gb2YgMSBhbmQgMiBhcmlzZSBmcm9tIHRoZSBmaXh1cAoJICAgICogYXBwbGllZCBiZWZvcmVoYW5kLgoJICAgICovCgkgICAgeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKHBjdHh0LCB0eXBlKTsKCSAgICB4bWxTY2hlbWFDaGVja0ZhY2V0VmFsdWVzKHR5cGUsIHBjdHh0KTsKCSAgICBpZiAoKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHx8CgkJKHR5cGUtPmJhc2VUeXBlLT5mYWNldFNldCAhPSBOVUxMKSkKCQl4bWxTY2hlbWFEZXJpdmVBbmRWYWxpZGF0ZUZhY2V0cyhwY3R4dCwgdHlwZSk7CgkgICAgLyoKCSAgICAqIFdoaXRlc3BhY2UgdmFsdWUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFUeXBlRml4dXBXaGl0ZXNwYWNlKHR5cGUpOwoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cE9wdGltRmFjZXRzKHR5cGUpOwoJfQogICAgfQoKI2lmZGVmIERFQlVHX1RZUEUKICAgIGlmICh0eXBlLT5ub2RlICE9IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIlR5cGUgb2YgJXMgOiAlczolZCA6IiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bm9kZS0+ZG9jLT5VUkwsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEdldExpbmVObyh0eXBlLT5ub2RlKSk7CiAgICB9IGVsc2UgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiVHlwZSBvZiAlcyA6IiwgbmFtZSk7CiAgICB9CiAgICBpZiAoKElTX1NJTVBMRV9UWVBFKHR5cGUpKSB8fCAoSVNfQ09NUExFWF9UWVBFKHR5cGUpKSkgewoJc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInNpbXBsZVxuIik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbGVtZW50c1xuIik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTjoKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInVua25vd24gISEhXG4iKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVtcHR5XG4iKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKCQlpZiAoeG1sU2NoZW1hSXNQYXJ0aWNsZUVtcHRpYWJsZSgoeG1sU2NoZW1hUGFydGljbGVQdHIpCgkJICAgIHR5cGUtPnN1YnR5cGVzKSkKCQkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSJtaXhlZCBhcyBlbXB0aWFibGUgcGFydGljbGVcbiIpOwoJCWVsc2UKCQkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZFxuIik7CgkJYnJlYWs7CgkJLyogUmVtb3ZlZCwgc2luY2Ugbm90IHVzZWQuICovCgkJLyoKCQljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkIG9yIGVsZW1zXG4iKTsKCQlicmVhazsKCQkqLwoJICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwoJCWJyZWFrOwoJfQogICAgfQojZW5kaWYKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRmFjZXQ6CiAqIEBmYWNldDogIHRoZSBmYWNldAogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAcGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IHRoZSBvcHRpb25hbCBuYW1lIG9mIHRoZSB0eXBlCiAqCiAqIENoZWNrcyBhbmQgY29tcHV0ZXMgdGhlIHZhbHVlcyBvZiBmYWNldHMuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGlmIG5vdCB2YWxpZCBhbmQKICogICAgICAgICAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaW50IHJldCA9IDAsIGN0eHRHaXZlbjsKCiAgICBpZiAoKGZhY2V0ID09IE5VTEwpIHx8ICh0eXBlRGVjbCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4oLTEpOwogICAgLyoKICAgICogVE9ETzogd2lsbCB0aGUgcGFyc2VyIGNvbnRleHQgYmUgZ2l2ZW4gaWYgdXNlZCBmcm9tCiAgICAqIHRoZSByZWxheE5HIG1vZHVsZT8KICAgICovCiAgICBpZiAocGN0eHQgPT0gTlVMTCkKCWN0eHRHaXZlbiA9IDA7CiAgICBlbHNlCgljdHh0R2l2ZW4gPSAxOwoKICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOiB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogT2theSB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogYXQgdGhhdCBwb2ludC4KICAgICAgICAgICAgICAgICAqLwoJCXhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCgkJLyogNC4zLjUuNSBDb25zdHJhaW50cyBvbiBlbnVtZXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50cwoJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBlbnVtZXJhdGlvbiB2YWxpZCByZXN0cmljdGlvbgoJCSogSXQgaXMgYW4gt2Vycm9ytyBpZiBhbnkgbWVtYmVyIG9mIHt2YWx1ZX0gaXMgbm90IGluIHRoZQoJCSogt3ZhbHVlIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259LgoJCSoKCQkqIG1pbkluY2x1c2l2ZSwgbWF4SW5jbHVzaXZlLCBtaW5FeGNsdXNpdmUsIG1heEV4Y2x1c2l2ZToKCQkqIFRoZSB2YWx1ZSC3bXVzdLcgYmUgaW4gdGhlCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHRoZSC3YmFzZSB0eXBlty4KCQkqLwoJCS8qCgkJKiBUaGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIHRvIGRlbGl2ZXIgYSBjb21waWxlZCB2YWx1ZQoJCSogb24gdGhlIGZhY2V0LiBJbiB0aGlzIGltcGxlbWVudGF0aW9uIG9mIFhNTCBTY2hlbWF0YSB0aGUKCQkqIHR5cGUgaG9sZGluZyBhIGZhY2V0LCB3b24ndCBiZSBhIGJ1aWx0LWluIHR5cGUuCgkJKiBUaHVzIHRvIGVuc3VyZSB0aGF0IG90aGVyIEFQSQoJCSogY2FsbHMgKHJlbGF4bmcpIGRvIHdvcmssIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGEgYnVpbHQtaW4KCQkqIHR5cGUsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUgKmlzCgkJKiBhbHJlYWR5KiB0aGUgYmFzZSB0eXBlLgoJCSovCgkJaWYgKHR5cGVEZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCSAgICBiYXNlID0gdHlwZURlY2wtPmJhc2VUeXBlOwoJCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrRmFjZXQiLAoJCQkgICAgImEgdHlwZSB1c2VyIGRlcml2ZWQgdHlwZSBoYXMgbm8gYmFzZSB0eXBlIik7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfSBlbHNlCgkJICAgIGJhc2UgPSB0eXBlRGVjbDsKCSAgICAgICAgICAgICAgICAgCgkJaWYgKCEgY3R4dEdpdmVuKSB7CgkJICAgIC8qCgkJICAgICogQSBjb250ZXh0IGlzIG5lZWRlZCBpZiBjYWxsZWQgZnJvbSBSZWxheE5HLgoJCSAgICAqLwkJICAgIAoJCSAgICBwY3R4dCA9IHhtbFNjaGVtYU5ld1BhcnNlckN0eHQoIioiKTsKCQkgICAgaWYgKHBjdHh0ID09IE5VTEwpCgkJCXJldHVybiAoLTEpOwoJCX0KCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLAoJCSogc2luY2UgdGhleSBhcmUgbm90IGF2YWlsYWJsZToKCQkqIGZhY2V0LT5ub2RlIGlzIGp1c3QgdGhlIG5vZGUgaG9sZGluZyB0aGUgZmFjZXQKCQkqIGRlZmluaXRpb24sICpub3QqIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgKnZhbHVlKgoJCSogb2YgdGhlIGZhY2V0LgoJCSovCQkKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJCSAgICAoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwgZmFjZXQtPm5vZGUsIGJhc2UsCgkJICAgIGZhY2V0LT52YWx1ZSwgJihmYWNldC0+dmFsKSwgMSwgMSwgMCk7CiAgICAgICAgICAgICAgICBpZiAocmV0ICE9IDApIHsKCQkgICAgaWYgKHJldCA8IDApIHsKCQkJLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkJaWYgKGN0eHRHaXZlbikgewkJCSAgICAKCQkJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBmYWNldC0+bm9kZSwgTlVMTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIiAKCQkJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJCSJmYWNldCAnJXMnIGFnYWluc3QgdGhlIGJhc2UgdHlwZSIsCgkJCQlmYWNldC0+dmFsdWUsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CgkJCX0KCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkgICAgfQoJCSAgICByZXQgPSBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFOwoJCSAgICAvKiBObyBlcnJvciBtZXNzYWdlIGZvciBSZWxheE5HLiAqLwoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgoJCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsCgkJCSAgICByZXQsIGZhY2V0LT5ub2RlLCAoeG1sU2NoZW1hVHlwZVB0cikgZmFjZXQsCgkJCSAgICAiVGhlIHZhbHVlICclcycgb2YgdGhlIGZhY2V0IGRvZXMgbm90IHZhbGlkYXRlICIKCQkJICAgICJhZ2FpbnN0IHRoZSBiYXNlIHR5cGUgJyVzJyIsCgkJCSAgICBmYWNldC0+dmFsdWUsCgkJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCQkJYmFzZS0+dGFyZ2V0TmFtZXNwYWNlLCBiYXNlLT5uYW1lKSk7CgkJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQkgICAgfQoJCSAgICBnb3RvIGV4aXQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZhY2V0LT52YWwgPT0gTlVMTCkgewoJCSAgICBpZiAoY3R4dEdpdmVuKSB7CgkJCVBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrRmFjZXQiLAoJCQkgICAgInZhbHVlIHdhcyBub3QgY29tcHV0ZWQiKTsKCQkgICAgfQoJCSAgICBUT0RPCgkJfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgZmFjZXQtPnJlZ2V4cCA9IHhtbFJlZ2V4cENvbXBpbGUoZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgaWYgKGZhY2V0LT5yZWdleHAgPT0gTlVMTCkgewoJCXJldCA9IFhNTF9TQ0hFTUFQX1JFR0VYUF9JTlZBTElEOwoJCS8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJaWYgKGN0eHRHaXZlbikgewoJCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsCgkJCXJldCwgZmFjZXQtPm5vZGUsIHR5cGVEZWNsLAoJCQkiVGhlIHZhbHVlICclcycgb2YgdGhlIGZhY2V0ICdwYXR0ZXJuJyBpcyBub3QgYSAiCgkJCSJ2YWxpZCByZWd1bGFyIGV4cHJlc3Npb24iLAoJCQlmYWNldC0+dmFsdWUsIE5VTEwpOwoJCX0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOnsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OTklOVEVHRVIpLAoJCSAgICBmYWNldC0+dmFsdWUsICYoZmFjZXQtPnZhbCkpOwogICAgICAgICAgICAgICAgaWYgKHJldCAhPSAwKSB7CgkJICAgIGlmIChyZXQgPCAwKSB7CgkJCS8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJCWlmIChjdHh0R2l2ZW4pIHsKCQkJICAgIFBFUlJPUl9JTlQoInhtbFNjaGVtYUNoZWNrRmFjZXQiLAoJCQkJInZhbGlkYXRpbmcgZmFjZXQgdmFsdWUiKTsKCQkJfQoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUU7CgkJICAgIC8qIE5vIGVycm9yIG1lc3NhZ2UgZm9yIFJlbGF4TkcuICovCgkJICAgIGlmIChjdHh0R2l2ZW4pIHsKCQkJLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsCgkJCSAgICByZXQsIGZhY2V0LT5ub2RlLCB0eXBlRGVjbCwKCQkJICAgICJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgJyVzJyBpcyBub3QgYSB2YWxpZCAiCgkJCSAgICAiJ25vbk5lZ2F0aXZlSW50ZWdlciciLAoJCQkgICAgZmFjZXQtPnZhbHVlLAoJCQkgICAgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOnsKICAgICAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJwcmVzZXJ2ZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicmVwbGFjZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJjb2xsYXBzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUU7CiAgICAgICAgICAgICAgICAgICAgLyogTm8gZXJyb3IgbWVzc2FnZSBmb3IgUmVsYXhORy4gKi8KCQkgICAgaWYgKGN0eHRHaXZlbikgewoJCQkvKiBlcnJvciB3YXMgcHJldmlvdXNseTogWE1MX1NDSEVNQVBfSU5WQUxJRF9XSElURV9TUEFDRSAqLwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsCgkJCSAgICByZXQsIGZhY2V0LT5ub2RlLCB0eXBlRGVjbCwKCQkJICAgICJUaGUgdmFsdWUgJyVzJyBvZiB0aGUgZmFjZXQgJ3doaXRlc3BhY2UnIGlzIG5vdCAiCgkJCSAgICAidmFsaWQiLCBmYWNldC0+dmFsdWUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQpleGl0OgogICAgaWYgKCghIGN0eHRHaXZlbikgJiYgKHBjdHh0ICE9IE5VTEwpKQoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgcmV0dXJuIChyZXQpOwppbnRlcm5hbF9lcnJvcjoKICAgIGlmICgoISBjdHh0R2l2ZW4pICYmIChwY3R4dCAhPSBOVUxMKSkKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHBjdHh0KTsKICAgIHJldHVybiAoLTEpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlczoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIENoZWNrcyB0aGUgZGVmYXVsdCB2YWx1ZXMgdHlwZXMsIGVzcGVjaWFsbHkgZm9yIGZhY2V0cwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tGYWNldFZhbHVlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAoJCQkgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IHR5cGVEZWNsLT5uYW1lOwogICAgLyoKICAgICogTk9URTogSXQgaXMgaW50ZW5kZWQgdG8gdXNlIHRoZSBmYWNldHMgbGlzdCwgaW5zdGVhZAogICAgKiBvZiBmYWNldFNldC4KICAgICovCiAgICBpZiAodHlwZURlY2wtPmZhY2V0cyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWNldCA9IHR5cGVEZWNsLT5mYWNldHM7CgoJLyoKCSogVGVtcG9yYXJpbHkgYXNzaWduIHRoZSAic2NoZW1hIiB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CgkqIG9mIHRoZSBwYXJzZXIgY29udGV4dC4gVGhpcyBpcyBuZWVkZWQgZm9yIE5PVEFUSU9OIHZhbGlkYXRpb24uCgkqLwoJaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KGN0eHQpID09IC0xKQoJCXJldHVybjsKCX0KCWN0eHQtPnZjdHh0LT5zY2hlbWEgPSBjdHh0LT5zY2hlbWE7CgoJd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDaGVja0ZhY2V0KGZhY2V0LCB0eXBlRGVjbCwgY3R4dCwgbmFtZSk7CgkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCX0KCgljdHh0LT52Y3R4dC0+c2NoZW1hID0gTlVMTDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmOgogKiBAY3R4dE1Hcm91cDogdGhlIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBzZWxmTUdyb3VwOiB0aGUgc2Vjb25kIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBwYXJ0aWNsZTogdGhlIGZpcnN0IHBhcnRpY2xlCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIHBhcnRpY2xlIHdpdGggdGhlIGNpcmN1bGFyIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLAogKiBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFUcmVlSXRlbVB0cgp4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZih4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyIGdyb3VwRGVmLAoJCQkgICAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciBwYXJ0aWNsZSkKewogICAgeG1sU2NoZW1hVHJlZUl0ZW1QdHIgY2lyYyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUcmVlSXRlbVB0ciB0ZXJtOwogICAgeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBnZGVmOwoKICAgIGZvciAoOyBwYXJ0aWNsZSAhPSBOVUxMOyBwYXJ0aWNsZSA9IHBhcnRpY2xlLT5uZXh0KSB7Cgl0ZXJtID0gcGFydGljbGUtPmNoaWxkcmVuOwoJaWYgKHRlcm0gPT0gTlVMTCkKCSAgICBjb250aW51ZTsKCXN3aXRjaCAodGVybS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCWdkZWYgPSAoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0cikgdGVybTsKCQlpZiAoZ2RlZiA9PSBncm91cERlZikKCQkgICAgcmV0dXJuIChwYXJ0aWNsZSk7CgkJLyoKCQkqIE1hcmsgdGhpcyBtb2RlbCBncm91cCBkZWZpbml0aW9uIHRvIGF2b2lkIGluZmluaXRlCgkJKiByZWN1cnNpb24gb24gY2lyY3VsYXIgcmVmZXJlbmNlcyBub3QgeWV0IGV4YW1pbmVkLgoJCSovCgkJaWYgKGdkZWYtPmZsYWdzICYgWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEKQoJCSAgICBjb250aW51ZTsKCQlpZiAoZ2RlZi0+Y2hpbGRyZW4gIT0gTlVMTCkgewoJCSAgICBnZGVmLT5mbGFncyB8PSBYTUxfU0NIRU1BX01PREVMX0dST1VQX0RFRl9NQVJLRUQ7CgkJICAgIGNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihncm91cERlZiwKCQkJZ2RlZi0+Y2hpbGRyZW4tPmNoaWxkcmVuKTsKCQkgICAgZ2RlZi0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9NT0RFTF9HUk9VUF9ERUZfTUFSS0VEOwoJCSAgICBpZiAoY2lyYyAhPSBOVUxMKQoJCQlyZXR1cm4gKGNpcmMpOwoJCX0KCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihncm91cERlZiwgdGVybS0+Y2hpbGRyZW4pOwoJCWlmIChjaXJjICE9IE5VTEwpCgkJICAgIHJldHVybiAoY2lyYyk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXI6CiAqIEBpdGVtOiAgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgdG8gbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoeG1sU2NoZW1hTW9kZWxHcm91cERlZlB0ciBpdGVtLAoJCQkgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBNb2RlbCBHcm91cCBDb3JyZWN0CiAgICAqIDIgQ2lyY3VsYXIgZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCB3aXRoaW4gdGhlIHtwYXJ0aWNsZXN9CiAgICAqIG9mIGEgZ3JvdXAgdGhlcmUgbXVzdCBub3QgYmUgYXQgYW55IGRlcHRoIGEgcGFydGljbGUgd2hvc2Uge3Rlcm19CiAgICAqIGlzIHRoZSBncm91cCBpdHNlbGYuCiAgICAqLwogICAgaWYgKChpdGVtID09IE5VTEwpIHx8CgkoaXRlbS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHx8CgkoaXRlbS0+Y2hpbGRyZW4gPT0gTlVMTCkpCglyZXR1cm47CiAgICB7Cgl4bWxTY2hlbWFUcmVlSXRlbVB0ciBjaXJjOwoKCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihpdGVtLCBpdGVtLT5jaGlsZHJlbi0+Y2hpbGRyZW4pOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFRPRE86IFRoZSBlcnJvciByZXBvcnQgaXMgbm90IGFkZXF1YXRlOiB0aGlzIGNvbnN0cmFpbnQKCSAgICAqIGlzIGRlZmluZWQgZm9yIG1vZGVsIGdyb3VwcyBidXQgbm90IGRlZmluaXRpb25zLCBidXQgc2luY2UKCSAgICAqIHRoZXJlIGNhbm5vdCBiZSBhbnkgY2lyY3VsYXIgbW9kZWwgZ3JvdXBzIHdpdGhvdXQgYSBtb2RlbCBncm91cAoJICAgICogZGVmaW5pdGlvbiAoaWYgbm90IHVzaW5nIGEgY29uc3RydWN0aW9uIEFQSSksIHdlIGNoZWNrIHRob3NlCgkgICAgKiBkZWZpbnRpb25zIG9ubHkuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfTUdfUFJPUFNfQ09SUkVDVF8yLAoJCU5VTEwsIE5VTEwsIEdFVF9OT0RFKGNpcmMpLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gJyVzJyAiCgkJImRlZmluZWQiLCB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBpdGVtLT50YXJnZXROYW1lc3BhY2UsIGl0ZW0tPm5hbWUpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICAvKgoJICAgICogTk9URTogV2Ugd2lsbCBjdXQgdGhlIHJlZmVyZW5jZSB0byBhdm9pZCBmdXJ0aGVyCgkgICAgKiBjb25mdXNpb24gb2YgdGhlIHByb2Nlc3Nvci4gVGhpcyBpcyBhIGZhdGFsIGVycm9yLgoJICAgICovCgkgICAgY2lyYy0+Y2hpbGRyZW4gPSBOVUxMOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hR3JvdXBEZWZUZXJtRml4dXA6CiAqIEBpdGVtOiAgdGhlIHBhcnRpY2xlIHdpdGggYSBtb2RlbCBncm91cCBkZWZpbml0aW9uIGFzIHRlcm0KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgY29zLWFsbC1saW1pdGVkLgogKgogKiBBc3NpZ25zIHRoZSBtb2RlbCBncm91cCBvZiBtb2RlbCBncm91cCBkZWZpbml0aW9ucyB0byB0aGUgInRlcm0iCiAqIG9mIHRoZSByZWZlcmVuY2luZyBwYXJ0aWNsZS4KICogSW4geG1sU2NoZW1hTWlzY1JlZkZpeHVwIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9ucyB3YXMgYXNzaWduZWQKICogdG8gdGhlICJ0ZXJtIiwgc2luY2UgbmVlZGVkIGZvciB0aGUgY2lyY3VsYXJpdHkgY2hlY2suIAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hR3JvdXBEZWZUZXJtRml4dXAoeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbSwKCQkJICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0IEFUVFJJQlVURV9VTlVTRUQsCgkJCSAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmICgoaXRlbSA9PSBOVUxMKSB8fAoJKGl0ZW0tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFKSB8fAoJKGl0ZW0tPmNoaWxkcmVuID09IE5VTEwpIHx8CgkoaXRlbS0+Y2hpbGRyZW4tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB8fAoJKGl0ZW0tPmNoaWxkcmVuLT5jaGlsZHJlbiA9PSBOVUxMKSkKCXJldHVybjsKICAgIGl0ZW0tPmNoaWxkcmVuID0gaXRlbS0+Y2hpbGRyZW4tPmNoaWxkcmVuOwogICAgLyoKICAgICogVE9ETzogTm90IG5pY2UsIGJ1dCB3ZSB3aWxsIGFuY2hvciBjb3MtYWxsLWxpbWl0ZWQgaGVyZS4KICAgICovCiAgICBpZiAoKGl0ZW0tPmNoaWxkcmVuLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpICYmCgkoaXRlbS0+bWF4T2NjdXJzICE9IDEpKSB7CgkvKgoJKiBTUEVDICgxLjIpICJ0aGUge3Rlcm19IHByb3BlcnR5IG9mIGEgcGFydGljbGUgd2l0aAoJKiB7bWF4IG9jY3Vyc309MXdoaWNoIGlzIHBhcnQgb2YgYSBwYWlyIHdoaWNoIGNvbnN0aXR1dGVzIHRoZQoJKiB7Y29udGVudCB0eXBlfSBvZiBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLiIKCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV9HUk9VUF8zLAoJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJICAgICJUaGUgcGFydGljbGUncyAnbWF4T2NjdXJzJyBtdXN0IGJlIDEsIHNpbmNlIGFuIHhzOmFsbCBtb2RlbCAiCgkgICAgImdyb3VwIGlzIGl0cyB0ZXJtIiwgTlVMTCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmOgogKiBAY3R4dEdyOiB0aGUgc2VhcmNoZWQgYXR0cmlidXRlIGdyb3VwCiAqIEBhdHRyOiB0aGUgY3VycmVudCBhdHRyaWJ1dGUgbGlzdCB0byBiZSBwcm9jZXNzZWQKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja1NSQ0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgYXR0cmlidXRlIGdyb3UgcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGN0eHRHciwKCQkJICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY2lyYyA9IE5VTEwsIGdyOwogICAgaW50IG1hcmtlZDsKICAgIC8qCiAgICAqIFdlIHdpbGwgc2VhcmNoIGZvciBhbiBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlIHdoaWNoCiAgICAqIHJlZmVyZW5jZXMgdGhlIGNvbnRleHQgYXR0cmlidXRlIGdyb3VwLgogICAgKi8KICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCW1hcmtlZCA9IDA7CglpZiAoYXR0ci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICBnciA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgYXR0cjsKCSAgICBpZiAoZ3ItPnJlZkl0ZW0gIT0gTlVMTCkgIHsKCQlpZiAoZ3ItPnJlZkl0ZW0gPT0gY3R4dEdyKQoJCSAgICByZXR1cm4gKGdyKTsKCQllbHNlIGlmIChnci0+cmVmSXRlbS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BU19BVFRSR1JPVVBfTUFSS0VEKSB7CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICAvKgoJCSAgICAqIE1hcmsgYXMgdmlzaXRlZCB0byBhdm9pZCBpbmZpbml0ZSByZWN1cnNpb24gb24KCQkgICAgKiBjaXJjdWxhciByZWZlcmVuY2VzIG5vdCB5ZXQgZXhhbWluZWQuCgkJICAgICovCgkJICAgIGdyLT5yZWZJdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfTUFSS0VEOwoJCSAgICBtYXJrZWQgPSAxOwoJCX0KCSAgICB9CgkgICAgaWYgKGdyLT5hdHRyaWJ1dGVzICE9IE5VTEwpCgkJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNBdHRyR3JSZWYoY3R4dEdyLCBnci0+YXR0cmlidXRlcyk7CgkgICAgLyoKCSAgICAqIFVubWFyayB0aGUgdmlzaXRlZCBncm91cCdzIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAobWFya2VkKQoJCWdyLT5yZWZJdGVtLT5mbGFncyBePSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfTUFSS0VEOwoJICAgIGlmIChjaXJjICE9IE5VTEwpCgkJcmV0dXJuIChjaXJjKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDQXR0cmlidXRlR3JvdXBDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIG9mIGF0dHJpYnV0ZSBncm91cHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyLAoJCQkJCXhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCQljb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICAvKgogICAgKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDoKICAgICogQXR0cmlidXRlIEdyb3VwIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sKICAgICogMyBDaXJjdWxhciBncm91cCByZWZlcmVuY2UgaXMgZGlzYWxsb3dlZCBvdXRzaWRlIDxyZWRlZmluZT4uCiAgICAqIFRoYXQgaXMsIHVubGVzcyB0aGlzIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHBhcmVudCBpcwogICAgKiA8cmVkZWZpbmU+LCB0aGVuIGFtb25nIHRoZSBbY2hpbGRyZW5dLCBpZiBhbnksIHRoZXJlIG11c3QKICAgICogbm90IGJlIGFuIDxhdHRyaWJ1dGVHcm91cD4gd2l0aCByZWYgW2F0dHJpYnV0ZV0gd2hpY2ggcmVzb2x2ZXMKICAgICogdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4gSW5kaXJlY3QKICAgICogY2lyY3VsYXJpdHkgaXMgYWxzbyBydWxlZCBvdXQuIFRoYXQgaXMsIHdoZW4gUU5hbWUgcmVzb2x1dGlvbgogICAgKiAoU2NoZW1hIERvY3VtZW50KSAopzMuMTUuMykgaXMgYXBwbGllZCB0byBhILdRTmFtZbcgYXJpc2luZyBmcm9tCiAgICAqIGFueSA8YXR0cmlidXRlR3JvdXA+cyB3aXRoIGEgcmVmIFthdHRyaWJ1dGVdIGFtb25nIHRoZSBbY2hpbGRyZW5dLAogICAgKiBpdCBtdXN0IG5vdCBiZSB0aGUgY2FzZSB0aGF0IGEgt1FOYW1ltyBpcyBlbmNvdW50ZXJlZCBhdCBhbnkgZGVwdGgKICAgICogd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4KICAgICovCiAgICAvKgogICAgKiBPbmx5IGdsb2JhbCBjb21wb25lbnRzIGNhbiBiZSByZWZlcmVuY2VkLgogICAgKi8KICAgIGlmICgoKGF0dHJHci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSA9PSAwKSB8fAoJKGF0dHJHci0+YXR0cmlidXRlcyA9PSBOVUxMKSkKCXJldHVybjsKICAgIGVsc2UgewoJeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY2lyYzsKCgljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihhdHRyR3IsIGF0dHJHci0+YXR0cmlidXRlcyk7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfR1JPVVBfMywKCQlOVUxMLCBOVUxMLCBjaXJjLT5ub2RlLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIGF0dHJpYnV0ZSBncm91cCAnJXMnICIKCQkiZGVmaW5lZCIsIGF0dHJHci0+bmFtZSk7CgkgICAgLyoKCSAgICAqIE5PVEU6IFdlIHdpbGwgY3V0IHRoZSByZWZlcmVuY2UgdG8gYXZvaWQgZnVydGhlcgoJICAgICogY29uZnVzaW9uIG9mIHRoZSBwcm9jZXNzb3IuCgkgICAgKiBCQURTUEVDOiBUaGUgc3BlYyBzaG91bGQgZGVmaW5lIGhvdyB0byBwcm9jZXNzIGluIHRoaXMgY2FzZS4KCSAgICAqLwoJICAgIGNpcmMtPmF0dHJpYnV0ZXMgPSBOVUxMOwoJICAgIGNpcmMtPnJlZkl0ZW0gPSBOVUxMOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXR0ckdycEZpeHVwOgogKiBAYXR0cmdycERlY2w6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckdycEZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJncnAsCiAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBhdHRyZ3JwLT5uYW1lOwogICAgaWYgKGF0dHJncnAtPmF0dHJpYnV0ZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0cmdycC0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZWY7CgogICAgICAgIHJlZiA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGN0eHQtPnNjaGVtYSwgYXR0cmdycC0+cmVmLAoJICAgIGF0dHJncnAtPnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkoeG1sU2NoZW1hVHlwZVB0cikgYXR0cmdycCwgYXR0cmdycC0+bm9kZSwKCQkicmVmIiwgYXR0cmdycC0+cmVmLCBhdHRyZ3JwLT5yZWZOcywKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVAsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJYXR0cmdycC0+cmVmSXRlbSA9IHJlZjsKCS8qCgkqIENoZWNrIGZvciBzZWxmIHJlZmVyZW5jZSEKCSovCiAgICAgICAgeG1sU2NoZW1hQXR0ckdycEZpeHVwKHJlZiwgY3R4dCwgTlVMTCk7CiAgICAgICAgYXR0cmdycC0+YXR0cmlidXRlcyA9IHJlZi0+YXR0cmlidXRlczsKCWF0dHJncnAtPmF0dHJpYnV0ZVdpbGRjYXJkID0gcmVmLT5hdHRyaWJ1dGVXaWxkY2FyZDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJDaGVja1ZhbENvbnN0cjoKICogQGl0ZW06ICBhbiBzY2hlbWEgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEF0dHJpYnV0ZSBEZWNsYXJhdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICogICAoYS1wcm9wcy1jb3JyZWN0KQogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIGNvbnN0cmFpbnRzIG9mIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UuCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBhdHRyaWJ1dGVzIGRlZmluaXRpb25zCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGl0ZW0sCgkJCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewoKICAgIC8qCiAgICAqIDIgaWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbAogICAgKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdAogICAgKiB0byB0aGUge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgogICAgKi8KICAgIGlmIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSB7CglpbnQgcmV0OwoKCWlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CgkgICAgUEVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyIiwKCQkidHlwZSBpcyBtaXNzaW5nIik7CgkgICAgcmV0dXJuOwoJfQoJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBwY3R4dCwKCSAgICBpdGVtLT5ub2RlLCBpdGVtLT5zdWJ0eXBlcywgaXRlbS0+ZGVmVmFsdWUsICYoaXRlbS0+ZGVmVmFsKSwKCSAgICAxLCAxLCAwKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hQXR0ckNoZWNrVmFsQ29uc3RyIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgpIik7CgkJcmV0dXJuOwoJICAgIH0KCSAgICByZXQgPSBYTUxfU0NIRU1BUF9BX1BST1BTX0NPUlJFQ1RfMjsKCSAgICB4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgcGN0eHQsCgkJcmV0LCBpdGVtLT5ub2RlLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwKCQkiVGhlIHZhbHVlIG9mIHRoZSB2YWx1ZSBjb25zdHJhaW50IGlzIG5vdCB2YWxpZCIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KICAgIH0KfQoKc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hQ2hlY2tTdWJzdEdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKCQkJCSB4bWxTY2hlbWFFbGVtZW50UHRyIGFuY2VzdG9yKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKCiAgICBpZiAoU1VCU1RfR1JPVVBfQUZGKGFuY2VzdG9yKSA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIGlmIChTVUJTVF9HUk9VUF9BRkYoYW5jZXN0b3IpID09IGVsZW1EZWNsKQoJcmV0dXJuIChhbmNlc3Rvcik7CgogICAgaWYgKFNVQlNUX0dST1VQX0FGRihhbmNlc3RvciktPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9DSVJDVUxBUikKCXJldHVybiAoTlVMTCk7CiAgICBTVUJTVF9HUk9VUF9BRkYoYW5jZXN0b3IpLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0NJUkNVTEFSOwogICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tTdWJzdEdyb3VwQ2lyY3VsYXIoZWxlbURlY2wsCglTVUJTVF9HUk9VUF9BRkYoYW5jZXN0b3IpKTsKICAgIFNVQlNUX0dST1VQX0FGRihhbmNlc3RvciktPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0VMRU1fQ0lSQ1VMQVI7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0OgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBkZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OgogKiBFbGVtZW50IERlY2xhcmF0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCAoZS1wcm9wcy1jb3JyZWN0KQogKgogKiBTVEFUVVM6CiAqICAgbWlzc2luZzogKDYpCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWYgPSBFTEVNX1RZUEUoZWxlbURlY2wpOwogICAgLyoKICAgICogU1BFQyAoMSkgIlRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgogICAgKiBtdXN0IGJlIGFzIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgRWxlbWVudAogICAgKiBEZWNsYXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50ICinMy4zLjEpLCBtb2R1bG8gdGhlIGltcGFjdCBvZiBNaXNzaW5nCiAgICAqIFN1Yi1jb21wb25lbnRzICinNS4zKS4iCiAgICAqLwogICAgaWYgKFNVQlNUX0dST1VQX0FGRihlbGVtRGVjbCkgIT0gTlVMTCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBoZWFkID0gU1VCU1RfR1JPVVBfQUZGKGVsZW1EZWNsKSwgY2lyYzsKCgl4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KGhlYWQsIHBjdHh0LCBOVUxMKTsKCS8qCgkqIFNQRUMgKDMpICJJZiB0aGVyZSBpcyBhIG5vbi23YWJzZW50tyB7c3Vic3RpdHV0aW9uIGdyb3VwCgkqIGFmZmlsaWF0aW9ufSwgdGhlbiB7c2NvcGV9IG11c3QgYmUgZ2xvYmFsLiIKCSovCglpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSA9PSAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfMywKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsIGVsZW1EZWNsLT5ub2RlLAoJCSJPbmx5IGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9ucyBjYW4gaGF2ZSBhICIKCQkic3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9uIiwgTlVMTCk7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzM7Cgl9CgkvKgoJKiBUT0RPOiBTUEVDICg2KSAiQ2lyY3VsYXIgc3Vic3RpdHV0aW9uIGdyb3VwcyBhcmUgZGlzYWxsb3dlZC4KCSogVGhhdCBpcywgaXQgbXVzdCBub3QgYmUgcG9zc2libGUgdG8gcmV0dXJuIHRvIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24KCSogYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259CgkqIHByb3BlcnR5LiIKCSovCglpZiAoaGVhZCA9PSBlbGVtRGVjbCkKCSAgICBjaXJjID0gaGVhZDsKCWVsc2UgaWYgKFNVQlNUX0dST1VQX0FGRihoZWFkKSAhPSBOVUxMKQoJICAgIGNpcmMgPSB4bWxTY2hlbWFDaGVja1N1YnN0R3JvdXBDaXJjdWxhcihoZWFkLCBoZWFkKTsKCWVsc2UKCSAgICBjaXJjID0gTlVMTDsKCWlmIChjaXJjICE9IE5VTEwpIHsKCSAgICB4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMOwoKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHBjdHh0LAoJCVhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF82LAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBjaXJjLCBjaXJjLT5ub2RlLAoJCSJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiAnJXMnIGRlZmluZXMgYSBjaXJjdWxhciAiCgkJInN1YnN0aXR1dGlvbiBncm91cCB0byBlbGVtZW50IGRlY2xhcmF0aW9uICclcyciLAoJCXhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJBLCBjaXJjKSwKCQl4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQiwgaGVhZCksCgkJTlVMTCk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHJBKQoJICAgIEZSRUVfQU5EX05VTEwoc3RyQikKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfNjsKCX0KCS8qCgkqIFNQRUMgKDQpICJJZiB0aGVyZSBpcyBhIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LAoJKiB0aGUge3R5cGUgZGVmaW5pdGlvbn0KCSogb2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUge3R5cGUKCSogZGVmaW5pdGlvbn0gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCBnaXZlbiB0aGUgdmFsdWUKCSogb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgZXhjbHVzaW9uc30gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAKCSogYWZmaWxpYXRpb259LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkgKKczLjQuNikKCSogKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4KSBvciBhcyBkZWZpbmVkIGluCgkqIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikgKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcwoJKiBzaW1wbGUpLiIKCSoKCSogTk9URToge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBtZWFucyB0aGUgdmFsdWVzIG9mIHRoZQoJKiBhdHRyaWJ1dGUgImZpbmFsIi4KCSovCgoJaWYgKHR5cGVEZWYgIT0gRUxFTV9UWVBFKFNVQlNUX0dST1VQX0FGRihlbGVtRGVjbCkpKSB7CgkgICAgaW50IHNldCA9IDA7CgoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfRVhURU5TSU9OKQoJCXNldCB8PSBTVUJTRVRfRVhURU5TSU9OOwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04pCgkJc2V0IHw9IFNVQlNFVF9SRVNUUklDVElPTjsKCgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TRGVyaXZlZE9LKHR5cGVEZWYsCgkJRUxFTV9UWVBFKGhlYWQpLCBzZXQpICE9IDApIHsKCQl4bWxDaGFyICpzdHJBID0gTlVMTCwgKnN0ckIgPSBOVUxMLCAqc3RyQyA9IE5VTEw7CgoJCXJldCA9IFhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF80OwoJCXhtbFNjaGVtYVBDdXN0b21FcnJFeHQocGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF80LAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsIGVsZW1EZWNsLT5ub2RlLAoJCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiAnJXMnIHdhcyAiCgkJICAgICJlaXRoZXIgcmVqZWN0ZWQgYnkgdGhlIHN1YnN0aXR1dGlvbiBncm91cCAiCgkJICAgICJhZmZpbGlhdGlvbiAnJXMnLCBvciBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gaXRzIHR5cGUgIgoJCSAgICAiZGVmaW5pdGlvbiAnJXMnIiwKCQkgICAgeG1sU2NoZW1hR2V0Q29tcG9uZW50UU5hbWUoJnN0ckEsIHR5cGVEZWYpLAoJCSAgICB4bWxTY2hlbWFHZXRDb21wb25lbnRRTmFtZSgmc3RyQiwgaGVhZCksCgkJICAgIHhtbFNjaGVtYUdldENvbXBvbmVudFFOYW1lKCZzdHJDLCBFTEVNX1RZUEUoaGVhZCkpKTsKCQlGUkVFX0FORF9OVUxMKHN0ckEpCgkJRlJFRV9BTkRfTlVMTChzdHJCKQoJCUZSRUVfQU5EX05VTEwoc3RyQykKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBTUEVDICg1KSAiSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IG9yIHt0eXBlIGRlZmluaXRpb259J3MKICAgICoge2NvbnRlbnQgdHlwZX0KICAgICogaXMgb3IgaXMgZGVyaXZlZCBmcm9tIElEIHRoZW4gdGhlcmUgbXVzdCBub3QgYmUgYSB7dmFsdWUgY29uc3RyYWludH0uCiAgICAqIE5vdGU6IFRoZSB1c2Ugb2YgSUQgYXMgYSB0eXBlIGRlZmluaXRpb24gZm9yIGVsZW1lbnRzIGdvZXMgYmV5b25kCiAgICAqIFhNTCAxLjAsIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBpZiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBpcyBkZXNpcmVkIgogICAgKi8KICAgIGlmICgoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpICYmCgkoKElTX1NJTVBMRV9UWVBFKHR5cGVEZWYpICYmCgkgIHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh0eXBlRGVmLCBYTUxfU0NIRU1BU19JRCkpIHx8CgkgKElTX0NPTVBMRVhfVFlQRSh0eXBlRGVmKSAmJgoJICBIQVNfU0lNUExFX0NPTlRFTlQodHlwZURlZikgJiYKCSAgeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLAoJICAgIFhNTF9TQ0hFTUFTX0lEKSkpKSB7CgoJcmV0ID0gWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzU7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKHBjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0VfUFJPUFNfQ09SUkVDVF81LAoJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgZWxlbURlY2wtPm5vZGUsCgkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gKG9yIHR5cGUgZGVmaW5pdGlvbidzIGNvbnRlbnQgdHlwZSkgaXMgb3IgIgoJICAgICJpcyBkZXJpdmVkIGZyb20gSUQ7IHZhbHVlIGNvbnN0cmFpbnRzIGFyZSBub3QgYWxsb3dlZCBpbiAiCgkgICAgImNvbmp1bmN0aW9uIHdpdGggc3VjaCBhIHR5cGUgZGVmaW5pdGlvbiIsIE5VTEwpOwogICAgfSBlbHNlIGlmIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJaW50IHZjcmV0OwoJeG1sTm9kZVB0ciBub2RlID0gTlVMTDsKCgkvKgoJKiBTUEVDICgyKSAiSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbAoJKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUKCSoge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKCSogKKczLjMuNikuIgoJKi8KCWlmICh0eXBlRGVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKHBjdHh0LCBlbGVtRGVjbC0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInRoZSB2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAoZWxlbURlY2wtPm5vZGUgIT0gTlVMTCkgewoJICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChlbGVtRGVjbC0+bm9kZSwKCQkgICAgQkFEX0NBU1QgImZpeGVkIik7CgkgICAgZWxzZQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChlbGVtRGVjbC0+bm9kZSwKCQkgICAgQkFEX0NBU1QgImRlZmF1bHQiKTsKCX0KCXZjcmV0ID0geG1sU2NoZW1hUGFyc2VDaGVja0NPU1ZhbGlkRGVmYXVsdChwY3R4dCwgbm9kZSwKCSAgICB0eXBlRGVmLCBlbGVtRGVjbC0+dmFsdWUsICYoZWxlbURlY2wtPmRlZlZhbCkpOwoJaWYgKHZjcmV0ICE9IDApIHsKCSAgICBpZiAodmNyZXQgPCAwKSB7CgkJUEVSUk9SX0lOVCgieG1sU2NoZW1hRWxlbUNoZWNrVmFsQ29uc3RyIiwKCQkgICAgImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBhbiAiCgkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9uIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHJldHVybiAodmNyZXQpOwoJfQogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRWxlbVN1YnN0R3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6CiAqIFN1YnN0aXR1dGlvbiBHcm91cCAoY29zLWVxdWl2LWNsYXNzKQogKgogKiBJbiBMaWJ4bWwyIHRoZSBzdWJzdC4gZ3JvdXBzIHdpbGwgYmUgcHJlY29tcHV0ZWQsIGluIHRlcm1zIG9mIHRoYXQKICogYSBsaXN0IHdpbGwgYmUgYnVpbHQgZm9yIGVhY2ggc3Vic3QuIGdyb3VwIGhlYWQsIGhvbGRpbmcgYWxsIGRpcmVjdAogKiByZWZlcmVudHMgdG8gdGhpcyBoZWFkLgogKiBOT1RFIHRoYXQgdGhpcyBmdW5jdGlvbiBuZWVkczoKICogICAxLiBjaXJjdWxhciBzdWJzdC4gZ3JvdXBzIHRvIGJlIGNoZWNrZWQgYmVmb3JlaGFuZAogKiAgIDIuIHRoZSBkZWNsYXJhdGlvbidzIHR5cGUgdG8gYmUgZGVyaXZlZCBmcm9tIHRoZSBoZWFkJ3MgdHlwZQogKgogKiBTVEFUVVM6CiAqCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0VsZW1TdWJzdEdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKQp7CiAgICBpZiAoKFNVQlNUX0dST1VQX0FGRihlbGVtRGVjbCkgPT0gTlVMTCkgfHwKCS8qIFNQRUMgKDEpICJJdHMge2Fic3RyYWN0fSBpcyBmYWxzZS4iICovCgkoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkpCglyZXR1cm47CiAgICB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGhlYWQ7Cgl4bWxTY2hlbWFUeXBlUHRyIGhlYWRUeXBlLCB0eXBlOwoJaW50IHNldCwgbWV0aFNldDsKCS8qCgkqIFNQRUMgKDIpICJJdCBpcyB2YWxpZGx5IHN1YnN0aXR1dGFibGUgZm9yIEhFQUQgc3ViamVjdCB0byBIRUFEJ3MKCSoge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYXMgdGhlIGJsb2NraW5nIGNvbnN0cmFpbnQsIGFzIGRlZmluZWQgaW4KCSogU3Vic3RpdHV0aW9uIEdyb3VwIE9LIChUcmFuc2l0aXZlKSAopzMuMy42KS4iCgkqLwoJZm9yIChoZWFkID0gU1VCU1RfR1JPVVBfQUZGKGVsZW1EZWNsKTsgaGVhZCAhPSBOVUxMOwoJICAgIGhlYWQgPSBTVUJTVF9HUk9VUF9BRkYoaGVhZCkpIHsKCSAgICBzZXQgPSAwOwoJICAgIG1ldGhTZXQgPSAwOwoJICAgIC8qCgkgICAgKiBUaGUgYmxvY2tpbmcgY29uc3RyYWludHMuCgkgICAgKi8KCSAgICBpZiAoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX1NVQlNUSVRVVElPTikKCQljb250aW51ZTsKCSAgICBoZWFkVHlwZSA9IGhlYWQtPnN1YnR5cGVzOwoJICAgIHR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXM7CgkgICAgaWYgKGhlYWRUeXBlID09IHR5cGUpCgkJZ290byBhZGRfbWVtYmVyOwoJICAgIGlmIChoZWFkLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04pCgkJc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT047CgkgICAgaWYgKGhlYWQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pCgkJc2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwoJICAgIC8qCgkgICAgKiBTUEVDOiBTdWJzdGl0dXRpb24gR3JvdXAgT0sgKFRyYW5zaXRpdmUpICgyLjMpCgkgICAgKiAiVGhlIHNldCBvZiBhbGwge2Rlcml2YXRpb24gbWV0aG9kfXMgaW52b2x2ZWQgaW4gdGhlCgkgICAgKiBkZXJpdmF0aW9uIG9mIEQncyB7dHlwZSBkZWZpbml0aW9ufSBmcm9tIEMncyB7dHlwZSBkZWZpbml0aW9ufQoJICAgICogZG9lcyBub3QgaW50ZXJzZWN0IHdpdGggdGhlIHVuaW9uIG9mIHRoZSBibG9ja2luZyBjb25zdHJhaW50LAoJICAgICogQydzIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9IChpZiBDIGlzIGNvbXBsZXgsIG90aGVyd2lzZSB0aGUKCSAgICAqIGVtcHR5IHNldCkgYW5kIHRoZSB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSAocmVzcGVjdGl2ZWx5IHRoZQoJICAgICogZW1wdHkgc2V0KSBvZiBhbnkgaW50ZXJtZWRpYXRlIHt0eXBlIGRlZmluaXRpb259cyBpbiB0aGUKCSAgICAqIGRlcml2YXRpb24gb2YgRCdzIHt0eXBlIGRlZmluaXRpb259IGZyb20gQydzIHt0eXBlIGRlZmluaXRpb259LiIKCSAgICAqLwoJICAgIC8qCgkgICAgKiBPUFRJTUlaRSBUT0RPOiBPcHRpbWl6ZSB0aGlzIGEgYml0LCBzaW5jZSwgaWYgdHJhdmVyc2luZyB0aGUKCSAgICAqIHN1YnN0LmhlYWQgYXhpcywgdGhlIG1ldGhTZXQgZG9lcyBub3QgbmVlZCB0byBiZSBjb21wdXRlZCBmb3IKCSAgICAqIHRoZSBmdWxsIGRlcHRoIG92ZXIgYW5kIG92ZXIuCgkgICAgKi8KCSAgICAvKgoJICAgICogVGhlIHNldCBvZiBhbGwge2Rlcml2YXRpb24gbWV0aG9kfXMgaW52b2x2ZWQgaW4gdGhlIGRlcml2YXRpb24KCSAgICAqLwoJICAgIHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZSAhPSBoZWFkVHlwZSkpIHsKCQlpZiAoKHR5cGUtPmZsYWdzICYKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmCgkJICAgICgobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKQoJCSAgICBtZXRoU2V0IHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OOwoKCQlpZiAoKHR5cGUtPmZsYWdzICYKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgJiYKCQkgICAgKChtZXRoU2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTikgPT0gMCkpCgkJICAgIG1ldGhTZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCgkJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIH0KCSAgICAvKgoJICAgICogVGhlIHtwcm9oaWJpdGVkIHN1YnN0aXR1dGlvbnN9IG9mIGFsbCBpbnRlcm1lZGlhdGUgdHlwZXMgKwoJICAgICogdGhlIGhlYWQncyB0eXBlLgoJICAgICovCgkgICAgdHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlcy0+YmFzZVR5cGU7CgkgICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJCWlmIChJU19DT01QTEVYX1RZUEUodHlwZSkpIHsKCQkgICAgaWYgKCh0eXBlLT5mbGFncyAmCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgJiYKCQkJKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgPT0gMCkpCgkJICAgIHNldCB8PSBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTjsKCQkgICAgaWYgKCh0eXBlLT5mbGFncyAmCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSAmJgoJCQkoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pID09IDApKQoJCSAgICBzZXQgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTjsKCQl9IGVsc2UKCQkgICAgYnJlYWs7CgkJaWYgKHR5cGUgPT0gaGVhZFR5cGUpCgkJICAgIGJyZWFrOwoJCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKCSAgICB9CgkgICAgaWYgKChzZXQgIT0gMCkgJiYKCQkoKChzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikgJiYKCQkobWV0aFNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OKSkgfHwKCQkoKHNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pICYmCgkJKG1ldGhTZXQgJiBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OKSkpKSB7CgkJY29udGludWU7CgkgICAgfQphZGRfbWVtYmVyOgoJICAgIHhtbFNjaGVtYUFkZEVsZW1lbnRTdWJzdGl0dXRpb25NZW1iZXIoY3R4dCwgaGVhZCwgZWxlbURlY2wpOwoJICAgIGlmICgoaGVhZC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1NVQlNUX0dST1VQX0hFQUQpID09IDApCgkJaGVhZC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9TVUJTVF9HUk9VUF9IRUFEOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudAogKiBAaXRlbTogIGFuIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uL3BhcnRpY2xlCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tFbGVtZW50RGVjbENvbXBvbmVudCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsLAoJCQkJICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpCglyZXR1cm47CiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9DSEVDS0VEKQoJcmV0dXJuOwogICAgZWxlbURlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfQ0hFQ0tFRDsKICAgIGlmICh4bWxTY2hlbWFDaGVja0VsZW1Qcm9wc0NvcnJlY3QoY3R4dCwgZWxlbURlY2wpID09IDApCgl4bWxTY2hlbWFDaGVja0VsZW1TdWJzdEdyb3VwKGN0eHQsIGVsZW1EZWNsKTsKfQoKLyoqCiAqIHhtbFNjaGVtYU1pc2NSZWZGaXh1cDoKICogQGl0ZW06ICBhbiBzY2hlbWEgY29tcG9uZW50CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgaW50ZXJuYWwgbmFtZSBvZiB0aGUgY29tcG9uZW50CiAqCiAqIFJlc29sdmVzIHJlZmVyZW5jZXMgb2YgbWlzYy4gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFNaXNjUmVmRml4dXAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfUEFSVElDTEUpIHsKCWlmICgoaXRlbS0+Y2hpbGRyZW4gIT0gTlVMTCkgJiYKCSAgICAoaXRlbS0+Y2hpbGRyZW4tPnR5cGUgPT0gWE1MX1NDSEVNQV9FWFRSQV9RTkFNRVJFRikpIHsKCSAgICB4bWxTY2hlbWFRTmFtZVJlZlB0ciByZWYgPSAoeG1sU2NoZW1hUU5hbWVSZWZQdHIpIGl0ZW0tPmNoaWxkcmVuOwoJICAgIHhtbFNjaGVtYVRyZWVJdGVtUHRyIHJlZkl0ZW07CgkgICAgLyoKCSAgICAqIFJlc29sdmUgdGhlIHJlZmVyZW5jZS4KCSAgICAqLwoJICAgIGl0ZW0tPmNoaWxkcmVuID0gTlVMTDsKCSAgICByZWZJdGVtID0geG1sU2NoZW1hR2V0TmFtZWRDb21wb25lbnQoY3R4dC0+c2NoZW1hLAoJCXJlZi0+aXRlbVR5cGUsIHJlZi0+bmFtZSwgcmVmLT50YXJnZXROYW1lc3BhY2UpOwoJICAgIGlmIChyZWZJdGVtID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJICAgIE5VTEwsIEdFVF9OT0RFKGl0ZW0pLCAicmVmIiwgcmVmLT5uYW1lLAoJCSAgICByZWYtPnRhcmdldE5hbWVzcGFjZSwgcmVmLT5pdGVtVHlwZSwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQlpZiAocmVmSXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHsKCQkgICAgLyoKCQkgICAgKiBOT1RFIHRoYXQgd2Ugd2lsbCBhc3NpZ24gdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KCQkgICAgKiBpdHNlbGYgdG8gdGhlICJ0ZXJtIiBvZiB0aGUgcGFydGljbGUuIFRoaXMgd2lsbCBlYXNlCgkJICAgICogdGhlIGNoZWNrIGZvciBjaXJjdWxhciBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4gQWZ0ZXIKCQkgICAgKiB0aGF0IHRoZSAidGVybSIgd2lsbCBiZSBhc3NpZ25lZCB0aGUgbW9kZWwgZ3JvdXAgb2YgdGhlCgkJICAgICogbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KCQkgICAgKi8KCQkgICAgaXRlbS0+Y2hpbGRyZW4gPSByZWZJdGVtOwoJCX0gZWxzZQoJCSAgICBpdGVtLT5jaGlsZHJlbiA9IHJlZkl0ZW07CgkgICAgfQoJfQogICAgfQp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKHhtbFNjaGVtYVZhbFB0ciB4LAoJCSAgICAgICB4bWxTY2hlbWFWYWxQdHIgeSkgCnsgICAKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHgsIHR5LCBwdHgsIHB0eTsgICAgCiAgICBpbnQgcmV0OwoKICAgIHdoaWxlICh4ICE9IE5VTEwpIHsKCS8qIFNhbWUgdHlwZXMuICovCgl0eCA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKHhtbFNjaGVtYUdldFZhbFR5cGUoeCkpOwoJdHkgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZSh4bWxTY2hlbWFHZXRWYWxUeXBlKHkpKTsKCXB0eCA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHgpOwoJcHR5ID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eSk7CgkvKgoJKiAoMSkgaWYgYSBkYXRhdHlwZSBUJyBpcyC3ZGVyaXZlZLcgYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGFuCgkqIGF0b21pYyBkYXRhdHlwZSBUIHRoZW4gdGhlILd2YWx1ZSBzcGFjZbcgb2YgVCcgaXMgYSBzdWJzZXQgb2YKCSogdGhlILd2YWx1ZSBzcGFjZbcgb2YgVC4gKi8KCS8qCgkqICgyKSBpZiBkYXRhdHlwZXMgVCcgYW5kIFQnJyBhcmUgt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcKCSogZnJvbSBhIGNvbW1vbiBhdG9taWMgYW5jZXN0b3IgVCB0aGVuIHRoZSC3dmFsdWUgc3BhY2W3cyBvZiBUJwoJKiBhbmQgVCcnIG1heSBvdmVybGFwLgoJKi8KCWlmIChwdHggIT0gcHR5KQoJICAgIHJldHVybigwKTsKCS8qCgkqIFdlIGFzc3VtZSBjb21wdXRlZCB2YWx1ZXMgdG8gYmUgbm9ybWFsaXplZCwgc28gZG8gYSBmYXN0CgkqIHN0cmluZyBjb21wYXJpc29uIGZvciBzdHJpbmcgYmFzZWQgdHlwZXMuCgkqLwoJaWYgKChwdHgtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgfHwKCSAgICBJU19BTllfU0lNUExFX1RZUEUocHR4KSkgewoJICAgIGlmICghIHhtbFN0ckVxdWFsKAoJCXhtbFNjaGVtYVZhbHVlR2V0QXNTdHJpbmcoeCksCgkJeG1sU2NoZW1hVmFsdWVHZXRBc1N0cmluZyh5KSkpCgkJcmV0dXJuICgwKTsKCX0gZWxzZSB7CgkgICAgcmV0ID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKAoJCXgsIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSwKCQl5LCBYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUFJFU0VSVkUpOwoJICAgIGlmIChyZXQgPT0gLTIpCgkJcmV0dXJuKC0xKTsKCSAgICBpZiAocmV0ICE9IDApCgkJcmV0dXJuKDApOwoJfQoJLyoKCSogTGlzdHMuCgkqLwoJeCA9IHhtbFNjaGVtYVZhbHVlR2V0TmV4dCh4KTsKCWlmICh4ICE9IE5VTEwpIHsKCSAgICB5ID0geG1sU2NoZW1hVmFsdWVHZXROZXh0KHkpOwoJICAgIGlmICh5ID09IE5VTEwpCgkJcmV0dXJuICgwKTsJICAgIAoJfSBlbHNlIGlmICh4bWxTY2hlbWFWYWx1ZUdldE5leHQoeSkgIT0gTlVMTCkKCSAgICByZXR1cm4gKDApOwoJZWxzZQoJICAgIHJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQXR0ckZpeHVwOgogKiBAaXRlbTogIGFuIHNjaGVtYSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zL3VzZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyRml4dXAoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGl0ZW0sCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgLyoKICAgICogVE9ETzogSWYgaW5jbHVkaW5nIHRoaXMgaXMgZG9uZSB0d2ljZSAoISkgZm9yIGV2ZXJ5IGF0dHJpYnV0ZS4KICAgICogICAgICAgLT4gSG1tLCBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIGRvbmUuCiAgICAqLwogICAgLyoKICAgICogVGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+IGVsZW1lbnQKICAgICogaW5mb3JtYXRpb24gaXRlbSBpbiB0aGUgW2NoaWxkcmVuXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSBzaW1wbGUKICAgICogdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlCiAgICAqIFthdHRyaWJ1dGVdLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEKQoJcmV0dXJuOwogICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9JTlRFUk5BTF9SRVNPTFZFRDsKICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChpdGVtLT50eXBlTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+dHlwZU5hbWUsCgkgICAgaXRlbS0+dHlwZU5zKTsKCWlmICgodHlwZSA9PSBOVUxMKSB8fCAoISBJU19TSU1QTEVfVFlQRSh0eXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgaXRlbS0+bm9kZSwKCQkidHlwZSIsIGl0ZW0tPnR5cGVOYW1lLCBpdGVtLT50eXBlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7Cgl9IGVsc2UKCSAgICBpdGVtLT5zdWJ0eXBlcyA9IHR5cGU7CgogICAgfSBlbHNlIGlmIChpdGVtLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwoKCS8qCgkqIFdlIGhhdmUgYW4gYXR0cmlidXRlIHVzZSBoZXJlOyBhc3NpZ24gdGhlIHJlZmVyZW5jZWQKCSogYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8KCS8qCgkqIFRPRE86IEV2YWx1YXRlLCB3aGF0IGVycm9ycyBjb3VsZCBvY2N1ciBpZiB0aGUgZGVjbGFyYXRpb24gaXMgbm90CgkqIGZvdW5kLiBJdCBtaWdodCBiZSBwb3NzaWJsZSB0aGF0IHRoZSAidHlwZWZpeHVwIiBtaWdodCBjcmFzaCBpZgoJKiBubyByZWYgZGVjbGFyYXRpb24gd2FzIGZvdW5kLgoJKi8KCWRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKGN0eHQtPnNjaGVtYSwgaXRlbS0+cmVmLCBpdGVtLT5yZWZOcyk7CiAgICAgICAgaWYgKGRlY2wgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJICAgIAlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgaXRlbS0+bm9kZSwKCQkicmVmIiwgaXRlbS0+cmVmLCBpdGVtLT5yZWZOcywKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCWl0ZW0tPnJlZkRlY2wgPSBkZWNsOwogICAgICAgIHhtbFNjaGVtYUF0dHJGaXh1cChkZWNsLCBjdHh0LCBOVUxMKTsKICAgICAgICBpdGVtLT5zdWJ0eXBlcyA9IGRlY2wtPnN1YnR5cGVzOwoJLyoKCSogQXR0cmlidXRlIFVzZSBDb3JyZWN0CgkqIGF1LXByb3BzLWNvcnJlY3QuMjogSWYgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyBhIGZpeGVkCgkqIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlbiBpZiB0aGUgYXR0cmlidXRlIHVzZSBpdHNlbGYgaGFzIGEKCSoge3ZhbHVlIGNvbnN0cmFpbnR9LCBpdCBtdXN0IGFsc28gYmUgZml4ZWQgYW5kIGl0cyB2YWx1ZSBtdXN0IG1hdGNoCgkqIHRoYXQgb2YgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9LgoJKi8KCWlmICgoZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSAmJgoJICAgIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJICAgIGlmICgoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9BVV9QUk9QU19DT1JSRUNUXzIsCgkJICAgIE5VTEwsIE5VTEwsIGl0ZW0tPm5vZGUsCgkJICAgICJUaGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGhhcyBhICdmaXhlZCcgdmFsdWUgY29uc3RyYWludCAiCgkJICAgICIsIHRodXMgaXQgbXVzdCBiZSAnZml4ZWQnIGluIGF0dHJpYnV0ZSB1c2UgYXMgd2VsbCIsCgkJICAgIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJaWYgKCEgeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoaXRlbS0+ZGVmVmFsLCBkZWNsLT5kZWZWYWwpKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQVVfUFJPUFNfQ09SUkVDVF8yLAoJCQlOVUxMLCBOVUxMLCBpdGVtLT5ub2RlLAoJCQkiVGhlICdmaXhlZCcgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgYXR0cmlidXRlIHVzZSAiCgkJCSJtdXN0IG1hdGNoIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24ncyB2YWx1ZSAiCgkJCSJjb25zdHJhaW50ICclcyciLAoJCQlkZWNsLT5kZWZWYWx1ZSk7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogRlVUVVJFOiBPbmUgc2hvdWxkIGNoYW5nZSB0aGUgdmFsdWVzIG9mIHRoZSBhdHRyLiB1c2UKCSAgICAqIGlmIGV2ZXIgdmFsaWRhdGlvbiBzaG91bGQgYmUgYXR0ZW1wdGVkIGV2ZW4gaWYgdGhlCgkgICAgKiBzY2hlbWEgaXRzZWxmIHdhcyBub3QgZnVsbHkgdmFsaWQuCgkgICAgKi8KCX0KICAgIH0gZWxzZSB7CglpdGVtLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUmVzb2x2ZUlEQ0tleVJlZjoKICogQGlkYzogIHRoZSBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGF0dHJpYnV0ZSBuYW1lCiAqCiAqIFJlc29sdmUga2V5UmVmIHJlZmVyZW5jZXMgdG8ga2V5L3VuaXF1ZSBJRENzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUmVzb2x2ZUlEQ0tleVJlZih4bWxTY2hlbWFJRENQdHIgaWRjLAoJCQkgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKGlkYy0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikKICAgICAgICByZXR1cm47CiAgICBpZiAoaWRjLT5yZWYtPm5hbWUgIT0gTlVMTCkgewoJaWRjLT5yZWYtPml0ZW0gPSAoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSB4bWxIYXNoTG9va3VwMigKCSAgICBwY3R4dC0+c2NoZW1hLT5pZGNEZWYsCgkgICAgaWRjLT5yZWYtPm5hbWUsCgkgICAgaWRjLT5yZWYtPnRhcmdldE5hbWVzcGFjZSk7CiAgICAgICAgaWYgKGlkYy0+cmVmLT5pdGVtID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogSXQgaXMgYWN0dWFsbHkgbm90IGFuIGVycm9yIHRvIGZhaWwgdG8gcmVzb2x2ZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihwY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkoeG1sU2NoZW1hVHlwZVB0cikgaWRjLCBpZGMtPm5vZGUsCgkJInJlZmVyIiwgaWRjLT5yZWYtPm5hbWUsCgkJaWRjLT5yZWYtPnRhcmdldE5hbWVzcGFjZSwKCQlYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRiwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKCX0gZWxzZSB7CgkgICAgaWYgKGlkYy0+bmJGaWVsZHMgIT0KCQkoKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW0pLT5uYkZpZWxkcykgewoJCXhtbENoYXIgKnN0ciA9IE5VTEw7CgkJeG1sU2NoZW1hSURDUHRyIHJlZmVyOwoJCQoJCXJlZmVyID0gKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW07CgkJLyoKCQkqIFNQRUMgYy1wcm9wcy1jb3JyZWN0KDIpCgkJKiAiSWYgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyBrZXlyZWYsCgkJKiB0aGUgY2FyZGluYWxpdHkgb2YgdGhlIHtmaWVsZHN9IG11c3QgZXF1YWwgdGhhdCBvZgoJCSogdGhlIHtmaWVsZHN9IG9mIHRoZSB7cmVmZXJlbmNlZCBrZXl9LgoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihwY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ19QUk9QU19DT1JSRUNULAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaWRjLCBpZGMtPm5vZGUsCgkJICAgICJUaGUgY2FyZGluYWxpdHkgb2YgdGhlIGtleXJlZiBkaWZmZXJzIGZyb20gdGhlICIKCQkgICAgImNhcmRpbmFsaXR5IG9mIHRoZSByZWZlcmVuY2VkIGtleSAnJXMnIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgcmVmZXItPnRhcmdldE5hbWVzcGFjZSwKCQkJcmVmZXItPm5hbWUpIAoJCSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgfQoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQgPSBOVUxMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBwcmVzZXJ2ZSA9IDA7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYQogICAgKiB0aGUgQVBJOyBpLmUuIG5vdCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgZG9jdW1lbnQuCiAgICAqLwoKICAgIHhtbFNjaGVtYUluaXRUeXBlcygpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IE5VTEw7CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgaWYgKGN0eHQtPlVSTCAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZEZpbGUoKGNvbnN0IGNoYXIgKikgY3R4dC0+VVJMLCBOVUxMLAoJICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgbG9hZCAnJXMnLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5VUkwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoY3R4dC0+YnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkTWVtb3J5KGN0eHQtPmJ1ZmZlciwgY3R4dC0+c2l6ZSwgTlVMTCwgTlVMTCwKCSAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX1BBUlNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgZG9jLT5VUkwgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiKTsKICAgICAgICBjdHh0LT5VUkwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIiwgLTEpOwogICAgfSBlbHNlIGlmIChjdHh0LT5kb2MgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IGN0eHQtPmRvYzsKCXByZXNlcnZlID0gMTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9USElOR19UT19QQVJTRSwKCQkgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZS5cbiIsCgkJICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogVGhlbiBleHRyYWN0IHRoZSByb290IGFuZCBTY2hlbWEgcGFyc2UgaXQKICAgICAqLwogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9ST09ULAoJCSAgICAgICJUaGUgc2NoZW1hIGhhcyBubyBkb2N1bWVudCBlbGVtZW50LlxuIiwgTlVMTCwgTlVMTCk7CglpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFJlbW92ZSBhbGwgdGhlIGJsYW5rIHRleHQgbm9kZXMKICAgICAqLwogICAgeG1sU2NoZW1hQ2xlYW51cERvYyhjdHh0LCByb290KTsKCiAgICAvKgogICAgICogVGhlbiBkbyB0aGUgcGFyc2luZyBmb3IgZ29vZAogICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZVNjaGVtYShjdHh0LCByb290KTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5wcmVzZXJ2ZSA9IHByZXNlcnZlOwogICAgY3R4dC0+c2NoZW1hID0gcmV0OwogICAgY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CgogICAgLyoKICAgICogUmVzb2x2ZSBiYXNlIHR5cGVzIG9mIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hUmVzb2x2ZVR5cGVEZWZzLCBjdHh0KTsKCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdDsKCiAgICBpZiAocmV0LT52b2xhdGlsZXMgIT0gTlVMTCkgewoJeG1sU2NoZW1hSXRlbUxpc3RQdHIgbGlzdCA9ICh4bWxTY2hlbWFJdGVtTGlzdFB0cikgcmV0LT52b2xhdGlsZXM7CglpbnQgaTsKCXhtbFNjaGVtYVRyZWVJdGVtUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IGxpc3QtPm5iSXRlbXM7IGkrKykgewoJICAgIGl0ZW0gPSAoeG1sU2NoZW1hVHJlZUl0ZW1QdHIpIGxpc3QtPml0ZW1zW2ldOwoJICAgIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRSkKCQl4bWxTY2hlbWFNaXNjUmVmRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7Cgl9CiAgICB9CiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyRml4dXAsIGN0eHQpOwogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZ3JvdXAgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckdycEZpeHVwLAogICAgICAgICAgICAgICAgY3R4dCk7CiAgICAvKgogICAgKiBSZXNvbHZlIGlkZW50aXR5LWNvbnN0cmFpbnQga2V5UmVmcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmlkY0RlZiwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmLCBjdHh0KTsKICAgIC8qCiAgICAqIENoZWNrIHR5cGUgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpCgl4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhciwgY3R4dCk7CiAgICAvKgogICAgKiBDaGVjayBtb2RlbCBncm91cHMgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKQoJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyLCBjdHh0KTsKICAgIC8qCiAgICAqIFNldCB0aGUgInRlcm0iIG9mIHBhcnRpY2xlcyBwb2ludGluZyB0byBtb2RlbCBncm91cCBkZWZpbml0aW9ucwogICAgKiB0byB0aGUgY29udGFpbmVkIG1vZGVsIGdyb3VwLgogICAgKi8KICAgIGlmIChyZXQtPnZvbGF0aWxlcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJdGVtTGlzdFB0ciBsaXN0ID0gKHhtbFNjaGVtYUl0ZW1MaXN0UHRyKSByZXQtPnZvbGF0aWxlczsKCWludCBpOwoJeG1sU2NoZW1hUGFydGljbGVQdHIgaXRlbTsKCglmb3IgKGkgPSAwOyBpIDwgbGlzdC0+bmJJdGVtczsgaSsrKSB7CgkgICAgaXRlbSA9ICh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgbGlzdC0+aXRlbXNbaV07CgkgICAgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFKQoJCXhtbFNjaGVtYUdyb3VwRGVmVGVybUZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOwoJfQogICAgfQogICAgLyoKICAgICogQ2hlY2sgYXR0cmlidXRlIGdyb3VwcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpCgl4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIsIGN0eHQpOwogICAgLyoKICAgICAqIFRoZW4gZml4IHJlZmVyZW5jZXMgb2YgZWxlbWVudCBkZWNsYXJhdGlvbjsgYXBwbHkgY29uc3RyYWludHMuCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuRnVsbChyZXQtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYUVsZW1lbnRGaXh1cCwgY3R4dCk7CiAgICAvKgogICAgKiBXZSB3aWxsIHN0b3AgaGVyZSBpZiB0aGUgc2NoZW1hIHdhcyBub3QgdmFsaWQgdG8gYXZvaWQgaW50ZXJuYWwgZXJyb3JzCiAgICAqIG9uIG1pc3Npbmcgc3ViLWNvbXBvbmVudHMuIFRoaXMgaXMgbm90IGNvbmZvcm1pbmcgdG8gdGhlIHNwZWMsIHNpbmNlIGl0CiAgICAqIGFsbG93cyBtaXNzaW5nIGNvbXBvbmVudHMsIGJ1dCBpdCBtaWdodCBtYWtlIGZ1cnRoZXIgcHJvY2Vzc2luZyBjcmFzaC4KICAgICogU28gc2VlIGl0IGFzIGEgdmVyeSBzdHJpY3QgaGFuZGxpbmcsIHdoaWNoIG1pZ2h0IGJlIG1hZGUgbW9yZSBsYXggaW4gdGhlCiAgICAqIGZ1dHVyZS4KICAgICovCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCWdvdG8gZXhpdDsKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUZpeHVwLCBjdHh0KTsKICAgIC8qCiAgICAqIFZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMvdXNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgY3R4dCk7CiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmVsZW1EZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrRWxlbWVudERlY2xDb21wb25lbnQsIGN0eHQpOwoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJZ290byBleGl0OwoKICAgIC8qCiAgICAqIFRPRE86IGNvcy1lbGVtZW50LWNvbnNpc3RlbnQsIGNvcy1hbGwtbGltaXRlZAogICAgKgogICAgKiBUaGVuIGJ1aWxkIHRoZSBjb250ZW50IG1vZGVsIGZvciBhbGwgY29tcGxleCB0eXBlcwogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsLCBjdHh0KTsKCmV4aXQ6CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYUZyZWUocmV0KTsKICAgICAgICByZXQgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGNhbGxiYWNrCiAqIEB3YXJuOiAgdGhlIHdhcm5pbmcgY2FsbGJhY2sKICogQGN0eDogIGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcwogKgogKiBTZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9ucyB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+dXNlckRhdGEgPSBjdHg7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBYTWwtU2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnI6IHRoZSBlcnJvciBjYWxsYmFjayByZXN1bHQKICogQHdhcm46IHRoZSB3YXJuaW5nIGNhbGxiYWNrIHJlc3VsdAogKiBAY3R4OiBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MgcmVzdWx0CiAqCiAqIEdldCB0aGUgY2FsbGJhY2sgaW5mb3JtYXRpb24gdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHBhcnNlciBjb250ZXh0CiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLCAwIG90aGVyd2lzZQogKi8KaW50CnhtbFNjaGVtYUdldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKEJBRF9DQVNUICJJbnRlcm5hbCBFcnJvciIpOwp9CgpzdGF0aWMgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZQp4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIC8qCiAgICAqIFRoZSBub3JtYWxpemF0aW9uIHR5cGUgY2FuIGJlIGNoYW5nZWQgb25seSBmb3IgdHlwZXMgd2hpY2ggYXJlIGRlcml2ZWQKICAgICogZnJvbSB4c2Q6c3RyaW5nLgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJLyoKCSogTm90ZSB0aGF0IHdlIGFzc3VtZSBhIHdoaXRlc3BhY2Ugb2YgcHJlc2VydmUgZm9yIGFueVNpbXBsZVR5cGUuCgkqLwoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHx8CgkgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKQoJICAgIHJldHVybihYTUxfU0NIRU1BX1dISVRFU1BBQ0VfUFJFU0VSVkUpOwoJZWxzZSBpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfTk9STVNUUklORykKCSAgICByZXR1cm4oWE1MX1NDSEVNQV9XSElURVNQQUNFX1JFUExBQ0UpOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3CgkgICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvCgkgICAgKiBjb2xsYXBzZQoJICAgICogTm90ZSB0aGF0IHRoaXMgaW5jbHVkZXMgYnVpbHQtaW4gbGlzdCBkYXRhdHlwZXMuCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKTsKCX0KICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKSB7CgkvKgoJKiBGb3IgbGlzdCB0eXBlcyB0aGUgZmFjZXQgIndoaXRlU3BhY2UiIGlzIGZpeGVkIHRvICJjb2xsYXBzZSIuCgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0UpOwogICAgfSBlbHNlIGlmIChWQVJJRVRZX1VOSU9OKHR5cGUpKSB7CglyZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9VTktOT1dOKTsKICAgIH0gZWxzZSBpZiAoVkFSSUVUWV9BVE9NSUModHlwZSkpIHsKCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9QUkVTRVJWRSkKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9QUkVTRVJWRSk7CgllbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfV0hJVEVTUEFDRV9SRVBMQUNFKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX1JFUExBQ0UpOwoJZWxzZQoJICAgIHJldHVybiAoWE1MX1NDSEVNQV9XSElURVNQQUNFX0NPTExBUFNFKTsKICAgIH0KICAgIHJldHVybiAoLTEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU2ltcGxlIHR5cGUgdmFsaWRhdGlvbgkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRE9NIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBvc3RTY2hlbWFBc3NlbWJsZUZpeHVwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaW50IGksIG5iSXRlbXM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sICppdGVtczsKCgogICAgLyoKICAgICogRHVyaW5nIHRoZSBBc3NlbWJsZSBvZiB0aGUgc2NoZW1hIGN0eHQtPmN1ckl0ZW1zIGhhcwogICAgKiBiZWVuIGZpbGxlZCB3aXRoIHRoZSByZWxldmFudCBuZXcgaXRlbXMuIEZpeCB0aG9zZSB1cC4KICAgICovCiAgICBuYkl0ZW1zID0gY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXM7CiAgICBpdGVtcyA9ICh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtczsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQl4bWxTY2hlbWFSZXNvbHZlVHlwZURlZnMoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJCXhtbFNjaGVtYUF0dHJGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQl4bWxTY2hlbWFBdHRyR3JwRml4dXAoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLAoJCSAgICBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9QQVJUSUNMRToKCQl4bWxTY2hlbWFNaXNjUmVmRml4dXAoKHhtbFNjaGVtYVRyZWVJdGVtUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCQl4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCXJldHVybjsKICAgIC8qCiAgICAqIENpcmN1bGFyaXR5IGNoZWNrcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQl4bWxTY2hlbWFDaGVja1R5cGVEZWZDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCXhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApCglyZXR1cm47CiAgICAvKgogICAgKiBTZXQgdGhlICJ0ZXJtIiBvZiBwYXJ0aWNsZXMgcG9pbnRpbmcgdG8gbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMKICAgICogdG8gdGhlIGNvbnRhaW5lZCBtb2RlbCBncm91cC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07CglpZiAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1BBUlRJQ0xFKSAmJgoJICAgICgoKHhtbFNjaGVtYVBhcnRpY2xlUHRyKSBpdGVtKS0+Y2hpbGRyZW4gIT0gTlVMTCkgJiYKCSAgICAoKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgaXRlbSktPmNoaWxkcmVuLT50eXBlID09CgkgICAgWE1MX1NDSEVNQV9UWVBFX0dST1VQKSkgewoJICAgIHhtbFNjaGVtYUdyb3VwRGVmVGVybUZpeHVwKCh4bWxTY2hlbWFQYXJ0aWNsZVB0cikgaXRlbSwKCQljdHh0LCBOVUxMKTsKCX0KICAgIH0KICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKQoJcmV0dXJuOwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFFbGVtZW50Rml4dXAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0sIGN0eHQsCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkKCXJldHVybjsKCiAgICAvKgogICAgKiBGaXh1cCBmb3Igc2ltcGxlL2NvbXBsZXggdHlwZXMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApCglyZXR1cm47CiAgICAvKgogICAgKiBWYWxpZGF0ZSB2YWx1ZSBjb250cmFpbnQgdmFsdWVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQl4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSwKCQkgICAgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFDaGVja0VsZW1lbnREZWNsQ29tcG9uZW50KCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLAoJCSAgICBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApCglyZXR1cm47CiAgICAvKgogICAgKiBCdWlsZCB0aGUgY29udGVudCBtb2RlbCBmb3IgY29tcGxleCB0eXBlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb246CiAqIEBwY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiB0aGUgZXhpc3Rpbmcgc2NoZW1hCiAqIEBub2RlOiB0aGUgbm9kZSB0aGF0IGZpcmVkIHRoZSBhc3NlbWJsaW5nCiAqIEBuc05hbWU6IHRoZSBuYW1lc3BhY2UgbmFtZSBvZiB0aGUgbmV3IHNjaGVtYQogKiBAbG9jYXRpb246IHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkJICAgIGNvbnN0IHhtbENoYXIgKmxvY2F0aW9uKQp7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROcywgKm9sZHRuczsKICAgIHhtbERvY1B0ciBkb2MsIG9sZGRvYzsKICAgIGludCBvbGRmbGFncywgcmV0ID0gMCwgb2xkSXNTNFM7CiAgICB4bWxOb2RlUHRyIGRvY0VsZW07CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwoKICAgIC8qCiAgICAqIFRoaXMgc2hvdWxkIGJlIHVzZWQ6CiAgICAqIDEuIG9uIDxpbXBvcnQ+KHMpCiAgICAqIDIuIGlmIHJlcXVlc3RlZCBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlCiAgICAqIDMuIGlmIHJlcXVlc3RlZCB2aWEgdGhlIEFQSQogICAgKi8KICAgIGlmICgodmN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogQ3JlYXRlIGEgdGVtcG9yYXJ5IHBhcnNlciBjb250ZXh0LgogICAgKi8KICAgIGlmICgodmN0eHQtPnBjdHh0ID09IE5VTEwpICYmCgkoeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHZjdHh0KSA9PSAtMSkpCglyZXR1cm4gKC0xKTsKICAgIHBjdHh0ID0gdmN0eHQtPnBjdHh0OwogICAgLyoKICAgICogU2V0IHRoZSBjb3VudGVyIHRvIHByb2R1Y2UgdW5pcXVlIG5hbWVzIGZvciBhbm9ueW1vdXMgaXRlbXMuCiAgICAqLwogICAgcGN0eHQtPmNvdW50ZXIgPSBzY2hlbWEtPmNvdW50ZXI7CiAgICAvKgogICAgKiBBY3F1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYygoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgc2NoZW1hLAoJbm9kZSwgbnNOYW1lLCBsb2NhdGlvbiwgJmRvYywgJnRhcmdldE5zLCAwKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKGRvYyAhPSBOVUxMKQoJICAgIHhtbEZyZWVEb2MoZG9jKTsKICAgIH0gZWxzZSBpZiAoZG9jICE9IE5VTEwpIHsKCWRvY0VsZW0gPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwoJLyoKCSogQ3JlYXRlIG5ldyBhc3NlbWJsZSBpbmZvLgoJKi8KCWlmIChwY3R4dC0+YXNzZW1ibGUgPT0gTlVMTCkgewoJICAgIHBjdHh0LT5hc3NlbWJsZSA9IHhtbFNjaGVtYU5ld0Fzc2VtYmxlKCk7CgkgICAgaWYgKHBjdHh0LT5hc3NlbWJsZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkgICAgIk1lbW9yeSBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uLCAiCgkJICAgICJhbGxvY2F0aW5nIGFzc2VtYmxlIGluZm8iLCBOVUxMKTsKCQl4bWxGcmVlRG9jKGRvYyk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJLyoKCSogU2F2ZSBhbmQgcmVzZXQgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJb2xkZmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwoJb2xkdG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CglvbGRkb2MgPSBzY2hlbWEtPmRvYzsKCW9sZElzUzRTID0gdmN0eHQtPnBjdHh0LT5pc1M0UzsKCgl4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHNjaGVtYSk7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5zOwoJaWYgKCh0YXJnZXROcyAhPSBOVUxMKSAmJgoJICAgIHhtbFN0ckVxdWFsKHRhcmdldE5zLCB4bWxTY2hlbWFOcykpIHsKCSAgICAvKgoJICAgICogV2UgYXJlIHBhcnNpbmcgdGhlIHNjaGVtYSBmb3Igc2NoZW1hIQoJICAgICovCgkgICAgdmN0eHQtPnBjdHh0LT5pc1M0UyA9IDE7Cgl9CgkvKiBzY2hlbWEtPm5iQ3VySXRlbXMgPSAwOyAqLwoJcGN0eHQtPnNjaGVtYSA9IHNjaGVtYTsKCXBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CglwY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CgoJeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyhwY3R4dCwgc2NoZW1hLCBkb2NFbGVtKTsKCWlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkgewoJICAgIHZjdHh0LT5uYmVycm9ycyArPSBwY3R4dC0+bmJlcnJvcnM7CgkgICAgZ290byBmaW5hbGx5OwoJfQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgc2NoZW1hLCBkb2NFbGVtLT5jaGlsZHJlbik7CglpZiAocGN0eHQtPm5iZXJyb3JzICE9IDApIHsKCSAgICB2Y3R4dC0+bmJlcnJvcnMgKz0gcGN0eHQtPm5iZXJyb3JzOwoJICAgIGdvdG8gZmluYWxseTsKCX0KCXhtbFNjaGVtYVBvc3RTY2hlbWFBc3NlbWJsZUZpeHVwKHBjdHh0KTsKCWlmIChwY3R4dC0+bmJlcnJvcnMgIT0gMCkKCSAgICB2Y3R4dC0+bmJlcnJvcnMgKz0gcGN0eHQtPm5iZXJyb3JzOwpmaW5hbGx5OgoJLyoKCSogU2V0IHRoZSBjb3VudGVyIG9mIGl0ZW1zLgoJKi8KCXNjaGVtYS0+Y291bnRlciA9IHBjdHh0LT5jb3VudGVyOwoJLyoKCSogRnJlZSB0aGUgbGlzdCBvZiBhc3NlbWJsZWQgY29tcG9uZW50cy4KCSovCglwY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXMgPSAwOwoJLyoKCSogUmVzdG9yZSB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCgl2Y3R4dC0+cGN0eHQtPmlzUzRTID0gb2xkSXNTNFM7CglzY2hlbWEtPmZsYWdzID0gb2xkZmxhZ3M7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IG9sZHRuczsKCXNjaGVtYS0+ZG9jID0gb2xkZG9jOwoJcmV0ID0gcGN0eHQtPmVycjsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHhtbFNjaGVtYUF0dHJJbmZvUHRyCnhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCQkgICAgICAKCQkJIGludCBtZXRhVHlwZSkKewogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuIChOVUxMKTsKICAgIHsKCWludCBpOwoJeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CgoJZm9yIChpID0gMDsgaSA8IHZjdHh0LT5uYkF0dHJJbmZvczsgaSsrKSB7CgkgICAgaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIGlmIChpYXR0ci0+bWV0YVR5cGUgPT0gbWV0YVR5cGUpCgkJcmV0dXJuIChpYXR0cik7Cgl9CgogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlYU0k6CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZQogKiBvZiBhbiBpbnN0YW5jZS4gSWYgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gaXMgdXNlZCwgQG5vTmFtZXNwYWNlCiAqIG11c3QgYmUgc2V0IHRvIDEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlYU0koeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBjb25zdCB4bWxDaGFyICpuc25hbWUgPSBOVUxMLCAqbG9jYXRpb247CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKCiAgICAvKgogICAgKiBQYXJzZSB0aGUgdmFsdWU7IHdlIHdpbGwgYXNzdW1lIGFuIGV2ZW4gbnVtYmVyIG9mIHZhbHVlcwogICAgKiB0byBiZSBnaXZlbiAodGhpcyBpcyBob3cgWGVyY2VzIGFuZCBYU1Ygd29yaykuCiAgICAqLwogICAgaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCglYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9TQ0hFTUFfTE9DKTsKICAgIGlmIChpYXR0ciA9PSBOVUxMKQoJeG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTk9fTlNfU0NIRU1BX0xPQyk7CiAgICBpZiAoaWF0dHIgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBjdXIgPSBpYXR0ci0+dmFsdWU7CiAgICBkbyB7CglpZiAoaWF0dHItPm1ldGFUeXBlID09IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1NDSEVNQV9MT0MpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgY291bnQrKzsKCSAgICBuc25hbWUgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsKCSAgICBjdXIgPSBlbmQ7Cgl9CgkvKgoJKiBHZXQgdGhlIFVSSS4KCSovCgl3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkgICAgY3VyKys7CgllbmQgPSBjdXI7Cgl3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCSAgICBlbmQrKzsKCWlmIChlbmQgPT0gY3VyKQoJICAgIGJyZWFrOwoJY291bnQrKzsKCWxvY2F0aW9uID0geG1sRGljdExvb2t1cCh2Y3R4dC0+c2NoZW1hLT5kaWN0LCBjdXIsIGVuZCAtIGN1cik7CgljdXIgPSBlbmQ7CglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24odmN0eHQsIHZjdHh0LT5zY2hlbWEsCgkgICAgaWF0dHItPm5vZGUsIG5zbmFtZSwgbG9jYXRpb24pOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUFzc2VtYmxlQnlYU0kiLAoJCSJhc3NlbWJsaW5nIHNjaGVtYXRhIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9IHdoaWxlICgqY3VyICE9IDApOwogICAgcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSBjb25zdCB4bWxDaGFyICpwcmVmaXgpCnsKICAgIGlmICh2Y3R4dC0+c2F4ICE9IE5VTEwpIHsKCWludCBpLCBqOwoJeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGU7CgkKCWZvciAoaSA9IHZjdHh0LT5kZXB0aDsgaSA+PSAwOyBpLS0pIHsKCSAgICBpZiAodmN0eHQtPmVsZW1JbmZvc1tpXS0+bmJOc0JpbmRpbmdzICE9IDApIHsKCQlpbm9kZSA9IHZjdHh0LT5lbGVtSW5mb3NbaV07CgkJZm9yIChqID0gMDsgaiA8IGlub2RlLT5uYk5zQmluZGluZ3MgKiAyOyBqICs9IDIpIHsKCQkgICAgaWYgKCgocHJlZml4ID09IE5VTEwpICYmCgkJCSAgICAoaW5vZGUtPm5zQmluZGluZ3Nbal0gPT0gTlVMTCkpIHx8CgkJCSgocHJlZml4ICE9IE5VTEwpICYmIHhtbFN0ckVxdWFsKHByZWZpeCwKCQkJICAgIGlub2RlLT5uc0JpbmRpbmdzW2pdKSkpIHsKCgkJCS8qCgkJCSogTm90ZSB0aGF0IHRoZSBuYW1lc3BhY2UgYmluZGluZ3MgYXJlIGFscmVhZHkKCQkJKiBpbiBhIHN0cmluZyBkaWN0LgoJCQkqLwoJCQlyZXR1cm4gKGlub2RlLT5uc0JpbmRpbmdzW2orMV0pOwkJCQoJCSAgICB9CgkJfQoJICAgIH0KCX0KCXJldHVybiAoTlVMTCk7CiNpZmRlZiBMSUJYTUxfV1JJVEVSX0VOQUJMRUQKICAgIH0gZWxzZSBpZiAodmN0eHQtPnJlYWRlciAhPSBOVUxMKSB7Cgl4bWxDaGFyICpuc05hbWU7CgkKCW5zTmFtZSA9IHhtbFRleHRSZWFkZXJMb29rdXBOYW1lc3BhY2UodmN0eHQtPnJlYWRlciwgcHJlZml4KTsKCWlmIChuc05hbWUgIT0gTlVMTCkgewoJICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCgkgICAgcmV0ID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbnNOYW1lLCAtMSk7CgkgICAgeG1sRnJlZShuc05hbWUpOwoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldHVybiAoTlVMTCk7CiNlbmRpZgogICAgfSBlbHNlIHsKCXhtbE5zUHRyIG5zOwoKCWlmICgodmN0eHQtPmlub2RlLT5ub2RlID09IE5VTEwpIHx8CgkgICAgKHZjdHh0LT5pbm9kZS0+bm9kZS0+ZG9jID09IE5VTEwpKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlIiwKCQkibm8gbm9kZSBvciBub2RlJ3MgZG9jIGF2YWxpYWJsZSIpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglucyA9IHhtbFNlYXJjaE5zKHZjdHh0LT5pbm9kZS0+bm9kZS0+ZG9jLAoJICAgIHZjdHh0LT5pbm9kZS0+bm9kZSwgcHJlZml4KTsKCWlmIChucyAhPSBOVUxMKQoJICAgIHJldHVybiAobnMtPmhyZWYpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKLyoKKiBUaGlzIG9uZSB3b3JrcyBvbiB0aGUgc2NoZW1hIG9mIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQuCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsIAkJCSAgCgkJCSAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgeG1sU2NoZW1hVmFsUHRyICp2YWwsCgkJCSAgaW50IHZhbE5lZWRlZCkKewogICAgaW50IHJldDsKCiAgICBpZiAodmN0eHQgJiYgKHZjdHh0LT5zY2hlbWEgPT0gTlVMTCkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24iLAoJICAgICJhIHNjaGVtYSBpcyBuZWVkZWQgb24gdGhlIHZhbGlkYXRpb24gY29udGV4dCIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgIT0gMCkKCXJldHVybiAocmV0KTsKICAgIHsKCXhtbENoYXIgKmxvY2FsTmFtZSA9IE5VTEw7Cgl4bWxDaGFyICpwcmVmaXggPSBOVUxMOwoKCWxvY2FsTmFtZSA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSA9IE5VTEw7CgoJICAgIGlmICh2Y3R4dCAhPSBOVUxMKSAKCQluc05hbWUgPSB4bWxTY2hlbWFMb29rdXBOYW1lc3BhY2UodmN0eHQsIEJBRF9DQVNUIHByZWZpeCk7CgkgICAgZWxzZSBpZiAobm9kZSAhPSBOVUxMKSB7CgkJeG1sTnNQdHIgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CgkJaWYgKG5zICE9IE5VTEwpCgkJICAgIG5zTmFtZSA9IG5zLT5ocmVmOwoJICAgIH0gZWxzZSB7CgkJeG1sRnJlZShwcmVmaXgpOwoJCXhtbEZyZWUobG9jYWxOYW1lKTsKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICBpZiAobnNOYW1lID09IE5VTEwpIHsKCQl4bWxGcmVlKHByZWZpeCk7CgkJeG1sRnJlZShsb2NhbE5hbWUpOwoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIGlmICh4bWxIYXNoTG9va3VwMihzY2hlbWEtPm5vdGFEZWNsLCBsb2NhbE5hbWUsCgkJbnNOYW1lKSAhPSBOVUxMKSB7CgkJaWYgKHZhbE5lZWRlZCAmJiAodmFsICE9IE5VTEwpKSB7CgkJICAgICgqdmFsKSA9IHhtbFNjaGVtYU5ld05PVEFUSU9OVmFsdWUoQkFEX0NBU1QgbG9jYWxOYW1lLAoJCQlCQURfQ0FTVCB4bWxTdHJkdXAobnNOYW1lKSk7CgkJICAgIGlmICgqdmFsID09IE5VTEwpCgkJCXJldCA9IC0xOwoJCX0KCSAgICB9IGVsc2UKCQlyZXQgPSAxOwoJICAgIHhtbEZyZWUocHJlZml4KTsKCSAgICB4bWxGcmVlKGxvY2FsTmFtZSk7Cgl9IGVsc2UgewoJICAgIGlmICh4bWxIYXNoTG9va3VwMihzY2hlbWEtPm5vdGFEZWNsLCB2YWx1ZSwgTlVMTCkgIT0gTlVMTCkgewoJCWlmICh2YWxOZWVkZWQgJiYgKHZhbCAhPSBOVUxMKSkgewoJCSAgICAoKnZhbCkgPSB4bWxTY2hlbWFOZXdOT1RBVElPTlZhbHVlKAoJCQlCQURfQ0FTVCB4bWxTdHJkdXAodmFsdWUpLCBOVUxMKTsKCQkgICAgaWYgKCp2YWwgPT0gTlVMTCkKCQkJcmV0ID0gLTE7CgkJfQoJICAgIH0gZWxzZQoJCXJldHVybiAoMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkFkZE5vZGVRTmFtZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIGNvbnN0IHhtbENoYXIqIGxuYW1lLAoJCSAgICAgICBjb25zdCB4bWxDaGFyKiBuc25hbWUpCnsKICAgIGludCBpOwoKICAgIGxuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbG5hbWUsIC0xKTsKICAgIGlmIChsbmFtZSA9PSBOVUxMKQoJcmV0dXJuKC0xKTsKICAgIGlmIChuc25hbWUgIT0gTlVMTCkgewoJbnNuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+ZGljdCwgbnNuYW1lLCAtMSk7CglpZiAobnNuYW1lID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bm9kZVFOYW1lcy0+bmJJdGVtczsgaSArPSAyKSB7CglpZiAoKHZjdHh0LT5ub2RlUU5hbWVzLT5pdGVtcyBbaV0gPT0gbG5hbWUpICYmCgkgICAgKHZjdHh0LT5ub2RlUU5hbWVzLT5pdGVtc1tpICsxXSA9PSBuc25hbWUpKQoJICAgIC8qIEFscmVhZHkgdGhlcmUgKi8KCSAgICByZXR1cm4oaSk7CiAgICB9CiAgICAvKiBBZGQgbmV3IGVudHJ5LiAqLwogICAgaSA9IHZjdHh0LT5ub2RlUU5hbWVzLT5uYkl0ZW1zOwogICAgeG1sU2NoZW1hSXRlbUxpc3RBZGQodmN0eHQtPm5vZGVRTmFtZXMsICh2b2lkICopIGxuYW1lKTsKICAgIHhtbFNjaGVtYUl0ZW1MaXN0QWRkKHZjdHh0LT5ub2RlUU5hbWVzLCAodm9pZCAqKSBuc25hbWUpOwogICAgcmV0dXJuKGkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogIFZhbGlkYXRpb24gb2YgaWRlbnRpdHktY29uc3RyYWludHMgKElEQykgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQXVnbWVudElEQzoKICogQGlkY0RlZjogdGhlIElEQyBkZWZpbml0aW9uCiAqCiAqIENyZWF0ZXMgYW4gYXVnbWVudGVkIElEQyBkZWZpbml0aW9uIGl0ZW0uCiAqCiAqIFJldHVybnMgdGhlIGl0ZW0sIG9yIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXVnbWVudElEQyh4bWxTY2hlbWFJRENQdHIgaWRjRGVmLAoJCSAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOwoKICAgIGFpZGMgPSAoeG1sU2NoZW1hSURDQXVnUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ0F1ZykpOwogICAgaWYgKGFpZGMgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCSAgICAieG1sU2NoZW1hQXVnbWVudElEQzogYWxsb2NhdGluZyBhbiBhdWdtZW50ZWQgSURDIGRlZmluaXRpb24iLAoJICAgIE5VTEwpOwoJcmV0dXJuOwogICAgfQogICAgYWlkYy0+YnViYmxlRGVwdGggPSAtMTsKICAgIGFpZGMtPmRlZiA9IGlkY0RlZjsKICAgIGFpZGMtPm5leHQgPSBOVUxMOwogICAgaWYgKHZjdHh0LT5haWRjcyA9PSBOVUxMKQoJdmN0eHQtPmFpZGNzID0gYWlkYzsKICAgIGVsc2UgewoJYWlkYy0+bmV4dCA9IHZjdHh0LT5haWRjczsKCXZjdHh0LT5haWRjcyA9IGFpZGM7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENOZXdCaW5kaW5nOgogKiBAaWRjRGVmOiB0aGUgSURDIGRlZmluaXRpb24gb2YgdGhpcyBiaW5kaW5nCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURDIGJpbmRpbmcuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBiaW5kaW5nIGluIGNhc2Ugb2Ygc3VjY2VlZGVkLCBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cgp4bWxTY2hlbWFJRENOZXdCaW5kaW5nKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIpIHhtbE1hbGxvYygKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJICAgICJhbGxvY2F0aW5nIGEgUFNWSSBJREMgYmluZGluZyBpdGVtIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nKSk7CiAgICByZXQtPmRlZmluaXRpb24gPSBpZGNEZWY7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENTdG9yZU5vZGVUYWJsZUl0ZW06CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGl0ZW06IHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtCiAqCiAqIFRoZSB2YWxpZGF0aW9uIGNvbnRleHQgaXMgdXNlZCB0byBzdG9yZSBhbiBJREMgbm9kZSB0YWJsZSBpdGVtcy4KICogVGhleSBhcmUgc3RvcmVkIHRvIGF2b2lkIGNvcHlpbmcgdGhlbSBpZiBJREMgbm9kZS10YWJsZXMgYXJlIG1lcmdlZAogKiB3aXRoIGNvcnJlc3BvbmRpbmcgcGFyZW50IElEQyBub2RlLXRhYmxlcyAoYnViYmxpbmcpLgogKgogKiBSZXR1cm5zIDAgaWYgc3VjY2VlZGVkLCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1N0b3JlTm9kZVRhYmxlSXRlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBpdGVtKQp7CiAgICAvKgogICAgKiBBZGQgdG8gZ29iYWwgbGlzdC4KICAgICovCiAgICBpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsKCXZjdHh0LT5pZGNOb2RlcyA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKQoJICAgIHhtbE1hbGxvYygyMCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKHZjdHh0LT5pZGNOb2RlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyB0aGUgSURDIG5vZGUgdGFibGUgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl2Y3R4dC0+c2l6ZUlkY05vZGVzID0gMjA7CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5zaXplSWRjTm9kZXMgPD0gdmN0eHQtPm5iSWRjTm9kZXMpIHsKCXZjdHh0LT5zaXplSWRjTm9kZXMgKj0gMjsKCXZjdHh0LT5pZGNOb2RlcyA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKQoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmlkY05vZGVzLCB2Y3R4dC0+c2l6ZUlkY05vZGVzICoKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgdGhlIElEQyBub2RlIHRhYmxlIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgdmN0eHQtPmlkY05vZGVzW3ZjdHh0LT5uYklkY05vZGVzKytdID0gaXRlbTsKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDU3RvcmVLZXk6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGl0ZW06IHRoZSBJREMga2V5CiAqCiAqIFRoZSB2YWxpZGF0aW9uIGNvbnRleHQgaXMgdXNlZCB0byBzdG9yZSBhbiBJREMga2V5LgogKgogKiBSZXR1cm5zIDAgaWYgc3VjY2VlZGVkLCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1N0b3JlS2V5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5KQp7CiAgICAvKgogICAgKiBBZGQgdG8gZ29iYWwgbGlzdC4KICAgICovCiAgICBpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJdmN0eHQtPmlkY0tleXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKQoJICAgIHhtbE1hbGxvYyg0MCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CglpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgdGhlIElEQyBrZXkgc3RvcmFnZSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl2Y3R4dC0+c2l6ZUlkY0tleXMgPSA0MDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVJZGNLZXlzIDw9IHZjdHh0LT5uYklkY0tleXMpIHsKCXZjdHh0LT5zaXplSWRjS2V5cyAqPSAyOwoJdmN0eHQtPmlkY0tleXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKQoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmlkY0tleXMsIHZjdHh0LT5zaXplSWRjS2V5cyAqCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCWlmICh2Y3R4dC0+aWRjS2V5cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkicmUtYWxsb2NhdGluZyB0aGUgSURDIGtleSBzdG9yYWdlIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHZjdHh0LT5pZGNLZXlzW3ZjdHh0LT5uYklkY0tleXMrK10gPSBrZXk7CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FwcGVuZE5vZGVUYWJsZUl0ZW06CiAqIEBiaW5kOiB0aGUgSURDIGJpbmRpbmcKICogQG50SXRlbTogdGhlIG5vZGUtdGFibGUgaXRlbQogKgogKiBBcHBlbmRzIHRoZSBJREMgbm9kZS10YWJsZSBpdGVtIHRvIHRoZSBiaW5kaW5nLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQsCgkJCQl4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBudEl0ZW0pCnsKICAgIGlmIChiaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJYmluZC0+c2l6ZU5vZGVzID0gMTA7CgliaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikKCSAgICB4bWxNYWxsb2MoMTAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmIChiaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwKCQkiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9IGVsc2UgaWYgKGJpbmQtPnNpemVOb2RlcyA8PSBiaW5kLT5uYk5vZGVzKSB7CgliaW5kLT5zaXplTm9kZXMgKj0gMjsKCWJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKQoJICAgIHhtbFJlYWxsb2MoYmluZC0+bm9kZVRhYmxlLCBiaW5kLT5zaXplTm9kZXMgKgoJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKGJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCSJyZS1hbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIGJpbmQtPm5vZGVUYWJsZVtiaW5kLT5uYk5vZGVzKytdID0gbnRJdGVtOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDQXF1aXJlQmluZGluZzoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAbWF0Y2hlcjogdGhlIElEQyBtYXRjaGVyCiAqCiAqIExvb2tzIHVwIGFuIFBTVkkgSURDIGJpbmRpbmcsIGZvciB0aGUgSURDIGRlZmluaXRpb24gYW5kCiAqIG9mIHRoZSBnaXZlbiBtYXRjaGVyLiBJZiBub25lIGZvdW5kLCBhIG5ldyBvbmUgaXMgY3JlYXRlZAogKiBhbmQgYWRkZWQgdG8gdGhlIElEQyB0YWJsZS4KICoKICogUmV0dXJucyBhbiBJREMgYmluZGluZyBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cgp4bWxTY2hlbWFJRENBcXVpcmVCaW5kaW5nKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIpCnsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGluZm87CgogICAgaW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbbWF0Y2hlci0+ZGVwdGhdOwoKICAgIGlmIChpbmZvLT5pZGNUYWJsZSA9PSBOVUxMKSB7CglpbmZvLT5pZGNUYWJsZSA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcobWF0Y2hlci0+YWlkYy0+ZGVmKTsKCWlmIChpbmZvLT5pZGNUYWJsZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXR1cm4oaW5mby0+aWRjVGFibGUpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQgPSBOVUxMOwoKCWJpbmQgPSBpbmZvLT5pZGNUYWJsZTsKCWRvIHsKCSAgICBpZiAoYmluZC0+ZGVmaW5pdGlvbiA9PSBtYXRjaGVyLT5haWRjLT5kZWYpCgkJcmV0dXJuKGJpbmQpOwoJICAgIGlmIChiaW5kLT5uZXh0ID09IE5VTEwpIHsKCQliaW5kLT5uZXh0ID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhtYXRjaGVyLT5haWRjLT5kZWYpOwoJCWlmIChiaW5kLT5uZXh0ID09IE5VTEwpCgkJICAgIHJldHVybiAoTlVMTCk7CgkJcmV0dXJuKGJpbmQtPm5leHQpOwoJICAgIH0KCSAgICBiaW5kID0gYmluZC0+bmV4dDsKCX0gd2hpbGUgKGJpbmQgIT0gTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZUtleToKICogQGtleTogdGhlIElEQyBrZXkKICoKICogRnJlZXMgYW4gSURDIGtleSB0b2dldGhlciB3aXRoIGl0cyBjb21waWxlZCB2YWx1ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlEQ0ZyZWVLZXkoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkpCnsKICAgIGlmIChrZXktPnZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGtleS0+dmFsKTsKICAgIHhtbEZyZWUoa2V5KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nOgogKgogKiBGcmVlcyBhbiBJREMgYmluZGluZy4gTm90ZSB0aGF0IHRoZSBub2RlIHRhYmxlLWl0ZW1zCiAqIGFyZSBub3QgZnJlZWQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlQmluZGluZyh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlICE9IE5VTEwpIHsKCWlmIChiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgaW50IGk7CgkgICAgLyoKCSAgICAqIE5vZGUtdGFibGUgaXRlbXMgZm9yIGtleXJlZnMgYXJlIG5vdCBzdG9yZWQgZ2xvYmFsbHkKCSAgICAqIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQsIHNpbmNlIHRoZXkgYXJlIG5vdCBidWJibGVkLgoJICAgICogV2UgbmVlZCB0byBmcmVlIHRoZW0gaGVyZS4KCSAgICAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQl4bWxGcmVlKGJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5cyk7CgkJeG1sRnJlZShiaW5kLT5ub2RlVGFibGVbaV0pOwoJICAgIH0KCX0KCXhtbEZyZWUoYmluZC0+bm9kZVRhYmxlKTsKICAgIH0KICAgIHhtbEZyZWUoYmluZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlSURDVGFibGU6CiAqIEBiaW5kOiB0aGUgZmlyc3QgSURDIGJpbmRpbmcgaW4gdGhlIGxpc3QKICoKICogRnJlZXMgYW4gSURDIHRhYmxlLCBpLmUuIGFsbCB0aGUgSURDIGJpbmRpbmdzIGluIHRoZSBsaXN0LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHByZXY7CgogICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJcHJldiA9IGJpbmQ7CgliaW5kID0gYmluZC0+bmV4dDsKCXhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nKHByZXYpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0OgogKiBAbWF0Y2hlcjogdGhlIGZpcnN0IElEQyBtYXRjaGVyIGluIHRoZSBsaXN0CiAqCiAqIEZyZWVzIGEgbGlzdCBvZiBJREMgbWF0Y2hlcnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlTWF0Y2hlckxpc3QoeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7CgogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJbmV4dCA9IG1hdGNoZXItPm5leHQ7CglpZiAobWF0Y2hlci0+a2V5U2VxcyAhPSBOVUxMKSB7CgkgICAgaW50IGk7CgkgICAgZm9yIChpID0gMDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspCgkJaWYgKG1hdGNoZXItPmtleVNlcXNbaV0gIT0gTlVMTCkKCQkgICAgeG1sRnJlZShtYXRjaGVyLT5rZXlTZXFzW2ldKTsKCSAgICB4bWxGcmVlKG1hdGNoZXItPmtleVNlcXMpOwoJfQoJeG1sRnJlZShtYXRjaGVyKTsKCW1hdGNoZXIgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3Q6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG1hdGNoZXI6IHRoZSBJREMgbWF0Y2hlcgogKiBAc2VsOiB0aGUgWFBhdGggaW5mb3JtYXRpb24KICogQHBhcmVudDogdGhlIHBhcmVudCAic2VsZWN0b3IiIHN0YXRlIG9iamVjdCBpZiBhbnkKICogQHR5cGU6ICJzZWxlY3RvciIgb3IgImZpZWxkIgogKgogKiBDcmVhdGVzL3JldXNlcyBhbmQgYWN0aXZhdGVzIHN0YXRlIG9iamVjdHMgZm9yIHRoZSBnaXZlbgogKiBYUGF0aCBpbmZvcm1hdGlvbjsgaWYgdGhlIFhQYXRoIGV4cHJlc3Npb24gY29uc2lzdHMgb2YgdW5pb25zLAogKiBtdWx0aXBsZSBzdGF0ZSBvYmplY3RzIGFyZSBjcmVhdGVkIGZvciBldmVyeSB1bmlvbmVkIGV4cHJlc3Npb24uCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyLAoJCQl4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsLAoJCQlpbnQgdHlwZSkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvOwoKICAgIC8qCiAgICAqIFJldXNlIHRoZSBzdGF0ZSBvYmplY3RzIGZyb20gdGhlIHBvb2wuCiAgICAqLwogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlUG9vbCAhPSBOVUxMKSB7CglzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2w7Cgl2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgPSBzdG8tPm5leHQ7CglzdG8tPm5leHQgPSBOVUxMOwogICAgfSBlbHNlIHsJCgkvKgoJKiBDcmVhdGUgYSBuZXcgc3RhdGUgb2JqZWN0LgoJKi8KCXN0byA9ICh4bWxTY2hlbWFJRENTdGF0ZU9ialB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENTdGF0ZU9iaikpOwoJaWYgKHN0byA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCSJhbGxvY2F0aW5nIGFuIElEQyBzdGF0ZSBvYmplY3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCW1lbXNldChzdG8sIDAsIHNpemVvZih4bWxTY2hlbWFJRENTdGF0ZU9iaikpOwogICAgfQkKICAgIC8qCiAgICAqIEFkZCB0byBnbG9iYWwgbGlzdC4gCiAgICAqLwkKICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkKCXN0by0+bmV4dCA9IHZjdHh0LT54cGF0aFN0YXRlczsKICAgIHZjdHh0LT54cGF0aFN0YXRlcyA9IHN0bzsKCiAgICAvKgogICAgKiBGcmVlIHRoZSBvbGQgeHBhdGggdmFsaWRhdGlvbiBjb250ZXh0LgogICAgKi8KICAgIGlmIChzdG8tPnhwYXRoQ3R4dCAhPSBOVUxMKQoJeG1sRnJlZVN0cmVhbUN0eHQoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCiAgICAvKgogICAgKiBDcmVhdGUgYSBuZXcgWFBhdGggKHBhdHRlcm4pIHZhbGlkYXRpb24gY29udGV4dC4KICAgICovCiAgICBzdG8tPnhwYXRoQ3R4dCA9ICh2b2lkICopIHhtbFBhdHRlcm5HZXRTdHJlYW1DdHh0KAoJKHhtbFBhdHRlcm5QdHIpIHNlbC0+eHBhdGhDb21wKTsKICAgIGlmIChzdG8tPnhwYXRoQ3R4dCA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCIsCgkgICAgImZhaWxlZCB0byBjcmVhdGUgYW4gWFBhdGggdmFsaWRhdGlvbiBjb250ZXh0Iik7CglyZXR1cm4gKC0xKTsKICAgIH0gICAgCiAgICBzdG8tPnR5cGUgPSB0eXBlOwogICAgc3RvLT5kZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHN0by0+bWF0Y2hlciA9IG1hdGNoZXI7CiAgICBzdG8tPnNlbCA9IHNlbDsKICAgIHN0by0+bmJIaXN0b3J5ID0gMDsKICAgIAojaWYgREVCVUdfSURDCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBTVE8gcHVzaCAnJXMnXG4iLAoJc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZVR5cGU6IHRoZSBub2RlVHlwZSBvZiB0aGUgY3VycmVudCBub2RlCiAqCiAqIEV2YWx1YXRlcyBhbGwgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAqCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBJQyAiZmllbGQiIHN0YXRlIG9iamVjdHMgd2hpY2ggcmVzb2x2ZWQgdG8KICogdGhpcyBub2RlLCAwIGlmIG5vbmUgcmVzb2x2ZWQgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIHhtbEVsZW1lbnRUeXBlIG5vZGVUeXBlKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8sIGhlYWQgPSBOVUxMLCBmaXJzdDsKICAgIGludCByZXMsIHJlc29sdmVkID0gMCwgZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICAgICAgCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCglkZXB0aCsrOwojaWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IEVWQUwgb24gJXMsIGRlcHRoICVkLCB0eXBlICVkXG4iLAkgICAgCgkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwgdmN0eHQtPmlub2RlLT5uc05hbWUsCgkJdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUpLCBkZXB0aCwgbm9kZVR5cGUpOwoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9CiNlbmRpZgogICAgLyoKICAgICogUHJvY2VzcyBhbGwgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAgICAqLwogICAgZmlyc3QgPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CiAgICBzdG8gPSBmaXJzdDsKICAgIHdoaWxlIChzdG8gIT0gaGVhZCkgewojaWYgREVCVUdfSURDCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBbJyVzJ10gc2VsZWN0b3IgJyVzJ1xuIiwgCgkJc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYtPm5hbWUsIHN0by0+c2VsLT54cGF0aCk7CgllbHNlCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgWyclcyddIGZpZWxkICclcydcbiIsIAoJCXN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5uYW1lLCBzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCWlmIChub2RlVHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIHJlcyA9IHhtbFN0cmVhbVB1c2goKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0LAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CgllbHNlCgkgICAgcmVzID0geG1sU3RyZWFtUHVzaEF0dHIoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0LAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCB2Y3R4dC0+aW5vZGUtPm5zTmFtZSk7CgoJaWYgKHJlcyA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoRXZhbHVhdGUiLAoJCSJjYWxsaW5nIHhtbFN0cmVhbVB1c2goKSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJaWYgKHJlcyA9PSAwKQoJICAgIGdvdG8gbmV4dF9zdG87CgkvKgoJKiBGdWxsIG1hdGNoLgoJKi8KI2lmIERFQlVHX0lEQwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgICAiCgkgICAgIk1BVENIXG4iKTsKI2VuZGlmCgkvKgoJKiBSZWdpc3RlciBhIG1hdGNoIGluIHRoZSBzdGF0ZSBvYmplY3QgaGlzdG9yeS4KCSovCglpZiAoc3RvLT5oaXN0b3J5ID09IE5VTEwpIHsKCSAgICBzdG8tPmhpc3RvcnkgPSAoaW50ICopIHhtbE1hbGxvYyg1ICogc2l6ZW9mKGludCkpOwoJICAgIGlmIChzdG8tPmhpc3RvcnkgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIHRoZSBzdGF0ZSBvYmplY3QgaGlzdG9yeSIsIE5VTEwpOwoJCXJldHVybigtMSk7CgkgICAgfQoJICAgIHN0by0+c2l6ZUhpc3RvcnkgPSAxMDsKCX0gZWxzZSBpZiAoc3RvLT5zaXplSGlzdG9yeSA8PSBzdG8tPm5iSGlzdG9yeSkgewoJICAgIHN0by0+c2l6ZUhpc3RvcnkgKj0gMjsKCSAgICBzdG8tPmhpc3RvcnkgPSAoaW50ICopIHhtbFJlYWxsb2Moc3RvLT5oaXN0b3J5LAoJCXN0by0+c2l6ZUhpc3RvcnkgKiBzaXplb2YoaW50KSk7CgkgICAgaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgInJlLWFsbG9jYXRpbmcgdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5IiwgTlVMTCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9Cgl9CQkKCXN0by0+aGlzdG9yeVtzdG8tPm5iSGlzdG9yeSsrXSA9IGRlcHRoOwoKI2lmZGVmIERFQlVHX0lEQwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgICAgIHB1c2ggbWF0Y2ggJyVkJ1xuIiwKCSAgICB2Y3R4dC0+ZGVwdGgpOwojZW5kaWYKCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikgewoJICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWw7CgkgICAgLyoKCSAgICAqIEFjdGl2YXRlIHN0YXRlIG9iamVjdHMgZm9yIHRoZSBJREMgZmllbGRzIG9mCgkgICAgKiB0aGUgSURDIHNlbGVjdG9yLgoJICAgICovCiNpZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICIKCQkiYWN0aXZhdGluZyBmaWVsZCBzdGF0ZXNcbiIpOwojZW5kaWYKCSAgICBzZWwgPSBzdG8tPm1hdGNoZXItPmFpZGMtPmRlZi0+ZmllbGRzOwoJICAgIHdoaWxlIChzZWwgIT0gTlVMTCkgewoJCWlmICh4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh2Y3R4dCwgc3RvLT5tYXRjaGVyLAoJCSAgICBzZWwsIFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgPT0gLTEpCgkJICAgIHJldHVybiAoLTEpOwoJCXNlbCA9IHNlbC0+bmV4dDsKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQpIHsKCSAgICAvKgoJICAgICogQW4gSURDIGtleSBub2RlIHdhcyBmb3VuZCBieSB0aGUgSURDIGZpZWxkLgoJICAgICovCiNpZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiSURDOiAgICAga2V5IGZvdW5kXG4iKTsKI2VuZGlmCgkgICAgLyoKCSAgICAqIE5vdGlmeSB0aGF0IHRoZSBjaGFyYWN0ZXIgdmFsdWUgb2YgdGhpcyBub2RlIGlzCgkgICAgKiBuZWVkZWQuCgkgICAgKi8KCSAgICBpZiAocmVzb2x2ZWQgPT0gMCkgewoJCWlmICgodmN0eHQtPmlub2RlLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRCkgPT0gMCkKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRDsKCSAgICB9CgkgICAgcmVzb2x2ZWQrKzsKCX0KbmV4dF9zdG86CglpZiAoc3RvLT5uZXh0ID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogRXZhbHVhdGUgZmllbGQgc3RhdGUgb2JqZWN0cyBjcmVhdGVkIG9uIHRoaXMgbm9kZSBhcyB3ZWxsLgoJICAgICovCgkgICAgaGVhZCA9IGZpcnN0OwoJICAgIHN0byA9IHZjdHh0LT54cGF0aFN0YXRlczsKCX0gZWxzZQoJICAgIHN0byA9IHN0by0+bmV4dDsKICAgIH0KICAgIHJldHVybiAocmVzb2x2ZWQpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdElEQ0tleVNlcXVlbmNlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgeG1sQ2hhciAqKmJ1ZiwKCQkJICAgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqc2VxLAoJCQkgICAgICBpbnQgY291bnQpCnsKICAgIGludCBpLCByZXM7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CgogICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiWyIpOwogICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCXJlcyA9IHhtbFNjaGVtYUdldENhbm9uVmFsdWVXaHRzcChzZXFbaV0tPnZhbCwgJnZhbHVlLAoJICAgIHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHNlcVtpXS0+dHlwZSkpOwoJaWYgKHJlcyA9PSAwKQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgdmFsdWUpOwoJZWxzZSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UiLAoJCSJmYWlsZWQgdG8gY29tcHV0ZSBhIGNhbm9uaWNhbCB2YWx1ZSIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIj8/PyIpOwoJfQoJaWYgKGkgPCBjb3VudCAtMSkKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInLCAiKTsKCWVsc2UKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CglpZiAodmFsdWUgIT0gTlVMTCkgewoJICAgIHhtbEZyZWUoKHhtbENoYXIgKikgdmFsdWUpOwoJICAgIHZhbHVlID0gTlVMTDsKCX0KICAgIH0KICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIl0iKTsKCiAgICByZXR1cm4gKEJBRF9DQVNUICpidWYpOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhQb3A6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogUG9wcyBhbGwgWFBhdGggc3RhdGVzLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFYUGF0aFBvcCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bzsKICAgIGludCByZXM7CgogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyA9PSBOVUxMKQoJcmV0dXJuKDApOwogICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwogICAgZG8gewoJcmVzID0geG1sU3RyZWFtUG9wKCh4bWxTdHJlYW1DdHh0UHRyKSBzdG8tPnhwYXRoQ3R4dCk7CglpZiAocmVzID09IC0xKQoJICAgIHJldHVybiAoLTEpOwoJc3RvID0gc3RvLT5uZXh0OwogICAgfSB3aGlsZSAoc3RvICE9IE5VTEwpOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogdGhlIHNpbXBsZS9jb21wbGV4IHR5cGUgb2YgdGhlIGN1cnJlbnQgbm9kZSBpZiBhbnkgYXQgYWxsCiAqIEB2YWw6IHRoZSBwcmVjb21waWxlZCB2YWx1ZQogKgogKiBQcm9jZXNzZXMgYW5kIHBvcHMgdGhlIGhpc3RvcnkgaXRlbXMgb2YgdGhlIElEQyBzdGF0ZSBvYmplY3RzLgogKiBJREMga2V5LXNlcXVlbmNlcyBhcmUgdmFsaWRhdGVkL2NyZWF0ZWQgb24gSURDIGJpbmRpbmdzLgogKiAKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgaW50IGRlcHRoKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8sIG5leHRzdG87CiAgICBpbnQgcmVzLCBtYXRjaERlcHRoOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkgPSBOVUxMOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlID0gdmN0eHQtPmlub2RlLT50eXBlRGVmOwoKICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CgojaWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IEJBQ0sgb24gJXMsIGRlcHRoICVkXG4iLAoJICAgIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSwgdmN0eHQtPmRlcHRoKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYgICAgCiAgICAvKgogICAgKiBFdmFsdWF0ZSB0aGUgc3RhdGUgb2JqZWN0cy4KICAgICovCiAgICB3aGlsZSAoc3RvICE9IE5VTEwpIHsKCXJlcyA9IHhtbFN0cmVhbVBvcCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQpOwoJaWYgKHJlcyA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkiLAoJCSJjYWxsaW5nIHhtbFN0cmVhbVBvcCgpIik7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiNpZiBERUJVR19JREMKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIHN0cmVhbSBwb3AgJyVzJ1xuIiwKCSAgICBzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCWlmIChzdG8tPm5iSGlzdG9yeSA9PSAwKQoJICAgIGdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCgltYXRjaERlcHRoID0gc3RvLT5oaXN0b3J5W3N0by0+bmJIaXN0b3J5IC0xXTsKCgkvKgoJKiBPbmx5IG1hdGNoZXMgYXQgdGhlIGN1cnJlbnQgZGVwdGggYXJlIG9mIGludGVyZXN0LgoJKi8KCWlmIChtYXRjaERlcHRoICE9IGRlcHRoKSB7CgkgICAgc3RvID0gc3RvLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQkKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSB7CgkgICAgaWYgKCEgSVNfU0lNUExFX1RZUEUodHlwZSkpIHsKCQkvKgoJCSogTm90IHF1YWxpZmllZCBpZiB0aGUgZmllbGQgcmVzb2x2ZXMgdG8gYSBub2RlIG9mIG5vbgoJCSogc2ltcGxlIHR5cGUuCgkJKi8JCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfSURDLCBOVUxMLAkJICAgIAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYsCgkJICAgICJUaGUgZmllbGQgJyVzJyBkb2VzIGV2YWx1YXRlIHRvIGEgbm9kZSBvZiAiCgkJICAgICJub24tc2ltcGxlIHR5cGUiLCBzdG8tPnNlbC0+eHBhdGgsIE5VTEwpOwoJCQoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0KCSAgICBpZiAoKGtleSA9PSBOVUxMKSAmJiAodmN0eHQtPmlub2RlLT52YWwgPT0gTlVMTCkpIHsKCQkvKgoJCSogRmFpbGVkIHRvIHByb3ZpZGUgdGhlIG5vcm1hbGl6ZWQgdmFsdWU7IG1heWJlCgkJKiB0aGUgdmFsdWUgd2FzIGludmFsaWQuCgkJKi8KCQlWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0lEQywKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLAoJCSAgICAiV2FybmluZzogTm8gcHJlY29tcHV0ZWQgdmFsdWUgYXZhaWxhYmxlLCB0aGUgdmFsdWUgIgoJCSAgICAid2FzIGVpdGhlciBpbnZhbGlkIG9yIHNvbWV0aGluZyBzdHJhbmdlIGhhcHBlbmQiKTsKCQlzdG8tPm5iSGlzdG9yeS0tOwoJCWdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCSAgICB9IGVsc2UgewoJCXhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciA9IHN0by0+bWF0Y2hlcjsKCQl4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICprZXlTZXE7CgkJaW50IHBvcywgaWR4OwoJCQoJCS8qCgkJKiBUaGUga2V5IHdpbGwgYmUgYW5jaG9yZWQgb24gdGhlIG1hdGNoZXIncyBsaXN0IG9mCgkJKiBrZXktc2VxdWVuY2VzLiBUaGUgcG9zaXRpb24gaW4gdGhpcyBsaXN0IGlzIGRldGVybWluZWQKCQkqIGJ5IHRoZSB0YXJnZXQgbm9kZSdzIGRlcHRoIHJlbGF0aXZlIHRvIHRoZSBtYXRjaGVyJ3MKCQkqIGRlcHRoIG9mIGNyZWF0aW9uIChpLmUuIHRoZSBkZXB0aCBvZiB0aGUgc2NvcGUgZWxlbWVudCkuCgkJKi8JCSAgICAKCQlwb3MgPSBzdG8tPmRlcHRoIC0gbWF0Y2hlci0+ZGVwdGg7CgkJaWR4ID0gc3RvLT5zZWwtPmluZGV4OwoJCQoJCS8qCgkJKiBDcmVhdGUvZ3JvdyB0aGUgYXJyYXkgb2Yga2V5LXNlcXVlbmNlcy4KCQkqLwoJCWlmIChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHsKCQkgICAgaWYgKHBvcyA+IDkpIAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyA9IHBvcyAqIDI7CgkJICAgIGVsc2UKCQkJbWF0Y2hlci0+c2l6ZUtleVNlcXMgPSAxMDsKCQkgICAgbWF0Y2hlci0+a2V5U2VxcyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqKSAKCQkJeG1sTWFsbG9jKG1hdGNoZXItPnNpemVLZXlTZXFzICoKCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikpOwkJCQoJCSAgICBpZiAobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB7CQkKCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCQkgICAgImFsbG9jYXRpbmcgYW4gYXJyYXkgb2Yga2V5LXNlcXVlbmNlcyIsCgkJCSAgICBOVUxMKTsKCQkJcmV0dXJuKC0xKTsKCQkgICAgfQoJCSAgICBtZW1zZXQobWF0Y2hlci0+a2V5U2VxcywgMCwKCQkJbWF0Y2hlci0+c2l6ZUtleVNlcXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSk7CgkJfSBlbHNlIGlmIChwb3MgPj0gbWF0Y2hlci0+c2l6ZUtleVNlcXMpIHsJCgkJICAgIGludCBpID0gbWF0Y2hlci0+c2l6ZUtleVNlcXM7CgkJICAgIAoJCSAgICBtYXRjaGVyLT5zaXplS2V5U2VxcyAqPSAyOwoJCSAgICBtYXRjaGVyLT5rZXlTZXFzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiopCgkJCXhtbFJlYWxsb2MobWF0Y2hlci0+a2V5U2VxcywKCQkJbWF0Y2hlci0+c2l6ZUtleVNlcXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSk7CgkJICAgIGlmIChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCQkgICAgInJlYWxsb2NhdGluZyBhbiBhcnJheSBvZiBrZXktc2VxdWVuY2VzIiwKCQkJICAgIE5VTEwpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIFRoZSBhcnJheSBuZWVkcyB0byBiZSBOVUxMZWQuCgkJICAgICogVE9ETzogVXNlIG1lbXNldD8KCQkgICAgKi8KCQkgICAgZm9yICg7IGkgPCBtYXRjaGVyLT5zaXplS2V5U2VxczsgaSsrKSAKCQkJbWF0Y2hlci0+a2V5U2Vxc1tpXSA9IE5VTEw7CQkJCgkJfQoJCQoJCS8qCgkJKiBHZXQvY3JlYXRlIHRoZSBrZXktc2VxdWVuY2UuCgkJKi8KCQlrZXlTZXEgPSBtYXRjaGVyLT5rZXlTZXFzW3Bvc107CQkgICAgCgkJaWYgKGtleVNlcSA9PSBOVUxMKSB7CQoJCSAgICBnb3RvIGNyZWF0ZV9zZXF1ZW5jZTsKCQl9IGVsc2UgewoJCSAgICBpZiAoa2V5U2VxW2lkeF0gIT0gTlVMTCkgewoJCQkvKgoJCQkqIGN2Yy1pZGVudGl0eS1jb25zdHJhaW50OgoJCQkqIDMgRm9yIGVhY2ggbm9kZSBpbiB0aGUgt3RhcmdldCBub2RlIHNldLcgYWxsCgkJCSogb2YgdGhlIHtmaWVsZHN9LCB3aXRoIHRoYXQgbm9kZSBhcyB0aGUgY29udGV4dAoJCQkqIG5vZGUsIGV2YWx1YXRlIHRvIGVpdGhlciBhbiBlbXB0eSBub2RlLXNldCBvcgoJCQkqIGEgbm9kZS1zZXQgd2l0aCBleGFjdGx5IG9uZSBtZW1iZXIsIHdoaWNoIG11c3QKCQkJKiBoYXZlIGEgc2ltcGxlIHR5cGUuCgkJCSogCgkJCSogVGhlIGtleSB3YXMgYWxyZWFkeSBzZXQ7IHJlcG9ydCBhbiBlcnJvci4KCQkJKi8KCQkJeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgbWF0Y2hlci0+YWlkYy0+ZGVmLAoJCQkgICAgIlRoZSBmaWVsZCAnJXMnIGV2YWx1YXRlcyB0byBhIG5vZGUtc2V0ICIKCQkJICAgICJ3aXRoIG1vcmUgdGhhbiBvbmUgbWVtYmVyIiwKCQkJICAgIHN0by0+c2VsLT54cGF0aCwgTlVMTCk7CgkJCXN0by0+bmJIaXN0b3J5LS07CgkJCWdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCQkgICAgfSBlbHNlIHsKCQkJZ290byBjcmVhdGVfa2V5OwoJCSAgICB9CgkJfQoJCQpjcmVhdGVfc2VxdWVuY2U6CgkJLyoKCQkqIENyZWF0ZSBhIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopIHhtbE1hbGxvYygKCQkgICAgbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkcyAqIAoJCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJCWlmIChrZXlTZXEgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkiYWxsb2NhdGluZyBhbiBJREMga2V5LXNlcXVlbmNlIiwgTlVMTCk7CgkJICAgIHJldHVybigtMSk7CQkJCgkJfQkKCQltZW1zZXQoa2V5U2VxLCAwLCBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzICogCgkJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CgkJbWF0Y2hlci0+a2V5U2Vxc1twb3NdID0ga2V5U2VxOwpjcmVhdGVfa2V5OgoJCS8qCgkJKiBDcmVhdGVkIGEga2V5IG9uY2UgcGVyIG5vZGUgb25seS4KCQkqLyAgCgkJaWYgKGtleSA9PSBOVUxMKSB7CgkJICAgIGtleSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSB4bWxNYWxsb2MoCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5KSk7CgkJICAgIGlmIChrZXkgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhIElEQyBrZXkiLCBOVUxMKTsKCQkJeG1sRnJlZShrZXlTZXEpOwoJCQltYXRjaGVyLT5rZXlTZXFzW3Bvc10gPSBOVUxMOwoJCQlyZXR1cm4oLTEpOwkJCQoJCSAgICB9CgkJICAgIC8qCgkJICAgICogQ29uc3VtZSB0aGUgY29tcGlsZWQgdmFsdWUuCgkJICAgICovCgkJICAgIGtleS0+dHlwZSA9IHR5cGU7CgkJICAgIGtleS0+dmFsID0gdmN0eHQtPmlub2RlLT52YWw7CgkJICAgIHZjdHh0LT5pbm9kZS0+dmFsID0gTlVMTDsKCQkgICAgLyoKCQkgICAgKiBTdG9yZSB0aGUga2V5IGluIGEgZ2xvYmFsIGxpc3QuCgkJICAgICovCgkJICAgIGlmICh4bWxTY2hlbWFJRENTdG9yZUtleSh2Y3R4dCwga2V5KSA9PSAtMSkgewoJCQl4bWxTY2hlbWFJRENGcmVlS2V5KGtleSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfQoJCWtleVNlcVtpZHhdID0ga2V5OwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikgewoJCQoJICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiprZXlTZXEgPSBOVUxMOwoJICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbnRJdGVtOwoJICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcjsKCSAgICB4bWxTY2hlbWFJRENQdHIgaWRjOwoJICAgIGludCBwb3MsIGksIGosIG5iS2V5czsKCSAgICAvKgoJICAgICogSGVyZSB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgc2NlbmFyaW86CgkgICAgKiBBbiBJREMgJ3NlbGVjdG9yJyBzdGF0ZSBvYmplY3QgcmVzb2x2ZWQgdG8gYSB0YXJnZXQgbm9kZSwKCSAgICAqIGR1cmluZyB0aGUgdGltZSB0aGlzIHRhcmdldCBub2RlIHdhcyBpbiB0aGUgCgkgICAgKiBhbmNlc3Rvci1vci1zZWxmIGF4aXMsIHRoZSAnZmllbGQnIHN0YXRlIG9iamVjdChzKSBsb29rZWQgCgkgICAgKiBvdXQgZm9yIG1hdGNoaW5nIG5vZGVzIHRvIGNyZWF0ZSBhIGtleS1zZXF1ZW5jZSBmb3IgdGhpcyAKCSAgICAqIHRhcmdldCBub2RlLiBOb3cgd2UgYXJlIGJhY2sgdG8gdGhpcyB0YXJnZXQgbm9kZSBhbmQgbmVlZAoJICAgICogdG8gcHV0IHRoZSBrZXktc2VxdWVuY2UsIHRvZ2V0aGVyIHdpdGggdGhlIHRhcmdldCBub2RlIAoJICAgICogaXRzZWxmLCBpbnRvIHRoZSBub2RlLXRhYmxlIG9mIHRoZSBjb3JyZXNwb25kaW5nIElEQyAKCSAgICAqIGJpbmRpbmcuCgkgICAgKi8KCSAgICBtYXRjaGVyID0gc3RvLT5tYXRjaGVyOwoJICAgIGlkYyA9IG1hdGNoZXItPmFpZGMtPmRlZjsKCSAgICBuYktleXMgPSBpZGMtPm5iRmllbGRzOwoJICAgIHBvcyA9IGRlcHRoIC0gbWF0Y2hlci0+ZGVwdGg7CQkKCSAgICAvKgoJICAgICogQ2hlY2sgaWYgdGhlIG1hdGNoZXIgaGFzIGFueSBrZXktc2VxdWVuY2VzIGF0IGFsbCwgcGx1cwoJICAgICogaWYgaXQgaGFzIGEga2V5LXNlcXVlbmNlIGZvciB0aGUgY3VycmVudCB0YXJnZXQgbm9kZS4KCSAgICAqLwkJCgkgICAgaWYgKChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHx8CgkJKG1hdGNoZXItPnNpemVLZXlTZXFzIDw9IHBvcykpIHsKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKQoJCSAgICBnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQllbHNlCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkgICAgfQoJICAgIAoJICAgIGtleVNlcSA9ICYobWF0Y2hlci0+a2V5U2Vxc1twb3NdKTsJCQoJICAgIGlmICgqa2V5U2VxID09IE5VTEwpIHsKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKQoJCSAgICBnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQllbHNlCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkgICAgfQoJICAgIAoJICAgIGZvciAoaSA9IDA7IGkgPCBuYktleXM7IGkrKykgewoJCWlmICgoKmtleVNlcSlbaV0gPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIE5vdCBxdWFsaWZpZWQsIGlmIG5vdCBhbGwgZmllbGRzIGRpZCByZXNvbHZlLgoJCSAgICAqLwoJCSAgICBpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZKSB7CgkJCS8qCgkJCSogQWxsIGZpZWxkcyBvZiBhICJrZXkiIElEQyBtdXN0IHJlc29sdmUuCgkJCSovCgkJCWdvdG8gc2VsZWN0b3Jfa2V5X2Vycm9yOwoJCSAgICB9CQkgICAgCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogQWxsIGZpZWxkcyBkaWQgcmVzb2x2ZS4KCSAgICAqLwoJICAgIAoJICAgIC8qCgkgICAgKiA0LjEgSWYgdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGNhdGVnb3J5fSBpcyB1bmlxdWUoL2tleSksCgkgICAgKiB0aGVuIG5vIHR3byBtZW1iZXJzIG9mIHRoZSC3cXVhbGlmaWVkIG5vZGUgc2V0tyBoYXZlCgkgICAgKiC3a2V5LXNlcXVlbmNlc7cgd2hvc2UgbWVtYmVycyBhcmUgcGFpcndpc2UgZXF1YWwsIGFzCgkgICAgKiBkZWZpbmVkIGJ5IEVxdWFsIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KCSAgICAqCgkgICAgKiBHZXQgdGhlIElEQyBiaW5kaW5nIGZyb20gdGhlIG1hdGNoZXIgYW5kIGNoZWNrIGZvcgoJICAgICogZHVwbGljYXRlIGtleS1zZXF1ZW5jZXMuCgkgICAgKi8KCSAgICBiaW5kID0geG1sU2NoZW1hSURDQXF1aXJlQmluZGluZyh2Y3R4dCwgbWF0Y2hlcik7CgkgICAgaWYgKChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpICYmIAoJCShiaW5kLT5uYk5vZGVzICE9IDApKSB7CgkJeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBja2V5LCBia2V5LCAqYmtleVNlcTsKCQkKCQlpID0gMDsKCQlyZXMgPSAwOwoJCS8qCgkJKiBDb21wYXJlIHRoZSBrZXktc2VxdWVuY2VzLCBrZXkgYnkga2V5LgoJCSovCgkJZG8gewoJCSAgICBia2V5U2VxID0gYmluZC0+bm9kZVRhYmxlW2ldLT5rZXlzOwkJICAgIAoJCSAgICBmb3IgKGogPSAwOyBqIDwgbmJLZXlzOyBqKyspIHsKCQkJY2tleSA9ICgqa2V5U2VxKVtqXTsKCQkJYmtleSA9IGJrZXlTZXFbal07CQkJCQkJCQoJCQlyZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChja2V5LT52YWwsIGJrZXktPnZhbCk7CgkJCWlmIChyZXMgPT0gLTEpIHsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9IGVsc2UgaWYgKHJlcyA9PSAwKQoJCQkgICAgYnJlYWs7CgkJICAgIH0KCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCS8qCgkJCSogRHVwbGljYXRlIGZvdW5kLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBpKys7CgkJfSB3aGlsZSAoaSA8IGJpbmQtPm5iTm9kZXMpOwoJCWlmIChpICE9IGJpbmQtPm5iTm9kZXMpIHsKCQkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCQkgICAgLyogICAKCQkgICAgKiBUT0RPOiBUcnkgdG8gcmVwb3J0IHRoZSBrZXktc2VxdWVuY2UuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsIE5VTEwsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBpZGMsCgkJCSJEdXBsaWNhdGUga2V5LXNlcXVlbmNlICVzIiwKCQkJeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UodmN0eHQsICZzdHIsCgkJCSAgICAoKmtleVNlcSksIG5iS2V5cyksIE5VTEwpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgZ290byBzZWxlY3Rvcl9sZWF2ZTsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBBZGQgYSBub2RlLXRhYmxlIGl0ZW0gdG8gdGhlIElEQyBiaW5kaW5nLgoJICAgICovCgkgICAgbnRJdGVtID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSB4bWxNYWxsb2MoCgkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlKSk7CgkgICAgaWYgKG50SXRlbSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgImFsbG9jYXRpbmcgYW4gSURDIG5vZGUtdGFibGUgaXRlbSIsIE5VTEwpOwoJCXhtbEZyZWUoKmtleVNlcSk7CgkJKmtleVNlcSA9IE5VTEw7CgkJcmV0dXJuKC0xKTsKCSAgICB9CQoJICAgIG1lbXNldChudEl0ZW0sIDAsIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZSkpOwoJICAgIAoJICAgIC8qIAoJICAgICogU3RvcmUgdGhlIG5vZGUtdGFibGUgaXRlbSBvbiBnbG9iYWwgbGlzdC4KCSAgICAqLwoJICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCQlpZiAoeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtKHZjdHh0LCBudEl0ZW0pID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQludEl0ZW0tPm5vZGVRTmFtZUlEID0gLTE7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogU2F2ZSBhIGNhY2hlZCBRTmFtZSBmb3IgdGhpcyBub2RlIG9uIHRoZSBJREMgbm9kZSwgdG8gYmUKCQkqIGFibGUgdG8gcmVwb3J0IGl0LCBldmVuIGlmIHRoZSBub2RlIGlzIG5vdCBzYXZlZC4KCQkqLwoJCW50SXRlbS0+bm9kZVFOYW1lSUQgPSB4bWxTY2hlbWFWQWRkTm9kZVFOYW1lKHZjdHh0LAoJCSAgICB2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoJCWlmIChudEl0ZW0tPm5vZGVRTmFtZUlEID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwkJICAgIAoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEluaXQgdGhlIG5vZGUtdGFibGUgaXRlbTogU2F2ZSB0aGUgbm9kZSwgcG9zaXRpb24gYW5kCgkgICAgKiBjb25zdW1lIHRoZSBrZXktc2VxdWVuY2UuCgkgICAgKi8KCSAgICBudEl0ZW0tPm5vZGUgPSB2Y3R4dC0+bm9kZTsKCSAgICBudEl0ZW0tPm5vZGVMaW5lID0gdmN0eHQtPmlub2RlLT5ub2RlTGluZTsKCSAgICBudEl0ZW0tPmtleXMgPSAqa2V5U2VxOwoJICAgICprZXlTZXEgPSBOVUxMOwoJICAgIGlmICh4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtKGJpbmQsIG50SXRlbSkgPT0gLTEpIHsJCSAgICAKCQlpZiAoaWRjLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkJICAgIC8qIAoJCSAgICAqIEZyZWUgdGhlIGl0ZW0sIHNpbmNlIGtleXJlZiBpdGVtcyB3b24ndCBiZQoJCSAgICAqIHB1dCBvbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICB4bWxGcmVlKG50SXRlbS0+a2V5cyk7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQl9CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIAoJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CnNlbGVjdG9yX2tleV9lcnJvcjoKCSAgICAvKgoJICAgICogNC4yLjEgKEtFWSkgVGhlILd0YXJnZXQgbm9kZSBzZXS3IGFuZCB0aGUgCgkgICAgKiC3cXVhbGlmaWVkIG5vZGUgc2V0tyBhcmUgZXF1YWwsIHRoYXQgaXMsIGV2ZXJ5IAoJICAgICogbWVtYmVyIG9mIHRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBpcyBhbHNvIGEgbWVtYmVyCgkgICAgKiBvZiB0aGUgt3F1YWxpZmllZCBub2RlIHNldLcgYW5kIHZpY2UgdmVyc2EuCgkgICAgKi8KCSAgICBWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX0lEQywgKHhtbFNjaGVtYVR5cGVQdHIpIGlkYywKCQkiQWxsICdrZXknIGZpZWxkcyBtdXN0IGV2YWx1YXRlIHRvIGEgbm9kZSIpOwpzZWxlY3Rvcl9sZWF2ZToKCSAgICAvKgoJICAgICogRnJlZSB0aGUga2V5LXNlcXVlbmNlIGlmIG5vdCBhZGRlZCB0byB0aGUgSURDIHRhYmxlLgoJICAgICovCgkgICAgaWYgKChrZXlTZXEgIT0gTlVMTCkgJiYgKCprZXlTZXEgIT0gTlVMTCkpIHsKCQl4bWxGcmVlKCprZXlTZXEpOwoJCSprZXlTZXEgPSBOVUxMOwoJICAgIH0KCX0gLyogaWYgc2VsZWN0b3IgKi8KCQoJc3RvLT5uYkhpc3RvcnktLTsKCmRlcmVnaXN0ZXJfY2hlY2s6CgkvKgoJKiBEZXJlZ2lzdGVyIHN0YXRlIG9iamVjdHMgaWYgdGhleSByZWFjaCB0aGUgZGVwdGggb2YgY3JlYXRpb24uCgkqLwoJaWYgKChzdG8tPm5iSGlzdG9yeSA9PSAwKSAmJiAoc3RvLT5kZXB0aCA9PSBkZXB0aCkpIHsKI2lmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIFNUTyBwb3AgJyVzJ1xuIiwKCQlzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCSAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzICE9IHN0bykgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkiLAoJCSAgICAiVGhlIHN0YXRlIG9iamVjdCB0byBiZSByZW1vdmVkIGlzIG5vdCB0aGUgZmlyc3QgIgoJCSAgICAiaW4gdGhlIGxpc3QiKTsKCSAgICB9CgkgICAgbmV4dHN0byA9IHN0by0+bmV4dDsKCSAgICAvKgoJICAgICogVW5saW5rIGZyb20gdGhlIGxpc3Qgb2YgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBzdG8tPm5leHQ7CgkgICAgc3RvLT5uZXh0ID0gdmN0eHQtPnhwYXRoU3RhdGVQb29sOwoJICAgIC8qCgkgICAgKiBMaW5rIGl0IHRvIHRoZSBwb29sIG9mIHJldXNhYmxlIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgPSBzdG87CSAgICAKCSAgICBzdG8gPSBuZXh0c3RvOwoJfSBlbHNlCgkgICAgc3RvID0gc3RvLT5uZXh0OwogICAgfSAvKiB3aGlsZSAoc3RvICE9IE5VTEwpICovCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVyczoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbURlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqCiAqIENyZWF0ZXMgaGVscGVyIG9iamVjdHMgdG8gZXZhbHVhdGUgSURDIHNlbGVjdG9ycy9maWVsZHMKICogc3VjY2Vzc2l2ZWx5LgogKgogKiBSZXR1cm5zIDAgaWYgT0sgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyLCBsYXN0ID0gTlVMTDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGMsIHJlZklkYzsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOwogICAgICAgIAogICAgaWRjID0gKHhtbFNjaGVtYUlEQ1B0cikgZWxlbURlY2wtPmlkY3M7CiAgICBpZiAoaWRjID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgCiNpZiBERUJVR19JREMKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgCgkgICAgIklEQzogUkVHSVNURVIgb24gJXMsIGRlcHRoICVkXG4iLAoJICAgIChjaGFyICopIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJCXZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lKSwgdmN0eHQtPmRlcHRoKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmlkY01hdGNoZXJzICE9IE5VTEwpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMiLAoJICAgICJUaGUgY2hhaW4gb2YgSURDIG1hdGNoZXJzIGlzIGV4cGVjdGVkIHRvIGJlIGVtcHR5Iik7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGRvIHsKCWlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCSAgICAvKgoJICAgICogU2luY2UgSURDcyBidWJibGVzIGFyZSBleHBlbnNpdmUgd2UgbmVlZCB0byBrbm93IHRoZQoJICAgICogZGVwdGggYXQgd2hpY2ggdGhlIGJ1YmJsZXMgc2hvdWxkIHN0b3A7IHRoaXMgd2lsbCBiZQoJICAgICogdGhlIGRlcHRoIG9mIHRoZSB0b3AtbW9zdCBrZXlyZWYgSURDLiBJZiBubyBrZXlyZWYKCSAgICAqIHJlZmVyZW5jZXMgYSBrZXkvdW5pcXVlIElEQywgdGhlIGJ1YmJsZURlcHRoIHdpbGwKCSAgICAqIGJlIC0xLCBpbmRpY2F0aW5nIHRoYXQgbm8gYnViYmxlcyBhcmUgbmVlZGVkLgoJICAgICovCgkgICAgcmVmSWRjID0gKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW07CgkgICAgaWYgKHJlZklkYyAhPSBOVUxMKSB7CgkJLyoKCQkqIExvb2t1cCB0aGUgYXVnbWVudGVkIElEQy4KCQkqLwoJCWFpZGMgPSB2Y3R4dC0+YWlkY3M7CgkJd2hpbGUgKGFpZGMgIT0gTlVMTCkgewoJCSAgICBpZiAoYWlkYy0+ZGVmID09IHJlZklkYykKCQkJYnJlYWs7CgkJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJCX0KCQlpZiAoYWlkYyA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMiLAoJCQkiQ291bGQgbm90IGZpbmQgYW4gYXVnbWVudGVkIElEQyBpdGVtIGZvciBhbiBJREMgIgoJCQkiZGVmaW5pdGlvbiIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCQlpZiAoKGFpZGMtPmJ1YmJsZURlcHRoID09IC0xKSB8fAoJCSAgICAodmN0eHQtPmRlcHRoIDwgYWlkYy0+YnViYmxlRGVwdGgpKQoJCSAgICBhaWRjLT5idWJibGVEZXB0aCA9IHZjdHh0LT5kZXB0aDsKCSAgICB9Cgl9CgkvKgoJKiBMb29rdXAgdGhlIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgdGhlIElEQyBkZWZpbml0aW9uLgoJKi8KCWFpZGMgPSB2Y3R4dC0+YWlkY3M7Cgl3aGlsZSAoYWlkYyAhPSBOVUxMKSB7CgkgICAgaWYgKGFpZGMtPmRlZiA9PSBpZGMpCgkJYnJlYWs7CgkgICAgYWlkYyA9IGFpZGMtPm5leHQ7Cgl9CglpZiAoYWlkYyA9PSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyIsCgkJIkNvdWxkIG5vdCBmaW5kIGFuIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgYW4gSURDIGRlZmluaXRpb24iKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIENyZWF0ZSBhbiBJREMgbWF0Y2hlciBmb3IgZXZlcnkgSURDIGRlZmluaXRpb24uCgkqLwoJbWF0Y2hlciA9ICh4bWxTY2hlbWFJRENNYXRjaGVyUHRyKSAKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ01hdGNoZXIpKTsKCWlmIChtYXRjaGVyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiYWxsb2NhdGluZyBhbiBJREMgbWF0Y2hlciIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbWVtc2V0KG1hdGNoZXIsIDAsIHNpemVvZih4bWxTY2hlbWFJRENNYXRjaGVyKSk7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgIHZjdHh0LT5pbm9kZS0+aWRjTWF0Y2hlcnMgPSBtYXRjaGVyOwoJZWxzZQoJICAgIGxhc3QtPm5leHQgPSBtYXRjaGVyOwoJbGFzdCA9IG1hdGNoZXI7CgoJbWF0Y2hlci0+dHlwZSA9IElEQ19NQVRDSEVSOwoJbWF0Y2hlci0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CQoJbWF0Y2hlci0+YWlkYyA9IGFpZGM7CiNpZiBERUJVR19JREMJCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICByZWdpc3RlciBtYXRjaGVyXG4iKTsKI2VuZGlmIAoJLyoKCSogSW5pdCB0aGUgYXV0b21hdG9uIHN0YXRlIG9iamVjdC4gCgkqLwoJaWYgKHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHZjdHh0LCBtYXRjaGVyLCAKCSAgICBpZGMtPnNlbGVjdG9yLCBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpID09IC0xKQoJICAgIHJldHVybiAoLTEpOwoKCWlkYyA9IGlkYy0+bmV4dDsKICAgIH0gd2hpbGUgKGlkYyAhPSBOVUxMKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWJibGVJRENOb2RlVGFibGVzOiAKICogQGRlcHRoOiB0aGUgY3VycmVudCB0cmVlIGRlcHRoCiAqCiAqIE1lcmdlcyBJREMgYmluZGluZ3Mgb2YgYW4gZWxlbWVudCBhdCBAZGVwdGggaW50byB0aGUgY29ycmVzcG9uZGluZyBJREMgCiAqIGJpbmRpbmdzIG9mIGl0cyBwYXJlbnQgZWxlbWVudC4gSWYgYSBkdXBsaWNhdGUgbm90ZS10YWJsZSBlbnRyeSBpcyBmb3VuZCwgCiAqIGJvdGgsIHRoZSBwYXJlbnQgbm9kZS10YWJsZSBlbnRyeSBhbmQgY2hpbGQgZW50cnkgYXJlIGRpc2NhcmRlZCBmcm9tIHRoZSAKICogbm9kZS10YWJsZSBvZiB0aGUgcGFyZW50LgogKgogKiBSZXR1cm5zIDAgaWYgT0sgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7IC8qIElEQyBiaW5kaW5ncyBvZiB0aGUgY3VycmVudCBub2RlLiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgKnBhclRhYmxlLCBwYXJCaW5kID0gTlVMTCwgbGFzdFBhckJpbmQgPSBOVUxMOyAvKiBwYXJlbnQgSURDIGJpbmRpbmdzLiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbm9kZSwgcGFyTm9kZSA9IE5VTEw7IC8qIG5vZGUtdGFibGUgZW50cmllcy4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5LCBwYXJLZXk7IC8qIGtleXMgb2YgaW4gYSBrZXktc2VxdWVuY2UuICovCiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKICAgIGludCBpLCBqLCBrLCByZXQgPSAwLCBvbGROdW0sIG5ld0R1cGxzOwogICAgaW50IGR1cGxUb3A7CgogICAgLyoKICAgICogVGhlIG5vZGUgdGFibGUgaGFzIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnM6CiAgICAqCiAgICAqICBPIC0tPiBvbGQgbm9kZS10YWJsZSBlbnRyaWVzIChmaXJzdCkKICAgICogIE8gCiAgICAqICArIC0tPiBuZXcgbm9kZS10YWJsZSBlbnRyaWVzCiAgICAqICArIAogICAgKiAgJSAtLT4gbmV3IGR1cGxpY2F0ZSBub2RlLXRhYmxlIGVudHJpZXMgICAgCiAgICAqICAlIAogICAgKiAgIyAtLT4gb2xkIGR1cGxpY2F0ZSBub2RlLXRhYmxlIGVudHJpZXMgICAgCiAgICAqICAjIChsYXN0KQogICAgKgogICAgKi8KICAgIGJpbmQgPSB2Y3R4dC0+aW5vZGUtPmlkY1RhYmxlOyAgICAgICAgCiAgICBpZiAoYmluZCA9PSBOVUxMKSB7CgkvKiBGaW5lLCBubyB0YWJsZSwgbm8gYnViYmxlcy4gKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICAKICAgIHBhclRhYmxlID0gJih2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aCAtMV0tPmlkY1RhYmxlKTsKICAgIC8qCiAgICAqIFdhbGsgYWxsIGJpbmRpbmdzOyBjcmVhdGUgbmV3IG9yIGFkZCB0byBleGlzdGluZyBiaW5kaW5ncy4KICAgICogUmVtb3ZlIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2VzLgogICAgKi8Kc3RhcnRfYmluZGluZzoKICAgIHdoaWxlIChiaW5kICE9IE5VTEwpIHsKCS8qCgkqIFNraXAga2V5cmVmIElEQ3MuCgkqLwoJaWYgKGJpbmQtPmRlZmluaXRpb24tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCSAgICBiaW5kID0gYmluZC0+bmV4dDsKCSAgICBjb250aW51ZTsKCX0KCS8qCgkqIENoZWNrIGlmIHRoZSBrZXkvdW5pcXVlIElEQyB0YWJsZSBuZWVkcyB0byBiZSBidWJibGVkLgoJKi8KCWFpZGMgPSB2Y3R4dC0+YWlkY3M7CglkbyB7CgkgICAgaWYgKGFpZGMtPmRlZiA9PSBiaW5kLT5kZWZpbml0aW9uKSB7CgkJaWYgKChhaWRjLT5idWJibGVEZXB0aCA9PSAtMSkgfHwgCgkJICAgIChhaWRjLT5idWJibGVEZXB0aCA+PSB2Y3R4dC0+ZGVwdGgpKSB7CgkJICAgIGJpbmQgPSBiaW5kLT5uZXh0OwoJCSAgICBnb3RvIHN0YXJ0X2JpbmRpbmc7CgkJfQoJCWJyZWFrOwoJICAgIH0KCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7CgoJaWYgKHBhclRhYmxlICE9IE5VTEwpCgkgICAgcGFyQmluZCA9ICpwYXJUYWJsZTsKCXdoaWxlIChwYXJCaW5kICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogU2VhcmNoIGEgbWF0Y2hpbmcgcGFyZW50IGJpbmRpbmcgZm9yIHRoZQoJICAgICogSURDIGRlZmluaXRpb24uCgkgICAgKi8KCSAgICBpZiAocGFyQmluZC0+ZGVmaW5pdGlvbiA9PSBiaW5kLT5kZWZpbml0aW9uKSB7CgoJCS8qCgkJKiBDb21wYXJlIGV2ZXJ5IG5vZGUtdGFibGUgZW50cnkgb2YgdGhlIGNoaWxkIG5vZGUsIAoJCSogaS5lLiB0aGUga2V5LXNlcXVlbmNlIHdpdGhpbiwgLi4uCgkJKi8KCQlvbGROdW0gPSBwYXJCaW5kLT5uYk5vZGVzOyAvKiBTa2lwIG5ld2x5IGFkZGVkIGl0ZW1zLiAqLwoJCWR1cGxUb3AgPSBvbGROdW0gKyBwYXJCaW5kLT5uYkR1cGxzOwoJCW5ld0R1cGxzID0gMDsKCgkJZm9yIChpID0gMDsgaSA8IGJpbmQtPm5iTm9kZXM7IGkrKykgewoJCSAgICBub2RlID0gYmluZC0+bm9kZVRhYmxlW2ldOwoJCSAgICBpZiAobm9kZSA9PSBOVUxMKQoJCQljb250aW51ZTsKCQkgICAgLyoKCQkgICAgKiAuLi53aXRoIGV2ZXJ5IGtleS1zZXF1ZW5jZSBvZiB0aGUgcGFyZW50IG5vZGUsIGFscmVhZHkKCQkgICAgKiBldmFsdWF0ZWQgdG8gYmUgYSBkdXBsaWNhdGUga2V5LXNlcXVlbmNlLgoJCSAgICAqLwoJCSAgICBpZiAocGFyQmluZC0+bmJEdXBscyAhPSAwKSB7CgkJCWogPSBiaW5kLT5uYk5vZGVzICsgbmV3RHVwbHM7IAoJCQl3aGlsZSAoaiA8IGR1cGxUb3ApIHsKCQkJICAgIHBhck5vZGUgPSBwYXJCaW5kLT5ub2RlVGFibGVbal07CgkJCSAgICBmb3IgKGsgPSAwOyBrIDwgYmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGsrKykgewoJCQkJa2V5ID0gbm9kZS0+a2V5c1trXTsKCQkJCXBhcktleSA9IHBhck5vZGUtPmtleXNba107CgkJCQlyZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXktPnZhbCwKCQkJCSAgICBwYXJLZXktPnZhbCk7CgkJCQlpZiAocmV0ID09IC0xKSB7CgkJCQkgICAgLyogVE9ETzogSW50ZXJuYWwgZXJyb3IgKi8KCQkJCSAgICByZXR1cm4oLTEpOwoJCQkJfSBlbHNlIGlmIChyZXQgPT0gMCkKCQkJCSAgICBicmVhazsKCgkJCSAgICB9CgkJCSAgICBpZiAocmV0ID09IDEpCgkJCQkvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCQlicmVhazsKCQkJICAgIGorKzsKCQkJfQoJCQlpZiAoaiAhPSBkdXBsVG9wKSB7CgkJCSAgICAvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCSAgICBjb250aW51ZTsKCQkJfQoJCSAgICB9CQkgICAgCgkJICAgIC8qCgkJICAgICogLi4uIGFuZCB3aXRoIGV2ZXJ5IGtleS1zZXF1ZW5jZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkJICAgICovCQkgICAgCQkgICAgCgkJICAgIGogPSAwOwoJCSAgICB3aGlsZSAoaiA8IG9sZE51bSkgewoJCQlwYXJOb2RlID0gcGFyQmluZC0+bm9kZVRhYmxlW2pdOwoJCQkvKgoJCQkqIENvbXBhcmUga2V5IGJ5IGtleS4gCgkJCSovCgkJCWZvciAoayA9IDA7IGsgPCBwYXJCaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaysrKSB7CgkJCSAgICBrZXkgPSBub2RlLT5rZXlzW2tdOwoJCQkgICAgcGFyS2V5ID0gcGFyTm9kZS0+a2V5c1trXTsJCQkKCgkJCSAgICByZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXktPnZhbCwKCQkJCXBhcktleS0+dmFsKTsKCQkJICAgIGlmIChyZXQgPT0gLTEpIHsKCQkJCS8qIFRPRE86IEludGVybmFsIGVycm9yICovCgkJCSAgICB9IGVsc2UgaWYgKHJldCA9PSAwKQoJCQkJYnJlYWs7CgoJCQl9CgkJCWlmIChyZXQgPT0gMSkKCQkJICAgIC8qCgkJCSAgICAqIFRoZSBrZXktc2VxdWVuY2VzIGFyZSBlcXVhbC4KCQkJICAgICovCgkJCSAgICBicmVhazsKCQkJaisrOwoJCSAgICB9CgkJICAgIGlmIChqICE9IG9sZE51bSkgewoJCQkvKgoJCQkqIEhhbmRsZSBkdXBsaWNhdGVzLgoJCQkqLwoJCQluZXdEdXBscysrOwoJCQlvbGROdW0tLTsKCQkJcGFyQmluZC0+bmJOb2Rlcy0tOwoJCQkvKgoJCQkqIE1vdmUgbGFzdCBvbGQgaXRlbSB0byBwb3Mgb2YgZHVwbGljYXRlLgoJCQkqLwoJCQlwYXJCaW5kLT5ub2RlVGFibGVbal0gPSAKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZVtvbGROdW1dOwoJCQkKCQkJaWYgKHBhckJpbmQtPm5iTm9kZXMgIT0gb2xkTnVtKSB7CgkJCSAgICAvKgoJCQkgICAgKiBJZiBuZXcgaXRlbXMgZXhpc3QsIG1vdmUgbGFzdCBuZXcgaXRlbSB0byAKCQkJICAgICogbGFzdCBvZiBvbGQgaXRlbXMuCgkJCSAgICAqLwoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW29sZE51bV0gPSAKCQkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXTsKCQkJfQoJCQkvKgoJCQkqIE1vdmUgZHVwbGljYXRlIHRvIGxhc3QgcG9zIG9mIG5ldy9vbGQgaXRlbXMuCgkJCSovCgkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXSA9IHBhck5vZGU7CQkJCgkJCQoJCSAgICB9IGVsc2UgewoJCQkvKgoJCQkqIEFkZCB0aGUgbm9kZS10YWJsZSBlbnRyeSAobm9kZSBhbmQga2V5LXNlcXVlbmNlKSBvZiAKCQkJKiB0aGUgY2hpbGQgbm9kZSB0byB0aGUgbm9kZSB0YWJsZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkJCSovCgkJCWlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewkJCQoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCQkJeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgImFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJcmV0dXJuKC0xKTsKCQkJICAgIH0KCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcyA9IDE7CgkJCX0gZWxzZSBpZiAoZHVwbFRvcCA+PSBwYXJCaW5kLT5zaXplTm9kZXMpIHsKCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcyAqPSAyOwoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCQkJeG1sUmVhbGxvYyhwYXJCaW5kLT5ub2RlVGFibGUsIHBhckJpbmQtPnNpemVOb2RlcyAqIAoJCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgInJlLWFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJcmV0dXJuKC0xKTsKCQkJICAgIH0KCQkJfQoJCQkKCQkJLyoKCQkJKiBNb3ZlIGZpcnN0IG9sZCBkdXBsaWNhdGUgdG8gbGFzdCBwb3NpdGlvbgoJCQkqIG9mIG9sZCBkdXBsaWNhdGVzICsxLgoJCQkqLwoJCQlpZiAocGFyQmluZC0+bmJEdXBscyAhPSAwKSB7CgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGVbZHVwbFRvcF0gPQoJCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXMgKyBuZXdEdXBsc107CgkJCX0KCQkJLyoKCQkJKiBNb3ZlIGZpcnN0IG5ldyBkdXBsaWNhdGUgdG8gbGFzdCBwb3NpdGlvbiBvZgoJCQkqIG5ldyBkdXBsaWNhdGVzICsxLgoJCQkqLwoJCQlpZiAobmV3RHVwbHMgIT0gMCkgewoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXMgKyBuZXdEdXBsc10gPQoJCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdOwoJCQl9CgkJCS8qCgkJCSogQXBwZW5kIHRoZSBuZXcgbm9kZS10YWJsZSBlbnRyeSB0byB0aGUgJ25ldyBub2RlLXRhYmxlCgkJCSogZW50cmllcycgc2VjdGlvbi4KCQkJKi8KCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdID0gbm9kZTsKCQkJcGFyQmluZC0+bmJOb2RlcysrOwoJCQlkdXBsVG9wKys7CgkJICAgIH0KCQl9CgkJcGFyQmluZC0+bmJEdXBscyArPSBuZXdEdXBsczsKCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBhckJpbmQtPm5leHQgPT0gTlVMTCkKCQlsYXN0UGFyQmluZCA9IHBhckJpbmQ7CgkgICAgcGFyQmluZCA9IHBhckJpbmQtPm5leHQ7Cgl9CglpZiAoKHBhckJpbmQgPT0gTlVMTCkgJiYgKGJpbmQtPm5iTm9kZXMgIT0gMCkpIHsKCSAgICAvKgoJICAgICogTm8gYmluZGluZyBmb3IgdGhlIElEQyB3YXMgZm91bmQ6IGNyZWF0ZSBhIG5ldyBvbmUgYW5kCgkgICAgKiBjb3B5IGFsbCBub2RlLXRhYmxlcy4KCSAgICAqLwoJICAgIHBhckJpbmQgPSB4bWxTY2hlbWFJRENOZXdCaW5kaW5nKGJpbmQtPmRlZmluaXRpb24pOwoJICAgIGlmIChwYXJCaW5kID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCgkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCXhtbE1hbGxvYyhiaW5kLT5uYk5vZGVzICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgImFsbG9jYXRpbmcgYW4gYXJyYXkgb2YgSURDIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCQl4bWxTY2hlbWFJRENGcmVlQmluZGluZyhwYXJCaW5kKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCSAgICBwYXJCaW5kLT5zaXplTm9kZXMgPSBiaW5kLT5uYk5vZGVzOwoJICAgIHBhckJpbmQtPm5iTm9kZXMgPSBiaW5kLT5uYk5vZGVzOwoJICAgIG1lbWNweShwYXJCaW5kLT5ub2RlVGFibGUsIGJpbmQtPm5vZGVUYWJsZSwKCQliaW5kLT5uYk5vZGVzICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkgICAgaWYgKCpwYXJUYWJsZSA9PSBOVUxMKQoJCSpwYXJUYWJsZSA9IHBhckJpbmQ7CgkgICAgZWxzZQoJCWxhc3RQYXJCaW5kLT5uZXh0ID0gcGFyQmluZDsKCX0KCWJpbmQgPSBiaW5kLT5uZXh0OwogICAgfSAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWY6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW1EZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKgogKiBDaGVjayB0aGUgY3ZjLWlkYy1rZXlyZWYgY29uc3RyYWludHMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgcmVmYmluZCwgYmluZDsKCiAgICByZWZiaW5kID0gdmN0eHQtPmlub2RlLT5pZGNUYWJsZTsKICAgIC8qCiAgICAqIEZpbmQgYSBrZXlyZWYuCiAgICAqLwogICAgd2hpbGUgKHJlZmJpbmQgIT0gTlVMTCkgewoJaWYgKHJlZmJpbmQtPmRlZmluaXRpb24tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCSAgICBpbnQgaSwgaiwgaywgcmVzOwoJICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKnJlZktleXMsICprZXlzOwoJICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgcmVmS2V5LCBrZXk7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgcmVmTm9kZSA9IE5VTEw7CgoJICAgIC8qCgkgICAgKiBGaW5kIHRoZSByZWZlcnJlZCBrZXkvdW5pcXVlLgoJICAgICovCgkgICAgYmluZCA9IHZjdHh0LT5pbm9kZS0+aWRjVGFibGU7CgkgICAgZG8gewoJCWlmICgoeG1sU2NoZW1hSURDUHRyKSByZWZiaW5kLT5kZWZpbml0aW9uLT5yZWYtPml0ZW0gPT0gCgkJICAgIGJpbmQtPmRlZmluaXRpb24pCgkJICAgIGJyZWFrOwoJCWJpbmQgPSBiaW5kLT5uZXh0OwoJICAgIH0gd2hpbGUgKGJpbmQgIT0gTlVMTCk7CgoJICAgIC8qCgkgICAgKiBTZWFyY2ggZm9yIGEgbWF0Y2hpbmcga2V5LXNlcXVlbmNlcy4KCSAgICAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCByZWZiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQlyZXMgPSAwOwoJCXJlZk5vZGUgPSByZWZiaW5kLT5ub2RlVGFibGVbaV07CgkJaWYgKGJpbmQgIT0gTlVMTCkgewoJCSAgICByZWZLZXlzID0gcmVmTm9kZS0+a2V5czsKCQkgICAgZm9yIChqID0gMDsgaiA8IGJpbmQtPm5iTm9kZXM7IGorKykgewoJCQlrZXlzID0gYmluZC0+bm9kZVRhYmxlW2pdLT5rZXlzOwoJCQlmb3IgKGsgPSAwOyBrIDwgYmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGsrKykgewoJCQkgICAgcmVmS2V5ID0gcmVmS2V5c1trXTsKCQkJICAgIGtleSA9IGtleXNba107CgkJCSAgICByZXMgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbChrZXktPnZhbCwKCQkJCXJlZktleS0+dmFsKTsKCQkJICAgIGlmIChyZXMgPT0gMCkKCQkJCWJyZWFrOwoJCQkgICAgZWxzZSBpZiAocmVzID09IC0xKSB7CgkJCQlyZXR1cm4gKC0xKTsKCQkJICAgIH0KCQkJfQoJCQlpZiAocmVzID09IDEpIHsKCQkJICAgIC8qCgkJCSAgICAqIE1hdGNoIGZvdW5kLgoJCQkgICAgKi8KCQkJICAgIGJyZWFrOwoJCQl9CgkJICAgIH0KCQl9CgkJaWYgKHJlcyA9PSAwKSB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICpzdHJCID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hS2V5cmVmRXJyKHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLCByZWZOb2RlLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgcmVmYmluZC0+ZGVmaW5pdGlvbiwKCQkJIk5vIG1hdGNoIGZvdW5kIGZvciBrZXktc2VxdWVuY2UgJXMgb2Yga2V5ICIKCQkJInJlZmVyZW5jZSAnJXMnIiwKCQkJeG1sU2NoZW1hRm9ybWF0SURDS2V5U2VxdWVuY2UodmN0eHQsICZzdHIsCgkJCSAgICByZWZiaW5kLT5ub2RlVGFibGVbaV0tPmtleXMsCgkJCSAgICByZWZiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkcyksCgkJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHJCLAoJCQkgICAgcmVmYmluZC0+ZGVmaW5pdGlvbi0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkgICAgcmVmYmluZC0+ZGVmaW5pdGlvbi0+bmFtZSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQik7CgkJfQoJICAgIH0KCX0KCXJlZmJpbmQgPSByZWZiaW5kLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVhNTCBSZWFkZXIgdmFsaWRhdGlvbiBjb2RlICAgICAgICAgICAgICAgICAgICAgICoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHhtbFNjaGVtYUF0dHJJbmZvUHRyCnhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFBdHRySW5mb1B0ciBpYXR0cjsKICAgIC8qCiAgICAqIEdyb3cvY3JlYXRlIGxpc3Qgb2YgYXR0cmlidXRlIGluZm9zLgogICAgKi8KICAgIGlmICh2Y3R4dC0+YXR0ckluZm9zID09IE5VTEwpIHsKCXZjdHh0LT5hdHRySW5mb3MgPSAoeG1sU2NoZW1hQXR0ckluZm9QdHIgKikKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJJbmZvUHRyKSk7Cgl2Y3R4dC0+c2l6ZUF0dHJJbmZvcyA9IDE7CglpZiAodmN0eHQtPmF0dHJJbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwKCQkiYWxsb2NhdGluZyBhdHRyaWJ1dGUgaW5mbyBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVBdHRySW5mb3MgPD0gdmN0eHQtPm5iQXR0ckluZm9zKSB7Cgl2Y3R4dC0+c2l6ZUF0dHJJbmZvcysrOwoJdmN0eHQtPmF0dHJJbmZvcyA9ICh4bWxTY2hlbWFBdHRySW5mb1B0ciAqKQoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmF0dHJJbmZvcywKCQl2Y3R4dC0+c2l6ZUF0dHJJbmZvcyAqIHNpemVvZih4bWxTY2hlbWFBdHRySW5mb1B0cikpOwoJaWYgKHZjdHh0LT5hdHRySW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgYXR0cmlidXRlIGluZm8gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW3ZjdHh0LT5uYkF0dHJJbmZvcysrXTsKCWlmIChpYXR0ci0+bG9jYWxOYW1lICE9IE5VTEwpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvIiwKCQkiYXR0ciBpbmZvIG5vdCBjbGVhcmVkIik7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCWlhdHRyLT5ub2RlVHlwZSA9IFhNTF9BVFRSSUJVVEVfTk9ERTsKCXJldHVybiAoaWF0dHIpOwogICAgfQogICAgLyoKICAgICogQ3JlYXRlIGFuIGF0dHJpYnV0ZSBpbmZvLgogICAgKi8KICAgIGlhdHRyID0gKHhtbFNjaGVtYUF0dHJJbmZvUHRyKQoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRySW5mbykpOwogICAgaWYgKGlhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsICJjcmVhdGluZyBuZXcgYXR0cmlidXRlIGluZm8iLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQoaWF0dHIsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRySW5mbykpOwogICAgaWF0dHItPm5vZGVUeXBlID0gWE1MX0FUVFJJQlVURV9OT0RFOwogICAgdmN0eHQtPmF0dHJJbmZvc1t2Y3R4dC0+bmJBdHRySW5mb3MrK10gPSBpYXR0cjsKCiAgICByZXR1cm4gKGlhdHRyKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sTm9kZVB0ciBhdHRyTm9kZSwKCQkJaW50IG5vZGVMaW5lLAoJCQljb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsCgkJCWNvbnN0IHhtbENoYXIgKm5zTmFtZSwJCQkKCQkJaW50IG93bmVkTmFtZXMsCgkJCXhtbENoYXIgKnZhbHVlLAoJCQlpbnQgb3duZWRWYWx1ZSkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFQdXNoQXR0cmlidXRlIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKCkiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgYXR0ci0+bm9kZSA9IGF0dHJOb2RlOwogICAgYXR0ci0+bm9kZUxpbmUgPSBub2RlTGluZTsKICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOwogICAgYXR0ci0+bG9jYWxOYW1lID0gbG9jYWxOYW1lOwogICAgYXR0ci0+bnNOYW1lID0gbnNOYW1lOwogICAgaWYgKG93bmVkTmFtZXMpCglhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX05BTUVTOwogICAgLyoKICAgICogRXZhbHVhdGUgaWYgaXQncyBhbiBYU0kgYXR0cmlidXRlLgogICAgKi8KICAgIGlmIChuc05hbWUgIT0gTlVMTCkgewoJaWYgKHhtbFN0ckVxdWFsKGxvY2FsTmFtZSwgQkFEX0NBU1QgIm5pbCIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX05JTDsJCQoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobG9jYWxOYW1lLCBCQURfQ0FTVCAidHlwZSIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1RZUEU7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCQlhdHRyLT5tZXRhVHlwZSA9IFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX1NDSEVNQV9MT0M7CgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChsb2NhbE5hbWUsIEJBRF9DQVNUICJub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIikpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnNOYW1lLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJCWF0dHItPm1ldGFUeXBlID0gWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfTk9fTlNfU0NIRU1BX0xPQzsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zTmFtZSwgeG1sTmFtZXNwYWNlTnMpKSB7CgkgICAgYXR0ci0+bWV0YVR5cGUgPSBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hNTE5TOwoJfQogICAgfQogICAgYXR0ci0+dmFsdWUgPSB2YWx1ZTsKICAgIGlmIChvd25lZFZhbHVlKQoJYXR0ci0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVM7CiAgICBpZiAoYXR0ci0+bWV0YVR5cGUgIT0gMCkKCWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NRVRBOwogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYXJFbGVtSW5mbyh4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbSkKewogICAgaWYgKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVMpIHsKCUZSRUVfQU5EX05VTEwoaWVsZW0tPmxvY2FsTmFtZSk7CglGUkVFX0FORF9OVUxMKGllbGVtLT5uc05hbWUpOwogICAgfSBlbHNlIHsKCWllbGVtLT5sb2NhbE5hbWUgPSBOVUxMOwoJaWVsZW0tPm5zTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCUZSRUVfQU5EX05VTEwoaWVsZW0tPnZhbHVlKTsKICAgIH0gZWxzZSB7CglpZWxlbS0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT52YWwgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZVZhbHVlKGllbGVtLT52YWwpOwoJaWVsZW0tPnZhbCA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPmlkY01hdGNoZXJzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdChpZWxlbS0+aWRjTWF0Y2hlcnMpOwoJaWVsZW0tPmlkY01hdGNoZXJzID0gTlVMTDsKICAgIH0KICAgIGlmIChpZWxlbS0+aWRjVGFibGUgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlKGllbGVtLT5pZGNUYWJsZSk7CglpZWxlbS0+aWRjVGFibGUgPSBOVUxMOwogICAgfQogICAgaWYgKGllbGVtLT5yZWdleEN0eHQgIT0gTlVMTCkgewoJeG1sUmVnRnJlZUV4ZWNDdHh0KGllbGVtLT5yZWdleEN0eHQpOwoJaWVsZW0tPnJlZ2V4Q3R4dCA9IE5VTEw7CiAgICB9CiAgICBpZiAoaWVsZW0tPm5zQmluZGluZ3MgIT0gTlVMTCkgewoJeG1sRnJlZSgoeG1sQ2hhciAqKilpZWxlbS0+bnNCaW5kaW5ncyk7CglpZWxlbS0+bnNCaW5kaW5ncyA9IE5VTEw7CglpZWxlbS0+bmJOc0JpbmRpbmdzID0gMDsKCWllbGVtLT5zaXplTnNCaW5kaW5ncyA9IDA7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvOgogKiBAdmN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMvcmV1c2VzIGFuZCBpbml0aWFsaXplcyB0aGUgZWxlbWVudCBpbmZvIGl0ZW0gZm9yCiAqIHRoZSBjdXJyZWN0IHRyZWUgZGVwdGguCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgaW5mbyBpdGVtIG9yIE5VTEwgb24gQVBJIG9yIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFOb2RlSW5mb1B0cgp4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5mbyA9IE5VTEw7CgogICAgaWYgKHZjdHh0LT5kZXB0aCA+IHZjdHh0LT5zaXplRWxlbUluZm9zKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvIiwKCSAgICAiaW5jb25zaXN0ZW50IGRlcHRoIGVuY291bnRlcmVkIik7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewoJdmN0eHQtPmVsZW1JbmZvcyA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0ciAqKQoJICAgIHhtbE1hbGxvYygxMCAqIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJImFsbG9jYXRpbmcgdGhlIGVsZW1lbnQgaW5mbyBhcnJheSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgltZW1zZXQodmN0eHQtPmVsZW1JbmZvcywgMCwgMTAgKiBzaXplb2YoeG1sU2NoZW1hTm9kZUluZm9QdHIpKTsKCXZjdHh0LT5zaXplRWxlbUluZm9zID0gMTA7CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5zaXplRWxlbUluZm9zIDw9IHZjdHh0LT5kZXB0aCkgewoJaW50IGkgPSB2Y3R4dC0+c2l6ZUVsZW1JbmZvczsKCgl2Y3R4dC0+c2l6ZUVsZW1JbmZvcyAqPSAyOwoJdmN0eHQtPmVsZW1JbmZvcyA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0ciAqKQoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmVsZW1JbmZvcywgdmN0eHQtPnNpemVFbGVtSW5mb3MgKgoJICAgIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJInJlLWFsbG9jYXRpbmcgdGhlIGVsZW1lbnQgaW5mbyBhcnJheSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgkvKgoJKiBXZSBuZWVkIHRoZSBuZXcgbWVtb3J5IHRvIGJlIE5VTExlZC4KCSogVE9ETzogVXNlIG1lbXNldCBpbnN0ZWFkPwoJKi8KCWZvciAoOyBpIDwgdmN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykKCSAgICB2Y3R4dC0+ZWxlbUluZm9zW2ldID0gTlVMTDsKICAgIH0gZWxzZQoJaW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKCiAgICBpZiAoaW5mbyA9PSBOVUxMKSB7CglpbmZvID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyKQoJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTm9kZUluZm8pKTsKCWlmIChpbmZvID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCSJhbGxvY2F0aW5nIGFuIGVsZW1lbnQgaW5mbyIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9Cgl2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF0gPSBpbmZvOwogICAgfSBlbHNlIHsKCWlmIChpbmZvLT5sb2NhbE5hbWUgIT0gTlVMTCkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8iLAoJCSJlbGVtIGluZm8gaGFzIG5vdCBiZWVuIGNsZWFyZWQiKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfQogICAgbWVtc2V0KGluZm8sIDAsIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mbykpOwogICAgaW5mby0+bm9kZVR5cGUgPSBYTUxfRUxFTUVOVF9OT0RFOwogICAgaW5mby0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CgogICAgcmV0dXJuIChpbmZvKTsKfQoKI2RlZmluZSBBQ1RJVkFURV9BVFRSSUJVVEUoaXRlbSkgdmN0eHQtPmlub2RlID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSBpdGVtOwojZGVmaW5lIEFDVElWQVRFX0VMRU0gdmN0eHQtPmlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwojZGVmaW5lIEFDVElWQVRFX1BBUkVOVF9FTEVNIHZjdHh0LT5pbm9kZSA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoIC0xXTsKCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJeG1sU2NoZW1hVmFsVHlwZSB2YWxUeXBlLAoJCQljb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCXhtbFNjaGVtYVZhbFB0ciB2YWwsCgkJCXVuc2lnbmVkIGxvbmcgbGVuZ3RoLAoJCQlpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldCwgZXJyb3IgPSAwOwoKICAgIHhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbms7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHVuc2lnbmVkIGxvbmcgbGVuID0gMDsKICAgIHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUgd3M7CgogICAgLyoKICAgICogSW4gTGlieG1sMiwgZGVyaXZlZCBidWlsdC1pbiB0eXBlcyBoYXZlIGN1cnJlbnRseSBubyBleHBsaWNpdCBmYWNldHMuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKQoJcmV0dXJuICgwKTsKCiAgICAvKgogICAgKiBOT1RFOiBEbyBub3QganVtcCBhd2F5LCBpZiB0aGUgZmFjZXRTZXQgb2YgdGhlIGdpdmVuIHR5cGUgaXMKICAgICogZW1wdHk6IHVudGlsIG5vdywgInBhdHRlcm4iIGFuZCAiZW51bWVyYXRpb24iIGZhY2V0cyBvZiB0aGUKICAgICogKmJhc2UgdHlwZXMqIG5lZWQgdG8gYmUgY2hlY2tlZCBhcyB3ZWxsLgogICAgKi8KICAgIGlmICh0eXBlLT5mYWNldFNldCA9PSBOVUxMKQoJZ290byBwYXR0ZXJuX2FuZF9lbnVtOwoKICAgIGlmICghIFZBUklFVFlfQVRPTUlDKHR5cGUpKSB7CglpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKQoJICAgIGdvdG8gdmFyaWV0eV9saXN0OwoJZWxzZQoJICAgIGdvdG8gcGF0dGVybl9hbmRfZW51bTsKICAgIH0KICAgIC8qCiAgICAqIFdoaXRlc3BhY2UgaGFuZGxpbmcgaXMgb25seSBvZiBpbXBvcnRhbmNlIGZvciBzdHJpbmctYmFzZWQKICAgICogdHlwZXMuCiAgICAqLwogICAgdG1wVHlwZSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHlwZSk7CiAgICBpZiAoKHRtcFR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgfHwKCUlTX0FOWV9TSU1QTEVfVFlQRSh0bXBUeXBlKSkgewoJd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKTsKICAgIH0gZWxzZQoJd3MgPSBYTUxfU0NIRU1BX1dISVRFU1BBQ0VfQ09MTEFQU0U7CiAgICAvKgogICAgKiBJZiB0aGUgdmFsdWUgd2FzIG5vdCBjb21wdXRlZCAoZm9yIHN0cmluZyBvcgogICAgKiBhbnlTaW1wbGVUeXBlIGJhc2VkIHR5cGVzKSwgdGhlbiB1c2UgdGhlIHByb3ZpZGVkCiAgICAqIHR5cGUuCiAgICAqLwogICAgaWYgKHZhbCA9PSBOVUxMKQoJdmFsVHlwZSA9IHZhbFR5cGU7CiAgICBlbHNlCgl2YWxUeXBlID0geG1sU2NoZW1hR2V0VmFsVHlwZSh2YWwpOwogICAgCiAgICByZXQgPSAwOwogICAgZm9yIChmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7CglmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCS8qCgkqIFNraXAgdGhlIHBhdHRlcm4gIndoaXRlU3BhY2UiOiBpdCBpcyB1c2VkIHRvCgkqIGZvcm1hdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgYmVmb3JlaGFuZC4KCSovCglzd2l0Y2ggKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJY29udGludWU7CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMZW5ndGhGYWNldFdodHNwKGZhY2V0TGluay0+ZmFjZXQsCgkJICAgIHZhbFR5cGUsIHZhbHVlLCB2YWwsICZsZW4sIHdzKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRXaHRzcChmYWNldExpbmstPmZhY2V0LCB3cywKCQkgICAgdmFsVHlwZSwgdmFsdWUsIHZhbCwgd3MpOwoJCWJyZWFrOwoJfQoJaWYgKHJldCA8IDApIHsKCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJInZhbGlkYXRpbmcgYWdhaW5zdCBhIGF0b21pYyB0eXBlIGZhY2V0Iik7CgkgICAgcmV0dXJuICgtMSk7Cgl9IGVsc2UgaWYgKHJldCA+IDApIHsKCSAgICBpZiAoZmlyZUVycm9ycykKCQl4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCXZhbHVlLCBsZW4sIHR5cGUsIGZhY2V0TGluay0+ZmFjZXQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIGVsc2UKCQlyZXR1cm4gKHJldCk7CgkgICAgaWYgKGVycm9yID09IDApCgkJZXJyb3IgPSByZXQ7Cgl9CglyZXQgPSAwOwogICAgfQoKdmFyaWV0eV9saXN0OgogICAgaWYgKCEgVkFSSUVUWV9MSVNUKHR5cGUpKQoJZ290byBwYXR0ZXJuX2FuZF9lbnVtOwogICAgLyoKICAgICogImxlbmd0aCIsICJtaW5MZW5ndGgiIGFuZCAibWF4TGVuZ3RoIiBvZiBsaXN0IHR5cGVzLgogICAgKi8KICAgIHJldCA9IDA7CiAgICBmb3IgKGZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCglzd2l0Y2ggKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoJCSAgICAKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxpc3RTaW1wbGVUeXBlRmFjZXQoZmFjZXRMaW5rLT5mYWNldCwKCQkgICAgdmFsdWUsIGxlbmd0aCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQljb250aW51ZTsKCX0KCWlmIChyZXQgPCAwKSB7CgkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVGYWNldHMiLAoJCSJ2YWxpZGF0aW5nIGFnYWluc3QgYSBsaXN0IHR5cGUgZmFjZXQiKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewoJICAgIGlmIChmaXJlRXJyb3JzKQkJCgkJeG1sU2NoZW1hRmFjZXRFcnIoYWN0eHQsIHJldCwgbm9kZSwKCQl2YWx1ZSwgbGVuZ3RoLCB0eXBlLCBmYWNldExpbmstPmZhY2V0LCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICBlbHNlCgkJcmV0dXJuIChyZXQpOwoJICAgIGlmIChlcnJvciA9PSAwKQoJCWVycm9yID0gcmV0OwoJfQoJcmV0ID0gMDsKICAgIH0KCnBhdHRlcm5fYW5kX2VudW06CiAgICBpZiAoZXJyb3IgPj0gMCkgewoJaW50IGZvdW5kID0gMDsKCS8qCgkqIFByb2Nlc3MgZW51bWVyYXRpb25zLiBGYWNldCB2YWx1ZXMgYXJlIGluIHRoZSB2YWx1ZSBzcGFjZQoJKiBvZiB0aGUgZGVmaW5pbmcgdHlwZSdzIGJhc2UgdHlwZS4gVGhpcyBzZWVtcyB0byBiZSBhIGJ1ZyBpbiB0aGUKCSogWE1MIFNjaGVtYSAxLjAgc3BlYy4gVXNlIHRoZSB3aGl0ZXNwYWNlIHR5cGUgb2YgdGhlIGJhc2UgdHlwZS4KCSogT25seSB0aGUgZmlyc3Qgc2V0IG9mIGVudW1lcmF0aW9ucyBpbiB0aGUgYW5jZXN0b3Itb3Itc2VsZiBheGlzCgkqIGlzIHVzZWQgZm9yIHZhbGlkYXRpb24uCgkqLwoJcmV0ID0gMDsKCXRtcFR5cGUgPSB0eXBlOwoJZG8gewoJICAgIGZvciAoZmFjZXQgPSB0bXBUeXBlLT5mYWNldHM7IGZhY2V0ICE9IE5VTEw7IGZhY2V0ID0gZmFjZXQtPm5leHQpIHsKCQlpZiAoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikKCQkgICAgY29udGludWU7CgkJZm91bmQgPSAxOwoJCXJldCA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGZhY2V0LT52YWwsIHZhbCk7CgkJaWYgKHJldCA9PSAxKQoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzIiwKCQkJInZhbGlkYXRpbmcgYWdhaW5zdCBhbiBlbnVtZXJhdGlvbiBmYWNldCIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIGlmIChyZXQgIT0gMCkKCQlicmVhazsKCSAgICB0bXBUeXBlID0gdG1wVHlwZS0+YmFzZVR5cGU7Cgl9IHdoaWxlICgodG1wVHlwZSAhPSBOVUxMKSAmJgoJICAgICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJaWYgKGZvdW5kICYmIChyZXQgPT0gMCkpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQ7CgkgICAgaWYgKGZpcmVFcnJvcnMpIHsKCQl4bWxTY2hlbWFGYWNldEVycihhY3R4dCwgcmV0LCBub2RlLAoJCSAgICB2YWx1ZSwgMCwgdHlwZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuIChyZXQpOwoJICAgIGlmIChlcnJvciA9PSAwKQoJCWVycm9yID0gcmV0OwoJfQogICAgfQoKICAgIGlmIChlcnJvciA+PSAwKSB7CglpbnQgZm91bmQ7CgkvKgoJKiBQcm9jZXNzIHBhdHRlcnMuIFBhdHRlcm4gZmFjZXRzIGFyZSBPUmVkIGF0IHR5cGUgbGV2ZWwKCSogYW5kIEFORGVkIGlmIGRlcml2ZWQuIFdhbGsgdGhlIGJhc2UgdHlwZSBheGlzLgoJKi8KCXRtcFR5cGUgPSB0eXBlOwoJZmFjZXQgPSBOVUxMOwoJZG8gewoJICAgIGZvdW5kID0gMDsKCSAgICBmb3IgKGZhY2V0TGluayA9IHRtcFR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsKCQlmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCQlpZiAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pCgkJICAgIGNvbnRpbnVlOwoJCWZvdW5kID0gMTsKCQkvKiAKCQkqIE5PVEUgdGhhdCBmb3IgcGF0dGVybnMsIEB2YWx1ZSBuZWVkcyB0byBiZSB0aGUKCQkqIG5vcm1hbGl6ZWQgdmF1bGUuCgkJKi8KCQlyZXQgPSB4bWxSZWdleHBFeGVjKGZhY2V0TGluay0+ZmFjZXQtPnJlZ2V4cCwgdmFsdWUpOwoJCWlmIChyZXQgPT0gMSkKCQkgICAgYnJlYWs7CgkJZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyIsCgkJCSJ2YWxpZGF0aW5nIGFnYWluc3QgYSBwYXR0ZXJuIGZhY2V0Iik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0gZWxzZSB7CgkJICAgIC8qIAoJCSAgICAqIFNhdmUgdGhlIGxhc3Qgbm9uLXZhbGlkYXRpbmcgZmFjZXQuCgkJICAgICovCgkJICAgIGZhY2V0ID0gZmFjZXRMaW5rLT5mYWNldDsKCQl9CgkgICAgfQoJICAgIGlmIChmb3VuZCAmJiAocmV0ICE9IDEpKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1BBVFRFUk5fVkFMSUQ7CgkJaWYgKGZpcmVFcnJvcnMpIHsKCQkgICAgeG1sU2NoZW1hRmFjZXRFcnIoYWN0eHQsIHJldCwgbm9kZSwKCQkJdmFsdWUsIDAsIHR5cGUsIGZhY2V0LCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9IGVsc2UKCQkgICAgcmV0dXJuIChyZXQpOwoJCWlmIChlcnJvciA9PSAwKQoJCSAgICBlcnJvciA9IHJldDsKCQlicmVhazsKCSAgICB9CgkgICAgdG1wVHlwZSA9IHRtcFR5cGUtPmJhc2VUeXBlOwoJfSB3aGlsZSAoKHRtcFR5cGUgIT0gTlVMTCkgJiYgKHRtcFR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSk7CiAgICB9CgogICAgcmV0dXJuIChlcnJvcik7Cn0KIApzdGF0aWMgeG1sQ2hhciAqCnhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUpCnsKICAgIHN3aXRjaCAoeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSkpIHsJCgljYXNlIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9DT0xMQVBTRToKCSAgICByZXR1cm4gKHhtbFNjaGVtYUNvbGxhcHNlU3RyaW5nKHZhbHVlKSk7CgljYXNlIFhNTF9TQ0hFTUFfV0hJVEVTUEFDRV9SRVBMQUNFOgoJICAgIHJldHVybiAoeG1sU2NoZW1hV2hpdGVTcGFjZVJlcGxhY2UodmFsdWUpKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KfQoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVFOYW1lKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsLAoJCSAgICAgICBpbnQgdmFsTmVlZGVkKQp7CiAgICBpbnQgcmV0OwogICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lOwogICAgeG1sQ2hhciAqbG9jYWwsICpwcmVmaXggPSBOVUxMOwogICAgCiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKHJldCA9PSAtMSkgewoJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlUU5hbWUiLAoJCSJjYWxsaW5nIHhtbFZhbGlkYXRlUU5hbWUoKSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJcmV0dXJuKCBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEpOwogICAgfQogICAgLyoKICAgICogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCBhbHdheXMgcmV0dXJuIGEgZHVwbGljYXRlZAogICAgKiBzdHJpbmdzLgogICAgKi8KICAgIGxvY2FsID0geG1sU3BsaXRRTmFtZTIodmFsdWUsICZwcmVmaXgpOwogICAgaWYgKGxvY2FsID09IE5VTEwpCglsb2NhbCA9IHhtbFN0cmR1cCh2YWx1ZSk7CiAgICAvKgogICAgKiBPUFRJTUlaRSBUT0RPOiBVc2UgZmxhZ3MgZm9yOgogICAgKiAgLSBpcyB0aGVyZSBhbnkgbmFtZXNwYWNlIGJpbmRpbmc/CiAgICAqICAtIGlzIHRoZXJlIGEgZGVmYXVsdCBuYW1lc3BhY2U/CiAgICAqLwogICAgbnNOYW1lID0geG1sU2NoZW1hTG9va3VwTmFtZXNwYWNlKHZjdHh0LCBwcmVmaXgpOwogICAgCiAgICBpZiAocHJlZml4ICE9IE5VTEwpIHsKCXhtbEZyZWUocHJlZml4KTsKCS8qCgkqIEEgbmFtZXNwYWNlIG11c3QgYmUgZm91bmQgaWYgdGhlIHByZWZpeCBpcwoJKiBOT1QgTlVMTC4KCSovCglpZiAobnNOYW1lID09IE5VTEwpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCByZXQsIE5VTEwsCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSJUaGUgUU5hbWUgdmFsdWUgJyVzJyBoYXMgbm8gIgoJCSJjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBpbiAiCgkJInNjb3BlIiwgdmFsdWUsIE5VTEwpOwoJICAgIGlmIChsb2NhbCAhPSBOVUxMKQoJCXhtbEZyZWUobG9jYWwpOwoJICAgIHJldHVybiAocmV0KTsKCX0KICAgIH0KICAgIGlmICh2YWxOZWVkZWQgJiYgdmFsKSB7CglpZiAobnNOYW1lICE9IE5VTEwpCgkgICAgKnZhbCA9IHhtbFNjaGVtYU5ld1FOYW1lVmFsdWUoCgkJQkFEX0NBU1QgeG1sU3RyZHVwKG5zTmFtZSksIEJBRF9DQVNUIGxvY2FsKTsKCWVsc2UKCSAgICAqdmFsID0geG1sU2NoZW1hTmV3UU5hbWVWYWx1ZShOVUxMLAoJCUJBRF9DQVNUIGxvY2FsKTsKICAgIH0gZWxzZQoJeG1sRnJlZShsb2NhbCk7CiAgICByZXR1cm4gKDApOwp9CgovKgoqIGN2Yy1zaW1wbGUtdHlwZQoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyIGFjdHh0LAoJCQkgICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgeG1sU2NoZW1hVmFsUHRyICpyZXRWYWwsCgkJCSAgICAgaW50IGZpcmVFcnJvcnMsCgkJCSAgICAgaW50IG5vcm1hbGl6ZSwKCQkJICAgICBpbnQgaXNOb3JtYWxpemVkKQp7CiAgICBpbnQgcmV0ID0gMCwgdmFsTmVlZGVkID0gKHJldFZhbCkgPyAxIDogMDsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWwgPSBOVUxMOwogICAgeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSB3czsKICAgIHhtbENoYXIgKm5vcm1WYWx1ZSA9IE5VTEw7CgojZGVmaW5lIE5PUk1BTElaRShhdHlwZSkgXAogICAgaWYgKCghIGlzTm9ybWFsaXplZCkgJiYgXAogICAgKG5vcm1hbGl6ZSB8fCAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRCkpKSB7IFwKCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKGF0eXBlLCB2YWx1ZSk7IFwKCWlmIChub3JtVmFsdWUgIT0gTlVMTCkgXAoJICAgIHZhbHVlID0gbm9ybVZhbHVlOyBcCglpc05vcm1hbGl6ZWQgPSAxOyBcCiAgICB9CiAgICAKICAgIGlmICgocmV0VmFsICE9IE5VTEwpICYmICgqcmV0VmFsICE9IE5VTEwpKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUoKnJldFZhbCk7CgkqcmV0VmFsID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIDMuMTQuNCBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKICAgICogVmFsaWRhdGlvbiBSdWxlOiBTdHJpbmcgVmFsaWQKICAgICovCiAgICAvKgogICAgKiAxIEl0IGlzIHNjaGVtYS12YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQKICAgICogYnkgRGF0YXR5cGUgVmFsaWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgogICAgKi8KICAgIC8qCiAgICAqIDIuMSBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVFkgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRZIGdpdmVuCiAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgdGhlbgogICAgKiB0aGUgc3RyaW5nIG11c3QgYmUgYSC3ZGVjbGFyZWQgZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMiBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVElFUyBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVElFUwogICAgKiBnaXZlbiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNiksCiAgICAqIHRoZW4gZXZlcnkgd2hpdGVzcGFjZS1kZWxpbWl0ZWQgc3Vic3RyaW5nIG9mIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZAogICAgKiBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4zIG90aGVyd2lzZSBubyBmdXJ0aGVyIGNvbmRpdGlvbiBhcHBsaWVzLgogICAgKi8KICAgIGlmICgoISB2YWxOZWVkZWQpICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFKSkKCXZhbE5lZWRlZCA9IDE7CiAgICBpZiAodmFsdWUgPT0gTlVMTCkKCXZhbHVlID0gQkFEX0NBU1QgIiI7CiAgICBpZiAoSVNfQU5ZX1NJTVBMRV9UWVBFKHR5cGUpIHx8IFZBUklFVFlfQVRPTUlDKHR5cGUpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGJpVHlwZTsgLyogVGhlIGJ1aWx0LWluIHR5cGUuICovCgkvKgoJKiBTUEVDICgxLjIuMSkgImlmIHt2YXJpZXR5fSBpcyC3YXRvbWljtyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3CgkqIGEgbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0iCgkqLwoJLyoKCSogV2hpdGVzcGFjZS1ub3JtYWxpemUuCgkqLwoJTk9STUFMSVpFKHR5cGUpOwoJaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkgICAgLyoKCSAgICAqIEdldCB0aGUgYnVpbHQtaW4gdHlwZS4KCSAgICAqLwoJICAgIGJpVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIHdoaWxlICgoYmlUeXBlICE9IE5VTEwpICYmCgkJKGJpVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJCWJpVHlwZSA9IGJpVHlwZS0+YmFzZVR5cGU7CgoJICAgIGlmIChiaVR5cGUgPT0gTlVMTCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAiY291bGQgbm90IGdldCB0aGUgYnVpbHQtaW4gdHlwZSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJfSBlbHNlCgkgICAgYmlUeXBlID0gdHlwZTsKCS8qCgkqIE5PVEFUSU9OcyBuZWVkIHRvIGJlIHByb2Nlc3NlZCBoZXJlLCBzaW5jZSB0aGV5IG5lZWQKCSogdG8gbG9va3VwIGluIHRoZSBoYXNodGFibGUgb2YgTk9UQVRJT04gZGVjbGFyYXRpb25zIG9mIHRoZSBzY2hlbWEuCgkqLwoJaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9WQUxJREFUT1IpIHsJICAgIAoJICAgIHN3aXRjaCAoYmlUeXBlLT5idWlsdEluVHlwZSkgewkJCgkJY2FzZSBYTUxfU0NIRU1BU19OT1RBVElPTjoJCSAgICAKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbigKCQkJKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQsCgkJCSgoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBhY3R4dCktPnNjaGVtYSwKCQkJTlVMTCwgdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQVNfUU5BTUU6CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlUU5hbWUoKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgYWN0eHQsCgkJCXZhbHVlLCAmdmFsLCB2YWxOZWVkZWQpOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICB3cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwoJCSAgICBpZiAodmFsTmVlZGVkKQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgJnZhbCwgTlVMTCk7CgkJICAgIGVsc2UKCQkJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGVOb05vcm0oYmlUeXBlLAoJCQkgICAgdmFsdWUsIE5VTEwsIE5VTEwpOwoJCSAgICBicmVhazsKCSAgICB9Cgl9IGVsc2UgaWYgKGFjdHh0LT50eXBlID09IFhNTF9TQ0hFTUFfQ1RYVF9QQVJTRVIpIHsJICAgIAoJICAgIHN3aXRjaCAoYmlUeXBlLT5idWlsdEluVHlwZSkgewkJICAgIAoJCWNhc2UgWE1MX1NDSEVNQVNfTk9UQVRJT046CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24oTlVMTCwKCQkJKCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSBhY3R4dCktPnNjaGVtYSwgbm9kZSwKCQkJdmFsdWUsICZ2YWwsIHZhbE5lZWRlZCk7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSk7CgkJICAgIGlmICh2YWxOZWVkZWQpCgkJCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKGJpVHlwZSwKCQkJICAgIHZhbHVlLCAmdmFsLCBub2RlKTsKCQkgICAgZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybShiaVR5cGUsCgkJCSAgICB2YWx1ZSwgTlVMTCwgbm9kZSk7CgkJICAgIGJyZWFrOwoJICAgIH0JICAgCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBWYWxpZGF0aW9uIHZpYSBhIHB1YmxpYyBBUEkgaXMgbm90IGltcGxlbWVudGVkIHlldC4KCSAgICAqLwoJICAgIFRPRE8KCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJaWYgKHJldCAhPSAwKSB7CgkgICAgaWYgKHJldCA8IDApIHsKCQlBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkgICAgInZhbGlkYXRpbmcgYWdhaW5zdCBhIGJ1aWx0LWluIHR5cGUiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBpZiAoVkFSSUVUWV9MSVNUKHR5cGUpKQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCSAgICBlbHNlCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwkgICAgCgl9CglpZiAoKHJldCA9PSAwKSAmJiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0hBU19GQUNFVFMpKSB7CgkgICAgLyoKCSAgICAqIENoZWNrIGZhY2V0cy4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKGFjdHh0LCBub2RlLCB0eXBlLAoJCSh4bWxTY2hlbWFWYWxUeXBlKSBiaVR5cGUtPmJ1aWx0SW5UeXBlLCB2YWx1ZSwgdmFsLAoJCTAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIEFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCQkidmFsaWRhdGluZyBmYWNldHMgb2YgYXRvbWljIHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWlmIChWQVJJRVRZX0xJU1QodHlwZSkpIAoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJZWxzZQoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CQkKCSAgICB9Cgl9CglpZiAoZmlyZUVycm9ycyAmJiAocmV0ID4gMCkpCgkgICAgeG1sU2NoZW1hU2ltcGxlVHlwZUVycihhY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSwgMSk7CiAgICB9IGVsc2UgaWYgKFZBUklFVFlfTElTVCh0eXBlKSkgewoKCXhtbFNjaGVtYVR5cGVQdHIgaXRlbVR5cGU7Cgljb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXBWYWx1ZSA9IE5VTEw7Cgl1bnNpZ25lZCBsb25nIGxlbiA9IDA7Cgl4bWxTY2hlbWFWYWxQdHIgcHJldlZhbCA9IE5VTEwsIGN1clZhbCA9IE5VTEw7CgkvKiAxLjIuMiBpZiB7dmFyaWV0eX0gaXMgt2xpc3S3IHRoZW4gdGhlIHN0cmluZyBtdXN0IGJlIGEgc2VxdWVuY2UKCSogb2Ygd2hpdGUgc3BhY2Ugc2VwYXJhdGVkIHRva2VucywgZWFjaCBvZiB3aGljaCC3bWF0Y2i3ZXMgYSBsaXRlcmFsCgkqIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2l0ZW0gdHlwZSBkZWZpbml0aW9ufQoJKi8KCS8qCgkqIE5vdGUgdGhhdCBYTUxfU0NIRU1BU19UWVBFX05PUk1WQUxVRU5FRURFRCB3aWxsIGJlIHNldCBpZgoJKiB0aGUgbGlzdCB0eXBlIGhhcyBhbiBlbnVtIG9yIHBhdHRlcm4gZmFjZXQuCgkqLwoJTk9STUFMSVpFKHR5cGUpOwoJLyoKCSogVkFMIFRPRE86IE9wdGltaXplIHZhbGlkYXRpb24gb2YgZW1wdHkgdmFsdWVzLgoJKiBWQUwgVE9ETzogV2UgZG8gbm90IGhhdmUgY29tcHV0ZWQgdmFsdWVzIGZvciBsaXN0cy4KCSovCglpdGVtVHlwZSA9IEdFVF9MSVNUX0lURU1fVFlQRSh0eXBlKTsJCgljdXIgPSB2YWx1ZTsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcFZhbHVlID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgbGVuKys7CgoJICAgIGlmICh2YWxOZWVkZWQpCgkJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShhY3R4dCwgbm9kZSwgaXRlbVR5cGUsCgkJICAgIHRtcFZhbHVlLCAmY3VyVmFsLCBmaXJlRXJyb3JzLCAwLCAxKTsKCSAgICBlbHNlCgkJcmV0ID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZShhY3R4dCwgbm9kZSwgaXRlbVR5cGUsCgkJICAgIHRtcFZhbHVlLCBOVUxMLCBmaXJlRXJyb3JzLCAwLCAxKTsKCSAgICBGUkVFX0FORF9OVUxMKHRtcFZhbHVlKTsKCSAgICBpZiAoY3VyVmFsICE9IE5VTEwpIHsKCQkvKgoJCSogQWRkIHRvIGxpc3Qgb2YgY29tcHV0ZWQgdmFsdWVzLgoJCSovCgkJaWYgKHZhbCA9PSBOVUxMKQoJCSAgICB2YWwgPSBjdXJWYWw7CgkJZWxzZQoJCSAgICB4bWxTY2hlbWFWYWx1ZUFwcGVuZChwcmV2VmFsLCBjdXJWYWwpOwoJCXByZXZWYWwgPSBjdXJWYWw7CgkJY3VyVmFsID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgQUVSUk9SX0lOVCgieG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSIsCgkJCSJ2YWxpZGF0aW5nIGFuIGl0ZW0gb2YgbGlzdCBzaW1wbGUgdHlwZSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJYnJlYWs7CgkgICAgfQkgICAgCgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsKCUZSRUVfQU5EX05VTEwodG1wVmFsdWUpOwoJaWYgKChyZXQgPT0gMCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTKSkgewoJICAgIC8qCgkgICAgKiBBcHBseSBmYWNldHMgKHBhdHRlcm4sIGVudW1lcmF0aW9uKS4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzKGFjdHh0LCBub2RlLCB0eXBlLAoJCVhNTF9TQ0hFTUFTX1VOS05PV04sIHZhbHVlLCB2YWwsCgkJbGVuLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgZmFjZXRzIG9mIGxpc3Qgc2ltcGxlIHR5cGUiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJICAgIH0KCX0KCWlmIChmaXJlRXJyb3JzICYmIChyZXQgPiAwKSkgewoJICAgIC8qIAoJICAgICogUmVwb3J0IHRoZSBub3JtYWxpemVkIHZhbHVlLgoJICAgICovCgkgICAgbm9ybWFsaXplID0gMTsKCSAgICBOT1JNQUxJWkUodHlwZSk7CgkgICAgeG1sU2NoZW1hU2ltcGxlVHlwZUVycihhY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSwgMSk7Cgl9CiAgICB9IGVsc2UgaWYgKFZBUklFVFlfVU5JT04odHlwZSkpIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlckxpbms7CgkvKgoJKiBUT0RPOiBGb3IgYWxsIGRhdGF0eXBlcyC3ZGVyaXZlZLcgYnkgt3VuaW9utyAgd2hpdGVTcGFjZSBkb2VzCgkqIG5vdCBhcHBseSBkaXJlY3RseTsgaG93ZXZlciwgdGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utwoJKiB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZQoJKiC3bWVtYmVyVHlwZXO3IGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4KCSoKCSogVGhpcyBtZWFucyB0aGF0IHRoZSB2YWx1ZSBpcyBub3JtYWxpemVkIGJ5IHRoZSBmaXJzdCB2YWxpZGF0aW5nCgkqIG1lbWJlciB0eXBlLCB0aGVuIHRoZSBmYWNldHMgb2YgdGhlIHVuaW9uIHR5cGUgYXJlIGFwcGxpZWQuIFRoaXMKCSogbmVlZHMgY2hhbmdpbmcgb2YgdGhlIHZhbHVlIQoJKi8KCgkvKgoJKiAxLjIuMyBpZiB7dmFyaWV0eX0gaXMgt3VuaW9utyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IGEKCSogbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIGF0IGxlYXN0IG9uZSBtZW1iZXIgb2YKCSoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfQoJKi8KCW1lbWJlckxpbmsgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlKTsKCWlmIChtZW1iZXJMaW5rID09IE5VTEwpIHsKCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkidW5pb24gc2ltcGxlIHR5cGUgaGFzIG5vIG1lbWJlciB0eXBlcyIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CQoJLyoKCSogQWx3YXlzIG5vcm1hbGl6ZSB1bmlvbiB0eXBlIHZhbHVlcywgc2luY2Ugd2UgY3VycmVudGx5CgkqIGNhbm5vdCBzdG9yZSB0aGUgd2hpdGVzcGFjZSBpbmZvcm1hdGlvbiB3aXRoIHRoZSB2YWx1ZQoJKiBpdHNlbGY7IG90aGVyd2lzZSBhIGxhdGVyIHZhbHVlLWNvbXBhcmlzb24gd291bGQgYmUKCSogbm90IHBvc3NpYmxlLgoJKi8KCXdoaWxlIChtZW1iZXJMaW5rICE9IE5VTEwpIHsKCSAgICBpZiAodmFsTmVlZGVkKSAKCQlyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKGFjdHh0LCBub2RlLAoJCSAgICBtZW1iZXJMaW5rLT50eXBlLCB2YWx1ZSwgJnZhbCwgMCwgMSwgMCk7CgkgICAgZWxzZQoJCXJldCA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoYWN0eHQsIG5vZGUsCgkJICAgIG1lbWJlckxpbmstPnR5cGUsIHZhbHVlLCBOVUxMLCAwLCAxLCAwKTsKCSAgICBpZiAocmV0IDw9IDApCgkJYnJlYWs7CgkgICAgbWVtYmVyTGluayA9IG1lbWJlckxpbmstPm5leHQ7Cgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCUFFUlJPUl9JTlQoInhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUiLAoJCSAgICAidmFsaWRhdGluZyBtZW1iZXJzIG9mIHVuaW9uIHNpbXBsZSB0eXBlIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJfQoJLyoKCSogQXBwbHkgZmFjZXRzIChwYXR0ZXJuLCBlbnVtZXJhdGlvbikuCgkqLwoJaWYgKChyZXQgPT0gMCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9IQVNfRkFDRVRTKSkgewoJICAgIC8qCgkgICAgKiBUaGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkKCSAgICAqIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZSC3bWVtYmVyVHlwZXO3CgkgICAgKiBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuCgkgICAgKi8KCSAgICBOT1JNQUxJWkUobWVtYmVyTGluay0+dHlwZSk7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoYWN0eHQsIG5vZGUsIHR5cGUsCgkJWE1MX1NDSEVNQVNfVU5LTk9XTiwgdmFsdWUsIHZhbCwKCQkwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBBRVJST1JfSU5UKCJ4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlIiwKCQkJInZhbGlkYXRpbmcgZmFjZXRzIG9mIHVuaW9uIHNpbXBsZSB0eXBlIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsJCQoJICAgIH0KCX0KCWlmIChmaXJlRXJyb3JzICYmIChyZXQgPiAwKSkKCSAgICB4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKGFjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlLCAxKTsKICAgIH0KCiAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKG5vcm1WYWx1ZSk7CiAgICBpZiAocmV0ID09IDApIHsKCWlmIChyZXRWYWwgIT0gTlVMTCkKCSAgICAqcmV0VmFsID0gdmFsOwoJZWxzZSBpZiAodmFsICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICB9IGVsc2UgaWYgKHZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZShub3JtVmFsdWUpOwogICAgaWYgKHZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKHZhbCk7CiAgICByZXR1cm4gKC0xKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFWRXhwYW5kUU5hbWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqKm5zTmFtZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsTmFtZSkKewogICAgaW50IHJldCA9IDA7CgogICAgaWYgKChuc05hbWUgPT0gTlVMTCkgfHwgKGxvY2FsTmFtZSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgKm5zTmFtZSA9IE5VTEw7CiAgICAqbG9jYWxOYW1lID0gTlVMTDsKCiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gLTEpCglyZXR1cm4gKC0xKTsKICAgIGlmIChyZXQgPiAwKSB7Cgl4bWxTY2hlbWFTaW1wbGVUeXBlRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwgTlVMTCwKCSAgICB2YWx1ZSwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCAxKTsKCXJldHVybiAoMSk7CiAgICB9CiAgICB7Cgl4bWxDaGFyICpsb2NhbCA9IE5VTEw7Cgl4bWxDaGFyICpwcmVmaXg7CgoJLyoKCSogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCByZXR1cm4gYSBkdXBsaWNhdGVkCgkqIHN0cmluZy4KCSovCglsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChsb2NhbCA9PSBOVUxMKQoJICAgICpsb2NhbE5hbWUgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5kaWN0LCB2YWx1ZSwgLTEpOwoJZWxzZSB7CgkgICAgKmxvY2FsTmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPmRpY3QsIGxvY2FsLCAtMSk7CgkgICAgeG1sRnJlZShsb2NhbCk7Cgl9CgoJKm5zTmFtZSA9IHhtbFNjaGVtYUxvb2t1cE5hbWVzcGFjZSh2Y3R4dCwgcHJlZml4KTsKCglpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxGcmVlKHByZWZpeCk7CgkgICAgLyoKCSAgICAqIEEgbmFtZXNwYWNlIG11c3QgYmUgZm91bmQgaWYgdGhlIHByZWZpeCBpcyBOT1QgTlVMTC4KCSAgICAqLwoJICAgIGlmICgqbnNOYW1lID09IE5VTEwpIHsKCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwgTlVMTCwKCQkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSAgICAiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vICIKCQkgICAgImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHNjb3BlIiwKCQkgICAgdmFsdWUsIE5VTEwpOwoJCXJldHVybiAoMik7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyLAoJCQl4bWxTY2hlbWFUeXBlUHRyICpsb2NhbFR5cGUsCgkJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIGludCByZXQgPSAwOwogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogKDQpCiAgICAqIEFORAogICAgKiBTY2hlbWEtVmFsaWRpdHkgQXNzZXNzbWVudCAoRWxlbWVudCkgKGN2Yy1hc3Nlc3MtZWx0KQogICAgKiAgICgxLjIuMS4yLjEpIC0gKDEuMi4xLjIuNCkKICAgICogSGFuZGxlICd4c2k6dHlwZScuCiAgICAqLwogICAgaWYgKGxvY2FsVHlwZSA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAqbG9jYWxUeXBlID0gTlVMTDsKICAgIGlmIChpYXR0ciA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGVsc2UgewoJY29uc3QgeG1sQ2hhciAqbnNOYW1lID0gTlVMTCwgKmxvY2FsID0gTlVMTDsKCS8qCgkqIFRPRE86IFdlIHNob3VsZCByZXBvcnQgYSAqd2FybmluZyogdGhhdCB0aGUgdHlwZSB3YXMgb3ZlcnJpZGVuCgkqIGJ5IHRoZSBpbnN0YW5jZS4KCSovCglBQ1RJVkFURV9BVFRSSUJVVEUoaWF0dHIpOwoJLyoKCSogKGN2Yy1lbHQpICgzLjMuNCkgOiAoNC4xKQoJKiAoY3ZjLWFzc2Vzcy1lbHQpICgxLjIuMS4yLjIpCgkqLwoJcmV0ID0geG1sU2NoZW1hVkV4cGFuZFFOYW1lKHZjdHh0LCBpYXR0ci0+dmFsdWUsCgkgICAgJm5zTmFtZSwgJmxvY2FsKTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVFOYW1lRXhwYW5kKCkgdG8gdmFsaWRhdGUgdGhlICIKCQkgICAgImF0dHJpYnV0ZSAneHNpOnR5cGUnIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgZ290byBleGl0OwoJfQoJLyoKCSogKGN2Yy1lbHQpICgzLjMuNCkgOiAoNC4yKQoJKiAoY3ZjLWFzc2Vzcy1lbHQpICgxLjIuMS4yLjMpCgkqLwoJKmxvY2FsVHlwZSA9IHhtbFNjaGVtYUdldFR5cGUodmN0eHQtPnNjaGVtYSwgbG9jYWwsIG5zTmFtZSk7CglpZiAoKmxvY2FsVHlwZSA9PSBOVUxMKSB7CgkgICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkgICAgeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8yLCBOVUxMLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkiVGhlIFFOYW1lIHZhbHVlICclcycgb2YgdGhlIHhzaTp0eXBlIGF0dHJpYnV0ZSBkb2VzIG5vdCAiCgkJInJlc29sdmUgdG8gYSB0eXBlIGRlZmluaXRpb24iLAoJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsIG5zTmFtZSwgbG9jYWwpLCBOVUxMKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cik7CgkgICAgcmV0ID0gdmN0eHQtPmVycjsKCSAgICBnb3RvIGV4aXQ7Cgl9CglpZiAoZWxlbURlY2wgIT0gTlVMTCkgewoJICAgIGludCBzZXQgPSAwOwoKCSAgICAvKgoJICAgICogU1BFQyBjdmMtZWx0ICgzLjMuNCkgOiAoNC4zKSAoVHlwZSBEZXJpdmF0aW9uIE9LKQoJICAgICogIlRoZSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utyBtdXN0IGJlIHZhbGlkbHkKCSAgICAqIGRlcml2ZWQgZnJvbSB0aGUge3R5cGUgZGVmaW5pdGlvbn0gZ2l2ZW4gdGhlIHVuaW9uIG9mCgkgICAgKiB0aGUge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYW5kIHRoZSB7dHlwZSBkZWZpbml0aW9ufSdzCgkgICAgKiB7cHJvaGliaXRlZCBzdWJzdGl0dXRpb25zfSwgYXMgZGVmaW5lZCBpbgoJICAgICogVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAopzMuNC42KQoJICAgICogKGlmIGl0IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24pLAoJICAgICogb3IgZ2l2ZW4ge2Rpc2FsbG93ZWQgc3Vic3RpdHV0aW9uc30gYXMgZGVmaW5lZCBpbiBUeXBlCgkgICAgKiBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSAoaWYgaXQgaXMgYSBzaW1wbGUgdHlwZQoJICAgICogZGVmaW5pdGlvbikuIgoJICAgICoKCSAgICAqIHtkaXNhbGxvd2VkIHN1YnN0aXR1dGlvbnN9OiB0aGUgImJsb2NrIiBvbiB0aGUgZWxlbWVudCBkZWNsLgoJICAgICoge3Byb2hpYml0ZWQgc3Vic3RpdHV0aW9uc306IHRoZSAiYmxvY2siIG9uIHRoZSB0eXBlIGRlZi4KCSAgICAqLwoJICAgIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04pIHx8CgkJKGVsZW1EZWNsLT5zdWJ0eXBlcy0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTikpCgkJc2V0IHw9IFNVQlNFVF9FWFRFTlNJT047CgoJICAgIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTikgfHwKCQkoZWxlbURlY2wtPnN1YnR5cGVzLT5mbGFncyAmCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfUkVTVFJJQ1RJT04pKQoJCXNldCB8PSBTVUJTRVRfUkVTVFJJQ1RJT047CgoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU0Rlcml2ZWRPSygqbG9jYWxUeXBlLAoJCWVsZW1EZWNsLT5zdWJ0eXBlcywgc2V0KSAhPSAwKSB7CgkJeG1sQ2hhciAqc3RyID0gTlVMTDsKCgkJeG1sU2NoZW1hQ3VzdG9tRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzRfMywgTlVMTCwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gJyVzJywgc3BlY2lmaWVkIGJ5IHhzaTp0eXBlLCBpcyAiCgkJICAgICJibG9ja2VkIG9yIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUgdHlwZSBkZWZpbml0aW9uICIKCQkgICAgIm9mIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJKCpsb2NhbFR5cGUpLT50YXJnZXROYW1lc3BhY2UsCgkJCSgqbG9jYWxUeXBlKS0+bmFtZSksCgkJICAgIE5VTEwpOwoJCUZSRUVfQU5EX05VTEwoc3RyKTsKCQlyZXQgPSB2Y3R4dC0+ZXJyOwoJCSpsb2NhbFR5cGUgPSBOVUxMOwoJICAgIH0KCX0KICAgIH0KZXhpdDoKICAgIEFDVElWQVRFX0VMRU07CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2woeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsID0gdmN0eHQtPmlub2RlLT5kZWNsOwogICAgeG1sU2NoZW1hVHlwZVB0ciBhY3R1YWxUeXBlID0gRUxFTV9UWVBFKGVsZW1EZWNsKTsKCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAxCiAgICAqLwogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzEsIE5VTEwsCgkgICAgIk5vIG1hdGNoaW5nIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIpOwogICAgICAgIHJldHVybiAodmN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAyCiAgICAqLwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHsKCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzIsIE5VTEwsCgkgICAgIlRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGlzIGFic3RyYWN0Iik7CiAgICAgICAgcmV0dXJuICh2Y3R4dC0+ZXJyKTsKICAgIH0KICAgIGlmIChhY3R1YWxUeXBlID09IE5VTEwpIHsKICAgIAlWRVJST1IoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSwgTlVMTCwKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8xKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkgewoJaW50IHJldDsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogMwoJKiBIYW5kbGUgJ3hzaTpuaWwnLgoJKi8KCWlhdHRyID0geG1sU2NoZW1hR2V0TWV0YUF0dHJJbmZvKHZjdHh0LAoJICAgIFhNTF9TQ0hFTUFfQVRUUl9JTkZPX01FVEFfWFNJX05JTCk7CglpZiAoaWF0dHIpIHsKCSAgICBBQ1RJVkFURV9BVFRSSUJVVEUoaWF0dHIpOwoJICAgIC8qCgkgICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJCSh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCBOVUxMLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJCWlhdHRyLT52YWx1ZSwgJihpYXR0ci0+dmFsKSwgMSwgMCwgMCk7CgkgICAgQUNUSVZBVEVfRUxFTTsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbURlY2wiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkgdG8gIgoJCSAgICAidmFsaWRhdGUgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSB7CgkJICAgIC8qCgkJICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMy4xCgkJICAgICovCgkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMSwgTlVMTCwKCQkJIlRoZSBlbGVtZW50IGlzIG5vdCAnbmlsbGFibGUnIik7CgkJICAgIC8qIERvZXMgbm90IHJldHVybiBhbiBlcnJvciBvbiBwdXJwb3NlLiAqLwoJCX0gZWxzZSB7CgkJICAgIGlmICh4bWxTY2hlbWFWYWx1ZUdldEFzQm9vbGVhbihpYXR0ci0+dmFsKSkgewoJCQkvKgoJCQkqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMi4yCgkJCSovCgkJCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCQkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCBOVUxMLAoJCQkJIlRoZSBlbGVtZW50IGNhbm5vdCBiZSAnbmlsbGVkJyBiZWNhdXNlICIKCQkJCSJ0aGVyZSBpcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQgZGVmaW5lZCAiCgkJCQkiZm9yIGl0Iik7CgkJCSAgICAgLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkJCX0gZWxzZQoJCQkgICAgdmN0eHQtPmlub2RlLT5mbGFncyB8PQoJCQkJWE1MX1NDSEVNQV9FTEVNX0lORk9fTklMTEVEOwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDQKCSogSGFuZGxlICd4c2k6dHlwZScuCgkqLwoJaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkgICAgWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CglpZiAoaWF0dHIpIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIGxvY2FsVHlwZSA9IE5VTEw7CgoJICAgIHJldCA9IHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHZjdHh0LCBpYXR0ciwgJmxvY2FsVHlwZSwKCQllbGVtRGVjbCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJCSJwcm9jZXNzIHRoZSBhdHRyaWJ1dGUgJ3hzaTp0eXBlJyIpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJLyogRG9lcyBub3QgcmV0dXJuIGFuIGVycm9yIG9uIHB1cnBvc2UuICovCgkgICAgfQoJICAgIGlmIChsb2NhbFR5cGUgIT0gTlVMTCkgewoJCXZjdHh0LT5pbm9kZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9FTEVNX0lORk9fTE9DQUxfVFlQRTsKCQlhY3R1YWxUeXBlID0gbG9jYWxUeXBlOwoJICAgIH0KCX0KICAgIH0KICAgIC8qCiAgICAqIElEQzogUmVnaXN0ZXIgaWRlbnRpdHktY29uc3RyYWludCBYUGF0aCBtYXRjaGVycy4KICAgICovCiAgICBpZiAoKGVsZW1EZWNsLT5pZGNzICE9IE5VTEwpICYmCgkoeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyh2Y3R4dCwgZWxlbURlY2wpID09IC0xKSkKCSAgICByZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIE5vIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgLyoKICAgICogUmVtZW1iZXIgdGhlIGFjdHVhbCB0eXBlIGRlZmluaXRpb24uCiAgICAqLwogICAgdmN0eHQtPmlub2RlLT50eXBlRGVmID0gYWN0dWFsVHlwZTsKCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZBdHRyaWJ1dGVzU2ltcGxlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgaWF0dHI7CiAgICBpbnQgcmV0ID0gMCwgaTsKCiAgICAvKgogICAgKiBTUEVDIGN2Yy10eXBlICgzLjEuMSkKICAgICogIlRoZSBhdHRyaWJ1dGVzIG9mIG11c3QgYmUgZW1wdHksIGV4Y2VwdGluZyB0aG9zZSB3aG9zZSBuYW1lc3BhY2UKICAgICogbmFtZSBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kCiAgICAqIHdob3NlIGxvY2FsIG5hbWUgaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3IKICAgICogbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbi4iCiAgICAqLwogICAgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyA9PSAwKQoJcmV0dXJuICgwKTsKICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJaWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJaWYgKCEgaWF0dHItPm1ldGFUeXBlKSB7CgkgICAgQUNUSVZBVEVfQVRUUklCVVRFKGlhdHRyKQoJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8xLCBpYXR0ciwgTlVMTCk7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzE7CiAgICAgICAgfQogICAgfQogICAgQUNUSVZBVEVfRUxFTQogICAgcmV0dXJuIChyZXQpOwp9CgovKgoqIENsZWFudXAgY3VycmVudGx5IHVzZWQgYXR0cmlidXRlIGluZm9zLgoqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGludCBpOwogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0cjsKCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zID09IDApCglyZXR1cm47CiAgICBmb3IgKGkgPSAwOyBpIDwgdmN0eHQtPm5iQXR0ckluZm9zOyBpKyspIHsKCWF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJaWYgKGF0dHItPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9OQU1FUykgewoJICAgIGlmIChhdHRyLT5sb2NhbE5hbWUgIT0gTlVMTCkKCQl4bWxGcmVlKCh4bWxDaGFyICopIGF0dHItPmxvY2FsTmFtZSk7CgkgICAgaWYgKGF0dHItPm5zTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUoKHhtbENoYXIgKikgYXR0ci0+bnNOYW1lKTsKCX0KCWlmIChhdHRyLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTKSB7CgkgICAgaWYgKGF0dHItPnZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSgoeG1sQ2hhciAqKSBhdHRyLT52YWx1ZSk7Cgl9CglpZiAoYXR0ci0+dmFsICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUoYXR0ci0+dmFsKTsKCSAgICBhdHRyLT52YWwgPSBOVUxMOwoJfQoJbWVtc2V0KGF0dHIsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRySW5mbykpOwogICAgfQogICAgdmN0eHQtPm5iQXR0ckluZm9zID0gMDsKfQoKLyoKKiAzLjQuNCBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBWYWxpZGF0aW9uIFJ1bGVzCiogICBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkgKGN2Yy1jb21wbGV4LXR5cGUpCiogMy4yLjQgQXR0cmlidXRlIERlY2xhcmF0aW9uIFZhbGlkYXRpb24gUnVsZXMKKiAgIFZhbGlkYXRpb24gUnVsZTogQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKGN2Yy1hdHRyaWJ1dGUpCiogICBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoVXNlKSAoY3ZjLWF1KQoqCiogT25seSAiYXNzZXNzZWQiIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtcyB3aWxsIGJlIHZpc2libGUgdG8KKiBJRENzLiBJLmUuIG5vdCAibGF4IiAod2l0aG91dCBkZWNsYXJhdGlvbikgYW5kICJza2lwIiB3aWxkIGF0dHJpYnV0ZXMuCiovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlID0gdmN0eHQtPmlub2RlLT50eXBlRGVmOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlTGluazsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyVXNlID0gTlVMTCwgYXR0ckRlY2wgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0ckluZm9QdHIgYXR0ciwgdG1wQXR0cjsKICAgIGludCBpLCBmb3VuZCwgbmJBdHRyczsKICAgIGludCB4cGF0aFJlcyA9IDAsIHJlcywgd2lsZElEcyA9IDAsIGZpeGVkOwoKICAgIC8qCiAgICAqIFNQRUMgKGN2Yy1hdHRyaWJ1dGUpCiAgICAqICgxKSAiVGhlIGRlY2xhcmF0aW9uIG11c3Qgbm90IGJlILdhYnNlbnS3IChzZWUgTWlzc2luZwogICAgKiBTdWItY29tcG9uZW50cyAopzUuMykgZm9yIGhvdyB0aGlzIGNhbiBmYWlsIHRvIGJlCiAgICAqIHRoZSBjYXNlKS4iCiAgICAqICgyKSAiSXRzIHt0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGJlIGFic2VudC4iCiAgICAqCiAgICAqIE5PVEUgKDEpICsgKDIpOiBUaGlzIGlzIG5vdCBoYW5kbGVkIGhlcmUsIHNpbmNlIHdlIGN1cnJlbnRseSBkbyBub3QKICAgICogYWxsb3cgdmFsaWRhdGlvbiBhZ2FpbnN0IHNjaGVtYXMgd2hpY2ggaGF2ZSBtaXNzaW5nIHN1Yi1jb21wb25lbnRzLgogICAgKgogICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQogICAgKiAoMykgIkZvciBlYWNoIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uCiAgICAqIGl0ZW0ncyBbYXR0cmlidXRlc10gZXhjZXB0aW5nIHRob3NlIHdob3NlIFtuYW1lc3BhY2UgbmFtZV0gaXMKICAgICogaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZQogICAgKiBbbG9jYWwgbmFtZV0gaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3IKICAgICogbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiwgdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZwogICAgKiBtdXN0IGJlIHRydWU6CiAgICAqCiAgICAqLyAgCiAgICBuYkF0dHJzID0gdmN0eHQtPm5iQXR0ckluZm9zOwogICAgZm9yIChhdHRyVXNlTGluayA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7IGF0dHJVc2VMaW5rICE9IE5VTEw7CglhdHRyVXNlTGluayA9IGF0dHJVc2VMaW5rLT5uZXh0KSB7CgogICAgICAgIGZvdW5kID0gMDsKCWF0dHJVc2UgPSBhdHRyVXNlTGluay0+YXR0cjsKCS8qCgkqIFZBTCBUT0RPOiBJbXBsZW1lbnQgYSByZWFsICJhdHRyaWJ1dGUgdXNlIiBjb21wb25lbnQuCgkqLwoJaWYgKGF0dHJVc2UtPnJlZkRlY2wgIT0gTlVMTCkKCSAgICBhdHRyRGVjbCA9IGF0dHJVc2UtPnJlZkRlY2w7CgllbHNlCgkgICAgYXR0ckRlY2wgPSBhdHRyVXNlOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYkF0dHJzOyBpKyspIHsKCSAgICBhdHRyID0gdmN0eHQtPmF0dHJJbmZvc1tpXTsKCSAgICAvKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkgKDMpCgkgICAgKiBTa2lwIG1ldGEgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChhdHRyLT5tZXRhVHlwZSkKCQljb250aW51ZTsKCSAgICBpZiAoYXR0ci0+bG9jYWxOYW1lWzBdICE9IGF0dHJEZWNsLT5uYW1lWzBdKQoJCWNvbnRpbnVlOwoJICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bG9jYWxOYW1lLCBhdHRyRGVjbC0+bmFtZSkpCgkJY29udGludWU7CgkgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uc05hbWUsIGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UpKQoJCWNvbnRpbnVlOwoJICAgIGZvdW5kID0gMTsKCSAgICAvKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSAgICAqICgzLjEpICJJZiB0aGVyZSBpcyBhbW9uZyB0aGUge2F0dHJpYnV0ZSB1c2VzfSBhbiBhdHRyaWJ1dGUKCSAgICAqIHVzZSB3aXRoIGFuIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IHdob3NlIHtuYW1lfSBtYXRjaGVzCgkgICAgKiB0aGUgYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0ncyBbbG9jYWwgbmFtZV0gYW5kIHdob3NlCgkgICAgKiB7dGFyZ2V0IG5hbWVzcGFjZX0gaXMgaWRlbnRpY2FsIHRvIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24KCSAgICAqIGl0ZW0ncyBbbmFtZXNwYWNlIG5hbWVdICh3aGVyZSBhbiC3YWJzZW50tyB7dGFyZ2V0IG5hbWVzcGFjZX0KCSAgICAqIGlzIHRha2VuIHRvIGJlIGlkZW50aWNhbCB0byBhIFtuYW1lc3BhY2UgbmFtZV0gd2l0aCBubyB2YWx1ZSksCgkgICAgKiB0aGVuIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdAoJICAgICogdG8gdGhhdCBhdHRyaWJ1dGUgdXNlIGFzIHBlciBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoVXNlKQoJICAgICogKKczLjUuNCkuIEluIHRoaXMgY2FzZSB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gb2YgdGhhdAoJICAgICogYXR0cmlidXRlIHVzZSBpcyB0aGUgt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgZm9yIHRoZQoJICAgICogYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gd2l0aCByZXNwZWN0IHRvIFNjaGVtYS1WYWxpZGl0eQoJICAgICogQXNzZXNzbWVudCAoQXR0cmlidXRlKSAopzMuMi40KSBhbmQKCSAgICAqIEFzc2Vzc21lbnQgT3V0Y29tZSAoQXR0cmlidXRlKSAopzMuMi41KS4KCSAgICAqLwoJICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRDsKCSAgICBhdHRyLT51c2UgPSBhdHRyVXNlOwoJICAgIC8qCgkgICAgKiBDb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24uCgkgICAgKi8KCSAgICBhdHRyLT5kZWNsID0gYXR0ckRlY2w7CgkgICAgYXR0ci0+dHlwZURlZiA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCSAgICBicmVhazsKCX0KCglpZiAoZm91bmQpCgkgICAgY29udGludWU7CgoJaWYgKGF0dHJVc2UtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkgewoJICAgIC8qCgkgICAgKiBIYW5kbGUgbm9uLWV4aXN0ZW50LCByZXF1aXJlZCBhdHRyaWJ1dGVzLgoJICAgICoKCSAgICAqIFNQRUMgKGN2Yy1jb21wbGV4LXR5cGUpCgkgICAgKiAoNCkgIlRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBvZiBlYWNoIGF0dHJpYnV0ZSB1c2UgaW4KCSAgICAqIHRoZSB7YXR0cmlidXRlIHVzZXN9IHdob3NlIHtyZXF1aXJlZH0gaXMgdHJ1ZSBtYXRjaGVzIG9uZQoJICAgICogb2YgdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtcyBpbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbgoJICAgICogaXRlbSdzIFthdHRyaWJ1dGVzXSBhcyBwZXIgY2xhdXNlIDMuMSBhYm92ZS4iCgkgICAgKi8KCSAgICB0bXBBdHRyID0geG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbyh2Y3R4dCk7CgkgICAgaWYgKHRtcEF0dHIgPT0gTlVMTCkgewoJCVZFUlJPUl9JTlQoCgkJICAgICJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFHZXRGcmVzaEF0dHJJbmZvKCkiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgdG1wQXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HOwoJICAgIHRtcEF0dHItPnVzZSA9IGF0dHJVc2U7CgkgICAgdG1wQXR0ci0+ZGVjbCA9IGF0dHJEZWNsOwkgICAgCgl9IGVsc2UgaWYgKChhdHRyVXNlLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkgICAgKChhdHRyVXNlLT5kZWZWYWx1ZSAhPSBOVUxMKSB8fAoJICAgICAoYXR0ckRlY2wtPmRlZlZhbHVlICE9IE5VTEwpKSkgewoJICAgIC8qCgkgICAgKiBIYW5kbGUgbm9uLWV4aXN0ZW50LCBvcHRpb25hbCwgZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgdG1wQXR0ciA9IHhtbFNjaGVtYUdldEZyZXNoQXR0ckluZm8odmN0eHQpOwoJICAgIGlmICh0bXBBdHRyID09IE5VTEwpIHsKCQlWRVJST1JfSU5UKAoJCSAgICAieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hR2V0RnJlc2hBdHRySW5mbygpIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcEF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9ERUZBVUxUOwoJICAgIHRtcEF0dHItPnVzZSA9IGF0dHJVc2U7CgkgICAgdG1wQXR0ci0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIHRtcEF0dHItPnR5cGVEZWYgPSBhdHRyRGVjbC0+c3VidHlwZXM7CgkgICAgdG1wQXR0ci0+bG9jYWxOYW1lID0gYXR0ckRlY2wtPm5hbWU7CgkgICAgdG1wQXR0ci0+bnNOYW1lID0gYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZTsKCX0KICAgIH0KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybiAoMCk7CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhZ2FpbnN0IHRoZSB3aWxkY2FyZC4KICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJLyoKCSogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSogKDMuMi4xKSAiVGhlcmUgbXVzdCBiZSBhbiB7YXR0cmlidXRlIHdpbGRjYXJkfS4iCgkqLwoJZm9yIChpID0gMDsgaSA8IG5iQXR0cnM7IGkrKykgewoJICAgIGF0dHIgPSB2Y3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMykKCSAgICAqIFNraXAgbWV0YSBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKGF0dHItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikKCQljb250aW51ZTsKCSAgICAvKgoJICAgICogU1BFQyAoY3ZjLWNvbXBsZXgtdHlwZSkKCSAgICAqICgzLjIuMikgIlRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aAoJICAgICogcmVzcGVjdCB0byBpdCBhcyBkZWZpbmVkIGluIEl0ZW0gVmFsaWQgKFdpbGRjYXJkKSAopzMuMTAuNCkuIgoJICAgICoKCSAgICAqIFNQRUMgSXRlbSBWYWxpZCAoV2lsZGNhcmQpIChjdmMtd2lsZGNhcmQpCgkgICAgKiAiLi4uIGl0cyBbbmFtZXNwYWNlIG5hbWVdIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8KCSAgICAqIHRoZSB3aWxkY2FyZCBjb25zdHJhaW50LCBhcyBkZWZpbmVkIGluIFdpbGRjYXJkIGFsbG93cwoJICAgICogTmFtZXNwYWNlIE5hbWUgKKczLjEwLjQpLiIKCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NWQ1dpbGRjYXJkTmFtZXNwYWNlKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCSAgICBhdHRyLT5uc05hbWUpKSB7CgkJLyoKCQkqIEhhbmRsZSBwcm9jZXNzQ29udGVudHMuCgkJKgoJCSogU1BFQyAoY3ZjLXdpbGRjYXJkKToKCQkqIHByb2Nlc3NDb250ZW50cyB8IGNvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbjoKCQkqICJzdHJpY3QiICAgICAgICAgICJtdXN0RmluZCIKCQkqICJsYXgiICAgICAgICAgICAgICJub25lIgoJCSogInNraXAiICAgICAgICAgICAgInNraXAiCgkJKi8KCQlpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PQoJCSAgICBYTUxfU0NIRU1BU19BTllfU0tJUCkgewoJCSAgICAgLyoKCQkgICAgKiBjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb24gPSAic2tpcCIKCQkgICAgKgoJCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCQkgICAgKiBbdmFsaWRpdHldID0gIm5vdEtub3duIgoJCSAgICAqIFt2YWxpZGF0aW9uIGF0dGVtcHRlZF0gPSAibm9uZSIKCQkgICAgKi8KCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1dJTERfU0tJUDsKCQkgICAgY29udGludWU7CgkJfQoJCS8qCgkJKiBGaW5kIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KCQkqLwoJCWF0dHItPmRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVEZWNsKHZjdHh0LT5zY2hlbWEsCgkJICAgIGF0dHItPmxvY2FsTmFtZSwgYXR0ci0+bnNOYW1lKTsKCQlpZiAoYXR0ci0+ZGVjbCAhPSBOVUxMKSB7CgkJICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRDsKCQkgICAgLyoKCQkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJCSAgICAqICg1KSAiTGV0IFtEZWZpbml0aW9uOl0gIHRoZSB3aWxkIElEcyBiZSB0aGUgc2V0IG9mCgkJICAgICogYWxsIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIHdoaWNoIGNsYXVzZSAzLjIKCQkgICAgKiBhcHBsaWVkIGFuZCB3aG9zZSC3dmFsaWRhdGlvbrcgcmVzdWx0ZWQgaW4gYQoJCSAgICAqILdjb250ZXh0LWRldGVybWluZWQgZGVjbGFyYXRpb263IG9mIG11c3RGaW5kIG9yIG5vCgkJICAgICogt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgYXQgYWxsLCBhbmQgd2hvc2UKCQkgICAgKiBbbG9jYWwgbmFtZV0gYW5kIFtuYW1lc3BhY2UgbmFtZV0gcmVzb2x2ZSAoYXMKCQkgICAgKiBkZWZpbmVkIGJ5IFFOYW1lIHJlc29sdXRpb24gKEluc3RhbmNlKSAopzMuMTUuNCkpIHRvCgkJICAgICogYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdob3NlIHt0eXBlIGRlZmluaXRpb259IGlzCgkJICAgICogb3IgaXMgZGVyaXZlZCBmcm9tIElELiBUaGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nCgkJICAgICogbXVzdCBiZSB0cnVlOiIKCQkgICAgKi8KCQkgICAgYXR0ci0+dHlwZURlZiA9IGF0dHItPmRlY2wtPnN1YnR5cGVzOwoJCSAgICBpZiAoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKAoJCQlhdHRyLT50eXBlRGVmLCBYTUxfU0NIRU1BU19JRCkpIHsKCQkJLyoKCQkJKiBTUEVDICg1LjEpICJUaGVyZSBtdXN0IGJlIG5vIG1vcmUgdGhhbiBvbmUKCQkJKiBpdGVtIGluILd3aWxkIElEc7cuIgoJCQkqLwoJCQlpZiAod2lsZElEcyAhPSAwKSB7CgkJCSAgICAvKiBWQUwgVE9ETyAqLwoJCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX0RVUExJQ0FURV9JRDsKCQkJICAgIFRPRE8KCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJCXdpbGRJRHMrKzsKCQkJLyoKCQkJKiBTUEVDIChjdmMtY29tcGxleC10eXBlKQoJCQkqICg1LjIpICJJZiC3d2lsZCBJRHO3IGlzIG5vbi1lbXB0eSwgdGhlcmUgbXVzdCBub3QKCQkJKiBiZSBhbnkgYXR0cmlidXRlIHVzZXMgYW1vbmcgdGhlIHthdHRyaWJ1dGUgdXNlc30KCQkJKiB3aG9zZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzIHt0eXBlIGRlZmluaXRpb259CgkJCSogaXMgb3IgaXMgZGVyaXZlZCBmcm9tIElELiIKCQkJKi8KCQkJZm9yIChhdHRyVXNlTGluayA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CgkJCSAgICBhdHRyVXNlTGluayAhPSBOVUxMOwoJCQkgICAgYXR0clVzZUxpbmsgPSBhdHRyVXNlTGluay0+bmV4dCkgewoJCQkgICAgaWYgKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSgKCQkJCWF0dHJVc2VMaW5rLT5hdHRyLT5zdWJ0eXBlcywKCQkJCVhNTF9TQ0hFTUFTX0lEKSkgewoJCQkJLyogVkFMIFRPRE8gKi8KCQkJCWF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfV0lMRF9BTkRfVVNFX0lEOwoJCQkJVE9ETwoJCQkgICAgfQoJCQl9CgkJICAgIH0KCQl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0KCQkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkgewoJCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9MQVhfTk9fREVDTDsKCQkgICAgLyoKCQkgICAgKiBTUEVDIFBTVkkgQXNzZXNzbWVudCBPdXRjb21lIChBdHRyaWJ1dGUpCgkJICAgICogW3ZhbGlkaXR5XSA9ICJub3RLbm93biIKCQkgICAgKiBbdmFsaWRhdGlvbiBhdHRlbXB0ZWRdID0gIm5vbmUiCgkJICAgICovCgkJfSBlbHNlIHsKCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX1NUUklDVF9OT19ERUNMOwoJCX0KCSAgICB9Cgl9CiAgICB9CgoKICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgPT0gMCkKCXJldHVybiAoMCk7CgogICAgLyoKICAgICogVmFsaWRhdGUgdmFsdWVzLCBjcmVhdGUgZGVmYXVsdCBhdHRyaWJ1dGVzLCBldmFsdWF0ZSBJRENzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CgkvKgoJKiBWQUwgVE9ETzogTm90ZSB0aGF0IHdlIHdvbid0IHRyeSB0byByZXNvbHZlIElEQ3MgdG8KCSogImxheCIgYW5kICJza2lwIiB2YWxpZGF0ZWQgYXR0cmlidXRlcy4gQ2hlY2sgd2hhdCB0bwoJKiBkbyBpbiB0aGlzIGNhc2UuCgkqLwoJaWYgKChhdHRyLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0FTU0VTU0VEKSAmJgoJICAgIChhdHRyLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQpKQoJICAgIGNvbnRpbnVlOwoJLyoKCSogVkFMIFRPRE86IFdoYXQgdG8gZG8gaWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBtaXNzaW5nPwoJKi8KCWlmIChhdHRyLT50eXBlRGVmID09IE5VTEwpIHsKCSAgICBhdHRyLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfRVJSX05PX1RZUEU7CgkgICAgY29udGludWU7Cgl9CgoJQUNUSVZBVEVfQVRUUklCVVRFKGF0dHIpOwoJZml4ZWQgPSAwOwoJeHBhdGhSZXMgPSAwOwoKCWlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBFdmFsdWF0ZSBJRENzLgoJICAgICovCgkgICAgeHBhdGhSZXMgPSB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKHZjdHh0LAoJCVhNTF9BVFRSSUJVVEVfTk9ERSk7CgkgICAgaWYgKHhwYXRoUmVzID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9CgoJaWYgKGF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCkgewoJICAgIC8qCgkgICAgKiBEZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICBpZiAoeHBhdGhSZXMpIHsKCQlpZiAoYXR0ci0+dXNlLT5kZWZWYWx1ZSA9PSBOVUxMKSB7CgkJICAgIGF0dHItPnZhbHVlID0gKHhtbENoYXIgKikgYXR0ci0+dXNlLT5kZWZWYWx1ZTsKCQkgICAgYXR0ci0+dmFsID0gYXR0ci0+dXNlLT5kZWZWYWw7CgkJfSBlbHNlIHsKCQkgICAgYXR0ci0+dmFsdWUgPSAoeG1sQ2hhciAqKSBhdHRyLT5kZWNsLT5kZWZWYWx1ZTsKCQkgICAgYXR0ci0+dmFsID0gYXR0ci0+ZGVjbC0+ZGVmVmFsOwoJCX0KCQkvKgoJCSogSURDcyB3aWxsIGNvbnN1bWUgdGhlIHByZWNvbXB1dGVkIGRlZmF1bHQgdmFsdWUsCgkJKiBzbyB3ZSBuZWVkIHRvIGNsb25lIGl0LgoJCSovCgkJaWYgKGF0dHItPnZhbCA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJCSJkZWZhdWx0L2ZpeGVkIHZhbHVlIG9uIGFuIGF0dHJpYnV0ZSB1c2Ugd2FzICIKCQkJIm5vdCBwcmVjb21wdXRlZCIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCQlhdHRyLT52YWwgPSB4bWxTY2hlbWFDb3B5VmFsdWUoYXR0ci0+dmFsKTsKCQlpZiAoYXR0ci0+dmFsID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hQ29weVZhbHVlKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBQU1ZJOiBBZGQgdGhlIGRlZmF1bHQgYXR0cmlidXRlIHRvIHRoZSBjdXJyZW50IGVsZW1lbnQuCgkgICAgKiBWQUwgVE9ETzogU2hvdWxkIHdlIHVzZSB0aGUgKm5vcm1hbGl6ZWQqIHZhbHVlPyBUaGlzIGN1cnJlbnRseQoJICAgICogICB1c2VzIHRoZSAqaW5pdGlhbCogdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoKHZjdHh0LT5vcHRpb25zICYgWE1MX1NDSEVNQV9WQUxfVkNfSV9DUkVBVEUpICYmCgkJKGF0dHItPm5vZGUgIT0gTlVMTCkgJiYgKGF0dHItPm5vZGUtPmRvYyAhPSBOVUxMKSkgewoJCXhtbENoYXIgKm5vcm1WYWx1ZTsKCQljb25zdCB4bWxDaGFyICp2YWx1ZTsKCgkJdmFsdWUgPSBhdHRyLT52YWx1ZTsKCQkvKgoJCSogTm9ybWFsaXplIHRoZSB2YWx1ZS4KCQkqLwoJCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYU5vcm1hbGl6ZVZhbHVlKGF0dHItPnR5cGVEZWYsCgkJICAgIGF0dHItPnZhbHVlKTsKCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJICAgIHZhbHVlID0gQkFEX0NBU1Qgbm9ybVZhbHVlOwoKCQlpZiAoYXR0ci0+bnNOYW1lID09IE5VTEwpIHsKCQkgICAgaWYgKHhtbE5ld1Byb3AoYXR0ci0+bm9kZS0+cGFyZW50LAoJCQlhdHRyLT5sb2NhbE5hbWUsIHZhbHVlKSA9PSBOVUxMKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJCSAgICAiY2FsbGxpbmcgeG1sTmV3UHJvcCgpIik7CgkJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkJICAgIHhtbEZyZWUobm9ybVZhbHVlKTsKCQkJZ290byBpbnRlcm5hbF9lcnJvcjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHhtbE5zUHRyIG5zOwoKCQkgICAgbnMgPSB4bWxTZWFyY2hOc0J5SHJlZihhdHRyLT5ub2RlLT5kb2MsCgkJCWF0dHItPm5vZGUtPnBhcmVudCwgYXR0ci0+bnNOYW1lKTsKCQkgICAgaWYgKG5zID09IE5VTEwpIHsKCQkJeG1sQ2hhciBwcmVmaXhbMTJdOwoJCQlpbnQgY291bnRlciA9IDA7CgoJCQkvKgoJCQkqIENyZWF0ZSBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBvbiB0aGUgdmFsaWRhdGlvbgoJCQkqIHJvb3Qgbm9kZSBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgaW4gc2NvcGUuCgkJCSovCgkJCWRvIHsKCQkJICAgIHNucHJpbnRmKChjaGFyICopIHByZWZpeCwgMTIsICJwJWQiLCBjb3VudGVyKyspOwoJCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhhdHRyLT5ub2RlLT5kb2MsCgkJCQlhdHRyLT5ub2RlLT5wYXJlbnQsIEJBRF9DQVNUIHByZWZpeCk7CgkJCSAgICBpZiAoY291bnRlciA+IDEwMDApIHsKCQkJCVZFUlJPUl9JTlQoCgkJCQkgICAgInhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCIsCgkJCQkgICAgImNvdWxkIG5vdCBjb21wdXRlIGEgbnMgcHJlZml4IGZvciBhICIKCQkJCSAgICAiZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGUiKTsKCQkJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkJCSAgICB4bWxGcmVlKG5vcm1WYWx1ZSk7CgkJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCQkgICAgfQoJCQl9IHdoaWxlIChucyAhPSBOVUxMKTsKCQkJbnMgPSB4bWxOZXdOcyh2Y3R4dC0+dmFsaWRhdGlvblJvb3QsCgkJCSAgICBhdHRyLT5uc05hbWUsIEJBRF9DQVNUIHByZWZpeCk7CgkJICAgIH0KCQkgICAgeG1sTmV3TnNQcm9wKGF0dHItPm5vZGUtPnBhcmVudCwgbnMsCgkJCWF0dHItPmxvY2FsTmFtZSwgdmFsdWUpOwoJCX0KCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJICAgIHhtbEZyZWUobm9ybVZhbHVlKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIEdvIGRpcmVjdGx5IHRvIElEQyBldmFsdWF0aW9uLgoJICAgICovCgkgICAgZ290byBldmFsX2lkY3M7Cgl9CgkvKgoJKiBWYWxpZGF0ZSB0aGUgdmFsdWUuCgkqLwoJaWYgKHZjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIEZyZWUgbGFzdCBjb21wdXRlZCB2YWx1ZTsganVzdCBmb3Igc2FmZXR5IHJlYXNvbnMuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUodmN0eHQtPnZhbHVlKTsKCSAgICB2Y3R4dC0+dmFsdWUgPSBOVUxMOwoJfQoJLyoKCSogTm90ZSB0aGF0IHRoZSBhdHRyaWJ1dGUgKnVzZSogY2FuIGJlIHVuYXZhaWxhYmxlLCBpZgoJKiB0aGUgYXR0cmlidXRlIHdhcyBhIHdpbGQgYXR0cmlidXRlLgoJKi8KCWlmICgoYXR0ci0+ZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSB8fAoJICAgICgoYXR0ci0+dXNlICE9IE5VTEwpICYmCgkgICAgIChhdHRyLT51c2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkpKQoJICAgIGZpeGVkID0gMTsKCWVsc2UKCSAgICBmaXhlZCA9IDA7CgkvKgoJKiBTUEVDIChjdmMtYXR0cmlidXRlKQoJKiAoMykgIlRoZSBpdGVtJ3Mgt25vcm1hbGl6ZWQgdmFsdWW3IG11c3QgYmUgbG9jYWxseSC3dmFsaWS3CgkqIHdpdGggcmVzcGVjdCB0byB0aGF0IHt0eXBlIGRlZmluaXRpb259IGFzIHBlciAKCSogU3RyaW5nIFZhbGlkICinMy4xNC40KS4iCgkqCgkqIFZBTCBUT0RPOiBEbyB3ZSBhbHJlYWR5IGhhdmUgdGhlCgkqICJub3JtYWxpemVkIGF0dHJpYnV0ZSB2YWx1ZSIgaGVyZT8KCSovCglpZiAoeHBhdGhSZXMgfHwgZml4ZWQpIHsKCSAgICBhdHRyLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19WQUxVRV9ORUVERUQ7CgkgICAgLyoKCSAgICAqIFJlcXVlc3QgYSBjb21wdXRlZCB2YWx1ZS4KCSAgICAqLwoJICAgIHJlcyA9IHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoCgkJKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJYXR0ci0+bm9kZSwgYXR0ci0+dHlwZURlZiwgYXR0ci0+dmFsdWUsICYoYXR0ci0+dmFsKSwKCQkxLCAxLCAwKTsKCX0gZWxzZSB7CgkgICAgcmVzID0geG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCQkoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQlhdHRyLT5ub2RlLCBhdHRyLT50eXBlRGVmLCBhdHRyLT52YWx1ZSwgTlVMTCwKCQkxLCAwLCAwKTsKCX0KCSAgICAKCWlmIChyZXMgIT0gMCkgewoJICAgIGlmIChyZXMgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWQXR0cmlidXRlc0NvbXBsZXgiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFTdHJlYW1WYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUU7CgkgICAgLyoKCSAgICAqIFNQRUMgUFNWSSBBc3Nlc3NtZW50IE91dGNvbWUgKEF0dHJpYnV0ZSkKCSAgICAqIFt2YWxpZGl0eV0gPSAiaW52YWxpZCIKCSAgICAqLwoJICAgIGdvdG8gZXZhbF9pZGNzOwoJfQoKCWlmIChmaXhlZCkgewoJICAgIGludCB3czsKCSAgICAvKgoJICAgICogU1BFQyBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoVXNlKSAoY3ZjLWF1KQoJICAgICogIkZvciBhbiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB0byBiZbd2YWxpZLcKCSAgICAqIHdpdGggcmVzcGVjdCB0byBhbiBhdHRyaWJ1dGUgdXNlIGl0cyAqbm9ybWFsaXplZCoKCSAgICAqIHZhbHVltyBtdXN0IG1hdGNoIHRoZSAqY2Fub25pY2FsKiBsZXhpY2FsCgkgICAgKiByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXR0cmlidXRlIHVzZSdzIHt2YWx1ZQoJICAgICogY29uc3RyYWludH12YWx1ZSwgaWYgaXQgaXMgcHJlc2VudCBhbmQgZml4ZWQuIgoJICAgICoKCSAgICAqIFZBTCBUT0RPOiBUaGUgcmVxdWlyZW1lbnQgZm9yIHRoZSAqY2Fub25pY2FsKiB2YWx1ZQoJICAgICogd2lsbCBiZSByZW1vdmVkIGluIFhNTCBTY2hlbWEgMS4xLgoJICAgICovCgkgICAgLyoKCSAgICAqIFNQRUMgQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKGN2Yy1hdHRyaWJ1dGUpCgkgICAgKiAoNCkgIlRoZSBpdGVtJ3MgKmFjdHVhbCogdmFsdWW3IG11c3QgbWF0Y2ggdGhlICp2YWx1ZSogb2YKCSAgICAqIHRoZSB7dmFsdWUgY29uc3RyYWludH0sIGlmIGl0IGlzIHByZXNlbnQgYW5kIGZpeGVkLiIKCSAgICAqLwoJICAgIHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoYXR0ci0+dHlwZURlZik7CgkgICAgaWYgKGF0dHItPnZhbCA9PSBOVUxMKSB7CgkJLyogVkFMIFRPRE86IEEgdmFsdWUgd2FzIG5vdCBwcmVjb21wdXRlZC4gKi8KCQlUT0RPCgkJZ290byBldmFsX2lkY3M7CgkgICAgfQoJICAgIGlmICgoYXR0ci0+dXNlICE9IE5VTEwpICYmCgkJKGF0dHItPnVzZS0+ZGVmVmFsdWUgIT0gTlVMTCkpIHsKCQlpZiAoYXR0ci0+dXNlLT5kZWZWYWwgPT0gTlVMTCkgewoJCSAgICAvKiBWQUwgVE9ETzogQSBkZWZhdWx0IHZhbHVlIHdhcyBub3QgcHJlY29tcHV0ZWQuICovCgkJICAgIFRPRE8KCQkgICAgZ290byBldmFsX2lkY3M7CgkJfQoJCWF0dHItPnZjVmFsdWUgPSBhdHRyLT51c2UtPmRlZlZhbHVlOwoJCS8qCgkJaWYgKHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXNXaHRzcChhdHRyLT52YWwsCgkJICAgICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cywKCQkgICAgYXR0ci0+dXNlLT5kZWZWYWwsCgkJICAgICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cykgIT0gMCkgewoJCSovCgkJaWYgKCEgeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwoYXR0ci0+dmFsLCBhdHRyLT51c2UtPmRlZlZhbCkpCgkJICAgIGF0dHItPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9FUlJfRklYRURfVkFMVUU7CgkgICAgfSBlbHNlIHsKCQlpZiAoYXR0ci0+ZGVjbC0+ZGVmVmFsID09IE5VTEwpIHsKCQkgICAgLyogVkFMIFRPRE86IEEgZGVmYXVsdCB2YWx1ZSB3YXMgbm90IHByZWNvbXB1dGVkLiAqLwoJCSAgICBUT0RPCgkJICAgIGdvdG8gZXZhbF9pZGNzOwoJCX0KCQlhdHRyLT52Y1ZhbHVlID0gYXR0ci0+ZGVjbC0+ZGVmVmFsdWU7CgkJLyoKCQlpZiAoeG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKGF0dHItPnZhbCwKCQkgICAgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzLAoJCSAgICBhdHRyRGVjbC0+ZGVmVmFsLAoJCSAgICAoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MpICE9IDApIHsKCQkqLwoJCWlmICghIHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKGF0dHItPnZhbCwgYXR0ci0+ZGVjbC0+ZGVmVmFsKSkKCQkgICAgYXR0ci0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFt2YWxpZGl0eV0gPSAidmFsaWQiCgkgICAgKi8KCX0KZXZhbF9pZGNzOgoJLyoKCSogRXZhbHVhdGUgSURDcy4KCSovCglpZiAoeHBhdGhSZXMpIHsKCSAgICBpZiAoeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSh2Y3R4dCwKCQl2Y3R4dC0+ZGVwdGggKzEpID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkF0dHJpYnV0ZXNDb21wbGV4IiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYVhQYXRoUG9wKHZjdHh0KTsKICAgIH0KCiAgICAvKgogICAgKiBSZXBvcnQgZXJyb3JzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJBdHRySW5mb3M7IGkrKykgewoJYXR0ciA9IHZjdHh0LT5hdHRySW5mb3NbaV07CglpZiAoKGF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUVUQSkgfHwKCSAgICAoYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9BU1NFU1NFRCkgfHwKCSAgICAoYXR0ci0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX1NLSVApIHx8CgkgICAgKGF0dHItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9MQVhfTk9fREVDTCkpCgkgICAgY29udGludWU7CglBQ1RJVkFURV9BVFRSSUJVVEUoYXR0cik7Cglzd2l0Y2ggKGF0dHItPnN0YXRlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9NSVNTSU5HOiB7CgkJICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgkJICAgIEFDVElWQVRFX0VMRU07CgkJICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV80LCBOVUxMLCBOVUxMLAoJCQkiVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nIiwKCQkJeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCQkJICAgIGF0dHItPmRlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgIGF0dHItPmRlY2wtPm5hbWUpLAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGJyZWFrOwoJCX0KCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfRVJSX05PX1RZUEU6CgkJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19BVFRSSUJVVEVfMiwgTlVMTCwKCQkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9GSVhFRF9WQUxVRToKCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19BVSwgTlVMTCwgTlVMTCwKCQkgICAgIlRoZSB2YWx1ZSAnJXMnIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCAiCgkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLCAKCQkgICAgYXR0ci0+dmFsdWUsIGF0dHItPnZjVmFsdWUpOwkJCgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19BVFRSX0VSUl9XSUxEX1NUUklDVF9OT19ERUNMOgoJCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfV0lMRENBUkQsIE5VTEwsCgkJICAgICJObyBtYXRjaGluZyBnbG9iYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSwgYnV0ICIKCQkgICAgImRlbWFuZGVkIGJ5IHRoZSBzdHJpY3Qgd2lsZGNhcmQiKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTjoKCQlpZiAoYXR0ci0+bWV0YVR5cGUpCgkJICAgIGJyZWFrOwoJCS8qCgkJKiBNQVlCRSBWQUwgVE9ETzogT25lIG1pZ2h0IHJlcG9ydCBkaWZmZXJlbnQgZXJyb3IgbWVzc2FnZXMKCQkqIGZvciB0aGUgZm9sbG93aW5nIGVycm9ycy4KCQkqLwoJCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUlsbGVnYWxBdHRyRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8xLCBhdHRyLCBOVUxMKTsKCQl9IGVsc2UgewoJCSAgICB4bWxTY2hlbWFJbGxlZ2FsQXR0ckVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMiwgYXR0ciwgTlVMTCk7CgkJfQoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoMCk7CmludGVybmFsX2Vycm9yOgogICAgQUNUSVZBVEVfRUxFTTsKICAgIHJldHVybiAoLTEpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgaW50ICpza2lwKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkID0gKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSB2Y3R4dC0+aW5vZGUtPmRlY2w7CiAgICAvKgogICAgKiBUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IHdhcyBhbHJlYWR5IGlkZW50aWZpZWQgdG8gYmUKICAgICogbWF0Y2hpbmcgdGhlIHdpbGRjYXJkLgogICAgKi8KICAgIGlmICgoc2tpcCA9PSBOVUxMKSB8fCAod2lsZCA9PSBOVUxMKSB8fAoJKHdpbGQtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkIiwKCSAgICAiYmFkIGFyZ3VtZW50cyIpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAqc2tpcCA9IDA7CiAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7CgkvKgoJKiBVUkdFTlQgVkFMIFRPRE86IEVpdGhlciB3ZSBuZWVkIHRvIHBvc2l0aW9uIHRoZSBzdHJlYW0gdG8gdGhlCgkqIG5leHQgc2libGluZywgb3Igd2FsayB0aGUgd2hvbGUgc3VidHJlZS4KCSovCgkqc2tpcCA9IDE7CglyZXR1cm4gKDApOwogICAgfQogICAgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKCglkZWNsID0geG1sSGFzaExvb2t1cDModmN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCgkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsIHZjdHh0LT5pbm9kZS0+bnNOYW1lLAoJICAgIE5VTEwpOwoJaWYgKGRlY2wgIT0gTlVMTCkgewoJICAgIHZjdHh0LT5pbm9kZS0+ZGVjbCA9IGRlY2w7CgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgPT0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkgewoJLyogVkFMIFRPRE86IENoYW5nZSB0byBwcm9wZXIgZXJyb3IgY29kZS4gKi8KCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfRUxUXzEsICh4bWxTY2hlbWFUeXBlUHRyKSB3aWxkLAoJICAgICJObyBtYXRjaGluZyBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbiBhdmFpbGFibGUsIGJ1dCAiCgkgICAgImRlbWFuZGVkIGJ5IHRoZSBzdHJpY3Qgd2lsZGNhcmQiKTsKCXJldHVybiAodmN0eHQtPmVycik7CiAgICB9CiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApIHsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoJLyoKCSogU1BFQyBWYWxpZGF0aW9uIFJ1bGU6IFNjaGVtYS1WYWxpZGl0eSBBc3Nlc3NtZW50IChFbGVtZW50KQoJKiAoMS4yLjEuMi4xKSAtICgxLjIuMS4yLjMgKQoJKgoJKiBVc2UgdGhlIHhzaTp0eXBlIGF0dHJpYnV0ZSBmb3IgdGhlIHR5cGUgZGVmaW5pdGlvbi4KCSovCglpYXR0ciA9IHhtbFNjaGVtYUdldE1ldGFBdHRySW5mbyh2Y3R4dCwKCSAgICBYTUxfU0NIRU1BX0FUVFJfSU5GT19NRVRBX1hTSV9UWVBFKTsKCWlmIChpYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYVByb2Nlc3NYU0lUeXBlKHZjdHh0LCBpYXR0ciwKCQkmKHZjdHh0LT5pbm9kZS0+dHlwZURlZiksIE5VTEwpID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtV2lsZGNhcmQiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSgpIHRvICIKCQkgICAgInByb2Nlc3MgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIERvbid0IHJldHVybiBhbiBlcnJvciBvbiBwdXJwb3NlLgoJICAgICovCgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIFNQRUMgVmFsaWRhdGlvbiBSdWxlOiBTY2hlbWEtVmFsaWRpdHkgQXNzZXNzbWVudCAoRWxlbWVudCkKICAgICoKICAgICogRmFsbGJhY2sgdG8gImFueVR5cGUiLgogICAgKi8KICAgIHZjdHh0LT5pbm9kZS0+dHlwZURlZiA9Cgl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qCiogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQ6CioKKiBUaGlzIHdpbGwgYmUgY2FsbGVkIGlmOiBub3QgbmlsbGVkLCBubyBjb250ZW50IGFuZCBhIGRlZmF1bHQvZml4ZWQKKiB2YWx1ZSBpcyBwcm92aWRlZC4KKi8KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICAgeG1sU2NoZW1hVmFsUHRyICp2YWwpCnsgICAKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgaW5vZGUgPSB2Y3R4dC0+aW5vZGU7CgogICAgLyoKICAgICogY29zLXZhbGlkLWRlZmF1bHQ6CiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpCiAgICAqIEZvciBhIHN0cmluZyB0byBiZSBhIHZhbGlkIGRlZmF1bHQgd2l0aCByZXNwZWN0IHRvIGEgdHlwZSAKICAgICogZGVmaW5pdGlvbiB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovICAgIAogICAgaWYgSVNfQ09NUExFWF9UWVBFKGlub2RlLT50eXBlRGVmKSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIFNQRUMgKDIuMSkgIml0cyB7Y29udGVudCB0eXBlfSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgoJKiBvciBtaXhlZC4iCgkqIFNQRUMgKDIuMi4yKSAiSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIG1peGVkLCB0aGVuIHRoZSB7Y29udGVudAoJKiB0eXBlfSdzIHBhcnRpY2xlIG11c3QgYmUgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBieSAKCSogUGFydGljbGUgRW1wdGlhYmxlICinMy45LjYpLiIKCSovCglpZiAoKCEgSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgJiYKCSAgICAoKCEgSEFTX01JWEVEX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB8fAoJICAgICAoISBJU19QQVJUSUNMRV9FTVBUSUFCTEUoaW5vZGUtPnR5cGVEZWYpKSkpIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BUF9DT1NfVkFMSURfREVGQVVMVF8yXzE7CgkgICAgLyogTk9URSB0aGF0IHRoaXMgY292ZXJzICgyLjIuMikgYXMgd2VsbC4gKi8KCSAgICBWRVJST1IocmV0LCBOVUxMLAoJCSJGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0LCB0aGUgdHlwZSBkZWZpbml0aW9uICIKCQkibXVzdCBiZSBhIHNpbXBsZSB0eXBlIG9yIGEgY29tcGxleCB0eXBlIHdpdGggc2ltcGxlIGNvbnRlbnQgIgoJCSJvciBtaXhlZCBjb250ZW50IGFuZCBhIHBhcnRpY2xlIGVtcHRpYWJsZSIpOwoJICAgIHJldHVybihyZXQpOwoJfQogICAgfQkKICAgIC8qCiAgICAqIDEgSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIHN0cmluZyAKICAgICogbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcgCiAgICAqIFZhbGlkICinMy4xNC40KS4KICAgICoKICAgICogQU5ECiAgICAqCiAgICAqIDIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIAogICAgKiBzdHJpbmcgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gCiAgICAqIGFzIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KICAgICovICAKICAgIGlmIChJU19TSU1QTEVfVFlQRShpbm9kZS0+dHlwZURlZikpIHsKCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJICAgIE5VTEwsIGlub2RlLT50eXBlRGVmLCB2YWx1ZSwgdmFsLCAxLCAxLCAwKTsKCiAgICB9IGVsc2UgaWYgKEhBU19TSU1QTEVfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHsKCglyZXQgPSB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJICAgIE5VTEwsIGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZURlZiwgdmFsdWUsIHZhbCwgMSwgMSwgMCk7CiAgICB9CiAgICBpZiAocmV0IDwgMCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQiLAoJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwogICAgfSAgICAKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hVkNvbnRlbnRNb2RlbENhbGxiYWNrKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgaXRlbSwKCQkJICAgICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlKQp7CiAgICBpbm9kZS0+ZGVjbCA9IGl0ZW07CiNpZmRlZiBERUJVR19DT05URU5UCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoKCWlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB7CgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJIkFVVE9NQVRPTiBjYWxsYmFjayBmb3IgJyVzJyBbZGVjbGFyYXRpb25dXG4iLAoJCXhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkJaW5vZGUtPmxvY2FsTmFtZSwgaW5vZGUtPm5zTmFtZSkpOwoJfSBlbHNlIHsKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkgICAgIkFVVE9NQVRPTiBjYWxsYmFjayBmb3IgJyVzJyBbd2lsZGNhcmRdXG4iLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRRTmFtZSgmc3RyLAoJCSAgICBpbm9kZS0+bG9jYWxOYW1lLCBpbm9kZS0+bnNOYW1lKSk7CgoJfQoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9CiNlbmRpZgp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRvclB1c2hFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKeyAgICAKICAgIHZjdHh0LT5pbm9kZSA9IHhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm8odmN0eHQpOwogICAgaWYgKHZjdHh0LT5pbm9kZSA9PSBOVUxMKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSIsCgkgICAgImNhbGxpbmcgeG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbygpIik7CglyZXR1cm4gKC0xKTsKICAgIH0gICAKICAgIHZjdHh0LT5uYkF0dHJJbmZvcyA9IDA7CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGlub2RlLAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSkKewogICAgaWYgKGlub2RlLT5mbGFncyAmIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX1ZBTFVFX05FRURFRCkKCXJldHVybiAoeG1sU2NoZW1hVkNoZWNrQ1ZDU2ltcGxlVHlwZSgKCSAgICAoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSB2Y3R4dCwgTlVMTCwKCSAgICB0eXBlLCB2YWx1ZSwgJihpbm9kZS0+dmFsKSwgMSwgMSwgMCkpOwogICAgZWxzZQoJcmV0dXJuICh4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKAoJICAgICh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LCBOVUxMLAoJICAgIHR5cGUsIHZhbHVlLCBOVUxMLCAxLCAwLCAwKSk7Cn0KCgoKLyogCiogUHJvY2VzcyBFTkQgb2YgZWxlbWVudC4KKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbm9kZSA9IHZjdHh0LT5pbm9kZTsKCiAgICBpZiAodmN0eHQtPm5iQXR0ckluZm9zICE9IDApCgl4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyh2Y3R4dCk7CiAgICBpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX05PVF9FWFBFQ1RFRCkgewoJLyoKCSogVGhpcyBlbGVtZW50IHdhcyBub3QgZXhwZWN0ZWQ7CgkqIHdlIHdpbGwgbm90IHZhbGlkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGJyb2tlbiBwYXJlbnRzLgoJKiBTa2lwIHZhbGlkYXRpb24gb2YgYWxsIGNvbnRlbnQgb2YgdGhlIHBhcmVudC4KCSovCgl2Y3R4dC0+c2tpcERlcHRoID0gdmN0eHQtPmRlcHRoIC0xOwoJZ290byBlbmRfZWxlbTsKICAgIH0gICAgCiAgICBpZiAoKGlub2RlLT50eXBlRGVmID09IE5VTEwpIHx8CgkoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRVJSX0JBRF9UWVBFKSkgewoJLyoKCSogMS4gdGhlIHR5cGUgZGVmaW5pdGlvbiBtaWdodCBiZSBtaXNzaW5nIGlmIHRoZSBlbGVtZW50IHdhcwoJKiAgICBlcnJvciBwcm9uZQoJKiAyLiBpdCBtaWdodCBiZSBhYnN0cmFjdC4KCSovCglnb3RvIGVuZF9lbGVtOwogICAgfQogICAgLyoKICAgICogQ2hlY2sgdGhlIGNvbnRlbnQgbW9kZWwuCiAgICAqLwogICAgaWYgKChpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB8fAoJKGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpKSB7CgoJLyoKCSogV29ya2Fyb3VuZCBmb3IgImFueVR5cGUiLgoJKi8KCWlmIChpbm9kZS0+dHlwZURlZi0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkKCSAgICBnb3RvIGNoYXJhY3Rlcl9jb250ZW50OwkJCQoJCglpZiAoKGlub2RlLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVCkgPT0gMCkgewoJICAgIHhtbENoYXIgKnZhbHVlc1sxMF07CgkgICAgaW50IHRlcm1pbmFsLCBuYnZhbCA9IDEwLCBuYm5lZzsKCgkgICAgaWYgKGlub2RlLT5yZWdleEN0eHQgPT0gTlVMTCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIHJlZ2V4IGNvbnRleHQuCgkJKi8KCQlpbm9kZS0+cmVnZXhDdHh0ID0KCQkgICAgeG1sUmVnTmV3RXhlY0N0eHQoaW5vZGUtPnR5cGVEZWYtPmNvbnRNb2RlbCwKCQkgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpIHhtbFNjaGVtYVZDb250ZW50TW9kZWxDYWxsYmFjaywKCQkgICAgdmN0eHQpOwoJCWlmIChpbm9kZS0+cmVnZXhDdHh0ID09IE5VTEwpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJCSJmYWlsZWQgdG8gY3JlYXRlIGEgcmVnZXggY29udGV4dCIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gY3JlYXRlIG9uICclcydcbiIsIGlub2RlLT5sb2NhbE5hbWUpOwojZW5kaWYJICAgIAoJICAgIH0KCSAgICAvKgoJICAgICogR2V0IGhvbGQgb2YgdGhlIHN0aWxsIGV4cGVjdGVkIGNvbnRlbnQsIHNpbmNlIGEgZnVydGhlcgoJICAgICogY2FsbCB0byB4bWxSZWdFeGVjUHVzaFN0cmluZygpIHdpbGwgbG9vc2UgdGhpcyBpbmZvcm1hdGlvbi4KCSAgICAqLyAKCSAgICB4bWxSZWdFeGVjTmV4dFZhbHVlcyhpbm9kZS0+cmVnZXhDdHh0LAoJCSZuYnZhbCwgJm5ibmVnLCAmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKGlub2RlLT5yZWdleEN0eHQsIE5VTEwsIE5VTEwpOwoJICAgIGlmIChyZXQgPD0gMCkgewkJCgkJLyoKCQkqIFN0aWxsIG1pc3Npbmcgc29tZXRoaW5nLgoJCSovCgkJcmV0ID0gMTsKCQlpbm9kZS0+ZmxhZ3MgfD0KCQkgICAgWE1MX1NDSEVNQV9FTEVNX0lORk9fRVJSX0JBRF9DT05URU5UOwoJCXhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsIE5VTEwsIE5VTEwsCgkJICAgICJNaXNzaW5nIGNoaWxkIGVsZW1lbnQocykiLAoJCSAgICBuYnZhbCwgbmJuZWcsIHZhbHVlcyk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAiQVVUT01BVE9OIG1pc3NpbmcgRVJST1Igb24gJyVzJ1xuIiwKCQkgICAgaW5vZGUtPmxvY2FsTmFtZSk7CiNlbmRpZgoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIENvbnRlbnQgbW9kZWwgaXMgc2F0aXNmaWVkLgoJCSovCgkJcmV0ID0gMDsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICJBVVRPTUFUT04gc3VjY2VlZGVkIG9uICclcydcbiIsCgkJICAgIGlub2RlLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICB9CgoJfQogICAgfQogICAgaWYgKGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpCglnb3RvIGVuZF9lbGVtOwoKY2hhcmFjdGVyX2NvbnRlbnQ6CgogICAgaWYgKHZjdHh0LT52YWx1ZSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUodmN0eHQtPnZhbHVlKTsKCXZjdHh0LT52YWx1ZSA9IE5VTEw7CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBjaGFyYWN0ZXIgY29udGVudC4KICAgICovCiAgICBpZiAoaW5vZGUtPmRlY2wgPT0gTlVMTCkgewoJLyoKCSogU3BlZWR1cCBpZiBubyBkZWNsYXJhdGlvbiBleGlzdHMuCgkqLwoJaWYgKElTX1NJTVBMRV9UWVBFKGlub2RlLT50eXBlRGVmKSkgewkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYsIGlub2RlLT52YWx1ZSk7Cgl9IGVsc2UgaWYgKEhBU19TSU1QTEVfQ09OVEVOVChpbm9kZS0+dHlwZURlZikpIHsKCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCWlub2RlLCBpbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGVEZWYsCgkJaW5vZGUtPnZhbHVlKTsKCX0JCQoJaWYgKHJldCA8IDApIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtIiwKCQkiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJZ290byBlbmRfZWxlbTsKICAgIH0KICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDUgCiAgICAqIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDUuMSAKICAgICogSWYgdGhlIGRlY2xhcmF0aW9uIGhhcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgCiAgICAqIHRoZSBpdGVtIGhhcyBuZWl0aGVyIGVsZW1lbnQgbm9yIGNoYXJhY3RlciBbY2hpbGRyZW5dIGFuZCAKICAgICogY2xhdXNlIDMuMiBoYXMgbm90IGFwcGxpZWQsIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIGlmICgoaW5vZGUtPmRlY2wtPnZhbHVlICE9IE5VTEwpICYmCgkoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpICYmIAoJKCEgSU5PREVfTklMTEVEKGlub2RlKSkpIHsKCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDUuMS4xIAoJKiBJZiB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGlzIGEgt2xvY2FsIHR5cGUgZGVmaW5pdGlvbrcKCSogdGhlbiB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fQoJKiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgZGVmYXVsdCBmb3IgdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBhcyAKCSogZGVmaW5lZCBpbiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkgKKczLjMuNikuIAoJKi8KCS8qIAoJKiBOT1RFOiAnbG9jYWwnIGFib3ZlIG1lYW5zIHR5cGVzIGFxdWlyZWQgYnkgeHNpOnR5cGUuCgkqIE5PVEU6IEFsdGhvdWdoIHRoZSAqY2Fub25pY2FsKiB2YWx1ZSBpcyBzdGF0ZWQsIGl0IGlzIG5vdAoJKiByZWxldmFudCBpZiBjYW5vbmljYWwgb3Igbm90LiBBZGRpdGlvbmFsbHkgWE1MIFNjaGVtYSAxLjEKCSogd2lsbCByZW1vdmVkIHRoaXMgcmVxdWlyZW1lbnQgYXMgd2VsbC4KCSovCglpZiAoaW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fTE9DQUxfVFlQRSkgewoKCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh2Y3R4dCwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUsICYoaW5vZGUtPnZhbCkpOwoJICAgIGlmIChyZXQgIT0gMCkgewoJCWlmIChyZXQgPCAwKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWdvdG8gZW5kX2VsZW07CgkgICAgfQoJICAgIC8qCgkgICAgKiBTdG9wIGhlcmUsIHRvIGF2b2lkIHJlZHVuZGFudCB2YWxpZGF0aW9uIG9mIHRoZSB2YWx1ZQoJICAgICogKHNlZSBmb2xsb3dpbmcpLgoJICAgICovCgkgICAgZ290byBkZWZhdWx0X3Bzdmk7Cgl9CQoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjIgCgkqIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gd2l0aCB0aGUgY2Fub25pY2FsIGxleGljYWwgCgkqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgdXNlZCBhcyBpdHMgCgkqILdub3JtYWxpemVkIHZhbHVltyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSAKCSogt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKQoJKiAopzMuMy40KS4KCSovCSAgICAKCWlmIChJU19TSU1QTEVfVFlQRShpbm9kZS0+dHlwZURlZikpIHsKCSAgICByZXQgPSB4bWxTY2hlbWFWQ2hlY2tJTm9kZURhdGFUeXBlKHZjdHh0LAoJCWlub2RlLCBpbm9kZS0+dHlwZURlZiwgaW5vZGUtPmRlY2wtPnZhbHVlKTsKCX0gZWxzZSBpZiAoSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJaW5vZGUsIGlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZURlZiwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUpOwkgICAgCgl9CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWQ2hlY2tDVkNTaW1wbGVUeXBlKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGVuZF9lbGVtOwoJfQoKZGVmYXVsdF9wc3ZpOgoJLyoKCSogUFNWSTogQ3JlYXRlIGEgdGV4dCBub2RlIG9uIHRoZSBpbnN0YW5jZSBlbGVtZW50LgoJKi8KCWlmICgodmN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgJiYKCSAgICAoaW5vZGUtPm5vZGUgIT0gTlVMTCkpIHsKCSAgICB4bWxOb2RlUHRyIHRleHRDaGlsZDsKCSAgICB4bWxDaGFyICpub3JtVmFsdWU7CgkgICAgLyoKCSAgICAqIFZBTCBUT0RPOiBOb3JtYWxpemUgdGhlIHZhbHVlLgoJICAgICovCSAgICAKCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFOb3JtYWxpemVWYWx1ZShpbm9kZS0+dHlwZURlZiwKCQlpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkgewoJCXRleHRDaGlsZCA9IHhtbE5ld1RleHQoQkFEX0NBU1Qgbm9ybVZhbHVlKTsKCQl4bWxGcmVlKG5vcm1WYWx1ZSk7CgkgICAgfSBlbHNlCgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJICAgIGlmICh0ZXh0Q2hpbGQgPT0gTlVMTCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0iLAoJCSAgICAiY2FsbGluZyB4bWxOZXdUZXh0KCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0gZWxzZQoJCXhtbEFkZENoaWxkKGlub2RlLT5ub2RlLCB0ZXh0Q2hpbGQpOwkgICAgCgl9CgkKICAgIH0gZWxzZSBpZiAoISBJTk9ERV9OSUxMRUQoaW5vZGUpKSB7CQoJLyoKCSogNS4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IAoJKiB0byB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IAoJKiBWYWxpZCAoVHlwZSkgKKczLjMuNCkuCgkqLwkKCWlmIChJU19TSU1QTEVfVFlQRShpbm9kZS0+dHlwZURlZikpIHsKCSAgICAgLyoKCSAgICAqIFNQRUMgKGN2Yy10eXBlKSAoMy4xKQoJICAgICogIklmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAuLi4iCgkgICAgKiAoMy4xLjMpICJJZiBjbGF1c2UgMy4yIG9mIEVsZW1lbnQgTG9jYWxseSBWYWxpZAoJICAgICogKEVsZW1lbnQpICinMy4zLjQpIGRpZCBub3QgYXBwbHksIHRoZW4gdGhlILdub3JtYWxpemVkIHZhbHVltwoJICAgICogbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQKCSAgICAqIGJ5IFN0cmluZyBWYWxpZCAopzMuMTQuNCkuCgkgICAgKi8JICAgIAoJICAgIHJldCA9IHhtbFNjaGVtYVZDaGVja0lOb2RlRGF0YVR5cGUodmN0eHQsCgkJICAgIGlub2RlLCBpbm9kZS0+dHlwZURlZiwgaW5vZGUtPnZhbHVlKTsKCX0gZWxzZSBpZiAoSEFTX1NJTVBMRV9DT05URU5UKGlub2RlLT50eXBlRGVmKSkgewoJICAgIC8qCgkgICAgKiBTUEVDIChjdmMtdHlwZSkgKDMuMikgIklmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBjb21wbGV4IHR5cGUKCSAgICAqIGRlZmluaXRpb24sIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlCgkgICAgKiC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUgdHlwZSBkZWZpbml0aW9uIGFzIHBlcgoJICAgICogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpICinMy40LjQpOyIKCSAgICAqCgkgICAgKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMi4yKQoJICAgICogIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIC4uLiAKCSAgICAqIHRoZSC3bm9ybWFsaXplZCB2YWx1Zbcgb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcwoJICAgICogt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGFzCgkgICAgKiBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVkNoZWNrSU5vZGVEYXRhVHlwZSh2Y3R4dCwKCQlpbm9kZSwgaW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlRGVmLCBpbm9kZS0+dmFsdWUpOwoJfQkKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZDaGVja0NWQ1NpbXBsZVR5cGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZW5kX2VsZW07Cgl9CgkvKgoJKiA1LjIuMiBJZiB0aGVyZSBpcyBhIGZpeGVkIHt2YWx1ZSBjb25zdHJhaW50fSBhbmQgY2xhdXNlIDMuMiBoYXMgCgkqIG5vdCBhcHBsaWVkLCBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJaWYgKChpbm9kZS0+ZGVjbC0+dmFsdWUgIT0gTlVMTCkgJiYKCSAgICAoaW5vZGUtPmRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkpIHsKCgkgICAgLyoKCSAgICAqIFRPRE86IFdlIHdpbGwgbmVlZCBhIGNvbXB1dGVkIHZhbHVlLCB3aGVuIGNvbXBhcmlzb24gaXMKCSAgICAqIGRvbmUgb24gY29tcHV0ZWQgdmFsdWVzLgoJICAgICovCgkgICAgLyoKCSAgICAqIDUuMi4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqLwoJICAgIGlmIChpbm9kZS0+ZmxhZ3MgJgoJCSAgICBYTUxfU0NIRU1BX0VMRU1fSU5GT19IQVNfRUxFTV9DT05URU5UKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8xOwoJCVZFUlJPUihyZXQsIE5VTEwsCgkJICAgICJUaGUgY29udGVudCBtdXN0IG5vdCBjb250YWludCBlbGVtZW50IG5vZGVzIHNpbmNlICIKCQkgICAgInRoZXJlIGlzIGEgZml4ZWQgdmFsdWUgY29uc3RyYWludCIpOwoJCWdvdG8gZW5kX2VsZW07CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogNS4yLjIuMiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgCgkJKiBiZSB0cnVlOgoJCSovCQkKCQlpZiAoSEFTX01JWEVEX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIG1peGVkLCB0aGVuIHRoZSAqaW5pdGlhbCB2YWx1ZSogb2YgdGhlIAoJCSAgICAqIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gCgkJICAgICogb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKgoJCSAgICAqIC4uLiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBpcyB0aGUgc3RyaW5nIGNvbXBvc2VkIG9mLCBpbiBvcmRlciwgdGhlIAoJCSAgICAqIFtjaGFyYWN0ZXIgY29kZV0gb2YgZWFjaCBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gaXRlbSBpbiAKCQkgICAgKiB0aGUgW2NoaWxkcmVuXSBvZiB0aGF0IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbS4KCQkgICAgKi8JCSAgIAoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChpbm9kZS0+dmFsdWUsIGlub2RlLT5kZWNsLT52YWx1ZSkpewoJCQkvKiAKCQkJKiBWQUwgVE9ETzogUmVwb3J0IGludmFsaWQgJiBleHBlY3RlZCB2YWx1ZXMgYXMgd2VsbC4KCQkJKiBWQUwgVE9ETzogSW1wbGVtZW50IHRoZSBjYW5vbmljYWwgc3R1ZmYuCgkJCSovCgkJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8xOwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsIAoJCQkgICAgcmV0LCBOVUxMLCBOVUxMLAoJCQkgICAgIlRoZSBpbml0aWFsIHZhbHVlICclcycgZG9lcyBub3QgbWF0Y2ggdGhlIGZpeGVkICIKCQkJICAgICJ2YWx1ZSBjb25zdHJhaW50ICclcyciLAoJCQkgICAgaW5vZGUtPnZhbHVlLCBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJCQlnb3RvIGVuZF9lbGVtOwoJCSAgICB9CgkJfSBlbHNlIGlmIChIQVNfU0lNUExFX0NPTlRFTlQoaW5vZGUtPnR5cGVEZWYpKSB7CgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4yIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCgkJICAgICogKmFjdHVhbCB2YWx1ZSogb2YgdGhlIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIAoJCSAgICAqIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBWQUwgVE9ETzogKmFjdHVhbCB2YWx1ZSogaXMgdGhlIG5vcm1hbGl6ZWQgdmFsdWUsIGltcGwuCgkJICAgICogICAgICAgICAgIHRoaXMuCgkJICAgICogVkFMIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJICAgICogVkFMIFRPRE86IEltcGxlbWVudCBhIGNvbXBhcmlzb24gd2l0aCB0aGUgY29tcHV0ZWQgdmFsdWVzLgoJCSAgICAqLwoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChpbm9kZS0+dmFsdWUsCgkJCSAgICBpbm9kZS0+ZGVjbC0+dmFsdWUpKSB7CgkJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8yOwoJCQl4bWxTY2hlbWFDdXN0b21FcnIoKHhtbFNjaGVtYUFic3RyYWN0Q3R4dFB0cikgdmN0eHQsCgkJCSAgICByZXQsIE5VTEwsIE5VTEwsCgkJCSAgICAiVGhlIGFjdHVhbCB2YWx1ZSAnJXMnIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCAiCgkJCSAgICAidmFsdWUgY29uc3RyYWludCAnJXMnIiwgCgkJCSAgICBpbm9kZS0+dmFsdWUsCgkJCSAgICBpbm9kZS0+ZGVjbC0+dmFsdWUpOwoJCQlnb3RvIGVuZF9lbGVtOwoJCSAgICB9CQkgICAgCgkJfQoJICAgIH0JICAgIAoJfQogICAgfQogICAgCmVuZF9lbGVtOgogICAgaWYgKHZjdHh0LT5kZXB0aCA8IDApIHsKCS8qIFRPRE86IHJhaXNlIGVycm9yPyAqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+ZGVwdGggPT0gdmN0eHQtPnNraXBEZXB0aCkKCXZjdHh0LT5za2lwRGVwdGggPSAtMTsKICAgIC8qCiAgICAqIEV2YWx1YXRlIHRoZSBoaXN0b3J5IG9mIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAgICAqLyAgICAKICAgIGlmICh4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHZjdHh0LCB2Y3R4dC0+ZGVwdGgpID09IC0xKQoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIC8qCiAgICAqIFRPRE86IDYgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIGVhY2ggb2YgCiAgICAqIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uc30gYXMgcGVyIElkZW50aXR5LWNvbnN0cmFpbnQgCiAgICAqIFNhdGlzZmllZCAopzMuMTEuNCkuCiAgICAqLwogICAgLyoKICAgICogVmFsaWRhdGUgSURDIGtleXJlZnMuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmKHZjdHh0KSA9PSAtMSkKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICAvKgogICAgKiBNZXJnZS9mcmVlIHRoZSBJREMgdGFibGUuCiAgICAqLwogICAgaWYgKGlub2RlLT5pZGNUYWJsZSAhPSBOVUxMKSB7CiNpZmRlZiBERUJVR19JREMKCXhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlKHN0ZG91dCwKCSAgICBpbm9kZS0+bnNOYW1lLAoJICAgIGlub2RlLT5sb2NhbE5hbWUsCgkgICAgaW5vZGUtPmlkY1RhYmxlKTsKI2VuZGlmCglpZiAodmN0eHQtPmRlcHRoID4gMCkgewoJICAgIC8qCgkgICAgKiBNZXJnZSB0aGUgSURDIG5vZGUgdGFibGUgd2l0aCB0aGUgdGFibGUgb2YgdGhlIHBhcmVudCBub2RlLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUJ1YmJsZUlEQ05vZGVUYWJsZXModmN0eHQpID09IC0xKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9CQogICAgfQogICAgLyoKICAgICogQ2xlYXIgdGhlIGN1cnJlbnQgaWVsZW0uCiAgICAqIFZBTCBUT0RPOiBEb24ndCBmcmVlIHRoZSBQU1ZJIElEQyB0YWJsZXMgaWYgdGhleSBhcmUKICAgICogcmVxdWVzdGVkIGZvciB0aGUgUFNWSS4KICAgICovCiAgICB4bWxTY2hlbWFDbGVhckVsZW1JbmZvKGlub2RlKTsKICAgIC8qCiAgICAqIFNraXAgZnVydGhlciBwcm9jZXNzaW5nIGlmIHdlIGFyZSBvbiB0aGUgdmFsaWRhdGlvbiByb290LgogICAgKi8KICAgIGlmICh2Y3R4dC0+ZGVwdGggPT0gMCkgewoJdmN0eHQtPmRlcHRoLS07Cgl2Y3R4dC0+aW5vZGUgPSBOVUxMOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIFJlc2V0IHRoZSBidWJibGVEZXB0aCBpZiBuZWVkZWQuCiAgICAqLwogICAgaWYgKHZjdHh0LT5haWRjcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENBdWdQdHIgYWlkYyA9IHZjdHh0LT5haWRjczsKCWRvIHsKCSAgICBpZiAoYWlkYy0+YnViYmxlRGVwdGggPT0gdmN0eHQtPmRlcHRoKSB7CgkJLyoKCQkqIEEgYnViYmxlRGVwdGggb2YgYSBrZXkvdW5pcXVlIElEQyBtYXRjaGVzIHRoZSBjdXJyZW50CgkJKiBkZXB0aCwgdGhpcyBtZWFucyB0aGF0IHdlIGFyZSBsZWF2aW5nIHRoZSBzY29wZSBvZiB0aGUKCQkqIHRvcC1tb3N0IGtleXJlZiBJREMuCgkJKi8KCQlhaWRjLT5idWJibGVEZXB0aCA9IC0xOwoJICAgIH0KCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7CiAgICB9CiAgICB2Y3R4dC0+ZGVwdGgtLTsgICAgICAgIAogICAgdmN0eHQtPmlub2RlID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwogICAgLyoKICAgICogVkFMIFRPRE86IDcgSWYgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyB0aGUgt3ZhbGlkYXRpb24gcm9vdLcsIGl0IG11c3QgYmUgCiAgICAqILd2YWxpZLcgcGVyIFZhbGlkYXRpb24gUm9vdCBWYWxpZCAoSUQvSURSRUYpICinMy4zLjQpLgogICAgKi8KICAgIHJldHVybiAocmV0KTsKCmludGVybmFsX2Vycm9yOgogICAgdmN0eHQtPmVyciA9IC0xOwogICAgcmV0dXJuICgtMSk7Cn0KCi8qCiogMy40LjQgQ29tcGxleCBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwoqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpIChjdmMtY29tcGxleC10eXBlKQoqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hTm9kZUluZm9QdHIgcGllbGVtOwogICAgeG1sU2NoZW1hVHlwZVB0ciBwdHlwZTsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICh2Y3R4dC0+ZGVwdGggPD0gMCkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJICAgICJub3QgaW50ZW5kZWQgZm9yIHRoZSB2YWxpZGF0aW9uIHJvb3QiKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgcGllbGVtID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdOwogICAgaWYgKHBpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkKCXBpZWxlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFk7CiAgICAvKgogICAgKiBIYW5kbGUgJ25pbGxlZCcgZWxlbWVudHMuCiAgICAqLwogICAgaWYgKElOT0RFX05JTExFRChwaWVsZW0pKSB7CgkvKgoJKiBTUEVDIChjdmMtZWx0KSAoMy4zLjQpIDogKDMuMi4xKQoJKi8KCUFDVElWQVRFX1BBUkVOVF9FTEVNOwoJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMTsKCVZFUlJPUihyZXQsIE5VTEwsCgkgICAgIk5laXRoZXIgY2hhcmFjdGVyIG5vciBlbGVtZW50IGNvbnRlbnQgaXMgYWxsb3dlZCwgIgoJICAgICJiZWNhdXNlIHRoZSBlbGVtZW50IHdhcyAnbmlsbGVkJyIpOwoJQUNUSVZBVEVfRUxFTTsKCWdvdG8gdW5leHBlY3RlZF9lbGVtOwogICAgfQoKICAgIHB0eXBlID0gcGllbGVtLT50eXBlRGVmOwoKICAgIGlmIChwdHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkgewoJLyoKCSogV29ya2Fyb3VuZCBmb3IgImFueVR5cGUiOiB3ZSBoYXZlIGN1cnJlbnRseSBubyBjb250ZW50IG1vZGVsCgkqIGFzc2lnbmVkIGZvciAiYW55VHlwZSIsIHNvIGhhbmRsZSBpdCBleHBsaWNpdGVseS4KCSogImFueVR5cGUiIGhhcyBhbiB1bmJvdW5kZWQsIGxheCAiYW55IiB3aWxkY2FyZC4KCSovCgl2Y3R4dC0+aW5vZGUtPmRlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKHZjdHh0LT5zY2hlbWEsCgkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsCgkgICAgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoKCWlmICh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUF0dHJJbmZvUHRyIGlhdHRyOwoJICAgIC8qCgkgICAgKiBQcm9jZXNzICJ4c2k6dHlwZSIuCgkgICAgKiBTUEVDIChjdmMtYXNzZXNzLWVsdCkgKDEuMi4xLjIuMSkgLSAoMS4yLjEuMi4zKQoJICAgICovCgkgICAgaWF0dHIgPSB4bWxTY2hlbWFHZXRNZXRhQXR0ckluZm8odmN0eHQsCgkJWE1MX1NDSEVNQV9BVFRSX0lORk9fTUVUQV9YU0lfVFlQRSk7CgkgICAgaWYgKGlhdHRyICE9IE5VTEwpIHsKCQlyZXQgPSB4bWxTY2hlbWFQcm9jZXNzWFNJVHlwZSh2Y3R4dCwgaWF0dHIsCgkJICAgICYodmN0eHQtPmlub2RlLT50eXBlRGVmKSwgTlVMTCk7CgkJaWYgKHJldCAhPSAwKSB7CgkJICAgIGlmIChyZXQgPT0gLTEpIHsKCQkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hUHJvY2Vzc1hTSVR5cGUoKSB0byAiCgkJCSAgICAicHJvY2VzcyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICByZXR1cm4gKHJldCk7CgkJfQoJICAgIH0gZWxzZSB7CgkJIC8qCgkJICogRmFsbGJhY2sgdG8gImFueVR5cGUiLgoJCSAqCgkJICogU1BFQyAoY3ZjLWFzc2Vzcy1lbHQpCgkJICogIklmIHRoZSBpdGVtIGNhbm5vdCBiZSC3c3RyaWN0bHkgYXNzZXNzZWS3LCBbLi4uXQoJCSAqIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHNjaGVtYSB2YWxpZGl0eSBtYXkgYmUgbGF4bHkKCQkgKiBhc3Nlc3NlZCBpZiBpdHMgt2NvbnRleHQtZGV0ZXJtaW5lZCBkZWNsYXJhdGlvbrcgaXMgbm90CgkJICogc2tpcCBieSC3dmFsaWRhdGluZ7cgd2l0aCByZXNwZWN0IHRvIHRoZSC3dXItdHlwZQoJCSAqIGRlZmluaXRpb263IGFzIHBlciBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpICinMy4zLjQpLiIKCQkqLwoJCXZjdHh0LT5pbm9kZS0+dHlwZURlZiA9CgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CgogICAgc3dpdGNoIChwdHlwZS0+Y29udGVudFR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgoJICAgIC8qCgkgICAgKiBTUEVDICgyLjEpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlCgkgICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBvciBlbGVtZW50CgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgoJICAgICovCgkgICAgQUNUSVZBVEVfUEFSRU5UX0VMRU0KCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMTsKCSAgICBWRVJST1IocmV0LCBOVUxMLAoJCSJFbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVtcHR5Iik7CgkgICAgQUNUSVZBVEVfRUxFTQoJICAgIGdvdG8gdW5leHBlY3RlZF9lbGVtOwoJICAgIGJyZWFrOwoKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOiB7CgkgICAgeG1sUmVnRXhlY0N0eHRQdHIgcmVnZXhDdHh0OwoJICAgIHhtbENoYXIgKnZhbHVlc1sxMF07CgkgICAgaW50IHRlcm1pbmFsLCBuYnZhbCA9IDEwLCBuYm5lZzsKCgkgICAgLyogVkFMIFRPRE86IE9wdGltaXplZCAiYW55VHlwZSIgdmFsaWRhdGlvbi4qLwoKCSAgICBpZiAocHR5cGUtPmNvbnRNb2RlbCA9PSBOVUxMKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVDaGlsZEVsZW0iLAoJCSAgICAidHlwZSBoYXMgZWxlbSBjb250ZW50IGJ1dCBubyBjb250ZW50IG1vZGVsIik7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBTYWZldHkgYmVsZiBmb3IgZXZhbHVhdGlvbiBpZiB0aGUgY29udC4gbW9kZWwgd2FzIGFscmVhZHkKCSAgICAqIGV4YW1pbmVkIHRvIGJlIGludmFsaWQuCgkgICAgKi8KCSAgICBpZiAocGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkgICAgInZhbGlkYXRpbmcgZWxlbSwgYnV0IGVsZW0gY29udGVudCBpcyBhbHJlYWR5IGludmFsaWQiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgoJICAgIHJlZ2V4Q3R4dCA9IHBpZWxlbS0+cmVnZXhDdHh0OwoJICAgIGlmIChyZWdleEN0eHQgPT0gTlVMTCkgewoJCS8qCgkJKiBDcmVhdGUgdGhlIHJlZ2V4IGNvbnRleHQuCgkJKi8KCQlyZWdleEN0eHQgPSB4bWxSZWdOZXdFeGVjQ3R4dChwdHlwZS0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykgeG1sU2NoZW1hVkNvbnRlbnRNb2RlbENhbGxiYWNrLAoJCSAgICB2Y3R4dCk7CgkJaWYgKHJlZ2V4Q3R4dCA9PSBOVUxMKSB7CgkJICAgIFZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkJImZhaWxlZCB0byBjcmVhdGUgYSByZWdleCBjb250ZXh0Iik7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlwaWVsZW0tPnJlZ2V4Q3R4dCA9IHJlZ2V4Q3R4dDsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJBVVRPTUFUQSBjcmVhdGUgb24gJyVzJ1xuIiwKCQkgICAgcGllbGVtLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICB9CgoJICAgIC8qCgkgICAgKiBTUEVDICgyLjQpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZWxlbWVudC1vbmx5IG9yIG1peGVkLAoJICAgICogdGhlbiB0aGUgc2VxdWVuY2Ugb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzCgkgICAgKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgaWYgYW55LCB0YWtlbiBpbgoJICAgICogb3JkZXIsIGlzILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSB7Y29udGVudCB0eXBlfSdzCgkgICAgKiBwYXJ0aWNsZSwgYXMgZGVmaW5lZCBpbiBFbGVtZW50IFNlcXVlbmNlIExvY2FsbHkgVmFsaWQKCSAgICAqIChQYXJ0aWNsZSkgKKczLjkuNCkuIgoJICAgICovCgkgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcyKHJlZ2V4Q3R4dCwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwKCQl2Y3R4dC0+aW5vZGUtPm5zTmFtZSwKCQl2Y3R4dC0+aW5vZGUpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCSAgICBpZiAocmV0IDwgMCkKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIHB1c2ggRVJST1IgZm9yICclcycgb24gJyVzJ1xuIiwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgcGllbGVtLT5sb2NhbE5hbWUpOwoJICAgIGVsc2UKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiQVVUT01BVE9OIHB1c2ggT0sgZm9yICclcycgb24gJyVzJ1xuIiwKCQl2Y3R4dC0+aW5vZGUtPmxvY2FsTmFtZSwgcGllbGVtLT5sb2NhbE5hbWUpOwojZW5kaWYKCSAgICBpZiAodmN0eHQtPmVyciA9PSBYTUxfU0NIRU1BVl9JTlRFUk5BTCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sUmVnRXhlY1B1c2hTdHJpbmcyKCkiKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxSZWdFeGVjRXJySW5mbyhyZWdleEN0eHQsIE5VTEwsICZuYnZhbCwgJm5ibmVnLAoJCSAgICAmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJCXhtbFNjaGVtYUNvbXBsZXhUeXBlRXJyKCh4bWxTY2hlbWFBYnN0cmFjdEN0eHRQdHIpIHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsIE5VTEwsTlVMTCwKCQkgICAgIlRoaXMgZWxlbWVudCBpcyBub3QgZXhwZWN0ZWQiLAoJCSAgICBuYnZhbCwgbmJuZWcsIHZhbHVlcyk7CgkJcmV0ID0gdmN0eHQtPmVycjsKCQlnb3RvIHVuZXhwZWN0ZWRfZWxlbTsKCSAgICB9IGVsc2UKCQlyZXQgPSAwOwoJfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CgkgICAgQUNUSVZBVEVfUEFSRU5UX0VMRU0KCSAgICBpZiAoSVNfQ09NUExFWF9UWVBFKHB0eXBlKSkgewoJCS8qCgkJKiBTUEVDIChjdmMtY29tcGxleC10eXBlKSAoMi4yKQoJCSogIklmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4KCQkqIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGVsZW1lbnQgaW5mb3JtYXRpb24KCQkqIGl0ZW0gW2NoaWxkcmVuXSwgLi4uIgoJCSovCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJVkVSUk9SKHJldCwgTlVMTCwgIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJCSAgICAiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIFNQRUMgKGN2Yy10eXBlKSAoMy4xLjIpICJUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QKCQkqIGhhdmUgbm8gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uIgoJCSovCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzI7CgkJVkVSUk9SKHJldCwgTlVMTCwgIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJCSAgICAiYmVjYXVzZSB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIHNpbXBsZSIpOwoJICAgIH0KCSAgICBBQ1RJVkFURV9FTEVNCgkgICAgcmV0ID0gdmN0eHQtPmVycjsKCSAgICBnb3RvIHVuZXhwZWN0ZWRfZWxlbTsKCSAgICBicmVhazsKCglkZWZhdWx0OgoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp1bmV4cGVjdGVkX2VsZW06CiAgICAvKgogICAgKiBQb3AgdGhpcyBlbGVtZW50IGFuZCBzZXQgdGhlIHNraXBEZXB0aCB0byBza2lwCiAgICAqIGFsbCBmdXJ0aGVyIGNvbnRlbnQgb2YgdGhlIHBhcmVudCBlbGVtZW50LgogICAgKi8KICAgIHZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICB2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0VSUl9OT1RfRVhQRUNURUQ7CiAgICBwaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VSUl9CQURfQ09OVEVOVDsKICAgIHJldHVybiAocmV0KTsKfQoKI2RlZmluZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9QRVJTSVNUIDEKI2RlZmluZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9DUkVBVEVEIDIKI2RlZmluZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9WT0xBVElMRSAzCgpzdGF0aWMgaW50CnhtbFNjaGVtYVZQdXNoVGV4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICBpbnQgbm9kZVR5cGUsIGNvbnN0IHhtbENoYXIgKnZhbHVlLCBpbnQgbGVuLAoJCSAgaW50IG1vZGUsIGludCAqY29uc3VtZWQpCnsKICAgIC8qCiAgICAqIFVuZm9ydHVuYXRlbHkgd2UgaGF2ZSB0byBkdXBsaWNhdGUgdGhlIHRleHQgc29tZXRpbWVzLgogICAgKiBPUFRJTUlaRTogTWF5YmUgd2UgY291bGQgc2tpcCBpdCwgaWY6CiAgICAqICAgMS4gY29udGVudCB0eXBlIGlzIHNpbXBsZQogICAgKiAgIDIuIHdoaXRlc3BhY2UgaXMgImNvbGxhcHNlIgogICAgKiAgIDMuIGl0IGNvbnNpc3RzIG9mIHdoaXRlc3BhY2Ugb25seQogICAgKgogICAgKiBQcm9jZXNzIGNoYXJhY3RlciBjb250ZW50LgogICAgKi8KICAgIGlmIChjb25zdW1lZCAhPSBOVUxMKQoJKmNvbnN1bWVkID0gMDsKICAgIGlmIChJTk9ERV9OSUxMRUQodmN0eHQtPmlub2RlKSkgewoJLyogCgkqIFNQRUMgY3ZjLWVsdCAoMy4zLjQgLSAzLjIuMSkKCSogIlRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBoYXZlIG5vIGNoYXJhY3RlciBvcgoJKiBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4iCgkqLwoJVkVSUk9SKFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzEsIE5VTEwsCgkgICAgIk5laXRoZXIgY2hhcmFjdGVyIG5vciBlbGVtZW50IGNvbnRlbnQgaXMgYWxsb3dlZCAiCgkgICAgImJlY2F1c2UgdGhlIGVsZW1lbnQgaXMgJ25pbGxlZCciKTsKCXJldHVybiAodmN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgKiBTUEVDICgyLjEpICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlCiAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQKICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLiIKICAgICovCiAgICBpZiAodmN0eHQtPmlub2RlLT50eXBlRGVmLT5jb250ZW50VHlwZSA9PQoJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgeyAgICAKCVZFUlJPUihYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMSwgTlVMTCwKCSAgICAiQ2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCSAgICAiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVtcHR5Iik7CglyZXR1cm4gKHZjdHh0LT5lcnIpOwogICAgfQoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmNvbnRlbnRUeXBlID09CgkgICAgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSB7CglpZiAoKG5vZGVUeXBlICE9IFhNTF9URVhUX05PREUpIHx8CgkgICAgKCEgeG1sU2NoZW1hSXNCbGFuaygoeG1sQ2hhciAqKSB2YWx1ZSwgbGVuKSkpIHsKCSAgICAvKiAKCSAgICAqIFNQRUMgY3ZjLWNvbXBsZXgtdHlwZSAoMi4zKSAKCSAgICAqICJJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZWxlbWVudC1vbmx5LCB0aGVuIHRoZSAKCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIGluZm9ybWF0aW9uIAoJICAgICogaXRlbSBbY2hpbGRyZW5dIG90aGVyIHRoYW4gdGhvc2Ugd2hvc2UgW2NoYXJhY3RlciAKCSAgICAqIGNvZGVdIGlzIGRlZmluZWQgYXMgYSB3aGl0ZSBzcGFjZSBpbiBbWE1MIDEuMCAoU2Vjb25kIAoJICAgICogRWRpdGlvbildLiIKCSAgICAqLwoJICAgIFZFUlJPUihYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMywgTlVMTCwKCQkiQ2hhcmFjdGVyIGNvbnRlbnQgb3RoZXIgdGhhbiB3aGl0ZXNwYWNlIGlzIG5vdCBhbGxvd2VkICIKCQkiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzICdlbGVtZW50LW9ubHknIik7CgkgICAgcmV0dXJuICh2Y3R4dC0+ZXJyKTsKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAKICAgIGlmICgodmFsdWUgPT0gTlVMTCkgfHwgKHZhbHVlWzBdID09IDApKQoJcmV0dXJuICgwKTsKICAgIC8qCiAgICAqIFNhdmUgdGhlIHZhbHVlLgogICAgKiBOT1RFIHRoYXQgZXZlbiBpZiB0aGUgY29udGVudCB0eXBlIGlzICptaXhlZCosIHdlIG5lZWQgdGhlCiAgICAqICppbml0aWFsIHZhbHVlKiBmb3IgZGVmYXVsdC9maXhlZCB2YWx1ZSBjb25zdHJhaW50cy4KICAgICovCiAgICBpZiAoKHZjdHh0LT5pbm9kZS0+dHlwZURlZi0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSAmJgoJKCh2Y3R4dC0+aW5vZGUtPmRlY2wgPT0gTlVMTCkgfHwKCSh2Y3R4dC0+aW5vZGUtPmRlY2wtPnZhbHVlID09IE5VTEwpKSkKCXJldHVybiAoMCk7CiAgICAKICAgIGlmICh2Y3R4dC0+aW5vZGUtPnZhbHVlID09IE5VTEwpIHsKCS8qCgkqIFNldCB0aGUgdmFsdWUuCgkqLwoJc3dpdGNoIChtb2RlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1BVU0hfVEVYVF9QRVJTSVNUOgoJCS8qCgkJKiBXaGVuIHdvcmtpbmcgb24gYSB0cmVlLgoJCSovCgkJdmN0eHQtPmlub2RlLT52YWx1ZSA9IHZhbHVlOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9QVVNIX1RFWFRfQ1JFQVRFRDoKCQkvKgoJCSogV2hlbiB3b3JraW5nIHdpdGggdGhlIHJlYWRlci4KCQkqIFRoZSB2YWx1ZSB3aWxsIGJlIGZyZWVkIGJ5IHRoZSBlbGVtZW50IGluZm8uCgkJKi8KCQl2Y3R4dC0+aW5vZGUtPnZhbHVlID0gdmFsdWU7CgkJaWYgKGNvbnN1bWVkICE9IE5VTEwpCgkJICAgICpjb25zdW1lZCA9IDE7CgkJdmN0eHQtPmlub2RlLT5mbGFncyB8PQoJCSAgICBYTUxfU0NIRU1BX05PREVfSU5GT19GTEFHX09XTkVEX1ZBTFVFUzsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFOgoJCS8qCgkJKiBXaGVuIHdvcmtpbmcgd2l0aCBTQVguCgkJKiBUaGUgdmFsdWUgd2lsbCBiZSBmcmVlZCBieSB0aGUgZWxlbWVudCBpbmZvLgoJCSovCgkJaWYgKGxlbiAhPSAtMSkKCQkgICAgdmN0eHQtPmlub2RlLT52YWx1ZSA9IEJBRF9DQVNUIHhtbFN0cm5kdXAodmFsdWUsIGxlbik7CgkJZWxzZQoJCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0gQkFEX0NBU1QgeG1sU3RyZHVwKHZhbHVlKTsKCQl2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9CgkJICAgIFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9IGVsc2UgewkKCS8qCgkqIENvbmNhdCB0aGUgdmFsdWUuCgkqLwkKCWlmICh2Y3R4dC0+aW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9OT0RFX0lORk9fRkxBR19PV05FRF9WQUxVRVMpIHsKCSAgICB2Y3R4dC0+aW5vZGUtPnZhbHVlID0gQkFEX0NBU1QgeG1sU3RybmNhdCgKCQkoeG1sQ2hhciAqKSB2Y3R4dC0+aW5vZGUtPnZhbHVlLCB2YWx1ZSwgbGVuKTsKCX0gZWxzZSB7CgkgICAgdmN0eHQtPmlub2RlLT52YWx1ZSA9CgkJQkFEX0NBU1QgeG1sU3RybmNhdE5ldyh2Y3R4dC0+aW5vZGUtPnZhbHVlLCB2YWx1ZSwgbGVuKTsKCSAgICB2Y3R4dC0+aW5vZGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfVkFMVUVTOwoJfQogICAgfQkKCiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYKCSh2Y3R4dC0+ZGVwdGggPj0gdmN0eHQtPnNraXBEZXB0aCkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkgICAgImluIHNraXAtc3RhdGUiKTsKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICB9CiAgICBpZiAodmN0eHQtPnhzaUFzc2VtYmxlKSB7CglpZiAoeG1sU2NoZW1hQXNzZW1ibGVCeVhTSSh2Y3R4dCkgPT0gLTEpCgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIGlmICh2Y3R4dC0+ZGVwdGggPiAwKSB7CgkvKgoJKiBWYWxpZGF0ZSB0aGlzIGVsZW1lbnQgYWdhaW5zdCB0aGUgY29udGVudCBtb2RlbAoJKiBvZiB0aGUgcGFyZW50LgoJKi8KCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQ2hpbGRFbGVtKHZjdHh0KTsKCWlmIChyZXQgIT0gMCkgewoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hU3RyZWFtVmFsaWRhdGVDaGlsZEVsZW1lbnQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGdvdG8gZXhpdDsKCX0KCWlmICh2Y3R4dC0+ZGVwdGggPT0gdmN0eHQtPnNraXBEZXB0aCkKCSAgICBnb3RvIGV4aXQ7CglpZiAoKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKSAmJgoJICAgICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYgPT0gTlVMTCkpIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW0iLAoJCSJ0aGUgY2hpbGQgZWxlbWVudCB3YXMgdmFsaWQgYnV0IG5laXRoZXIgdGhlICIKCQkiZGVjbGFyYXRpb24gbm9yIHRoZSB0eXBlIHdhcyBzZXQiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQogICAgfSBlbHNlIHsKCS8qCgkqIEdldCB0aGUgZGVjbGFyYXRpb24gb2YgdGhlIHZhbGlkYXRpb24gcm9vdC4KCSovCgl2Y3R4dC0+aW5vZGUtPmRlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKHZjdHh0LT5zY2hlbWEsCgkgICAgdmN0eHQtPmlub2RlLT5sb2NhbE5hbWUsCgkgICAgdmN0eHQtPmlub2RlLT5uc05hbWUpOwoJaWYgKHZjdHh0LT5pbm9kZS0+ZGVjbCA9PSBOVUxMKSB7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xOwoJICAgIFZFUlJPUihyZXQsIE5VTEwsCgkJIk5vIG1hdGNoaW5nIGdsb2JhbCBkZWNsYXJhdGlvbiBhdmFpbGFibGUgIgoJCSJmb3IgdGhlIHZhbGlkYXRpb24gcm9vdCIpOwoJICAgIGdvdG8gZXhpdDsKCX0KICAgIH0KCiAgICBpZiAodmN0eHQtPmlub2RlLT5kZWNsID09IE5VTEwpCglnb3RvIHR5cGVfdmFsaWRhdGlvbjsKCiAgICBpZiAodmN0eHQtPmlub2RlLT5kZWNsLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTlkpIHsKCWludCBza2lwOwoJLyoKCSogV2lsZGNhcmRzLgoJKi8KCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkKHZjdHh0LCAmc2tpcCk7CglpZiAocmV0ICE9IDApIHsKCSAgICBpZiAocmV0IDwgMCkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbVdpbGRjYXJkKCkiKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICBnb3RvIGV4aXQ7Cgl9CglpZiAoc2tpcCkgewoJICAgIHZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CgkgICAgZ290byBleGl0OwoJfQoJLyoKCSogVGhlIGRlY2xhcmF0aW9uIG1pZ2h0IGJlIHNldCBieSB0aGUgd2lsZGNhcmQgdmFsaWRhdGlvbiwKCSogd2hlbiB0aGUgcHJvY2Vzc0NvbnRlbnRzIGlzICJsYXgiIG9yICJzdHJpY3QiLgoJKi8KCWlmICh2Y3R4dC0+aW5vZGUtPmRlY2wtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHsKCSAgICAvKgoJICAgICogQ2xlYXIgdGhlICJkZWNsIiBmaWVsZCB0byBub3QgY29uZnVzZSBmdXJ0aGVyIHByb2Nlc3NpbmcuCgkgICAgKi8KCSAgICB2Y3R4dC0+aW5vZGUtPmRlY2wgPSBOVUxMOwoJICAgIGdvdG8gdHlwZV92YWxpZGF0aW9uOwoJfQogICAgfQogICAgLyoKICAgICogVmFsaWRhdGUgYWdhaW5zdCB0aGUgZGVjbGFyYXRpb24uCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtRGVjbCh2Y3R4dCk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChyZXQgPCAwKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1EZWNsKCkiKTsKCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJfQoJZ290byBleGl0OwogICAgfQogICAgLyoKICAgICogVmFsaWRhdGUgYWdhaW5zdCB0aGUgdHlwZSBkZWZpbml0aW9uLgogICAgKi8KdHlwZV92YWxpZGF0aW9uOgoKICAgIGlmICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYgPT0gTlVMTCkgewoJdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfQkFEX1RZUEU7CglyZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8xOwogICAgCVZFUlJPUihyZXQsIE5VTEwsCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIpOwoJZ290byBleGl0OwogICAgfSAgICAKICAgIGlmICh2Y3R4dC0+aW5vZGUtPnR5cGVEZWYtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9BQlNUUkFDVCkgewoJdmN0eHQtPmlub2RlLT5mbGFncyB8PSBYTUxfU0NIRU1BX05PREVfSU5GT19FUlJfQkFEX1RZUEU7CglyZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8yOwogICAgCSAgICBWRVJST1IocmV0LCBOVUxMLAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnN0cmFjdCIpOwkKCWdvdG8gZXhpdDsKICAgIH0KICAgIC8qCiAgICAqIEV2YWx1YXRlIElEQ3MuIERvIGl0IGhlcmUsIHNpbmNlIG5ldyBJREMgbWF0Y2hlcnMgYXJlIHJlZ2lzdGVyZWQKICAgICogZHVyaW5nIHZhbGlkYXRpb24gYWdhaW5zdCB0aGUgZGVjbGFyYXRpb24uIFRoaXMgbXVzdCBiZSBkb25lCiAgICAqIF9iZWZvcmVfIGF0dHJpYnV0ZSB2YWxpZGF0aW9uLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUodmN0eHQsIFhNTF9FTEVNRU5UX05PREUpOwogICAgaWYgKHJldCA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVmFsaWRhdGVFbGVtIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKCkiKTsKCWdvdG8gaW50ZXJuYWxfZXJyb3I7CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChJU19DT01QTEVYX1RZUEUodmN0eHQtPmlub2RlLT50eXBlRGVmKSkgewoJaWYgKCh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkgfHwKCSAgICAodmN0eHQtPmlub2RlLT50eXBlRGVmLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpKSB7CgoJICAgIHJldCA9IHhtbFNjaGVtYVZBdHRyaWJ1dGVzQ29tcGxleCh2Y3R4dCk7Cgl9CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5uYkF0dHJJbmZvcyAhPSAwKSB7CgoJcmV0ID0geG1sU2NoZW1hVkF0dHJpYnV0ZXNTaW1wbGUodmN0eHQpOwogICAgfQogICAgLyoKICAgICogQ2xlYXIgcmVnaXN0ZXJlZCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCXhtbFNjaGVtYUNsZWFyQXR0ckluZm9zKHZjdHh0KTsKICAgIGlmIChyZXQgPT0gLTEpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZhbGlkYXRlRWxlbSIsCgkgICAgImNhbGxpbmcgYXR0cmlidXRlcyB2YWxpZGF0aW9uIik7Cglnb3RvIGludGVybmFsX2Vycm9yOwogICAgfQogICAgLyoKICAgICogRG9uJ3QgcmV0dXJuIGFuIGVycm9yIGlmIGF0dHJpYnV0ZXMgYXJlIGludmFsaWQgb24gcHVycG9zZS4KICAgICovCiAgICByZXQgPSAwOwoKZXhpdDoKICAgIGlmIChyZXQgIT0gMCkKCXZjdHh0LT5za2lwRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgcmV0dXJuICgtMSk7Cn0KCiNpZmRlZiBYTUxfU0NIRU1BX1JFQURFUl9FTkFCTEVECnN0YXRpYyBpbnQKeG1sU2NoZW1hVlJlYWRlcldhbGsoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBjb25zdCBpbnQgV0hUU1AgPSAxMywgU0lHTl9XSFRTUCA9IDE0LCBFTkRfRUxFTSA9IDE1OwogICAgaW50IGRlcHRoLCBub2RlVHlwZSwgcmV0ID0gMCwgY29uc3VtZWQ7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpZWxlbTsKCiAgICB2Y3R4dC0+ZGVwdGggPSAtMTsKICAgIHJldCA9IHhtbFRleHRSZWFkZXJSZWFkKHZjdHh0LT5yZWFkZXIpOwogICAgLyoKICAgICogTW92ZSB0byB0aGUgZG9jdW1lbnQgZWxlbWVudC4KICAgICovCiAgICB3aGlsZSAocmV0ID09IDEpIHsKCW5vZGVUeXBlID0geG1sVGV4dFJlYWRlck5vZGVUeXBlKHZjdHh0LT5yZWFkZXIpOwoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgZ290byByb290X2ZvdW5kOwoJcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CiAgICB9CiAgICBnb3RvIGV4aXQ7Cgpyb290X2ZvdW5kOgoKICAgIGRvIHsKCWRlcHRoID0geG1sVGV4dFJlYWRlckRlcHRoKHZjdHh0LT5yZWFkZXIpOwoJbm9kZVR5cGUgPSB4bWxUZXh0UmVhZGVyTm9kZVR5cGUodmN0eHQtPnJlYWRlcik7CgoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICAKCSAgICB2Y3R4dC0+ZGVwdGgrKzsKCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoRWxlbSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgaWVsZW0tPmxvY2FsTmFtZSA9IHhtbFRleHRSZWFkZXJMb2NhbE5hbWUodmN0eHQtPnJlYWRlcik7CgkgICAgaWVsZW0tPm5zTmFtZSA9IHhtbFRleHRSZWFkZXJOYW1lc3BhY2VVcmkodmN0eHQtPnJlYWRlcik7CgkgICAgaWVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfTk9ERV9JTkZPX0ZMQUdfT1dORURfTkFNRVM7CgkgICAgLyoKCSAgICAqIElzIHRoZSBlbGVtZW50IGVtcHR5PwoJICAgICovCgkgICAgcmV0ID0geG1sVGV4dFJlYWRlcklzRW1wdHlFbGVtZW50KHZjdHh0LT5yZWFkZXIpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJJc0VtcHR5RWxlbWVudCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9CgkgICAgaWYgKHJldCkgewoJCWllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJlZ2lzdGVyIGF0dHJpYnV0ZXMuCgkgICAgKi8KCSAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwoJICAgIHJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSh2Y3R4dC0+cmVhZGVyKTsKCSAgICBpZiAocmV0ID09IC0xKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxUZXh0UmVhZGVyTW92ZVRvRmlyc3RBdHRyaWJ1dGUoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIGlmIChyZXQgPT0gMSkgewoJCWRvIHsKCQkgICAgLyoKCQkgICAgKiBWQUwgVE9ETzogSG93IGRvIHdlIGtub3cgdGhhdCB0aGUgcmVhZGVyIHdvcmtzIG9uIGEKCQkgICAgKiBub2RlIHRyZWUsIHRvIGJlIGFibGUgdG8gcGFzcyBhIG5vZGUgaGVyZT8KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUodmN0eHQsIE5VTEwsCgkJCShjb25zdCB4bWxDaGFyICopIHhtbFRleHRSZWFkZXJMb2NhbE5hbWUodmN0eHQtPnJlYWRlciksCgkJCXhtbFRleHRSZWFkZXJOYW1lc3BhY2VVcmkodmN0eHQtPnJlYWRlciksIDEsCgkJCXhtbFRleHRSZWFkZXJWYWx1ZSh2Y3R4dC0+cmVhZGVyKSwgMSkgPT0gLTEpIHsKCgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclB1c2hBdHRyaWJ1dGUoKSIpOwoJCQlnb3RvIGludGVybmFsX2Vycm9yOwoJCSAgICB9CgkJICAgIHJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9OZXh0QXR0cmlidXRlKHZjdHh0LT5yZWFkZXIpOwoJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZSZWFkZXJXYWxrIiwKCQkJICAgICJjYWxsaW5nIHhtbFRleHRSZWFkZXJNb3ZlVG9GaXJzdEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQl9IHdoaWxlIChyZXQgPT0gMSk7CgkJLyoKCQkqIEJhY2sgdG8gZWxlbWVudCBwb3NpdGlvbi4KCQkqLwoJCXJldCA9IHhtbFRleHRSZWFkZXJNb3ZlVG9FbGVtZW50KHZjdHh0LT5yZWFkZXIpOwoJCWlmIChyZXQgPT0gLTEpIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkiY2FsbGluZyB4bWxUZXh0UmVhZGVyTW92ZVRvRWxlbWVudCgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogVmFsaWRhdGUgdGhlIGVsZW1lbnQuCgkgICAgKi8KCSAgICByZXQ9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWdvdG8gZXhpdDsKCSAgICB9CgkgICAgaWYgKHZjdHh0LT5kZXB0aCA9PSB2Y3R4dC0+c2tpcERlcHRoKSB7CgkJaW50IGN1ckRlcHRoOwoJCS8qCgkJKiBTa2lwIGFsbCBjb250ZW50LgoJCSovCgkJaWYgKChpZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWSkgPT0gMCkgewoJCSAgICByZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKCQkgICAgY3VyRGVwdGggPSB4bWxUZXh0UmVhZGVyRGVwdGgodmN0eHQtPnJlYWRlcik7CgkJICAgIHdoaWxlICgocmV0ID09IDEpICYmIChjdXJEZXB0aCAhPSBkZXB0aCkpIHsKCQkJcmV0ID0geG1sVGV4dFJlYWRlclJlYWQodmN0eHQtPnJlYWRlcik7CgkJCWN1ckRlcHRoID0geG1sVGV4dFJlYWRlckRlcHRoKHZjdHh0LT5yZWFkZXIpOwoJCSAgICB9CgkJICAgIGlmIChyZXQgPCAwKSB7CgkJCS8qCgkJCSogVkFMIFRPRE86IEEgcmVhZGVyIGVycm9yIG9jY3VyZWQ7IHdoYXQgdG8gZG8gaGVyZT8KCQkJKi8KCQkJcmV0ID0gMTsKCQkJZ290byBleGl0OwoJCSAgICB9CgkJfQoJCWdvdG8gbGVhdmVfZWxlbTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJFQURFUiBWQUwgVE9ETzogSXMgYW4gRU5EX0VMRU0gcmVhbGx5IG5ldmVyIGNhbGxlZAoJICAgICogaWYgdGhlIGVsZW0gaXMgZW1wdHk/CgkgICAgKi8KCSAgICBpZiAoaWVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgkJZ290byBsZWF2ZV9lbGVtOwoJfSBlbHNlIGlmIChub2RlVHlwZSA9PSBFTkRfRUxFTSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIEVORCBvZiBlbGVtZW50LgoJICAgICovCmxlYXZlX2VsZW06CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUG9wRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA8IDApIHsKCQkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVlJlYWRlcldhbGsiLAoJCQkiY2FsbGluZyB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJZ290byBleGl0OwoJICAgIH0KCSAgICBpZiAodmN0eHQtPmRlcHRoID49IDApCgkJaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgZWxzZQoJCWllbGVtID0gTlVMTDsKCX0gZWxzZSBpZiAoKG5vZGVUeXBlID09IFhNTF9URVhUX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFdIVFNQKSB8fAoJICAgIChub2RlVHlwZSA9PSBTSUdOX1dIVFNQKSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIGNoYXJhY3RlciBjb250ZW50LgoJICAgICovCgkgICAgeG1sQ2hhciAqdmFsdWU7CgoJICAgIGlmICgobm9kZVR5cGUgPT0gV0hUU1ApIHx8IChub2RlVHlwZSA9PSBTSUdOX1dIVFNQKSkKCQlub2RlVHlwZSA9IFhNTF9URVhUX05PREU7CgoJICAgIHZhbHVlID0geG1sVGV4dFJlYWRlclZhbHVlKHZjdHh0LT5yZWFkZXIpOwoJICAgIHJldCA9IHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgbm9kZVR5cGUsIEJBRF9DQVNUIHZhbHVlLAoJCS0xLCBYTUxfU0NIRU1BX1BVU0hfVEVYVF9DUkVBVEVELCAmY29uc3VtZWQpOwoJICAgIGlmICghIGNvbnN1bWVkKQoJCXhtbEZyZWUodmFsdWUpOwoJICAgIGlmIChyZXQgPT0gLTEpIHsKCQlWRVJST1JfSU5UKCJ4bWxTY2hlbWFWUmVhZGVyV2FsayIsCgkJICAgICJjYWxsaW5nIHhtbFNjaGVtYVZQdXNoVGV4dCgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9IGVsc2UgaWYgKChub2RlVHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CgkgICAgKG5vZGVUeXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpKSB7CgkgICAgLyoKCSAgICAqIFZBTCBUT0RPOiBXaGF0IHRvIGRvIHdpdGggZW50aXRpZXM/CgkgICAgKi8KCSAgICBUT0RPCgl9CgkvKgoJKiBSZWFkIG5leHQgbm9kZS4KCSovCglyZXQgPSB4bWxUZXh0UmVhZGVyUmVhZCh2Y3R4dC0+cmVhZGVyKTsKICAgIH0gd2hpbGUgKHJldCA9PSAxKTsKCmV4aXQ6CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgcmV0dXJuICgtMSk7Cn0KI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIHZhbGlkYXRpb24gaGFuZGxlcnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKgoqIFByb2Nlc3MgdGV4dCBjb250ZW50LgoqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVUZXh0KHZvaWQgKmN0eCwgCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBjaCwgCgkJICAgICAgIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgl2Y3R4dC0+aW5vZGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgaWYgKHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgWE1MX1RFWFRfTk9ERSwgY2gsIGxlbiwKCVhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFLCBOVUxMKSA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlQ0RhdGFTZWN0aW9uIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJdmN0eHQtPmVyciA9IC0xOwoJeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9Cn0KCi8qCiogUHJvY2VzcyBDREFUQSBjb250ZW50LgoqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb24odm9pZCAqY3R4LCAKCQkJICAgICBjb25zdCB4bWxDaGFyICogY2gsIAoJCQkgICAgIGludCBsZW4pCnsgICAKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIGlmICh2Y3R4dC0+aW5vZGUtPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fRU1QVFkpCgl2Y3R4dC0+aW5vZGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZOwogICAgaWYgKHhtbFNjaGVtYVZQdXNoVGV4dCh2Y3R4dCwgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSwgY2gsIGxlbiwKCVhNTF9TQ0hFTUFfUFVTSF9URVhUX1ZPTEFUSUxFLCBOVUxMKSA9PSAtMSkgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlQ0RhdGFTZWN0aW9uIiwKCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJdmN0eHQtPmVyciA9IC0xOwoJeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZSh2b2lkICpjdHggQVRUUklCVVRFX1VOVVNFRCwKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIGN0eDsKCiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkKCXJldHVybjsKICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYgKHZjdHh0LT5kZXB0aCA+PSB2Y3R4dC0+c2tpcERlcHRoKSkKCXJldHVybjsKICAgIC8qIFNBWCBWQUwgVE9ETzogV2hhdCB0byBkbyBoZXJlPyAqLwogICAgVE9ETwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyh2b2lkICpjdHgsCgkJCQkgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSwgCgkJCQkgY29uc3QgeG1sQ2hhciAqIHByZWZpeCBBVFRSSUJVVEVfVU5VU0VELCAKCQkJCSBjb25zdCB4bWxDaGFyICogVVJJLCAKCQkJCSBpbnQgbmJfbmFtZXNwYWNlcywgCgkJCQkgY29uc3QgeG1sQ2hhciAqKiBuYW1lc3BhY2VzLCAKCQkJCSBpbnQgbmJfYXR0cmlidXRlcywgCgkJCQkgaW50IG5iX2RlZmF1bHRlZCBBVFRSSUJVVEVfVU5VU0VELCAKCQkJCSBjb25zdCB4bWxDaGFyICoqIGF0dHJpYnV0ZXMpCnsgIAogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgY3R4OwogICAgaW50IHJldDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtOwogICAgaW50IGksIGo7CiAgICAKICAgIC8qCiAgICAqIFNBWCBWQUwgVE9ETzogV2hhdCB0byBkbyB3aXRoIG5iX2RlZmF1bHRlZD8KICAgICovCiAgICAvKgogICAgKiBTa2lwIGVsZW1lbnRzIGlmIGluc2lkZSBhICJza2lwIiB3aWxkY2FyZCBvciBpbnZhbGlkLgogICAgKi8KICAgIHZjdHh0LT5kZXB0aCsrOwogICAgaWYgKCh2Y3R4dC0+c2tpcERlcHRoICE9IC0xKSAmJiAodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJcmV0dXJuOwogICAgLyoKICAgICogUHVzaCB0aGUgZWxlbWVudC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKSB7CglWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROcyIsCgkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0oKSIpOwoJZ290byBpbnRlcm5hbF9lcnJvcjsKICAgIH0KICAgIGllbGVtID0gdmN0eHQtPmlub2RlOwogICAgLyoKICAgICogVE9ETzogSXMgdGhpcyBPSz8KICAgICovCiAgICBpZWxlbS0+bm9kZUxpbmUgPSB4bWxTQVgyR2V0TGluZU51bWJlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICBpZWxlbS0+bG9jYWxOYW1lID0gbG9jYWxuYW1lOwogICAgaWVsZW0tPm5zTmFtZSA9IFVSSTsKICAgIGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKICAgIC8qCiAgICAqIFJlZ2lzdGVyIG5hbWVzcGFjZXMgb24gdGhlIGVsZW0gaW5mby4KICAgICovICAgIAogICAgaWYgKG5iX25hbWVzcGFjZXMgIT0gMCkgewoJLyoKCSogQWx0aG91Z2ggdGhlIHBhcnNlciBidWlsZHMgaXRzIG93biBuYW1lc3BhY2UgbGlzdCwKCSogd2UgaGF2ZSBubyBhY2Nlc3MgdG8gaXQsIHNvIHdlJ2xsIHVzZSBhbiBvd24gb25lLgoJKi8KICAgICAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8IG5iX25hbWVzcGFjZXM7IGkrKywgaiArPSAyKSB7CSAgICAKCSAgICAvKgoJICAgICogU3RvcmUgcHJlZml4IGFuZCBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwkgICAKCSAgICBpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbE1hbGxvYygxMCAqCgkJCXNpemVvZihjb25zdCB4bWxDaGFyICopKTsKCQlpZiAoaWVsZW0tPm5zQmluZGluZ3MgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LAoJCQkiYWxsb2NhdGluZyBuYW1lc3BhY2UgYmluZGluZ3MgZm9yIFNBWCB2YWxpZGF0aW9uIiwKCQkJTlVMTCk7CgkJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJfQoJCWllbGVtLT5uYk5zQmluZGluZ3MgPSAwOwoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyA9IDU7CgkgICAgfSBlbHNlIGlmIChpZWxlbS0+c2l6ZU5zQmluZGluZ3MgPD0gaWVsZW0tPm5iTnNCaW5kaW5ncykgewoJCWllbGVtLT5zaXplTnNCaW5kaW5ncyAqPSAyOwoJCWllbGVtLT5uc0JpbmRpbmdzID0KCQkgICAgKGNvbnN0IHhtbENoYXIgKiopIHhtbFJlYWxsb2MoCgkJCSh2b2lkICopIGllbGVtLT5uc0JpbmRpbmdzLAoJCQlpZWxlbS0+c2l6ZU5zQmluZGluZ3MgKiAyICogc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJCWlmIChpZWxlbS0+bnNCaW5kaW5ncyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsCgkJCSJyZS1hbGxvY2F0aW5nIG5hbWVzcGFjZSBiaW5kaW5ncyBmb3IgU0FYIHZhbGlkYXRpb24iLAoJCQlOVUxMKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkgICAgfQoKCSAgICBpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMl0gPSBuYW1lc3BhY2VzW2pdOwoJICAgIGlmIChuYW1lc3BhY2VzW2orMV1bMF0gPT0gMCkgewoJCS8qCgkJKiBIYW5kbGUgeG1sbnM9IiIuCgkJKi8KCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0gTlVMTDsKCSAgICB9IGVsc2UKCQlpZWxlbS0+bnNCaW5kaW5nc1tpZWxlbS0+bmJOc0JpbmRpbmdzICogMiArIDFdID0KCQkgICAgbmFtZXNwYWNlc1tqKzFdOwoJICAgIGllbGVtLT5uYk5zQmluZGluZ3MrKzsJICAgIAkgICAgCgl9CiAgICB9CiAgICAvKgogICAgKiBSZWdpc3RlciBhdHRyaWJ1dGVzLgogICAgKiBTQVggVkFMIFRPRE86IFdlIGFyZSBub3QgYWRkaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgogICAgKiBhdHRyaWJ1dGVzIHlldC4KICAgICovCiAgICBpZiAobmJfYXR0cmlidXRlcyAhPSAwKSB7Cgl4bWxDaGFyICp2YWx1ZTsKCiAgICAgICAgZm9yIChqID0gMCwgaSA9IDA7IGkgPCBuYl9hdHRyaWJ1dGVzOyBpKyssIGogKz0gNSkgewoJICAgIC8qCgkgICAgKiBEdXBsaWNhdGUgdGhlIHZhbHVlLgoJICAgICovCSAKCSAgICB2YWx1ZSA9IHhtbFN0cm5kdXAoYXR0cmlidXRlc1tqKzNdLAoJCWF0dHJpYnV0ZXNbais0XSAtIGF0dHJpYnV0ZXNbaiszXSk7CgkgICAgLyoKCSAgICAqIFRPRE86IFNldCB0aGUgbm9kZSBsaW5lLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSh2Y3R4dCwKCQlOVUxMLCBpZWxlbS0+bm9kZUxpbmUsIGF0dHJpYnV0ZXNbal0sIGF0dHJpYnV0ZXNbaisyXSwgMCwKCQl2YWx1ZSwgMSk7CgkgICAgaWYgKHJldCA9PSAtMSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZVN0YXJ0RWxlbWVudE5zIiwKCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJZ290byBpbnRlcm5hbF9lcnJvcjsKCSAgICB9Cgl9CiAgICB9CiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW0odmN0eHQpOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAocmV0ID09IC0xKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hU0FYSGFuZGxlU3RhcnRFbGVtZW50TnMiLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRlRWxlbSgpIik7CgkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCX0KCWdvdG8gZXhpdDsKICAgIH0gICAgCgpleGl0OgogICAgcmV0dXJuOwppbnRlcm5hbF9lcnJvcjoKICAgIHZjdHh0LT5lcnIgPSAtMTsKICAgIHhtbFN0b3BQYXJzZXIodmN0eHQtPnBhcnNlckN0eHQpOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnModm9pZCAqY3R4LAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIHByZWZpeCBBVFRSSUJVVEVfVU5VU0VELAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIFVSSSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSBjdHg7CiAgICBpbnQgcmVzOwoKICAgIC8qCiAgICAqIFNraXAgZWxlbWVudHMgaWYgaW5zaWRlIGEgInNraXAiIHdpbGRjYXJkIG9yIGlmIGludmFsaWQuCiAgICAqLwogICAgaWYgKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpIHsKCWlmICh2Y3R4dC0+ZGVwdGggPiB2Y3R4dC0+c2tpcERlcHRoKSB7CgkgICAgdmN0eHQtPmRlcHRoLS07CgkgICAgcmV0dXJuOwoJfSBlbHNlCgkgICAgdmN0eHQtPnNraXBEZXB0aCA9IC0xOwogICAgfQogICAgLyoKICAgICogU0FYIFZBTCBUT0RPOiBKdXN0IGEgdGVtcG9yYXJ5IGNoZWNrLgogICAgKi8KICAgIGlmICgoIXhtbFN0ckVxdWFsKHZjdHh0LT5pbm9kZS0+bG9jYWxOYW1lLCBsb2NhbG5hbWUpKSB8fAoJKCF4bWxTdHJFcXVhbCh2Y3R4dC0+aW5vZGUtPm5zTmFtZSwgVVJJKSkpIHsKCVZFUlJPUl9JTlQoInhtbFNjaGVtYVNBWEhhbmRsZUVuZEVsZW1lbnROcyIsCgkgICAgImVsZW0gcG9wIG1pc21hdGNoIik7CiAgICB9CiAgICByZXMgPSB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHZjdHh0KTsKICAgIGlmIChyZXMgIT0gMCkgewoJaWYgKHJlcyA8IDApIHsKCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnMiLAoJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oKSIpOwoJICAgIGdvdG8gaW50ZXJuYWxfZXJyb3I7Cgl9Cglnb3RvIGV4aXQ7CiAgICB9CmV4aXQ6CiAgICByZXR1cm47CmludGVybmFsX2Vycm9yOgogICAgdmN0eHQtPmVyciA9IC0xOwogICAgeG1sU3RvcFBhcnNlcih2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEuCiAqCiAqIFJldHVybnMgdGhlIHZhbGlkYXRpb24gY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVZhbGlkQ3R4dFB0cgp4bWxTY2hlbWFOZXdWYWxpZEN0eHQoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hVmFsaWRDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyB2YWxpZGF0aW9uIGNvbnRleHQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVZhbGlkQ3R4dCkpOwogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9DVFhUX1ZBTElEQVRPUjsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIHJldC0+bm9kZVFOYW1lcyA9IHhtbFNjaGVtYUl0ZW1MaXN0Q3JlYXRlKCk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsZWFyVmFsaWRDdHh0OgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQ7CiAqIGxlYXZlcyBzb21lIGZpZWxkcyBhbGl2ZSBpbnRlbmRlZCBmb3IgcmV1c2Ugb2YgdGhlIGNvbnRleHQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhclZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGlmICh2Y3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICB2Y3R4dC0+ZmxhZ3MgPSAwOwogICAgdmN0eHQtPnZhbGlkYXRpb25Sb290ID0gTlVMTDsKICAgIHZjdHh0LT5kb2MgPSBOVUxMOwojaWZkZWYgTElCWE1MX1JFQURFUl9FTkFCTEVECiAgICB2Y3R4dC0+cmVhZGVyID0gTlVMTDsKI2VuZGlmCiAgICBpZiAodmN0eHQtPnZhbHVlICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUodmN0eHQtPnZhbHVlKTsKCXZjdHh0LT52YWx1ZSA9IE5VTEw7CiAgICB9CiAgICAvKgogICAgKiBBdWdtZW50ZWQgSURDIGluZm9ybWF0aW9uLgogICAgKi8KICAgIGlmICh2Y3R4dC0+YWlkY3MgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDQXVnUHRyIGN1ciA9IHZjdHh0LT5haWRjcywgbmV4dDsKCWRvIHsKCSAgICBuZXh0ID0gY3VyLT5uZXh0OwoJICAgIHhtbEZyZWUoY3VyKTsKCSAgICBjdXIgPSBuZXh0OwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwoJdmN0eHQtPmFpZGNzID0gTlVMTDsKICAgIH0KICAgIGlmICh2Y3R4dC0+aWRjTm9kZXMgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBpdGVtOwoKCWZvciAoaSA9IDA7IGkgPCB2Y3R4dC0+bmJJZGNOb2RlczsgaSsrKSB7CgkgICAgaXRlbSA9IHZjdHh0LT5pZGNOb2Rlc1tpXTsKCSAgICB4bWxGcmVlKGl0ZW0tPmtleXMpOwoJICAgIHhtbEZyZWUoaXRlbSk7Cgl9Cgl4bWxGcmVlKHZjdHh0LT5pZGNOb2Rlcyk7Cgl2Y3R4dC0+aWRjTm9kZXMgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogTm90ZSB0aGF0IHdlIHdvbid0IGRlbGV0ZSB0aGUgWFBhdGggc3RhdGUgcG9vbCBoZXJlLgogICAgKi8KICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdCh2Y3R4dC0+eHBhdGhTdGF0ZXMpOwoJdmN0eHQtPnhwYXRoU3RhdGVzID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIEF0dHJpYnV0ZSBpbmZvLgogICAgKi8KICAgIGlmICh2Y3R4dC0+bmJBdHRySW5mb3MgIT0gMCkgewoJeG1sU2NoZW1hQ2xlYXJBdHRySW5mb3ModmN0eHQpOwogICAgfQogICAgLyoKICAgICogRWxlbWVudCBpbmZvLgogICAgKi8KICAgIGlmICh2Y3R4dC0+ZWxlbUluZm9zICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hTm9kZUluZm9QdHIgZWk7CgoJZm9yIChpID0gMDsgaSA8IHZjdHh0LT5zaXplRWxlbUluZm9zOyBpKyspIHsKCSAgICBlaSA9IHZjdHh0LT5lbGVtSW5mb3NbaV07CgkgICAgaWYgKGVpID09IE5VTEwpCgkJYnJlYWs7CgkgICAgeG1sU2NoZW1hQ2xlYXJFbGVtSW5mbyhlaSk7Cgl9CiAgICB9ICAgIAogICAgeG1sU2NoZW1hSXRlbUxpc3RDbGVhcih2Y3R4dC0+bm9kZVFOYW1lcyk7CiAgICAvKiBSZWNyZWF0ZSB0aGUgZGljdC4gKi8KICAgIHhtbERpY3RGcmVlKHZjdHh0LT5kaWN0KTsKICAgIHZjdHh0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KGN0eHQtPnBjdHh0KTsKICAgIGlmIChjdHh0LT5pZGNOb2RlcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW07CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjTm9kZXM7IGkrKykgewoJICAgIGl0ZW0gPSBjdHh0LT5pZGNOb2Rlc1tpXTsKCSAgICB4bWxGcmVlKGl0ZW0tPmtleXMpOwoJICAgIHhtbEZyZWUoaXRlbSk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmlkY05vZGVzKTsKICAgIH0KICAgIGlmIChjdHh0LT5pZGNLZXlzICE9IE5VTEwpIHsKCWludCBpOwoJZm9yIChpID0gMDsgaSA8IGN0eHQtPm5iSWRjS2V5czsgaSsrKQoJICAgIHhtbFNjaGVtYUlEQ0ZyZWVLZXkoY3R4dC0+aWRjS2V5c1tpXSk7Cgl4bWxGcmVlKGN0eHQtPmlkY0tleXMpOwogICAgfQoKICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlcyk7CiAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZVBvb2wgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVJRENTdGF0ZU9iakxpc3QoY3R4dC0+eHBhdGhTdGF0ZVBvb2wpOwoKICAgIC8qCiAgICAqIEF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb24uCiAgICAqLwogICAgaWYgKGN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBjdXIgPSBjdHh0LT5haWRjcywgbmV4dDsKCWRvIHsKCSAgICBuZXh0ID0gY3VyLT5uZXh0OwoJICAgIHhtbEZyZWUoY3VyKTsKCSAgICBjdXIgPSBuZXh0OwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPmF0dHJJbmZvcyAhPSBOVUxMKSB7CglpbnQgaTsKCXhtbFNjaGVtYUF0dHJJbmZvUHRyIGF0dHI7CgoJLyogSnVzdCBhIHBhcmFub2lkIGNhbGwgdG8gdGhlIGNsZWFudXAuICovCglpZiAoY3R4dC0+bmJBdHRySW5mb3MgIT0gMCkKCSAgICB4bWxTY2hlbWFDbGVhckF0dHJJbmZvcyhjdHh0KTsKCWZvciAoaSA9IDA7IGkgPCBjdHh0LT5zaXplQXR0ckluZm9zOyBpKyspIHsKCSAgICBhdHRyID0gY3R4dC0+YXR0ckluZm9zW2ldOwoJICAgIHhtbEZyZWUoYXR0cik7Cgl9Cgl4bWxGcmVlKGN0eHQtPmF0dHJJbmZvcyk7CiAgICB9CiAgICBpZiAoY3R4dC0+ZWxlbUluZm9zICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hTm9kZUluZm9QdHIgZWk7CgoJZm9yIChpID0gMDsgaSA8IGN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykgewoJICAgIGVpID0gY3R4dC0+ZWxlbUluZm9zW2ldOwoJICAgIGlmIChlaSA9PSBOVUxMKQoJCWJyZWFrOwoJICAgIHhtbFNjaGVtYUNsZWFyRWxlbUluZm8oZWkpOwoJICAgIHhtbEZyZWUoZWkpOwoJfQoJeG1sRnJlZShjdHh0LT5lbGVtSW5mb3MpOwogICAgfQogICAgaWYgKGN0eHQtPm5vZGVRTmFtZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUl0ZW1MaXN0RnJlZShjdHh0LT5ub2RlUU5hbWVzKTsKICAgIGlmIChjdHh0LT5kaWN0ICE9IE5VTEwpCgl4bWxEaWN0RnJlZShjdHh0LT5kaWN0KTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1ZhbGlkOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQ2hlY2sgaWYgYW55IGVycm9yIHdhcyBkZXRlY3RlZCBkdXJpbmcgdmFsaWRhdGlvbi4KICogCiAqIFJldHVybnMgMSBpZiB2YWxpZCBzbyBmYXIsIDAgaWYgZXJyb3JzIHdlcmUgZGV0ZWN0ZWQsIGFuZCAtMSBpbiBjYXNlCiAqICAgICAgICAgb2YgaW50ZXJuYWwgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hSXNWYWxpZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4oLTEpOwogICAgcmV0dXJuKGN0eHQtPmVyciA9PSAwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoY3R4dC0+cGN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkU3RydWN0dXJlZEVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNlcnJvcjogIHRoZSBzdHJ1Y3R1cmVkIGVycm9yIGZ1bmN0aW9uCiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dAogKgogKiBTZXQgdGhlIHN0cnVjdHVyZWQgZXJyb3IgY2FsbGJhY2sKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRTdHJ1Y3R1cmVkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJCQkJCSAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3IsIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgljdHh0LT5zZXJyb3IgPSBzZXJyb3I7CiAgICBjdHh0LT5lcnJvciA9IE5VTEw7CiAgICBjdHh0LT53YXJuaW5nID0gTlVMTDsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4Owp9CgovKioKICogeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnM6CiAqIEBjdHh0OglhIFhNTC1TY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6IHRoZSBlcnJvciBmdW5jdGlvbiByZXN1bHQKICogQHdhcm46IHRoZSB3YXJuaW5nIGZ1bmN0aW9uIHJlc3VsdAogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQgcmVzdWx0CiAqCiAqIEdldCB0aGUgZXJyb3IgYW5kIHdhcm5pbmcgY2FsbGJhY2sgaW5mb3JtYXRpb25zCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciBhbmQgMCBvdGhlcndpc2UKICovCmludAp4bWxTY2hlbWFHZXRWYWxpZEVycm9ycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCQkJeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgKiB3YXJuLCB2b2lkICoqY3R4KQp7CglpZiAoY3R4dCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJaWYgKGVyciAhPSBOVUxMKQoJCSplcnIgPSBjdHh0LT5lcnJvcjsKCWlmICh3YXJuICE9IE5VTEwpCgkJKndhcm4gPSBjdHh0LT53YXJuaW5nOwoJaWYgKGN0eCAhPSBOVUxMKQoJCSpjdHggPSBjdHh0LT51c2VyRGF0YTsKCXJldHVybiAoMCk7Cn0KCgovKioKICogeG1sU2NoZW1hU2V0VmFsaWRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvcHRpb25zOiBhIGNvbWJpbmF0aW9uIG9mIHhtbFNjaGVtYVZhbGlkT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24uCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVNldFZhbGlkT3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJIGludCBvcHRpb25zKQoKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVZhbGlkT3B0aW9uLgogICAgKiBUT0RPOiBJcyB0aGVyZSBhbiBvdGhlciwgbW9yZSBlYXN5IHRvIG1haW50YWluLAogICAgKiB3YXk/CiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgY3R4dC0+b3B0aW9ucyA9IG9wdGlvbnM7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBHZXQgdGhlIHZhbGlkYXRpb24gY29udGV4dCBvcHRpb25zLgogKgogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb3IgLTEgb24gZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hVkRvY1dhbGsoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGllbGVtID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgbm9kZSwgdmFsUm9vdDsKICAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZTsKCiAgICAvKiBET0MgVkFMIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgc3RhcnQgZnVuY3Rpb24uICovCiAgICB2YWxSb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQodmN0eHQtPmRvYyk7CiAgICBpZiAodmFsUm9vdCA9PSBOVUxMKSB7CgkvKiBWQUwgVE9ETzogRXJyb3IgY29kZT8gKi8KCVZFUlJPUigxLCBOVUxMLCAiVGhlIGRvY3VtZW50IGhhcyBubyBkb2N1bWVudCBlbGVtZW50Iik7CglyZXR1cm4gKDEpOwogICAgfQogICAgdmN0eHQtPmRlcHRoID0gLTE7CiAgICB2Y3R4dC0+dmFsaWRhdGlvblJvb3QgPSB2YWxSb290OwogICAgbm9kZSA9IHZhbFJvb3Q7CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7CglpZiAoKHZjdHh0LT5za2lwRGVwdGggIT0gLTEpICYmICh2Y3R4dC0+ZGVwdGggPj0gdmN0eHQtPnNraXBEZXB0aCkpCgkgICAgZ290byBuZXh0X3NpYmxpbmc7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgoJICAgIC8qCgkgICAgKiBJbml0IHRoZSBub2RlLWluZm8uCgkgICAgKi8KCSAgICB2Y3R4dC0+ZGVwdGgrKzsKCSAgICBpZiAoeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEVsZW0odmN0eHQpID09IC0xKQoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgaWVsZW0gPSB2Y3R4dC0+aW5vZGU7CgkgICAgaWVsZW0tPm5vZGUgPSBub2RlOwoJICAgIGllbGVtLT5ub2RlTGluZSA9IG5vZGUtPmxpbmU7CgkgICAgaWVsZW0tPmxvY2FsTmFtZSA9IG5vZGUtPm5hbWU7CgkgICAgaWYgKG5vZGUtPm5zICE9IE5VTEwpCgkJaWVsZW0tPm5zTmFtZSA9IG5vZGUtPm5zLT5ocmVmOwoJICAgIGllbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICAvKgoJICAgICogUmVnaXN0ZXIgYXR0cmlidXRlcy4KCSAgICAqIERPQyBWQUwgVE9ETzogV2UgZG8gbm90IHJlZ2lzdGVyIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgoJICAgICogYXR0cmlidXRlcyB5ZXQuCgkgICAgKi8KCSAgICB2Y3R4dC0+bmJBdHRySW5mb3MgPSAwOwoJICAgIGlmIChub2RlLT5wcm9wZXJ0aWVzICE9IE5VTEwpIHsKCQlhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCQlkbyB7CgkJICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKQoJCQluc05hbWUgPSBhdHRyLT5ucy0+aHJlZjsKCQkgICAgZWxzZQoJCQluc05hbWUgPSBOVUxMOwoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQdXNoQXR0cmlidXRlKHZjdHh0LAoJCQkoeG1sTm9kZVB0cikgYXR0ciwKCQkJLyogCgkJCSogTm90ZSB0aGF0IHdlIGdpdmUgaXQgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZQoJCQkqIHBhcmVudCBlbGVtZW50LgoJCQkqLwoJCQlpZWxlbS0+bm9kZUxpbmUsCgkJCWF0dHItPm5hbWUsIG5zTmFtZSwgMCwKCQkJeG1sTm9kZUxpc3RHZXRTdHJpbmcoYXR0ci0+ZG9jLCBhdHRyLT5jaGlsZHJlbiwgMSksIDEpOwoJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCVZFUlJPUl9JTlQoInhtbFNjaGVtYURvY1dhbGsiLAoJCQkgICAgImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdG9yUHVzaEF0dHJpYnV0ZSgpIik7CgkJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkJICAgIH0KCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJfSB3aGlsZSAoYXR0cik7CgkgICAgfQoJICAgIC8qCgkgICAgKiBWYWxpZGF0ZSB0aGUgZWxlbWVudC4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbSh2Y3R4dCk7CgkgICAgaWYgKHJldCAhPSAwKSB7CgkJaWYgKHJldCA9PSAtMSkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFEb2NXYWxrIiwKCQkJImNhbGxpbmcgeG1sU2NoZW1hVmFsaWRhdGVFbGVtKCkiKTsKCQkgICAgZ290byBpbnRlcm5hbF9lcnJvcjsKCQl9CgkJLyoKCQkqIERvbid0IHN0b3AgdmFsaWRhdGlvbjsganVzdCBza2lwIHRoZSBjb250ZW50CgkJKiBvZiB0aGlzIGVsZW1lbnQuCgkJKi8KCQlnb3RvIGxlYXZlX25vZGU7CgkgICAgfQoJICAgIGlmICgodmN0eHQtPnNraXBEZXB0aCAhPSAtMSkgJiYKCQkodmN0eHQtPmRlcHRoID49IHZjdHh0LT5za2lwRGVwdGgpKQoJCWdvdG8gbGVhdmVfbm9kZTsKCX0gZWxzZSBpZiAoKG5vZGUtPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgfHwKCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIGNoYXJhY3RlciBjb250ZW50LgoJICAgICovCgkgICAgaWYgKGllbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX0VNUFRZKQoJCWllbGVtLT5mbGFncyBePSBYTUxfU0NIRU1BX0VMRU1fSU5GT19FTVBUWTsKCSAgICByZXQgPSB4bWxTY2hlbWFWUHVzaFRleHQodmN0eHQsIG5vZGUtPnR5cGUsIG5vZGUtPmNvbnRlbnQsCgkJLTEsIFhNTF9TQ0hFTUFfUFVTSF9URVhUX1BFUlNJU1QsIE5VTEwpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJVkVSUk9SX0lOVCgieG1sU2NoZW1hVkRvY1dhbGsiLAoJCSAgICAiY2FsbGluZyB4bWxTY2hlbWFWUHVzaFRleHQoKSIpOwoJCWdvdG8gaW50ZXJuYWxfZXJyb3I7CgkgICAgfQoJICAgIC8qCgkgICAgKiBET0MgVkFMIFRPRE86IFNob3VsZCB3ZSBza2lwIGZ1cnRoZXIgdmFsaWRhdGlvbiBvZiB0aGUKCSAgICAqIGVsZW1lbnQgY29udGVudCBoZXJlPwoJICAgICovCgl9IGVsc2UgaWYgKChub2RlLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwKCSAgICAobm9kZS0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSkgewoJICAgIC8qCgkgICAgKiBET0MgVkFMIFRPRE86IFdoYXQgdG8gZG8gd2l0aCBlbnRpdGllcz8KCSAgICAqLwoJICAgIFRPRE8KCX0gZWxzZSB7CgkgICAgZ290byBsZWF2ZV9ub2RlOwoJICAgIC8qCgkgICAgKiBET0MgVkFMIFRPRE86IFhJbmNsdWRlIG5vZGVzLCBldGMuCgkgICAgKi8KCX0KCS8qCgkqIFdhbGsgdGhlIGRvYy4KCSovCglpZiAobm9kZS0+Y2hpbGRyZW4gIT0gTlVMTCkgewoJICAgIG5vZGUgPSBub2RlLT5jaGlsZHJlbjsKCSAgICBjb250aW51ZTsKCX0KbGVhdmVfbm9kZToKCWlmIChub2RlLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICAvKgoJICAgICogTGVhdmluZyB0aGUgc2NvcGUgb2YgYW4gZWxlbWVudC4KCSAgICAqLwoJICAgIGlmIChub2RlICE9IHZjdHh0LT5pbm9kZS0+bm9kZSkgewoJCVZFUlJPUl9JTlQoInhtbFNjaGVtYVZEb2NXYWxrIiwKCQkgICAgImVsZW1lbnQgcG9zaXRpb24gbWlzbWF0Y2giKTsKCQlnb3RvIGludGVybmFsX2Vycm9yOwoJICAgIH0KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0b3JQb3BFbGVtKHZjdHh0KTsKCSAgICBpZiAocmV0ICE9IDApIHsKCQlpZiAocmV0IDwgMCkgewoJCSAgICBWRVJST1JfSU5UKCJ4bWxTY2hlbWFWRG9jV2FsayIsCgkJCSJjYWxsaW5nIHhtbFNjaGVtYVZhbGlkYXRvclBvcEVsZW0oKSIpOwoJCSAgICBnb3RvIGludGVybmFsX2Vycm9yOwoJCX0KCSAgICB9CgkgICAgaWYgKG5vZGUgPT0gdmFsUm9vdCkKCQlnb3RvIGV4aXQ7Cgl9Cm5leHRfc2libGluZzoKCWlmIChub2RlLT5uZXh0ICE9IE5VTEwpCgkgICAgbm9kZSA9IG5vZGUtPm5leHQ7CgllbHNlIHsKCSAgICBub2RlID0gbm9kZS0+cGFyZW50OwoJICAgIGdvdG8gbGVhdmVfbm9kZTsKCX0KICAgIH0KCmV4aXQ6CiAgICByZXR1cm4gKHJldCk7CmludGVybmFsX2Vycm9yOgogICAgcmV0dXJuICgtMSk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUHJlUnVuKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkgewogICAgLyoKICAgICogU29tZSBpbml0aWFsaXphdGlvbi4KICAgICovCiAgICB2Y3R4dC0+ZXJyID0gMDsKICAgIHZjdHh0LT5uYmVycm9ycyA9IDA7CiAgICB2Y3R4dC0+ZGVwdGggPSAtMTsKICAgIHZjdHh0LT5za2lwRGVwdGggPSAtMTsKICAgIC8qCiAgICAqIENyZWF0ZSBhIHNjaGVtYSArIHBhcnNlciBpZiBuZWNlc3NhcnkuCiAgICAqLwogICAgaWYgKHZjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoKCWlmICgodmN0eHQtPnBjdHh0ID09IE5VTEwpICYmCgkgICAoeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHZjdHh0KSA9PSAtMSkpCgkgICByZXR1cm4gKC0xKTsKCgl2Y3R4dC0+c2NoZW1hID0geG1sU2NoZW1hTmV3U2NoZW1hKHZjdHh0LT5wY3R4dCk7CglpZiAodmN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7CgkgICAgVkVSUk9SX0lOVCgieG1sU2NoZW1hVlN0YXJ0VmFsaWRhdGlvbiIsCgkJICAgICJjcmVhdGluZyBhIHNjaGVtYSIpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnhzaUFzc2VtYmxlID0gMTsKICAgIH0gZWxzZQoJdmN0eHQtPnhzaUFzc2VtYmxlID0gMDsKICAgIC8qCiAgICAqIEF1Z21lbnQgdGhlIElEQyBkZWZpbml0aW9ucy4KICAgICovCiAgICBpZiAodmN0eHQtPnNjaGVtYS0+aWRjRGVmICE9IE5VTEwpIHsKCXhtbEhhc2hTY2FuKHZjdHh0LT5zY2hlbWEtPmlkY0RlZiwKCSAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF1Z21lbnRJREMsIHZjdHh0KTsKICAgIH0KICAgIHJldHVybigwKTsKfQoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUG9zdFJ1bih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpIHsKICAgIGlmICh2Y3R4dC0+eHNpQXNzZW1ibGUpIHsKCWlmICh2Y3R4dC0+c2NoZW1hICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGcmVlKHZjdHh0LT5zY2hlbWEpOwoJICAgIHZjdHh0LT5zY2hlbWEgPSBOVUxMOwoJfQogICAgfQogICAgeG1sU2NoZW1hQ2xlYXJWYWxpZEN0eHQodmN0eHQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYVZTdGFydCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIGludCByZXQgPSAwOwoKICAgIGlmICh4bWxTY2hlbWFQcmVSdW4odmN0eHQpIDwgMCkKICAgICAgICByZXR1cm4oLTEpOwoKICAgIGlmICh2Y3R4dC0+ZG9jICE9IE5VTEwpIHsKCS8qCgkgKiBUcmVlIHZhbGlkYXRpb24uCgkgKi8KCXJldCA9IHhtbFNjaGVtYVZEb2NXYWxrKHZjdHh0KTsKI2lmZGVmIExJQlhNTF9SRUFERVJfRU5BQkxFRAogICAgfSBlbHNlIGlmICh2Y3R4dC0+cmVhZGVyICE9IE5VTEwpIHsKCS8qCgkgKiBYTUwgUmVhZGVyIHZhbGlkYXRpb24uCgkgKi8KI2lmZGVmIFhNTF9TQ0hFTUFfUkVBREVSX0VOQUJMRUQKCXJldCA9IHhtbFNjaGVtYVZSZWFkZXJXYWxrKHZjdHh0KTsKI2VuZGlmCiNlbmRpZgogICAgfSBlbHNlIGlmICgodmN0eHQtPnNheCAhPSBOVUxMKSAmJiAodmN0eHQtPnBhcnNlckN0eHQgIT0gTlVMTCkpIHsKCS8qCgkgKiBTQVggdmFsaWRhdGlvbi4KCSAqLwoJcmV0ID0geG1sUGFyc2VEb2N1bWVudCh2Y3R4dC0+cGFyc2VyQ3R4dCk7CiAgICB9IGVsc2UgewoJVkVSUk9SX0lOVCgieG1sU2NoZW1hVlN0YXJ0VmFsaWRhdGlvbiIsCgkgICAgIm5vIGluc3RhbmNlIHRvIHZhbGlkYXRlIik7CglyZXQgPSAtMTsKICAgIH0KCiAgICB4bWxTY2hlbWFQb3N0UnVuKHZjdHh0KTsKICAgIGlmIChyZXQgPT0gMCkKCXJldCA9IHZjdHh0LT5lcnI7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudCBub2RlCiAqCiAqIFZhbGlkYXRlIGEgYnJhbmNoIG9mIGEgdHJlZSwgc3RhcnRpbmcgd2l0aCB0aGUgZ2l2ZW4gQGVsZW0uCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBhbmQgaXRzIHN1YnRyZWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IKICogY29kZSBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpIHx8IChlbGVtLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CgogICAgY3R4dC0+ZG9jID0gZWxlbS0+ZG9jOwogICAgY3R4dC0+bm9kZSA9IGVsZW07CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGVsZW07CiAgICByZXR1cm4oeG1sU2NoZW1hVlN0YXJ0KGN0eHQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2MoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIGN0eHQtPm5vZGUgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKGN0eHQtPm5vZGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUN1c3RvbUVycigoeG1sU2NoZW1hQWJzdHJhY3RDdHh0UHRyKSBjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0RPQ1VNRU5UX0VMRU1FTlRfTUlTU0lORywKCSAgICAoeG1sTm9kZVB0cikgZG9jLCBOVUxMLAoJICAgICJUaGUgZG9jdW1lbnQgaGFzIG5vIGRvY3VtZW50IGVsZW1lbnQiLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGN0eHQtPm5vZGU7CiAgICByZXR1cm4gKHhtbFNjaGVtYVZTdGFydChjdHh0KSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQlGdW5jdGlvbiBhbmQgZGF0YSBmb3IgU0FYIHN0cmVhbWluZyBBUEkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVNwbGl0U0FYRGF0YSB4bWxTY2hlbWFTcGxpdFNBWERhdGE7CnR5cGVkZWYgeG1sU2NoZW1hU3BsaXRTQVhEYXRhICp4bWxTY2hlbWFTcGxpdFNBWERhdGFQdHI7CgpzdHJ1Y3QgX3htbFNjaGVtYVNwbGl0U0FYRGF0YSB7CiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAgdXNlcl9zYXg7CiAgICB2b2lkICAgICAgICAgICAgICAgICAqdXNlcl9kYXRhOwogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQ7CiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAgc2NoZW1hc19zYXg7Cn07CgojZGVmaW5lIFhNTF9TQVhfUExVR19NQUdJQyAweGRjNDNiYTIxCgpzdHJ1Y3QgX3htbFNjaGVtYVNBWFBsdWcgewogICAgdW5zaWduZWQgaW50IG1hZ2ljOwoKICAgIC8qIHRoZSBvcmlnaW5hbCBjYWxsYmFja3MgaW5mb3JtYXRpb25zICovCiAgICB4bWxTQVhIYW5kbGVyUHRyICAgICAqdXNlcl9zYXhfcHRyOwogICAgeG1sU0FYSGFuZGxlclB0ciAgICAgIHVzZXJfc2F4OwogICAgdm9pZCAgICAgICAgICAgICAgICAqKnVzZXJfZGF0YV9wdHI7CiAgICB2b2lkICAgICAgICAgICAgICAgICAqdXNlcl9kYXRhOwoKICAgIC8qIHRoZSBibG9jayBwbHVnZ2VkIGJhY2sgYW5kIHZhbGlkYXRpb24gaW5mb3JtYXRpb25zICovCiAgICB4bWxTQVhIYW5kbGVyICAgICAgICAgc2NoZW1hc19zYXg7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dDsKfTsKCi8qIEFsbCB0aG9zZSBmdW5jdGlvbnMganVzdCBib3VuY2VzIHRvIHRoZSB1c2VyIHByb3ZpZGVkIFNBWCBoYW5kbGVycyAqLwpzdGF0aWMgdm9pZAppbnRlcm5hbFN1YnNldFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSwKCSAgICAgICBjb25zdCB4bWxDaGFyICpFeHRlcm5hbElELCBjb25zdCB4bWxDaGFyICpTeXN0ZW1JRCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmludGVybmFsU3Vic2V0ICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmludGVybmFsU3Vic2V0KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSwgRXh0ZXJuYWxJRCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW1JRCk7Cn0KCnN0YXRpYyBpbnQKaXNTdGFuZGFsb25lU3BsaXQodm9pZCAqY3R4KQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aXNTdGFuZGFsb25lICE9IE5VTEwpKQoJcmV0dXJuKGN0eHQtPnVzZXJfc2F4LT5pc1N0YW5kYWxvbmUoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKaGFzSW50ZXJuYWxTdWJzZXRTcGxpdCh2b2lkICpjdHgpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5oYXNJbnRlcm5hbFN1YnNldCAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+aGFzSW50ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyBpbnQKaGFzRXh0ZXJuYWxTdWJzZXRTcGxpdCh2b2lkICpjdHgpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5oYXNFeHRlcm5hbFN1YnNldCAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+aGFzRXh0ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhKSk7CiAgICByZXR1cm4oMCk7Cn0KCnN0YXRpYyB2b2lkCmV4dGVybmFsU3Vic2V0U3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpuYW1lLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKkV4dGVybmFsSUQsIGNvbnN0IHhtbENoYXIgKlN5c3RlbUlEKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aW50ZXJuYWxTdWJzZXQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+aW50ZXJuYWxTdWJzZXQoY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBFeHRlcm5hbElELAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbUlEKTsKfQoKc3RhdGljIHhtbFBhcnNlcklucHV0UHRyCnJlc29sdmVFbnRpdHlTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKnB1YmxpY0lkLCBjb25zdCB4bWxDaGFyICpzeXN0ZW1JZCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnJlc29sdmVFbnRpdHkgIT0gTlVMTCkpCglyZXR1cm4oY3R4dC0+dXNlcl9zYXgtPnJlc29sdmVFbnRpdHkoY3R4dC0+dXNlcl9kYXRhLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1JZCkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgpzdGF0aWMgeG1sRW50aXR5UHRyCmdldEVudGl0eVNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmdldEVudGl0eSAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+Z2V0RW50aXR5KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgpzdGF0aWMgeG1sRW50aXR5UHRyCmdldFBhcmFtZXRlckVudGl0eVNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmdldFBhcmFtZXRlckVudGl0eSAhPSBOVUxMKSkKCXJldHVybihjdHh0LT51c2VyX3NheC0+Z2V0UGFyYW1ldGVyRW50aXR5KGN0eHQtPnVzZXJfZGF0YSwgbmFtZSkpOwogICAgcmV0dXJuKE5VTEwpOwp9CgoKc3RhdGljIHZvaWQKZW50aXR5RGVjbFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqbmFtZSwgaW50IHR5cGUsCiAgICAgICAgICBjb25zdCB4bWxDaGFyICpwdWJsaWNJZCwgY29uc3QgeG1sQ2hhciAqc3lzdGVtSWQsIHhtbENoYXIgKmNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5lbnRpdHlEZWNsICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmVudGl0eURlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCB0eXBlLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c3RlbUlkLCBjb250ZW50KTsKfQoKc3RhdGljIHZvaWQKYXR0cmlidXRlRGVjbFNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqIGVsZW0sCiAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgaW50IHR5cGUsIGludCBkZWYsCiAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogZGVmYXVsdFZhbHVlLCB4bWxFbnVtZXJhdGlvblB0ciB0cmVlKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+YXR0cmlidXRlRGVjbCAhPSBOVUxMKSkgewoJY3R4dC0+dXNlcl9zYXgtPmF0dHJpYnV0ZURlY2woY3R4dC0+dXNlcl9kYXRhLCBlbGVtLCBuYW1lLCB0eXBlLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmLCBkZWZhdWx0VmFsdWUsIHRyZWUpOwogICAgfSBlbHNlIHsKCXhtbEZyZWVFbnVtZXJhdGlvbih0cmVlKTsKICAgIH0KfQoKc3RhdGljIHZvaWQKZWxlbWVudERlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsIGludCB0eXBlLAoJICAgIHhtbEVsZW1lbnRDb250ZW50UHRyIGNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5lbGVtZW50RGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5lbGVtZW50RGVjbChjdHh0LT51c2VyX2RhdGEsIG5hbWUsIHR5cGUsIGNvbnRlbnQpOwp9CgpzdGF0aWMgdm9pZApub3RhdGlvbkRlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkgICAgIGNvbnN0IHhtbENoYXIgKnB1YmxpY0lkLCBjb25zdCB4bWxDaGFyICpzeXN0ZW1JZCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPm5vdGF0aW9uRGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5ub3RhdGlvbkRlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQpOwp9CgpzdGF0aWMgdm9pZAp1bnBhcnNlZEVudGl0eURlY2xTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKm5hbWUsCgkJICAgY29uc3QgeG1sQ2hhciAqcHVibGljSWQsIGNvbnN0IHhtbENoYXIgKnN5c3RlbUlkLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5vdGF0aW9uTmFtZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnVucGFyc2VkRW50aXR5RGVjbCAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT51bnBhcnNlZEVudGl0eURlY2woY3R4dC0+dXNlcl9kYXRhLCBuYW1lLCBwdWJsaWNJZCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdGVtSWQsIG5vdGF0aW9uTmFtZSk7Cn0KCnN0YXRpYyB2b2lkCnNldERvY3VtZW50TG9jYXRvclNwbGl0KHZvaWQgKmN0eCwgeG1sU0FYTG9jYXRvclB0ciBsb2MpCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoKGN0eHQgIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5zZXREb2N1bWVudExvY2F0b3IgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+c2V0RG9jdW1lbnRMb2NhdG9yKGN0eHQtPnVzZXJfZGF0YSwgbG9jKTsKfQoKc3RhdGljIHZvaWQKc3RhcnREb2N1bWVudFNwbGl0KHZvaWQgKmN0eCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnN0YXJ0RG9jdW1lbnQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+c3RhcnREb2N1bWVudChjdHh0LT51c2VyX2RhdGEpOwp9CgpzdGF0aWMgdm9pZAplbmREb2N1bWVudFNwbGl0KHZvaWQgKmN0eCkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmVuZERvY3VtZW50ICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmVuZERvY3VtZW50KGN0eHQtPnVzZXJfZGF0YSk7Cn0KCnN0YXRpYyB2b2lkCnByb2Nlc3NpbmdJbnN0cnVjdGlvblNwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqZGF0YSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPnByb2Nlc3NpbmdJbnN0cnVjdGlvbiAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oY3R4dC0+dXNlcl9kYXRhLCB0YXJnZXQsIGRhdGEpOwp9CgpzdGF0aWMgdm9pZApjb21tZW50U3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICp2YWx1ZSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmICgoY3R4dCAhPSBOVUxMKSAmJiAoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmNvbW1lbnQgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+Y29tbWVudChjdHh0LT51c2VyX2RhdGEsIHZhbHVlKTsKfQoKLyoKICogVmFyYXJncyBlcnJvciBjYWxsYmFja3MgdG8gdGhlIHVzZXIgYXBwbGljYXRpb24sIGhhcmRlciAuLi4KICovCgpzdGF0aWMgdm9pZCBYTUxDREVDTAp3YXJuaW5nU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+d2FybmluZyAhPSBOVUxMKSkgewoJVE9ETwogICAgfQp9CnN0YXRpYyB2b2lkIFhNTENERUNMCmVycm9yU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+ZXJyb3IgIT0gTlVMTCkpIHsKCVRPRE8KICAgIH0KfQpzdGF0aWMgdm9pZCBYTUxDREVDTApmYXRhbEVycm9yU3BsaXQodm9pZCAqY3R4LCBjb25zdCBjaGFyICptc2cgQVRUUklCVVRFX1VOVVNFRCwgLi4uKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+ZmF0YWxFcnJvciAhPSBOVUxMKSkgewoJVE9ETwogICAgfQp9CgovKgogKiBUaG9zZSBhcmUgZnVuY3Rpb24gd2hlcmUgYm90aCB0aGUgdXNlciBoYW5kbGVyIGFuZCB0aGUgc2NoZW1hcyBoYW5kbGVyCiAqIG5lZWQgdG8gYmUgY2FsbGVkLgogKi8Kc3RhdGljIHZvaWQKY2hhcmFjdGVyc1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqY2gsIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYgKGN0eHQtPnVzZXJfc2F4LT5jaGFyYWN0ZXJzICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPmNoYXJhY3RlcnMoY3R4dC0+dXNlcl9kYXRhLCBjaCwgbGVuKTsKICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTQVhIYW5kbGVUZXh0KGN0eHQtPmN0eHQsIGNoLCBsZW4pOwp9CgpzdGF0aWMgdm9pZAppZ25vcmFibGVXaGl0ZXNwYWNlU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpjaCwgaW50IGxlbikKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBjdHh0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIGN0eDsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+aWdub3JhYmxlV2hpdGVzcGFjZSAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5pZ25vcmFibGVXaGl0ZXNwYWNlKGN0eHQtPnVzZXJfZGF0YSwgY2gsIGxlbik7CiAgICBpZiAoY3R4dC0+Y3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU0FYSGFuZGxlVGV4dChjdHh0LT5jdHh0LCBjaCwgbGVuKTsKfQoKc3RhdGljIHZvaWQKY2RhdGFCbG9ja1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqdmFsdWUsIGludCBsZW4pCnsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgIT0gTlVMTCkpCgljdHh0LT51c2VyX3NheC0+aWdub3JhYmxlV2hpdGVzcGFjZShjdHh0LT51c2VyX2RhdGEsIHZhbHVlLCBsZW4pOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKCXhtbFNjaGVtYVNBWEhhbmRsZUNEYXRhU2VjdGlvbihjdHh0LT5jdHh0LCB2YWx1ZSwgbGVuKTsKfQoKc3RhdGljIHZvaWQKcmVmZXJlbmNlU3BsaXQodm9pZCAqY3R4LCBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKChjdHh0ICE9IE5VTEwpICYmIChjdHh0LT51c2VyX3NheCAhPSBOVUxMKSAmJgogICAgICAgIChjdHh0LT51c2VyX3NheC0+cmVmZXJlbmNlICE9IE5VTEwpKQoJY3R4dC0+dXNlcl9zYXgtPnJlZmVyZW5jZShjdHh0LT51c2VyX2RhdGEsIG5hbWUpOwogICAgaWYgKGN0eHQtPmN0eHQgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFTQVhIYW5kbGVSZWZlcmVuY2UoY3R4dC0+dXNlcl9kYXRhLCBuYW1lKTsKfQoKc3RhdGljIHZvaWQKc3RhcnRFbGVtZW50TnNTcGxpdCh2b2lkICpjdHgsIGNvbnN0IHhtbENoYXIgKiBsb2NhbG5hbWUsIAoJCSAgICBjb25zdCB4bWxDaGFyICogcHJlZml4LCBjb25zdCB4bWxDaGFyICogVVJJLCAKCQkgICAgaW50IG5iX25hbWVzcGFjZXMsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlcywgCgkJICAgIGludCBuYl9hdHRyaWJ1dGVzLCBpbnQgbmJfZGVmYXVsdGVkLCAKCQkgICAgY29uc3QgeG1sQ2hhciAqKiBhdHRyaWJ1dGVzKSB7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIGN0eHQgPSAoeG1sU2NoZW1hU0FYUGx1Z1B0cikgY3R4OwogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoKGN0eHQtPnVzZXJfc2F4ICE9IE5VTEwpICYmCiAgICAgICAgKGN0eHQtPnVzZXJfc2F4LT5zdGFydEVsZW1lbnROcyAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5zdGFydEVsZW1lbnROcyhjdHh0LT51c2VyX2RhdGEsIGxvY2FsbmFtZSwgcHJlZml4LAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSSSwgbmJfbmFtZXNwYWNlcywgbmFtZXNwYWNlcywKCQkJCSAgICAgICBuYl9hdHRyaWJ1dGVzLCBuYl9kZWZhdWx0ZWQsCgkJCQkgICAgICAgYXR0cmlidXRlcyk7CiAgICBpZiAoY3R4dC0+Y3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU0FYSGFuZGxlU3RhcnRFbGVtZW50TnMoY3R4dC0+Y3R4dCwgbG9jYWxuYW1lLCBwcmVmaXgsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUkksIG5iX25hbWVzcGFjZXMsIG5hbWVzcGFjZXMsCgkJCQkJIG5iX2F0dHJpYnV0ZXMsIG5iX2RlZmF1bHRlZCwKCQkJCQkgYXR0cmlidXRlcyk7Cn0KCnN0YXRpYyB2b2lkCmVuZEVsZW1lbnROc1NwbGl0KHZvaWQgKmN0eCwgY29uc3QgeG1sQ2hhciAqIGxvY2FsbmFtZSwgCgkJICAgIGNvbnN0IHhtbENoYXIgKiBwcmVmaXgsIGNvbnN0IHhtbENoYXIgKiBVUkkpIHsKICAgIHhtbFNjaGVtYVNBWFBsdWdQdHIgY3R4dCA9ICh4bWxTY2hlbWFTQVhQbHVnUHRyKSBjdHg7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmICgoY3R4dC0+dXNlcl9zYXggIT0gTlVMTCkgJiYKICAgICAgICAoY3R4dC0+dXNlcl9zYXgtPmVuZEVsZW1lbnROcyAhPSBOVUxMKSkKCWN0eHQtPnVzZXJfc2F4LT5lbmRFbGVtZW50TnMoY3R4dC0+dXNlcl9kYXRhLCBsb2NhbG5hbWUsIHByZWZpeCwgVVJJKTsKICAgIGlmIChjdHh0LT5jdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTQVhIYW5kbGVFbmRFbGVtZW50TnMoY3R4dC0+Y3R4dCwgbG9jYWxuYW1lLCBwcmVmaXgsIFVSSSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTQVhQbHVnOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2F4OiAgYSBwb2ludGVyIHRvIHRoZSBvcmlnaW5hbCB4bWxTQVhIYW5kbGVyUHRyCiAqIEB1c2VyX2RhdGE6ICBhIHBvaW50ZXIgdG8gdGhlIG9yaWdpbmFsIFNBWCB1c2VyIGRhdGEgcG9pbnRlcgogKgogKiBQbHVnIGEgU0FYIGJhc2VkIHZhbGlkYXRpb24gbGF5ZXIgaW4gYSBTQVggcGFyc2luZyBldmVudCBmbG93LgogKiBUaGUgb3JpZ2luYWwgQHNheHB0ciBhbmQgQGRhdGFwdHIgZGF0YSBhcmUgcmVwbGFjZWQgYnkgbmV3IHBvaW50ZXJzCiAqIGJ1dCB0aGUgY2FsbHMgdG8gdGhlIG9yaWdpbmFsIHdpbGwgYmUgbWFpbnRhaW5lZC4KICoKICogUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBkYXRhIHN0cnVjdHVyZSBuZWVkZWQgdG8gdW5wbHVnIHRoZSB2YWxpZGF0aW9uIGxheWVyCiAqICAgICAgICAgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9ycy4KICovCnhtbFNjaGVtYVNBWFBsdWdQdHIKeG1sU2NoZW1hU0FYUGx1Zyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkgeG1sU0FYSGFuZGxlclB0ciAqc2F4LCB2b2lkICoqdXNlcl9kYXRhKQp7CiAgICB4bWxTY2hlbWFTQVhQbHVnUHRyIHJldDsKICAgIHhtbFNBWEhhbmRsZXJQdHIgb2xkX3NheDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNheCA9PSBOVUxMKSB8fCAodXNlcl9kYXRhID09IE5VTEwpKQogICAgICAgIHJldHVybihOVUxMKTsKCiAgICAvKgogICAgICogV2Ugb25seSBhbGxvdyB0byBwbHVnIGludG8gU0FYMiBldmVudCBzdHJlYW1zCiAgICAgKi8KICAgIG9sZF9zYXggPSAqc2F4OwogICAgaWYgKChvbGRfc2F4ICE9IE5VTEwpICYmIChvbGRfc2F4LT5pbml0aWFsaXplZCAhPSBYTUxfU0FYMl9NQUdJQykpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgaWYgKChvbGRfc2F4ICE9IE5VTEwpICYmIAogICAgICAgIChvbGRfc2F4LT5zdGFydEVsZW1lbnROcyA9PSBOVUxMKSAmJiAob2xkX3NheC0+ZW5kRWxlbWVudE5zID09IE5VTEwpICYmCiAgICAgICAgKChvbGRfc2F4LT5zdGFydEVsZW1lbnQgIT0gTlVMTCkgfHwgKG9sZF9zYXgtPmVuZEVsZW1lbnQgIT0gTlVMTCkpKQogICAgICAgIHJldHVybihOVUxMKTsKCiAgICAvKgogICAgICogZXZlcnl0aGluZyBzZWVtcyByaWdodCBhbGxvY2F0ZSB0aGUgbG9jYWwgZGF0YSBuZWVkZWQgZm9yIHRoYXQgbGF5ZXIKICAgICAqLwogICAgcmV0ID0gKHhtbFNjaGVtYVNBWFBsdWdQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hU0FYUGx1Z1N0cnVjdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVNBWFBsdWdTdHJ1Y3QpKTsKICAgIHJldC0+bWFnaWMgPSBYTUxfU0FYX1BMVUdfTUFHSUM7CiAgICByZXQtPnNjaGVtYXNfc2F4LmluaXRpYWxpemVkID0gWE1MX1NBWDJfTUFHSUM7CiAgICByZXQtPmN0eHQgPSBjdHh0OwogICAgcmV0LT51c2VyX3NheF9wdHIgPSBzYXg7CiAgICByZXQtPnVzZXJfc2F4ID0gb2xkX3NheDsKICAgIGlmIChvbGRfc2F4ID09IE5VTEwpIHsJCiAgICAgICAgLyoKCSAqIGdvIGRpcmVjdCwgbm8gbmVlZCBmb3IgdGhlIHNwbGl0IGJsb2NrIGFuZCBmdW5jdGlvbnMuCgkgKi8KCXJldC0+c2NoZW1hc19zYXguc3RhcnRFbGVtZW50TnMgPSB4bWxTY2hlbWFTQVhIYW5kbGVTdGFydEVsZW1lbnROczsKCXJldC0+c2NoZW1hc19zYXguZW5kRWxlbWVudE5zID0geG1sU2NoZW1hU0FYSGFuZGxlRW5kRWxlbWVudE5zOwoJLyoKCSAqIE5vdGUgdGhhdCB3ZSB1c2UgdGhlIHNhbWUgdGV4dC1mdW5jdGlvbiBmb3IgYm90aCwgdG8gcHJldmVudAoJICogdGhlIHBhcnNlciBmcm9tIHRlc3RpbmcgZm9yIGlnbm9yYWJsZSB3aGl0ZXNwYWNlLgoJICovCglyZXQtPnNjaGVtYXNfc2F4Lmlnbm9yYWJsZVdoaXRlc3BhY2UgPSB4bWxTY2hlbWFTQVhIYW5kbGVUZXh0OwoJcmV0LT5zY2hlbWFzX3NheC5jaGFyYWN0ZXJzID0geG1sU2NoZW1hU0FYSGFuZGxlVGV4dDsKCglyZXQtPnNjaGVtYXNfc2F4LmNkYXRhQmxvY2sgPSB4bWxTY2hlbWFTQVhIYW5kbGVDRGF0YVNlY3Rpb247CglyZXQtPnNjaGVtYXNfc2F4LnJlZmVyZW5jZSA9IHhtbFNjaGVtYVNBWEhhbmRsZVJlZmVyZW5jZTsKCglyZXQtPnVzZXJfZGF0YSA9IGN0eHQ7CgkqdXNlcl9kYXRhID0gY3R4dDsKICAgIH0gZWxzZSB7CiAgICAgICAvKgogICAgICAgICogZm9yIGVhY2ggY2FsbGJhY2sgdW51c2VkIGJ5IFNjaGVtYXMgaW5pdGlhbGl6ZSBpdCB0byB0aGUgU3BsaXQKCSogcm91dGluZSBvbmx5IGlmIG5vbiBOVUxMIGluIHRoZSB1c2VyIGJsb2NrLCB0aGlzIGNhbiBzcGVlZCB1cCAKCSogdGhpbmdzIGF0IHRoZSBTQVggbGV2ZWwuCgkqLwogICAgICAgIGlmIChvbGRfc2F4LT5pbnRlcm5hbFN1YnNldCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmludGVybmFsU3Vic2V0ID0gaW50ZXJuYWxTdWJzZXRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+aXNTdGFuZGFsb25lICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaXNTdGFuZGFsb25lID0gaXNTdGFuZGFsb25lU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmhhc0ludGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguaGFzSW50ZXJuYWxTdWJzZXQgPSBoYXNJbnRlcm5hbFN1YnNldFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5oYXNFeHRlcm5hbFN1YnNldCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4Lmhhc0V4dGVybmFsU3Vic2V0ID0gaGFzRXh0ZXJuYWxTdWJzZXRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+cmVzb2x2ZUVudGl0eSAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnJlc29sdmVFbnRpdHkgPSByZXNvbHZlRW50aXR5U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmdldEVudGl0eSAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmdldEVudGl0eSA9IGdldEVudGl0eVNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5lbnRpdHlEZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZW50aXR5RGVjbCA9IGVudGl0eURlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+bm90YXRpb25EZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgubm90YXRpb25EZWNsID0gbm90YXRpb25EZWNsU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmF0dHJpYnV0ZURlY2wgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5hdHRyaWJ1dGVEZWNsID0gYXR0cmlidXRlRGVjbFNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5lbGVtZW50RGVjbCAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmVsZW1lbnREZWNsID0gZWxlbWVudERlY2xTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+dW5wYXJzZWRFbnRpdHlEZWNsICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXgudW5wYXJzZWRFbnRpdHlEZWNsID0gdW5wYXJzZWRFbnRpdHlEZWNsU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPnNldERvY3VtZW50TG9jYXRvciAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnNldERvY3VtZW50TG9jYXRvciA9IHNldERvY3VtZW50TG9jYXRvclNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5zdGFydERvY3VtZW50ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguc3RhcnREb2N1bWVudCA9IHN0YXJ0RG9jdW1lbnRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+ZW5kRG9jdW1lbnQgIT0gTlVMTCkKICAgICAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5lbmREb2N1bWVudCA9IGVuZERvY3VtZW50U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPnByb2Nlc3NpbmdJbnN0cnVjdGlvbiAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnByb2Nlc3NpbmdJbnN0cnVjdGlvbiA9IHByb2Nlc3NpbmdJbnN0cnVjdGlvblNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5jb21tZW50ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguY29tbWVudCA9IGNvbW1lbnRTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+d2FybmluZyAhPSBOVUxMKQogICAgICAgICAgICByZXQtPnNjaGVtYXNfc2F4Lndhcm5pbmcgPSB3YXJuaW5nU3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmVycm9yICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZXJyb3IgPSBlcnJvclNwbGl0OwogICAgICAgIGlmIChvbGRfc2F4LT5mYXRhbEVycm9yICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZmF0YWxFcnJvciA9IGZhdGFsRXJyb3JTcGxpdDsKICAgICAgICBpZiAob2xkX3NheC0+Z2V0UGFyYW1ldGVyRW50aXR5ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZ2V0UGFyYW1ldGVyRW50aXR5ID0gZ2V0UGFyYW1ldGVyRW50aXR5U3BsaXQ7CiAgICAgICAgaWYgKG9sZF9zYXgtPmV4dGVybmFsU3Vic2V0ICE9IE5VTEwpCiAgICAgICAgICAgIHJldC0+c2NoZW1hc19zYXguZXh0ZXJuYWxTdWJzZXQgPSBleHRlcm5hbFN1YnNldFNwbGl0OwoKCS8qCgkgKiB0aGUgNiBzY2hlbWFzIGNhbGxiYWNrIGhhdmUgdG8gZ28gdG8gdGhlIHNwbGl0dGVyIGZ1bmN0aW9ucwoJICogTm90ZSB0aGF0IHdlIHVzZSB0aGUgc2FtZSB0ZXh0LWZ1bmN0aW9uIGZvciBpZ25vcmFibGVXaGl0ZXNwYWNlCgkgKiBpZiBwb3NzaWJsZSwgdG8gcHJldmVudCB0aGUgcGFyc2VyIGZyb20gdGVzdGluZyBmb3IgaWdub3JhYmxlCgkgKiB3aGl0ZXNwYWNlLgoJICovCiAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5jaGFyYWN0ZXJzID0gY2hhcmFjdGVyc1NwbGl0OwoJaWYgKChvbGRfc2F4LT5pZ25vcmFibGVXaGl0ZXNwYWNlICE9IE5VTEwpICYmCgkgICAgKG9sZF9zYXgtPmlnbm9yYWJsZVdoaXRlc3BhY2UgIT0gb2xkX3NheC0+Y2hhcmFjdGVycykpCgkgICAgcmV0LT5zY2hlbWFzX3NheC5pZ25vcmFibGVXaGl0ZXNwYWNlID0gaWdub3JhYmxlV2hpdGVzcGFjZVNwbGl0OwoJZWxzZQoJICAgIHJldC0+c2NoZW1hc19zYXguaWdub3JhYmxlV2hpdGVzcGFjZSA9IGNoYXJhY3RlcnNTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmNkYXRhQmxvY2sgPSBjZGF0YUJsb2NrU3BsaXQ7CiAgICAgICAgcmV0LT5zY2hlbWFzX3NheC5yZWZlcmVuY2UgPSByZWZlcmVuY2VTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LnN0YXJ0RWxlbWVudE5zID0gc3RhcnRFbGVtZW50TnNTcGxpdDsKICAgICAgICByZXQtPnNjaGVtYXNfc2F4LmVuZEVsZW1lbnROcyA9IGVuZEVsZW1lbnROc1NwbGl0OwoKCXJldC0+dXNlcl9kYXRhX3B0ciA9IHVzZXJfZGF0YTsKCXJldC0+dXNlcl9kYXRhID0gKnVzZXJfZGF0YTsKCSp1c2VyX2RhdGEgPSByZXQ7CiAgICB9CgogICAgLyoKICAgICAqIHBsdWcgdGhlIHBvaW50ZXJzIGJhY2suCiAgICAgKi8KICAgICpzYXggPSAmKHJldC0+c2NoZW1hc19zYXgpOwogICAgY3R4dC0+c2F4ID0gKnNheDsKICAgIGN0eHQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFfVkFMSURfQ1RYVF9GTEFHX1NUUkVBTTsKICAgIHhtbFNjaGVtYVByZVJ1bihjdHh0KTsKICAgIHJldHVybihyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU0FYVW5wbHVnOgogKiBAcGx1ZzogIGEgZGF0YSBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgeG1sU2NoZW1hU0FYUGx1ZwogKgogKiBVbnBsdWcgYSBTQVggYmFzZWQgdmFsaWRhdGlvbiBsYXllciBpbiBhIFNBWCBwYXJzaW5nIGV2ZW50IGZsb3cuCiAqIFRoZSBvcmlnaW5hbCBwb2ludGVycyB1c2VkIGluIHRoZSBjYWxsIGFyZSByZXN0b3JlZC4KICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcyBhbmQgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLgogKi8KaW50CnhtbFNjaGVtYVNBWFVucGx1Zyh4bWxTY2hlbWFTQVhQbHVnUHRyIHBsdWcpCnsKICAgIHhtbFNBWEhhbmRsZXJQdHIgKnNheDsKICAgIHZvaWQgKip1c2VyX2RhdGE7CgogICAgaWYgKChwbHVnID09IE5VTEwpIHx8IChwbHVnLT5tYWdpYyAhPSBYTUxfU0FYX1BMVUdfTUFHSUMpKQogICAgICAgIHJldHVybigtMSk7CiAgICBwbHVnLT5tYWdpYyA9IDA7CgogICAgeG1sU2NoZW1hUG9zdFJ1bihwbHVnLT5jdHh0KTsKICAgIC8qIHJlc3RvcmUgdGhlIGRhdGEgKi8KICAgIHNheCA9IHBsdWctPnVzZXJfc2F4X3B0cjsKICAgICpzYXggPSBwbHVnLT51c2VyX3NheDsKICAgIGlmIChwbHVnLT51c2VyX3NheCAhPSBOVUxMKSB7Cgl1c2VyX2RhdGEgPSBwbHVnLT51c2VyX2RhdGFfcHRyOwoJKnVzZXJfZGF0YSA9IHBsdWctPnVzZXJfZGF0YTsKICAgIH0KCiAgICAvKiBmcmVlIGFuZCByZXR1cm4gKi8KICAgIHhtbEZyZWUocGx1Zyk7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGlucHV0OiAgdGhlIGlucHV0IHRvIHVzZSBmb3IgcmVhZGluZyB0aGUgZGF0YQogKiBAZW5jOiAgYW4gb3B0aW9uYWwgZW5jb2RpbmcgaW5mb3JtYXRpb24KICogQHNheDogIGEgU0FYIGhhbmRsZXIgZm9yIHRoZSByZXN1bHRpbmcgZXZlbnRzCiAqIEB1c2VyX2RhdGE6ICB0aGUgY29udGV4dCB0byBwcm92aWRlIHRvIHRoZSBTQVggaGFuZGxlci4KICoKICogVmFsaWRhdGUgYW4gaW5wdXQgYmFzZWQgb24gYSBmbG93IG9mIFNBWCBldmVudCBmcm9tIHRoZSBwYXJzZXIKICogYW5kIGZvcndhcmQgdGhlIGV2ZW50cyB0byB0aGUgQHNheCBoYW5kbGVyIHdpdGggdGhlIHByb3ZpZGVkIEB1c2VyX2RhdGEKICogdGhlIHVzZXIgcHJvdmlkZWQgQHNheCBoYW5kbGVyIG11c3QgYmUgYSBTQVgyIG9uZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dCwgeG1sQ2hhckVuY29kaW5nIGVuYywKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU0FYSGFuZGxlclB0ciBzYXgsIHZvaWQgKnVzZXJfZGF0YSkKewogICAgeG1sU2NoZW1hU0FYUGx1Z1B0ciBwbHVnID0gTlVMTDsKICAgIHhtbFNBWEhhbmRsZXJQdHIgb2xkX3NheCA9IE5VTEw7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBjdHh0ID0gTlVMTDsKICAgIHhtbFBhcnNlcklucHV0UHRyIGlucHV0U3RyZWFtID0gTlVMTDsKICAgIGludCByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChpbnB1dCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgICogcHJlcGFyZSB0aGUgcGFyc2VyCiAgICAgKi8KICAgIHBjdHh0ID0geG1sTmV3UGFyc2VyQ3R4dCgpOwogICAgaWYgKHBjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBvbGRfc2F4ID0gcGN0eHQtPnNheDsKICAgIHBjdHh0LT5zYXggPSBzYXg7CiAgICBwY3R4dC0+dXNlckRhdGEgPSB1c2VyX2RhdGE7CiNpZiAwCiAgICBpZiAob3B0aW9ucykKICAgICAgICB4bWxDdHh0VXNlT3B0aW9ucyhwY3R4dCwgb3B0aW9ucyk7CiNlbmRpZgogICAgcGN0eHQtPmxpbmVudW1iZXJzID0gMTsgICAgCgogICAgaW5wdXRTdHJlYW0gPSB4bWxOZXdJT0lucHV0U3RyZWFtKHBjdHh0LCBpbnB1dCwgZW5jKTs7CiAgICBpZiAoaW5wdXRTdHJlYW0gPT0gTlVMTCkgewogICAgICAgIHJldCA9IC0xOwoJZ290byBkb25lOwogICAgfQogICAgaW5wdXRQdXNoKHBjdHh0LCBpbnB1dFN0cmVhbSk7CiAgICBjdHh0LT5wYXJzZXJDdHh0ID0gcGN0eHQ7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwoKICAgIC8qCiAgICAgKiBQbHVnIHRoZSB2YWxpZGF0aW9uIGFuZCBsYXVuY2ggdGhlIHBhcnNpbmcKICAgICAqLwogICAgcGx1ZyA9IHhtbFNjaGVtYVNBWFBsdWcoY3R4dCwgJihwY3R4dC0+c2F4KSwgJihwY3R4dC0+dXNlckRhdGEpKTsKICAgIGlmIChwbHVnID09IE5VTEwpIHsKICAgICAgICByZXQgPSAtMTsKCWdvdG8gZG9uZTsKICAgIH0KICAgIGN0eHQtPmlucHV0ID0gaW5wdXQ7CiAgICBjdHh0LT5lbmMgPSBlbmM7CiAgICBjdHh0LT5zYXggPSBwY3R4dC0+c2F4OwogICAgY3R4dC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQV9WQUxJRF9DVFhUX0ZMQUdfU1RSRUFNOwogICAgcmV0ID0geG1sU2NoZW1hVlN0YXJ0KGN0eHQpOwoKICAgIGlmICgocmV0ID09IDApICYmICghIGN0eHQtPnBhcnNlckN0eHQtPndlbGxGb3JtZWQpKSB7CglyZXQgPSBjdHh0LT5wYXJzZXJDdHh0LT5lcnJObzsKCWlmIChyZXQgPT0gMCkKCSAgICByZXQgPSAxOwogICAgfSAgICAKCmRvbmU6CiAgICBjdHh0LT5wYXJzZXJDdHh0ID0gTlVMTDsKICAgIGN0eHQtPnNheCA9IE5VTEw7CiAgICBjdHh0LT5pbnB1dCA9IE5VTEw7CiAgICBpZiAocGx1ZyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hU0FYVW5wbHVnKHBsdWcpOwogICAgfQogICAgLyogY2xlYW51cCAqLwogICAgaWYgKHBjdHh0ICE9IE5VTEwpIHsKCXBjdHh0LT5zYXggPSBvbGRfc2F4OwoJeG1sRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVGaWxlOgogKiBAY3R4dDogYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBmaWxlbmFtZTogdGhlIFVSSSBvZiB0aGUgaW5zdGFuY2UKICogQG9wdGlvbnM6IGEgZnV0dXJlIHNldCBvZiBvcHRpb25zLCBjdXJyZW50bHkgdW51c2VkCiAqCiAqIERvIGEgc2NoZW1hcyB2YWxpZGF0aW9uIG9mIHRoZSBnaXZlbiByZXNvdXJjZSwgaXQgd2lsbCB1c2UgdGhlCiAqIFNBWCBzdHJlYW1hYmxlIHZhbGlkYXRpb24gaW50ZXJuYWxseS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZUZpbGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogZmlsZW5hbWUsCgkJICAgICAgaW50IG9wdGlvbnMgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaW50IHJldDsKICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZmlsZW5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAKICAgIGlucHV0ID0geG1sUGFyc2VySW5wdXRCdWZmZXJDcmVhdGVGaWxlbmFtZShmaWxlbmFtZSwKCVhNTF9DSEFSX0VOQ09ESU5HX05PTkUpOwogICAgaWYgKGlucHV0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKGN0eHQsIGlucHV0LCBYTUxfQ0hBUl9FTkNPRElOR19OT05FLAoJTlVMTCwgTlVMTCk7ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgojZGVmaW5lIGJvdHRvbV94bWxzY2hlbWFzCiNpbmNsdWRlICJlbGZnY2NoYWNrLmgiCiNlbmRpZiAvKiBMSUJYTUxfU0NIRU1BU19FTkFCTEVEICovCg==