LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlIAogKiAgICAgbmVlZCB0byB2YWxpZGF0ZSBhbGwgc2NoZW1hIGF0dHJpYnV0ZXMgKHJlZiwgdHlwZSwgbmFtZSkKICogICAgIGFnYWluc3QgdGhlaXIgdHlwZXMuCiAqLwojZGVmaW5lIElOX0xJQlhNTAojaW5jbHVkZSAibGlieG1sLmgiCgojaWZkZWYgTElCWE1MX1NDSEVNQVNfRU5BQkxFRAoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgojaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KCiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hcy5oPgojaW5jbHVkZSA8bGlieG1sL3NjaGVtYXNJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxzY2hlbWFzdHlwZXMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxhdXRvbWF0YS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHJlZ2V4cC5oPgojaW5jbHVkZSA8bGlieG1sL2RpY3QuaD4KCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKLyogI2RlZmluZSBERUJVR19VTklPTl9WQUxJREFUSU9OIDEgKi8KCgojZGVmaW5lIFVOQk9VTkRFRCAoMSA8PCAzMCkKI2RlZmluZSBUT0RPIAkJCQkJCQkJXAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCQkJCVwKCSAgICAiVW5pbXBsZW1lbnRlZCBibG9jayBhdCAlczolZFxuIiwJCQkJXAogICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOwoKI2RlZmluZSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikgIiMjIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgcmVmLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkF0dHJpYnV0ZSBkZWNsLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiQXR0cmlidXRlIHJlZi4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc1NUID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJTVCI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQ1QgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkNUIjsKCiNkZWZpbmUgSVNfU0NIRU1BKG5vZGUsIHR5cGUpCQkJCQkJXAogICAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPm5zICE9IE5VTEwpICYmCQkJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0eXBlKSkgJiYJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkKCiNkZWZpbmUgRlJFRV9BTkRfTlVMTChzdHIpCQkJCQkJXAogICAgaWYgKHN0ciAhPSBOVUxMKSB7CQkJCQkJCVwKCXhtbEZyZWUoc3RyKTsJCQkJCQkJXAoJc3RyID0gTlVMTDsJCQkJCQkJXAogICAgfQoKI2RlZmluZSBJU19BTllUWVBFKGl0ZW0pICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgICBcCiAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSAgIAoKI2RlZmluZSBJU19DT01QTEVYX1RZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fCAgICBcCiAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoKI2RlZmluZSBJU19TSU1QTEVfVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICAgXAogICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8ICAgICBcCiAgICAgKChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYgICAgIFwKICAgICAgKGl0ZW0tPmJ1aWx0SW5UeXBlICE9IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSkgCgojZGVmaW5lIFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1BSRVNFUlZFIDAKI2RlZmluZSBYTUxfU0NIRU1BU19WQUxfV1RTUF9SRVBMQUNFICAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UgMgoKI2RlZmluZSBYTUxfU0NIRU1BU19QQVJTRV9FUlJPUgkJMQoKI2RlZmluZSBTQ0hFTUFTX1BBUlNFX09QVElPTlMgWE1MX1BBUlNFX05PRU5UCgoKLyoKKiBYTUxfU0NIRU1BX1ZBTF9YU0lfQVNTRU1CTEVfVE5TX0NPTVBPU0UJIAoqIGFsbG93IHRvIGFzc2VtYmxlIHNjaGVtYXRhIHdpdGggCiogdGhlIHNhbWUgdGFyZ2V0IG5hbWVzcGFjZSBmcm9tIAoqIGRpZmZlcmVudCBzb3VyY2VzOyBvdGhlcndpc2UsIHRoZSBmaXJzdCAKKiBlbmNvdW50ZXJlZCBzY2hlbWEgd2l0aCBhIHNwZWNpZmljIHRhcmdldCAKKiBuYW1lc3BhY2Ugd2lsbCBiZSB1c2VkIG9ubHkgKgogICAKKiAKKiBYTUxfU0NIRU1BX1ZBTF9MT0NBVEVfQllfTlNOQU1FID0gMTw8MgoqIGxvY2F0ZSBzY2hlbWF0YSB0byBiZSBpbXBvcnRlZAoqIHVzaW5nIHRoZSBuYW1lc3BhY2UgbmFtZTsgb3RoZXJ3aXNlCiogdGhlIGxvY2F0aW9uIFVSSSB3aWxsIGJlIHVzZWQgKi8KCi8qCiogeG1sU2NoZW1hUGFyc2VyT3B0aW9uOgoqCiogVGhpcyBpcyB0aGUgc2V0IG9mIFhNTCBTY2hlbWEgcGFyc2VyIG9wdGlvbnMuCioKdHlwZWRlZiBlbnVtIHsKICAgIFhNTF9TQ0hFTUFfUEFSX0xPQ0FURV9CWV9OU05BTUUJPSAxPDwwCgkqIGxvY2F0ZSBzY2hlbWF0YSB0byBiZSBpbXBvcnRlZAoJKiB1c2luZyB0aGUgbmFtZXNwYWNlIG5hbWU7IG90aGVyd2lzZQoJKiB0aGUgbG9jYXRpb24gVVJJIHdpbGwgYmUgdXNlZCAqCn0geG1sU2NoZW1hUGFyc2VyT3B0aW9uOwoqLwoKLyoKWE1MUFVCRlVOIGludCBYTUxDQUxMCgkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJCSAgaW50IG9wdGlvbnMpOwpYTUxQVUJGVU4gaW50IFhNTENBTEwKCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpOwoKKi8KCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBc3NlbWJsZSB4bWxTY2hlbWFBc3NlbWJsZTsKdHlwZWRlZiB4bWxTY2hlbWFBc3NlbWJsZSAqeG1sU2NoZW1hQXNzZW1ibGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hQXNzZW1ibGUgewogICAgdm9pZCAqKml0ZW1zOyAgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IG5iSXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBzaXplSXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KfTsKCnN0cnVjdCBfeG1sU2NoZW1hUGFyc2VyQ3R4dCB7CiAgICB2b2lkICp1c2VyRGF0YTsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgICAgICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU2NoZW1hVmFsaWRFcnJvciBlcnI7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvcjsKCiAgICB4bWxTY2hlbWFQdHIgdG9wc2NoZW1hOwkvKiBUaGUgbWFpbiBzY2hlbWEgKi8KICAgIHhtbEhhc2hUYWJsZVB0ciBuYW1lc3BhY2VzOwkvKiBIYXNoIHRhYmxlIG9mIG5hbWVzcGFjZXMgdG8gc2NoZW1hcyAqLwoKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7ICAgICAgICAvKiBUaGUgc2NoZW1hIGluIHVzZSAqLwogICAgY29uc3QgeG1sQ2hhciAqY29udGFpbmVyOyAgIC8qIHRoZSBjdXJyZW50IGVsZW1lbnQsIGdyb3VwLCAuLi4gKi8KICAgIGludCBjb3VudGVyOwoKICAgIGNvbnN0IHhtbENoYXIgKlVSTDsKICAgIHhtbERvY1B0ciBkb2M7CiAgICBpbnQgcHJlc2VydmU7CQkvKiBXaGV0aGVyIHRoZSBkb2Mgc2hvdWxkIGJlIGZyZWVkICAqLwoKICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcjsKICAgIGludCBzaXplOwoKICAgIC8qCiAgICAgKiBVc2VkIHRvIGJ1aWxkIGNvbXBsZXggZWxlbWVudCBjb250ZW50IG1vZGVscwogICAgICovCiAgICB4bWxBdXRvbWF0YVB0ciBhbTsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGVuZDsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhdGU7CgogICAgeG1sRGljdFB0ciBkaWN0OwkJLyogZGljdGlvbm5hcnkgZm9yIGludGVybmVkIHN0cmluZyBuYW1lcyAqLwogICAgaW50ICAgICAgICBpbmNsdWRlczsJLyogdGhlIGluY2x1c2lvbiBsZXZlbCwgMCBmb3Igcm9vdCBvciBpbXBvcnRzICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIGN0eHRUeXBlOyAvKiBUaGUgY3VycmVudCBjb250ZXh0IHNpbXBsZS9jb21wbGV4IHR5cGUgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgcGFyZW50SXRlbTsgLyogVGhlIGN1cnJlbnQgcGFyZW50IHNjaGVtYSBpdGVtICovCiAgICB4bWxTY2hlbWFBc3NlbWJsZVB0ciBhc3NlbWJsZTsKICAgIGludCBvcHRpb25zOwogICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0Owp9OwoKCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOIDEKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQgMgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfUFJPSElCSVRFRCAzCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HIDQKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUUgNQojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQgNgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9GSVhFRF9WQUxVRSA3CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9ERUZBVUxUIDgKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7Cn07CgovKioKICogeG1sU2NoZW1hVmFsaWRDdHh0OgogKgogKiBBIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwoKc3RydWN0IF94bWxTY2hlbWFWYWxpZEN0eHQgewogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7ICAgICAgICAvKiBUaGUgc2NoZW1hIGluIHVzZSAqLwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0OwogICAgeG1sQ2hhckVuY29kaW5nIGVuYzsKICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4OwogICAgdm9pZCAqdXNlcl9kYXRhOwoKICAgIHhtbERvY1B0ciBteURvYzsKICAgIGludCBlcnI7CiAgICBpbnQgbmJlcnJvcnM7CgogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sTm9kZVB0ciBjdXI7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgogICAgeG1sUmVnRXhlY0N0eHRQdHIgcmVnZXhwOwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbHVlOwoKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRyVG9wOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHI7CiAgICAvKiB4bWxOb2RlUHRyIHNjb3BlOyBub3QgdXNlZCAqLwogICAgaW50IHZhbHVlV1M7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbE5vZGVQdHIgdmFsaWRhdGlvblJvb3Q7ICAgIAogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKICAgIGludCB4c2lBc3NlbWJsZTsKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBpbiB0aGUgc2NoZW1hcyBpbXBvcnRTY2hlbWFzIGhhc2ggdGFibGUKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgeG1sU2NoZW1hSW1wb3J0Owp0eXBlZGVmIHhtbFNjaGVtYUltcG9ydCAqeG1sU2NoZW1hSW1wb3J0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUltcG9ydCB7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7IC8qIG5vdCB1c2VkIGFueSBtb3JlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IGlzTWFpbjsKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBhc3NvY2lhdGVkIHRvIGluY2x1ZGVzIGluIGEgc2NoZW1hcwogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgeG1sU2NoZW1hSW5jbHVkZTsKdHlwZWRlZiB4bWxTY2hlbWFJbmNsdWRlICp4bWxTY2hlbWFJbmNsdWRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwoKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uOwogICAgeG1sRG9jUHRyIGRvYzsKfTsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQYXJ0aWNsZSB4bWxTY2hlbWFQYXJ0aWNsZTsKdHlwZWRlZiB4bWxTY2hlbWFQYXJ0aWNsZSAqeG1sU2NoZW1hUGFydGljbGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUGFydGljbGUgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIG5leHQ7IC8qIHRoZSBuZXh0IHBhcnRpY2xlIGlmIGluIGEgbGlzdCAqLwogICAgaW50IG1pbk9jY3VyczsKICAgIGludCBtYXhPY2N1cnM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHRlcm07Cn07CgoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXAgeG1sU2NoZW1hTW9kZWxHcm91cDsKdHlwZWRlZiB4bWxTY2hlbWFNb2RlbEdyb3VwICp4bWxTY2hlbWFNb2RlbEdyb3VwUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXAgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIGludCBjb21wb3NpdG9yOyAvKiBvbmUgb2YgYWxsLCBjaG9pY2Ugb3Igc2VxdWVuY2UgKi8KICAgIHhtbFNjaGVtYVBhcnRpY2xlUHRyIHBhcnRpY2xlczsgLyogbGlzdCBvZiBwYXJ0aWNsZXMgKi8KICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXBEZWYgeG1sU2NoZW1hTW9kZWxHcm91cERlZjsKdHlwZWRlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmICp4bWxTY2hlbWFNb2RlbEdyb3VwRGVmUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYU1vZGVsR3JvdXBEZWYgewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2U7CiAgICB4bWxTY2hlbWFNb2RlbEdyb3VwUHRyIG1vZGVsR3JvdXA7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdDsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTb21lIHByZWRlY2xhcmF0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBpbnQgeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKTsKc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKTsKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkJIGludCBmaXJlRXJyb3JzLAkJCQkgCgkJCQkgaW50IGFwcGx5RmFjZXRzLAoJCQkJIGludCBub3JtYWxpemUsCgkJCQkgaW50IGNoZWNrTm9kZXMpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKTsgCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlEYXRhdHlwZSBlcnJvciBoYW5kbGVycwkJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYVBFcnJNZW1vcnk6CiAqIEBub2RlOiBhIGNvbnRleHQgbm9kZQogKiBAZXh0cmE6ICBleHRyYSBpbmZvcm1hdGlvbnMKICoKICogSGFuZGxlIGFuIG91dCBvZiBtZW1vcnkgY29uZGl0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyTWVtb3J5KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpleHRyYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAoY3R4dCAhPSBOVUxMKQogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNQLCBYTUxfRVJSX05PX01FTU9SWSwgbm9kZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgZXh0cmEpOwp9CgovKioKICogeG1sU2NoZW1hUEVycjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CglzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwgTlVMTCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICBtc2csIHN0cjEsIHN0cjIpOwp9CgovKioKICogeG1sU2NoZW1hUEVycjI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBub2RlOiB0aGUgY3VycmVudCBjaGlsZAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSBwYXJzZXIgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnIyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICB4bWxOb2RlUHRyIGNoaWxkLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNoaWxkLCBlcnJvciwgbXNnLCBzdHIxLCBzdHIyKTsKICAgIGVsc2UKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBFcnJFeHQ6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUgCiAqIEBzdHJEYXRhMTogZXh0cmEgZGF0YQogKiBAc3RyRGF0YTI6IGV4dHJhIGRhdGEKICogQHN0ckRhdGEzOiBleHRyYSBkYXRhCiAqIEBtc2c6IHRoZSBtZXNzYWdlCiAqIEBzdHIxOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHIyOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHIzOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHI0OiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHI1OiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIAogKiBIYW5kbGUgYSBwYXJzZXIgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnJFeHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKCQljb25zdCB4bWxDaGFyICogc3RyRGF0YTEsIGNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMiwgCgkJY29uc3QgeG1sQ2hhciAqIHN0ckRhdGEzLCBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCAKCQljb25zdCB4bWxDaGFyICogc3RyMiwgY29uc3QgeG1sQ2hhciAqIHN0cjMsIGNvbnN0IHhtbENoYXIgKiBzdHI0LAoJCWNvbnN0IHhtbENoYXIgKiBzdHI1KQp7CgogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMSwgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTIsIAoJCSAgICAoY29uc3QgY2hhciAqKSBzdHJEYXRhMywgMCwgMCwgbXNnLCBzdHIxLCBzdHIyLCAKCQkgICAgc3RyMywgc3RyNCwgc3RyNSk7Cn0KCgovKioKICogeG1sU2NoZW1hVlR5cGVFcnJNZW1vcnk6CiAqIEBub2RlOiBhIGNvbnRleHQgbm9kZQogKiBAZXh0cmE6ICBleHRyYSBpbmZvcm1hdGlvbnMKICoKICogSGFuZGxlIGFuIG91dCBvZiBtZW1vcnkgY29uZGl0aW9uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyTWVtb3J5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGN0eHQtPmVyciA9IFhNTF9TQ0hFTUFWX0lOVEVSTkFMOwogICAgfQogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTViwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZFcnIzOgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIEBzdHIzOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyMyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqc3RyMSwgY29uc3QgeG1sQ2hhciAqc3RyMiwKCSAgICAgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CiAgICB9CiAgICAvKiByZWFqdXN0IHRvIGdsb2JhbCBlcnJvciBudW1iZXJzICovCiAgICAvKiBSZW1vdmVkLCBzaW5jZSB0aGUgb2xkIHNjaGVtYSBlcnJvciBjb2RlcyBoYXZlIGJlZW4gCiAgICAqIHN1YnN0aXR1dGVkIGZvciB0aGUgZ2xvYmFsIGVycm9yIGNvZGVzLgogICAgKgogICAgKiBlcnJvciArPSBYTUxfU0NIRU1BVl9OT1JPT1QgLSBYTUxfU0NIRU1BU19FUlJfTk9ST09UOyAKICAgICovCiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsCgkJICAgIChjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZFcnJFeHQ6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUgCiAqIEBtc2c6IHRoZSBtZXNzYWdlCiAqIEBzdHIxOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHIyOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHIzOiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHI0OiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIEBzdHI1OiAgZXh0cmEgcGFyYW1ldGVyIGZvciB0aGUgbWVzc2FnZSBkaXNwbGF5CiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyRXh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKCQkgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgCgkJIGNvbnN0IHhtbENoYXIgKiBzdHIyLCBjb25zdCB4bWxDaGFyICogc3RyMywgCgkJIGNvbnN0IHhtbENoYXIgKiBzdHI0LCBjb25zdCB4bWxDaGFyICogc3RyNSkKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CgljdHh0LT5lcnIgPSBlcnJvcjsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwogICAgfQogICAgLyogcmVhanVzdCB0byBnbG9iYWwgZXJyb3IgbnVtYmVycyAqLwogICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBvbGQgc2NoZW1hIGVycm9yIGNvZGVzIGhhdmUgYmVlbiAKICAgICogc3Vic3RpdHV0ZWQgZm9yIHRoZSBnbG9iYWwgZXJyb3IgY29kZXMuCiAgICAqCiAgICAqIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICAqLwogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwgTlVMTCwgTlVMTCwgTlVMTCwgMCwgMCwgCgkJICAgIG1zZywgc3RyMSwgc3RyMiwgc3RyMywgc3RyNCwgc3RyNSk7Cn0KLyoqCiAqIHhtbFNjaGVtYVZFcnI6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CiAgICAgICAgc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICAvKiByZWFqdXN0IHRvIGdsb2JhbCBlcnJvciBudW1iZXJzICovCiAgICAvKiBSZW1vdmVkLCBzaW5jZSB0aGUgb2xkIHNjaGVtYSBlcnJvciBjb2RlcyBoYXZlIGJlZW4gCiAgICAqIHN1YnN0aXR1dGVkIGZvciB0aGUgZ2xvYmFsIGVycm9yIGNvZGVzLgogICAgKgogICAgKiBlcnJvciArPSBYTUxfU0NIRU1BVl9OT1JPT1QgLSBYTUxfU0NIRU1BU19FUlJfTk9ST09UOwogICAgKi8KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1YsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwgTlVMTCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICBtc2csIHN0cjEsIHN0cjIpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0ck5hbWU6CiAqIEBhdHRyOiAgdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UKICoKICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlOyBpZiB0aGUgYXR0cmlidXRlCiAqIGlzIGEgcmVmZXJlbmNlLCB0aGUgbmFtZSBvZiB0aGUgcmVmZXJlbmNlZCBnbG9iYWwgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRBdHRyTmFtZSh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikgCnsKICAgIGlmIChhdHRyLT5yZWYgIT0gTlVMTCkgCglyZXR1cm4oYXR0ci0+cmVmKTsKICAgIGVsc2UKCXJldHVybihhdHRyLT5uYW1lKTsJCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkk6CiAqIEB0eXBlOiAgdGhlIHR5cGUgKGVsZW1lbnQgb3IgYXR0cmlidXRlKQogKgogKiBSZXR1cm5zIHRoZSB0YXJnZXQgbmFtZXNwYWNlIFVSSSBvZiB0aGUgdHlwZTsgaWYgdGhlIHR5cGUgaXMgYSByZWZlcmVuY2UsCiAqIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSByZWZlcmVuY2VkIHR5cGUgd2lsbCBiZSByZXR1cm5lZC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKQp7ICAKICAgIGlmIChhdHRyLT5yZWYgIT0gTlVMTCkKCXJldHVybiAoYXR0ci0+cmVmTnMpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPnRhcmdldE5hbWVzcGFjZSk7ICAKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWw6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEB1cmk6ICB0aGUgbmFtZXNwYWNlIFVSSQogKiBAbG9jYWw6IHRoZSBsb2NhbCBuYW1lCiAqCiAqIFJldHVybnMgYSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gVVJJIHVzZWQKICogZm9yIGVycm9yIHJlcG9ydHMuCiAqCiAqIFJldHVybnMgYW4gZW1wdHkgc3RyaW5nLCBpZiBAbnMgaXMgTlVMTCwgYSBmb3JtYXR0ZWQKICogc3RyaW5nIG90aGVyd2lzZS4KICovICAKc3RhdGljIGNvbnN0IHhtbENoYXIqICAgCnhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoeG1sQ2hhciAqKmJ1ZiwKCQkJICAgY29uc3QgeG1sQ2hhciAqdXJpLCBjb25zdCB4bWxDaGFyICpsb2NhbCkKewogICAgaWYgKCpidWYgIT0gTlVMTCkKCXhtbEZyZWUoKmJ1Zik7CiAgICBpZiAodXJpID09IE5VTEwpIHsKCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsKICAgIH0gZWxzZSB7CgkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7JyIpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB1cmkpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJywgJyIpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsb2NhbCk7CQogICAgfQogICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJ30iKTsKICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsOgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAbnM6ICB0aGUgbmFtZXNwYWNlCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBVUkkgdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4KICoKICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcsIGlmIEBucyBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8gIApzdGF0aWMgY29uc3QgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCh4bWxDaGFyICoqYnVmLAoJCQkgICAgICB4bWxOc1B0ciBucywgY29uc3QgeG1sQ2hhciAqbG9jYWwpCnsKICAgIGlmICgqYnVmICE9IE5VTEwpIHsKCXhtbEZyZWUoKmJ1Zik7CgkqYnVmID0gTlVMTDsKICAgIH0KICAgIGlmICgobnMgPT0gTlVMTCkgfHwgKG5zLT5wcmVmaXggPT0gTlVMTCkpCglyZXR1cm4obG9jYWwpOwogICAgZWxzZSB7CgkqYnVmID0geG1sU3RyZHVwKG5zLT5wcmVmaXgpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiOiIpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsb2NhbCk7CiAgICB9CiAgICByZXR1cm4gKChjb25zdCB4bWxDaGFyICopICpidWYpOwp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgaXRlbQogKiBAaXRlbU5hbWU6IHRoZSBuYW1lIG9mIHRoZSBpdGVtCiAqIEBpdGVtOiB0aGUgaXRlbSBhcyBhbiBvYmplY3QgCiAqIEBpdGVtTm9kZTogdGhlIG5vZGUgb2YgdGhlIGl0ZW0KICogQGxvY2FsOiB0aGUgbG9jYWwgbmFtZQogKiBAcGFyc2luZzogaWYgdGhlIGZ1bmN0aW9uIGlzIHVzZWQgZHVyaW5nIHRoZSBwYXJzZQogKgogKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIGl0ZW0gdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4gCiAqCiAqIFRoZSBmb2xsb3dpbmcgb3JkZXIgaXMgdXNlZCB0byBidWlsZCB0aGUgcmVzdWx0aW5nIAogKiBkZXNpZ25hdGlvbiBpZiB0aGUgYXJndW1lbnRzIGFyZSBub3QgTlVMTDoKICogMWEuIElmIGl0ZW1EZXMgbm90IE5VTEwgLT4gaXRlbURlcwogKiAxYi4gSWYgKGl0ZW1EZXMgbm90IE5VTEwpIGFuZCAoaXRlbU5hbWUgbm90IE5VTEwpCiAqICAgICAtPiBpdGVtRGVzICsgaXRlbU5hbWUKICogMi4gSWYgdGhlIHByZWNlZGluZyB3YXMgTlVMTCBhbmQgKGl0ZW0gbm90IE5VTEwpIC0+IGl0ZW0KICogMy4gSWYgdGhlIHByZWNlZGluZyB3YXMgTlVMTCBhbmQgKGl0ZW1Ob2RlIG5vdCBOVUxMKSAtPiBpdGVtTm9kZQogKiAKICogSWYgdGhlIGl0ZW1Ob2RlIGlzIGFuIGF0dHJpYnV0ZSBub2RlLCB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHJlc3VsdC4KICoKICogUmV0dXJucyB0aGUgZm9ybWF0dGVkIHN0cmluZyBhbmQgc2V0cyBAYnVmIHRvIHRoZSByZXN1bHRpbmcgdmFsdWUuCiAqLyAgCnN0YXRpYyB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KHhtbENoYXIgKipidWYsCQkgICAgIAoJCSAgICAgY29uc3QgeG1sQ2hhciAqaXRlbURlcywKCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgIHhtbE5vZGVQdHIgaXRlbU5vZGUsCgkJICAgICBpbnQgcGFyc2luZykKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKICAgIGludCBuYW1lZCA9IDE7CgogICAgaWYgKCpidWYgIT0gTlVMTCkgewoJeG1sRnJlZSgqYnVmKTsKCSpidWYgPSBOVUxMOwogICAgfQogICAgICAgICAgICAKICAgIGlmIChpdGVtRGVzICE9IE5VTEwpIHsKCSpidWYgPSB4bWxTdHJkdXAoaXRlbURlcyk7CQogICAgfSBlbHNlIGlmIChpdGVtICE9IE5VTEwpIHsKCWlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJICAgIGlmIChpdGVtLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIidhbnlUeXBlJyIpOwoJICAgIGVsc2UgaWYgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJ2FueVNpbXBsZVR5cGUnIik7CgkgICAgZWxzZSB7CgkJLyogKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiYmkgIik7ICovCgkJLyogKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFFbGVtRGVzU1QpOyAqLwoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9Cgl9IGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzU1QpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNTVCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiIGxvY2FsIik7CgkgICAgfQoJfSBlbHNlIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNDVCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0NUKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgbG9jYWwiKTsKCSAgICB9Cgl9IGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSkgewoJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyOwoKCSAgICBhdHRyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbTsJICAgIAoJICAgIGlmICgoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgfHwKCQkoYXR0ci0+cmVmID09IE5VTEwpKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNBdHRyUmVmKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgYXR0ci0+cmVmUHJlZml4KTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5yZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgIH0JCQoJfSBlbHNlIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UKSB7CgkgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtOwoKCSAgICBlbGVtID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW07CSAgICAKCSAgICBpZiAoKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHx8IAoJCShlbGVtLT5yZWYgPT0gTlVMTCkpIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNFbGVtRGVjbCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5yZWZQcmVmaXgpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIjoiKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPnJlZik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0JCQoJfSBlbHNlCgkgICAgbmFtZWQgPSAwOwogICAgfSBlbHNlIAoJbmFtZWQgPSAwOwoKICAgIGlmICgobmFtZWQgPT0gMCkgJiYgKGl0ZW1Ob2RlICE9IE5VTEwpKSB7Cgl4bWxOb2RlUHRyIGVsZW07CgoJaWYgKGl0ZW1Ob2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCSAgICBlbGVtID0gaXRlbU5vZGUtPnBhcmVudDsKCWVsc2UgCgkgICAgZWxlbSA9IGl0ZW1Ob2RlOwoJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiRWxlbWVudCAnIik7CglpZiAocGFyc2luZykKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPm5hbWUpOwoJZWxzZQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgCgkJeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyLCBlbGVtLT5ucywgZWxlbS0+bmFtZSkpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgfQogICAgaWYgKChpdGVtTm9kZSAhPSBOVUxMKSAmJiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSkgewoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiLCBhdHRyaWJ1dGUgJyIpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHIsIAoJICAgIGl0ZW1Ob2RlLT5ucywgaXRlbU5vZGUtPm5hbWUpKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKICAgIH0KICAgIEZSRUVfQU5EX05VTEwoc3RyKTsKICAgIAogICAgcmV0dXJuICgqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBGb3JtYXRJdGVtRGVzOgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAaXRlbTogdGhlIGl0ZW0gYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBpdGVtTm9kZTogdGhlIGl0ZW0gYXMgYSBub2RlCiAqCiAqIElmIHRoZSBwb2ludGVyIHRvIEBidWYgaXMgbm90IE5VTEwgYW5kIEBidXQgaG9sZHMgbm8gdmFsdWUsCiAqIHRoZSB2YWx1ZSBpcyBzZXQgdG8gYSBpdGVtIGRlc2lnbmF0aW9uIHVzaW5nIAogKiB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0LiBUaGlzIG9uZSBhdm9pZHMgYWRkaW5nCiAqIGFuIGF0dHJpYnV0ZSBkZXNpZ25hdGlvbiBwb3N0Zml4LgogKgogKiBSZXR1cm5zIGEgc3RyaW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBSZXF1ZXN0SXRlbURlcyh4bWxDaGFyICoqYnVmLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgICAgIHhtbE5vZGVQdHIgaXRlbU5vZGUpCnsKICAgIGlmICgoYnVmID09IDApIHx8ICgqYnVmICE9IE5VTEwpKSAKCXJldHVybjsKICAgIGlmIChpdGVtTm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCglpdGVtTm9kZSA9IGl0ZW1Ob2RlLT5wYXJlbnQ7CiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KGJ1ZiwgTlVMTCwgaXRlbSwgaXRlbU5vZGUsIDEpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQHR5cGU6IHRoZSB0eXBlIGhvbGRpbmcgdGhlIGVudW1lcmF0aW9uIGZhY2V0cwogKgogKiBCdWlsZHMgYSBzdHJpbmcgY29uc2lzdGluZyBvZiBhbGwgZW51bWVyYXRpb24gZWxlbWVudHMuCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQoeG1sQ2hhciAqKmJ1ZiwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgbGluazsKCiAgICBpZiAoKmJ1ZiAhPSBOVUxMKQoJeG1sRnJlZSgqYnVmKTsgICAgCiAgICAqYnVmID0gTlVMTDsKICAgIGZvciAobGluayA9IHR5cGUtPmZhY2V0U2V0OyBsaW5rICE9IE5VTEw7IGxpbmsgPSBsaW5rLT5uZXh0KSB7CglpZiAobGluay0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJICAgIGlmICgqYnVmID09IE5VTEwpIHsKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsaW5rLT5mYWNldC0+dmFsdWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiwgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbGluay0+ZmFjZXQtPnZhbHVlKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZGYWNldEVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBub2RlOiB0aGUgbm9kZSB0byBiZSB2YWxpZGF0ZWQgIAogKiBAdmFsdWU6IHRoZSB2YWx1ZSBvZiB0aGUgbm9kZQogKiBAdHlwZTogdGhlIHR5cGUgaG9sZGluZyB0aGUgZmFjZXQKICogQGZhY2V0OiB0aGUgZmFjZXQKICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlIG9mIE5VTEwKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICoKICogUmVwb3J0cyBhIGZhY2V0IHZhbGlkYXRpb24gZXJyb3IuCiAqIFRPRE86IFNob3VsZCB0aGlzIHJlcG9ydCB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBhcyB3ZWxsPwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkZhY2V0RXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgeG1sTm9kZVB0ciBub2RlLAkJICAgCgkJICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJICAgdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAkJICAgCgkJICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSBmYWNldFR5cGU7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCBOVUxMLCBub2RlLCAwKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLCBOVUxMLCAwKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLCBmYWNldCAnIik7CiAgICBpZiAoZXJyb3IgPT0gWE1MX1NDSEVNQVZfQ1ZDX0VOVU1FUkFUSU9OX1ZBTElEKSB7CglmYWNldFR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOwoJLyoKCSogSWYgZW51bWVyYXRpb25zIGFyZSB2YWxpZGF0ZWQsIG9uZSBtdXN0IG5vdCBleHBlY3QgdGhlCgkqIGZhY2V0IHRvIGJlIGdpdmVuLgoJKi8JCiAgICB9IGVsc2UJCglmYWNldFR5cGUgPSBmYWNldC0+dHlwZTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0VHlwZSkpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiddOiAiKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBhIGRlZmF1bHQgbWVzc2FnZS4KCSovCglpZiAoKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEgpKSB7CgoJICAgIGNoYXIgbGVuWzI1XSwgYWN0TGVuWzI1XTsKCgkgICAgLyogRklYTUUsIFRPRE86IFdoYXQgaXMgdGhlIG1heCBleHBlY3RlZCBzdHJpbmcgbGVuZ3RoIG9mIHRoZQoJICAgICogdGhpcyB2YWx1ZT8KCSAgICAqLwoJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaGFzIGEgbGVuZ3RoIG9mICclcyc7ICIpOwoJICAgIGVsc2UKCQltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGhhcyBhIGxlbmd0aCBvZiAnJXMnOyAiKTsKCgkgICAgc25wcmludGYobGVuLCAyNCwgIiVsdSIsIHhtbFNjaGVtYUdldEZhY2V0VmFsdWVBc1VMb25nKGZhY2V0KSk7CgkgICAgc25wcmludGYoYWN0TGVuLCAyNCwgIiVsdSIsIGxlbmd0aCk7CgoJICAgIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEgpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgCgkJQkFEX0NBU1QgInRoaXMgZGlmZmVycyBmcm9tIHRoZSBhbGxvd2VkIGxlbmd0aCBvZiAnJXMnLlxuIik7ICAgICAKCSAgICBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEgpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgCgkJQkFEX0NBU1QgInRoaXMgZXhjZWVkcyB0aGUgYWxsb3dlZCBtYXhpbXVtIGxlbmd0aCBvZiAnJXMnLlxuIik7CgkgICAgZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIHVuZGVycnVucyB0aGUgYWxsb3dlZCBtaW5pbXVtIGxlbmd0aCBvZiAnJXMnLlxuIik7CgkgICAgCgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCXhtbFNjaGVtYVZFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsCgkJICAgIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgdmFsdWUsIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuLAoJCSAgICBOVUxMLCBOVUxMKTsKCSAgICBlbHNlIAoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsICAKCQkgICAgKGNvbnN0IGNoYXIgKikgbXNnLAoJCSAgICAoY29uc3QgeG1sQ2hhciAqKSBhY3RMZW4sIChjb25zdCB4bWxDaGFyICopIGxlbik7CgkKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFuIGVsZW1lbnQgIgoJCSJvZiB0aGUgc2V0IHslc30uXG4iKTsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCAKCQl4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQoJnN0ciwgdHlwZSkpOwoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhY2NlcHRlZCAiCgkJImJ5IHRoZSBwYXR0ZXJuICclcycuXG4iKTsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCAKCQlmYWNldC0+dmFsdWUpOwkgICAgICAgCgl9IGVsc2UgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CQkKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGZhY2V0LXZhbGlkLlxuIik7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgTlVMTCk7Cgl9IGVsc2UgewkgICAgCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBpcyBub3QgZmFjZXQtdmFsaWQuXG4iKTsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwoJfQogICAgfSBlbHNlIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwoJeG1sU2NoZW1hVkVycjMoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgc3RyMiwgc3RyMyk7CiAgICB9ICAgICAgICAKICAgIEZSRUVfQU5EX05VTEwoc3RyKQogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAdHlwZTogdGhlIHR5cGUgdXNlZCBmb3IgdmFsaWRhdGlvbgogKiBAbm9kZTogdGhlIG5vZGUgY29udGFpbmluZyB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqIEB2YWx1ZTogdGhlIHZhbGlkYXRlZCB2YWx1ZQogKgogKiBSZXBvcnRzIGEgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWU2ltcGxlVHlwZUVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkKCQkJeG1sTm9kZVB0ciBub2RlLAoJCQljb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCAgTlVMTCwgbm9kZSwgMCk7ICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIl06IFRoZSB2YWx1ZSAnJXMnIGlzIG5vdCB2YWxpZC5cbiIpOwoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgTlVMTCk7CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIl06IFRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQuXG4iKTsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICB9CiAgICBGUkVFX0FORF9OVUxMKHN0cikJCiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIG5vZGUgY29udGFpbmluZyB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqIEB0eXBlOiB0aGUgY29tcGxleCB0eXBlIHVzZWQgZm9yIHZhbGlkYXRpb24KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYSBjb21wbGV4IHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDb21wbGV4VHlwZUVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJeG1sTm9kZVB0ciBub2RlLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCQkJCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsICBOVUxMLCBub2RlLCAwKTsKICAgIGlmICh0eXBlICE9IE5VTEwpIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLCBOVUxMLCAwKSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXSIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogJXMuXG4iKTsKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgCgkoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyKQkKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mICB0aGUgb3duZXIKICogQG93bmVyTmFtZTogdGhlIG5hbWUgb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGFzIGFuIGVsZW1lbnQgbm9kZQogKiBAbm9kZTogdGhlIHBhcmVudCBlbGVtZW50IG5vZGUgb2YgdGhlIG1pc3NpbmcgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAgICAKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsICIlczogJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZQkKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwgCgkgICAgIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgcmVxdWlyZWQgYnV0IG1pc3NpbmcuXG4iLCAKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nOgogKiBAdHlwZTogdGhlIHR5cGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqCiAqIFJldHVybnMgdGhlIGNvbXBvbmVudCBuYW1lIG9mIGEgc2NoZW1hIGl0ZW0uCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqCnhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSkKewogICAgc3dpdGNoICh0eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgcmV0dXJuKCJzaW1wbGUgdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIHJldHVybigiY29tcGxleCB0eXBlIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuKCJlbGVtZW50IGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuKCJhdHRyaWJ1dGUgZGVjbGFyYXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIHJldHVybigibW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgcmV0dXJuKCJhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkgICAgcmV0dXJuKCJub3RhdGlvbiBkZWNsYXJhdGlvbiIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQovKioKICogeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGFzIGFuIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSBRTmFtZSAKICogQHJlZk5hbWU6IHRoZSByZWZlcmVuY2VkIGxvY2FsIG5hbWUKICogQHJlZlVSSTogdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIFVSSQogKiBAbWVzc2FnZTogb3B0aW9uYWwgbWVzc2FnZQogKgogKiBVc2VkIHRvIHJlcG9ydCBRTmFtZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgZmFpbGVkIHRvIHJlc29sdmUKICogdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgeG1sQ2hhciAqcmVmTmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZlVSSSwKCQkJIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJCSBjb25zdCBjaGFyICpyZWZUeXBlU3RyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UKCWRlcyA9ICpvd25lckRlczsKICAgIGlmIChyZWZUeXBlU3RyID09IE5VTEwpCglyZWZUeXBlU3RyID0geG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyhyZWZUeXBlKTsgICAgCgl4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsIAoJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIiVzLCBhdHRyaWJ1dGUgJyVzJzogVGhlIFFOYW1lIHZhbHVlICVzIGRvZXMgbm90IHJlc29sdmUgdG8gYShuKSAiCgkgICAgIiVzLlxuIiwgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lLCAKCSAgICB4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHJBLCByZWZVUkksIHJlZk5hbWUpLCAKCSAgICBCQURfQ0FTVCByZWZUeXBlU3RyLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUgCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkJeG1sQ2hhciAqKm93bmVyRGVzLAoJCQl4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJeG1sQXR0clB0ciBhdHRyLAoJCQljb25zdCBjaGFyICptc2cpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgIAogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsIAoJQkFEX0NBU1QgZGVzLCBhdHRyLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGF0dHJpYnV0ZSdzIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBhdHRyaWJ1dGUncyBvd25lciBpdGVtCiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZSAKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZSBkdXJpbmcgdGhlIHBhcnNlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbEF0dHJQdHIgYXR0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgICAKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCAKCSIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwgQkFEX0NBU1QgZGVzLCAKCXhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIGF0dHItPm5zLCBhdHRyLT5uYW1lKSk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQXF1aXJlRGVzOgogKiBAZGVzOiB0aGUgZmlyc3QgZGVzaWduYXRpb24gCiAqIEBpdGVtRGVzOiB0aGUgc2Vjb25kIGRlc2lnbmF0aW9uCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqCiAqIENyZWF0ZXMgYSBkZXNpZ25hdGlvbiBmb3IgYW4gaXRlbS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBBcXVpcmVEZXMoeG1sQ2hhciAqKmRlcywKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsIAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0pCnsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KGRlcywgTlVMTCwgaXRlbSwgaXRlbUVsZW0sIDEpOwogICAgZWxzZSBpZiAoKml0ZW1EZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChpdGVtRGVzLCBOVUxMLCBpdGVtLCBpdGVtRWxlbSwgMSk7CgkqZGVzID0gKml0ZW1EZXM7CiAgICB9IGVsc2UgCgkqZGVzID0gKml0ZW1EZXM7ICAKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMjogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIzOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnJFeHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtKTsgICAKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXM6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICBpZiAoKGl0ZW1FbGVtID09IE5VTEwpICYmIChpdGVtICE9IE5VTEwpKQoJaXRlbUVsZW0gPSBpdGVtLT5ub2RlOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtRWxlbSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsIAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsIGVycm9yLCBpdGVtRGVzLCBpdGVtLCBpdGVtRWxlbSwgbWVzc2FnZSwKCXN0cjEsIE5VTEwsIE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUEF0dHJVc2VFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIHR5cGUKICogQGl0ZW06IHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAYXR0cjogdGhlIGludmFsaWQgc2NoZW1hIGF0dHJpYnV0ZQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBhdHRyaWJ1dGUgdXNlIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEF0dHJVc2VFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ciwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtKTsKICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShhdHRyKSwgCgl4bWxTY2hlbWFHZXRBdHRyTmFtZShhdHRyKSk7CiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzLCBhdHRyLiB1c2UgJXM6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICBpZiAoKGl0ZW1FbGVtID09IE5VTEwpICYmIChpdGVtICE9IE5VTEwpKQoJaXRlbUVsZW0gPSBpdGVtLT5ub2RlOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtRWxlbSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsIAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHN0ckEsIHN0cjEsIE5VTEwsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQSk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHR5cGUKICogQGl0ZW06IHRoZSBzY2hlbWEgdHlwZQogKiBAYmFzZUl0ZW06IHRoZSBiYXNlIHR5cGUgb2YgdHlwZQogKiBAZmFjZXQ6IHRoZSBpbGxlZ2FsIGZhY2V0CiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBmYWNldCBmb3IgYXRvbWljIHNpbXBsZSB0eXBlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZUl0ZW0sCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW0tPm5vZGUpOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtLT5ub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQgb24gdHlwZXMgZGVyaXZlZCBmcm9tIHRoZSAiCgkidHlwZSAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0clQsIE5VTEwsIGJhc2VJdGVtLCBOVUxMLCAxKSwKCU5VTEwsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIDxsaXN0PiBhbmQgPHVuaW9uPi4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwgZXJyb3IsIAoJIiVzOiBUaGUgZmFjZXQgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsIAoJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBlbGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50IG5vZGUKICogQGF0dHI6IHRoZSBiYWQgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxBdHRyUHRyIGF0dHIsCQkJIAoJCQkgY29uc3QgY2hhciAqbmFtZTEsCgkJCSBjb25zdCBjaGFyICpuYW1lMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwkKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJIiVzOiBUaGUgYXR0cmlidXRlcyAnJXMnIGFuZCAnJXMnIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuXG4iLCAKCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZTEsIEJBRF9DQVNUIG5hbWUyLCBOVUxMLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKgogKiB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgdHlwZSBzcGVjaWZpZXIKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IGlmIGV4aXN0ZW50IAogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB2YWx1ZTogdGhlIHZhbGlkYXRlZCB2YWx1ZQogKgogKiBSZXBvcnRzIGEgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQU2ltcGxlVHlwZUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbENoYXIgKipvd25lckRlcywKCQkJeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQljb25zdCBjaGFyICp0eXBlRGVzLAoJCQljb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJY29uc3QgY2hhciAqbWVzc2FnZSwKCQkJY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkJY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMLCAqc3RyVCA9IE5VTEw7ICAgIAogICAgCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYVBSZXF1ZXN0SXRlbURlcygmZGVzLCBvd25lckl0ZW0sIG5vZGUpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVBSZXF1ZXN0SXRlbURlcyhvd25lckRlcywgb3duZXJJdGVtLCBub2RlKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAKICAgIGlmICh0eXBlICE9IE5VTEwpCgl0eXBlRGVzID0gKGNvbnN0IGNoYXIgKikgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyVCwgTlVMTCwgdHlwZSwgTlVMTCwgMSk7CiAgICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CgkvKgoJKiBVc2UgZGVmYXVsdCBtZXNzYWdlcy4KCSovCglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCSIlcywgYXR0cmlidXRlICclcycgWyVzXTogVGhlIHZhbHVlICclcycgaXMgbm90ICIKCQkidmFsaWQuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIG5vZGUtPm5zLCAKCQlub2RlLT5uYW1lKSwgQkFEX0NBU1QgdHlwZURlcywgdmFsdWUsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAKCQkiJXMgWyVzXTogVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIsCgkJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCB0eXBlRGVzKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxDaGFyICptc2c7CgoJbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlcyIpOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsIGF0dHJpYnV0ZSAnJXMnIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFslc106ICIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCShjb25zdCBjaGFyICopIG1zZywgCgkJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHJBLCAKCQlub2RlLT5ucywgbm9kZS0+bmFtZSksIEJBRF9DQVNUIHR5cGVEZXMsIHN0cjEsIHN0cjIpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCShjb25zdCBjaGFyICopIG1zZywgCgkJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCB0eXBlRGVzLCBzdHIxLCBzdHIyLCBOVUxMKTsKCX0KCXhtbEZyZWUobXNnKTsKICAgIH0KICAgIC8qIENsZWFudXAuICovCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCiAgICBGUkVFX0FORF9OVUxMKHN0clQpCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQp9CgovKioKICogeG1sU2NoZW1hUENvbnRlbnRFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG9ud2VyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgaXRlbSBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBvd25lckVsZW06IHRoZSBub2RlIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQGNoaWxkOiB0aGUgaW52YWxpZCBjaGlsZCBub2RlCiAqIEBtZXNzYWdlOiB0aGUgb3B0aW9uYWwgZXJyb3IgbWVzc2FnZQogKiBAY29udGVudDogdGhlIG9wdGlvbmFsIHN0cmluZyBkZXNjcmliaW5nIHRoZSBjb3JyZWN0IGNvbnRlbnQKICoKICogUmVwb3J0cyBhbiBlcnJvciBjb25jZXJuaW5nIHRoZSBjb250ZW50IG9mIGEgc2NoZW1hIGVsZW1lbnQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ29udGVudEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwJCSAgICAgCgkJICAgICB4bWxOb2RlUHRyIGNoaWxkLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgIGNvbnN0IGNoYXIgKmNvbnRlbnQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CiAgICAKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgIAogICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkKCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLCAKCSAgICAiJXM6ICVzLlxuIiwgCgkgICAgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBtZXNzYWdlKTsKICAgIGVsc2UgewoJaWYgKGNvbnRlbnQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLCAKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC4gRXhwZWN0ZWQgaXMgJXMuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIGNvbnRlbnQpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwgCgkJIiVzOiBUaGUgY29udGVudCBpcyBub3QgdmFsaWQuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIE5VTEwpOwoJfQogICAgfQogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKfSAgIAoKLyoqCiAqIHhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxBdHRyUHRyIGF0dHIpCnsKICAgIHhtbENoYXIgKnN0ckUgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAkKCWVycm9yLAoJLyogWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLCAqLwoJIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iLAoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyRSwgTlVMTCwgTlVMTCwgYXR0ci0+cGFyZW50LCAwKSwKCXhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIGF0dHItPm5zLCBhdHRyLT5uYW1lKSk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckUpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCi8qKgogKiB4bWxTY2hlbWFWQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB0eXBlOiB0aGUgc2NoZW1hIHR5cGUgb2YgdGhlIHZhbGlkYXRlZCBub2RlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgbWVzc2FnZQogKgogKiBSZXBvcnRzIGEgdmFsaWRhdGlvbiBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDdXN0b21FcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgICAgCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgaWYgKG5vZGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVkN1c3RvbUVyciwgbm8gbm9kZSAiCgkgICAgImdpdmVuLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm47CiAgICB9CiAgICAvKiBUT0RPOiBBcmUgdGhlIEhUTUwgYW5kIERPQ0IgZG9jIG5vZGVzIGV4cGVjdGVkIGhlcmU/ICovCiAgICBpZiAobm9kZS0+dHlwZSAhPSBYTUxfRE9DVU1FTlRfTk9ERSkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCBOVUxMLCBub2RlLCAwKTsKCWlmICh0eXBlICE9IE5VTEwpIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXSIpOwoJfQoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICB9IGVsc2UKCW1zZyA9IHhtbFN0cmR1cCgoY29uc3QgeG1sQ2hhciAqKSAiIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsgICAKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgc3RyMSwgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKG1zZykKICAgIEZSRUVfQU5EX05VTEwoc3RyKQp9CgovKioKICogeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nOgogKiBAcGM6IHRoZSB0eXBlIG9mIHByb2Nlc3NDb250ZW50cwogKgogKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0eXBlIG9mIAogKiBwcm9jZXNzQ29udGVudHMuCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqCnhtbFNjaGVtYVdpbGRjYXJkUENUb1N0cmluZyhpbnQgcGMpCnsKICAgIHN3aXRjaCAocGMpIHsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX1NLSVA6CgkgICAgcmV0dXJuICgic2tpcCIpOwoJY2FzZSBYTUxfU0NIRU1BU19BTllfTEFYOgoJICAgIHJldHVybiAoImxheCIpOwoJY2FzZSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOgoJICAgIHJldHVybiAoInN0cmljdCIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gKCJpbnZhbGlkIHByb2Nlc3MgY29udGVudHMiKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVZXaWxkY2FyZEVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG5vZGU6IHRoZSB2YWxpZGF0ZWQgbm9kZQogKiBAd2lsZDogdGhlIHdpbGRjYXJkIHVzZWQKICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gdmFsaWRhdGlvbi1ieS13aWxkY2FyZCBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZXaWxkY2FyZEVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAgICAKCQkgICAgeG1sTm9kZVB0ciBub2RlLAoJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIE5VTEwsIG5vZGUsIDApOwogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlcywgWyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKHdpbGQtPnByb2Nlc3NDb250ZW50cykpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBXQ106ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIEJBRF9DQVNUIGRlcywgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIHBhcmVudCBlbGVtZW50IG5vZGUgb2YgdGhlIG1pc3NpbmcgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSB4bWxOb2RlUHRyIGVsZW0sCgkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgdHlwZSkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnVyaTsKICAgIHhtbENoYXIgKnN0ckUgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKHR5cGUtPnJlZiAhPSBOVUxMKSB7CQkJCQoJbmFtZSA9IHR5cGUtPnJlZjsKCXVyaSA9IHR5cGUtPnJlZk5zOwogICAgfSBlbHNlIHsKCW5hbWUgPSB0eXBlLT5uYW1lOwoJdXJpID0gdHlwZS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgfQkJCSAgICAKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgCglYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzQsCgkvKiBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywgKi8KCSIlczogVGhlIGF0dHJpYnV0ZSAlcyBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJFLCBOVUxMLCBOVUxMLCBlbGVtLCAwKSwKCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIHVyaSwgbmFtZSkpOwogICAgRlJFRV9BTkRfTlVMTChzdHJFKQogICAgRlJFRV9BTkRfTlVMTChzdHJBKQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJQWxsb2NhdGlvbiBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3U2NoZW1hRm9yUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEFsbG9jYXRlIGEgbmV3IFNjaGVtYSBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXNzZW1ibGVQdHIKeG1sU2NoZW1hTmV3QXNzZW1ibGUodm9pZCkKewogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBc3NlbWJsZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgLyogeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7ICovCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgcmV0LT5pdGVtcyA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIHhtbEZyZWUoYW5ub3QpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUltcG9ydDoKICogQGltcG9ydDogIGEgc2NoZW1hIGltcG9ydCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhbiBpbXBvcnQgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW1wb3J0KHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQpCnsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sU2NoZW1hRnJlZShpbXBvcnQtPnNjaGVtYSk7CiAgICB4bWxGcmVlRG9jKGltcG9ydC0+ZG9jKTsKICAgIHhtbEZyZWUoaW1wb3J0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbmNsdWRlOgogKiBAaW5jbHVkZTogIGEgc2NoZW1hIGluY2x1ZGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYW4gaW5jbHVkZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJbmNsdWRlKHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZSkKewogICAgaWYgKGluY2x1ZGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sRnJlZURvYyhpbmNsdWRlLT5kb2MpOwogICAgeG1sRnJlZShpbmNsdWRlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdDoKICogQGluY2x1ZGVzOiAgYSBzY2hlbWEgaW5jbHVkZSBsaXN0CiAqCiAqIERlYWxsb2NhdGUgYW4gaW5jbHVkZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdCh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGVzKQp7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIG5leHQ7CgogICAgd2hpbGUgKGluY2x1ZGVzICE9IE5VTEwpIHsKICAgICAgICBuZXh0ID0gaW5jbHVkZXMtPm5leHQ7Cgl4bWxTY2hlbWFGcmVlSW5jbHVkZShpbmNsdWRlcyk7CglpbmNsdWRlcyA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTm90YXRpb246CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBub3RhdGlvbiBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBOb3RhdGlvbiBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTm90YXRpb24oeG1sU2NoZW1hTm90YXRpb25QdHIgbm90YSkKewogICAgaWYgKG5vdGEgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKG5vdGEpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZToKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZSh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKewogICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ci0+YW5ub3QgIT0gTlVMTCkgCgl4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgaWYgKGF0dHItPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGF0dHItPmRlZlZhbCk7CiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQ6CiAqIHNldDogIGEgc2NoZW1hIHdpbGRjYXJkIG5hbWVzcGFjZQogKgogKiBEZWFsbG9jYXRlcyBhIGxpc3Qgb2Ygd2lsZGNhcmQgY29uc3RyYWludCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzZXQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbmV4dDsKICAgIAogICAgd2hpbGUgKHNldCAhPSBOVUxMKSB7CgluZXh0ID0gc2V0LT5uZXh0OwoJeG1sRnJlZShzZXQpOwoJc2V0ID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZDoKICogQHdpbGRjYXJkOiAgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZXMgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZCh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkY2FyZCkKewogICAgaWYgKHdpbGRjYXJkID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHdpbGRjYXJkLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdCh3aWxkY2FyZC0+YW5ub3QpOwogICAgaWYgKHdpbGRjYXJkLT5uc1NldCAhPSBOVUxMKSAKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHdpbGRjYXJkLT5uc1NldCk7ICAgIAogICAgaWYgKHdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSAKCXhtbEZyZWUod2lsZGNhcmQtPm5lZ05zU2V0KTsgICAgCiAgICB4bWxGcmVlKHdpbGRjYXJkKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBncm91cCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIGlmICgoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSAmJiAKCShhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZChhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCk7CgogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0OgogKiBAYXR0clVzZTogIGFuIGF0dHJpYnV0ZSBsaW5rCiAqCiAqIERlYWxsb2NhdGUgYSBsaXN0IG9mIHNjaGVtYSBhdHRyaWJ1dGUgdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0KHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBuZXh0OwoKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKCW5leHQgPSBhdHRyVXNlLT5uZXh0OwoJeG1sRnJlZShhdHRyVXNlKTsKCWF0dHJVc2UgPSBuZXh0OwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3Q6CiAqIEBhbGluazogYSB0eXBlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2YgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmspCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJbmV4dCA9IGxpbmstPm5leHQ7Cgl4bWxGcmVlKGxpbmspOwoJbGluayA9IG5leHQ7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hRnJlZUVsZW1lbnQ6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBlbGVtZW50IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEVsZW1lbnQgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUVsZW1lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChlbGVtLT5hbm5vdCk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cChlbGVtLT5jb250TW9kZWwpOwogICAgaWYgKGVsZW0tPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGVsZW0tPmRlZlZhbCk7CiAgICB4bWxGcmVlKGVsZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUZhY2V0OgogKiBAZmFjZXQ6ICBhIHNjaGVtYSBmYWNldCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBGYWNldCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgaWYgKGZhY2V0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGZhY2V0LT52YWwgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoZmFjZXQtPnZhbCk7CiAgICBpZiAoZmFjZXQtPnJlZ2V4cCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZmFjZXQtPnJlZ2V4cCk7CiAgICBpZiAoZmFjZXQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGZhY2V0LT5hbm5vdCk7CiAgICB4bWxGcmVlKGZhY2V0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlOgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QodHlwZS0+YW5ub3QpOwogICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsIG5leHQ7CgogICAgICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwogICAgICAgIHdoaWxlIChmYWNldCAhPSBOVUxMKSB7CiAgICAgICAgICAgIG5leHQgPSBmYWNldC0+bmV4dDsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICAgICAgZmFjZXQgPSBuZXh0OwogICAgICAgIH0KICAgIH0KICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkKCSAgICB4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdCh0eXBlLT5hdHRyaWJ1dGVVc2VzKTsKCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCSAgICAoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8CgkgICAgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEKSkpIHsKCSAgICAvKgoJICAgICogTk9URTogVGhlIG9ubHkgY2FzZSB3aGVyZSBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQKCSAgICAqIGlzIG5vdCBvd25lZCwgaXMgaWYgYSBjb21wbGV4IHR5cGUgaW5oZXJpdHMgaXQKCSAgICAqIGZyb20gYSBiYXNlIHR5cGUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpOwoJfQogICAgfQogICAgaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHR5cGUtPm1lbWJlclR5cGVzKTsKICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGYWNldExpbmtQdHIgbmV4dCwgbGluazsKCglsaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CglkbyB7CgkgICAgbmV4dCA9IGxpbmstPm5leHQ7CgkgICAgeG1sRnJlZShsaW5rKTsKCSAgICBsaW5rID0gbmV4dDsKCX0gd2hpbGUgKGxpbmsgIT0gTlVMTCk7CiAgICB9ICAKICAgIGlmICh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKHR5cGUtPmNvbnRNb2RlbCk7CiAgICB4bWxGcmVlKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVR5cGVMaXN0OgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpc3QoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG5leHQ7CgogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewogICAgICAgIG5leHQgPSB0eXBlLT5yZWRlZjsKCXhtbFNjaGVtYUZyZWVUeXBlKHR5cGUpOwoJdHlwZSA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlKHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPm5vdGFEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVOb3RhdGlvbik7CiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+YXR0ckRlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZSk7CiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+YXR0cmdycERlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKTsKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlRWxlbWVudCk7CiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZVR5cGVMaXN0KTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+Z3JvdXBEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVUeXBlKTsKICAgIGlmIChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzICE9IE5VTEwpCgl4bWxIYXNoRnJlZShzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLAoJCSAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlSW1wb3J0KTsKICAgIGlmIChzY2hlbWEtPmluY2x1ZGVzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoKHhtbFNjaGVtYUluY2x1ZGVQdHIpIHNjaGVtYS0+aW5jbHVkZXMpOwogICAgfQogICAgaWYgKHNjaGVtYS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3Qoc2NoZW1hLT5hbm5vdCk7CiAgICBpZiAoc2NoZW1hLT5kb2MgIT0gTlVMTCAmJiAhc2NoZW1hLT5wcmVzZXJ2ZSkKICAgICAgICB4bWxGcmVlRG9jKHNjaGVtYS0+ZG9jKTsKICAgIHhtbERpY3RGcmVlKHNjaGVtYS0+ZGljdCk7ICAgIAogICAgeG1sRnJlZShzY2hlbWEpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRGVidWcgZnVuY3Rpb25zCQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZmRlZiBMSUJYTUxfT1VUUFVUX0VOQUJMRUQKCi8qKgogKiB4bWxTY2hlbWFFbGVtZW50RHVtcDoKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICoKICogRHVtcCB0aGUgZWxlbWVudAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRWxlbWVudER1bXAoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtLCBGSUxFICogb3V0cHV0LAogICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogY29udGV4dCBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChlbGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGZwcmludGYob3V0cHV0LCAiRWxlbWVudCAiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiZ2xvYmFsICIpOwogICAgZnByaW50ZihvdXRwdXQsICI6ICVzICIsIGVsZW0tPm5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAibmFtZXNwYWNlICclcycgIiwgbmFtZXNwYWNlKTsKCiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKQogICAgICAgIGZwcmludGYob3V0cHV0LCAibmlsbGFibGUgIik7CiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0RFRkFVTFQpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJkZWZhdWx0ICIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImZpeGVkICIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImFic3RyYWN0ICIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9SRUYpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJyZWYgJyVzJyAiLCBlbGVtLT5yZWYpOwogICAgaWYgKGVsZW0tPmlkICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJpZCAnJXMnICIsIGVsZW0tPmlkKTsKICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgoZWxlbS0+bWluT2NjdXJzICE9IDEpIHx8IChlbGVtLT5tYXhPY2N1cnMgIT0gMSkpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgIik7CiAgICAgICAgaWYgKGVsZW0tPm1pbk9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1pbjogJWQgIiwgZWxlbS0+bWluT2NjdXJzKTsKICAgICAgICBpZiAoZWxlbS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6IHVuYm91bmRlZFxuIik7CiAgICAgICAgZWxzZSBpZiAoZWxlbS0+bWF4T2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiAlZFxuIiwgZWxlbS0+bWF4T2NjdXJzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmIChlbGVtLT5uYW1lZFR5cGUgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICB0eXBlOiAlcyIsIGVsZW0tPm5hbWVkVHlwZSk7CiAgICAgICAgaWYgKGVsZW0tPm5hbWVkVHlwZU5zICE9IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiIG5zICVzXG4iLCBlbGVtLT5uYW1lZFR5cGVOcyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICBpZiAoZWxlbS0+c3Vic3RHcm91cCAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIHN1YnN0aXR1dGlvbkdyb3VwOiAlcyIsIGVsZW0tPnN1YnN0R3JvdXApOwogICAgICAgIGlmIChlbGVtLT5zdWJzdEdyb3VwTnMgIT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICIgbnMgJXNcbiIsIGVsZW0tPnN1YnN0R3JvdXBOcyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICBpZiAoZWxlbS0+dmFsdWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgZGVmYXVsdDogJXMiLCBlbGVtLT52YWx1ZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBbm5vdER1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQGFubm90OiAgYSBhbm5vdGF0aW9uCiAqCiAqIER1bXAgdGhlIGFubm90YXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUFubm90RHVtcChGSUxFICogb3V0cHV0LCB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCkKewogICAgeG1sQ2hhciAqY29udGVudDsKCiAgICBpZiAoYW5ub3QgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgY29udGVudCA9IHhtbE5vZGVHZXRDb250ZW50KGFubm90LT5jb250ZW50KTsKICAgIGlmIChjb250ZW50ICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgQW5ub3Q6ICVzXG4iLCBjb250ZW50KTsKICAgICAgICB4bWxGcmVlKGNvbnRlbnQpOwogICAgfSBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIEFubm90OiBlbXB0eVxuIik7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAdHlwZTogIGEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYVR5cGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRHVtcCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIEZJTEUgKiBvdXRwdXQpCnsKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlR5cGU6IE5VTExcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiVHlwZTogIik7CiAgICBpZiAodHlwZS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMsICIsIHR5cGUtPm5hbWUpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gbmFtZSIpOwogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiYmFzaWMgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJzaW1wbGUgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiY29tcGxleCAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAic2VxdWVuY2UgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJjaG9pY2UgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJhbGwgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VSOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInVyICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJyZXN0cmljdGlvbiAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImV4dGVuc2lvbiAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJ1bmtub3dudHlwZSVkICIsIHR5cGUtPnR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImJhc2UgJXMsICIsIHR5cGUtPmJhc2UpOwogICAgfQogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAidW5rbm93biAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiZW1wdHkgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImVsZW1lbnQgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1peGVkICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKCS8qIG5vdCB1c2VkLiAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJiYXNpYyAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInNpbXBsZSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQU5ZOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImFueSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoKHR5cGUtPm1pbk9jY3VycyAhPSAxKSB8fCAodHlwZS0+bWF4T2NjdXJzICE9IDEpKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgICIpOwogICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtaW46ICVkICIsIHR5cGUtPm1pbk9jY3Vycyk7CiAgICAgICAgaWYgKHR5cGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiB1bmJvdW5kZWRcbiIpOwogICAgICAgIGVsc2UgaWYgKHR5cGUtPm1heE9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogJWRcbiIsIHR5cGUtPm1heE9jY3Vycyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICBpZiAodHlwZS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFBbm5vdER1bXAob3V0cHV0LCB0eXBlLT5hbm5vdCk7CiAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3ViID0gdHlwZS0+c3VidHlwZXM7CgogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBzdWJ0eXBlczogIik7CiAgICAgICAgd2hpbGUgKHN1YiAhPSBOVUxMKSB7CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMgIiwgc3ViLT5uYW1lKTsKICAgICAgICAgICAgc3ViID0gc3ViLT5uZXh0OwogICAgICAgIH0KICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9Cgp9CgovKioKICogeG1sU2NoZW1hRHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAc2NoZW1hOiAgYSBzY2hlbWEgc3RydWN0dXJlCiAqCiAqIER1bXAgYSBTY2hlbWEgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFEdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiU2NoZW1hczogTlVMTFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiAiKTsKICAgIGlmIChzY2hlbWEtPm5hbWUgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzLCAiLCBzY2hlbWEtPm5hbWUpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gbmFtZSwgIik7CiAgICBpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzIiwgKGNvbnN0IGNoYXIgKikgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpOwogICAgZWxzZQogICAgICAgIGZwcmludGYob3V0cHV0LCAibm8gdGFyZ2V0IG5hbWVzcGFjZSIpOwogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKHNjaGVtYS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFBbm5vdER1bXAob3V0cHV0LCBzY2hlbWEtPmFubm90KTsKCiAgICB4bWxIYXNoU2NhbihzY2hlbWEtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVEdW1wLAogICAgICAgICAgICAgICAgb3V0cHV0KTsKICAgIHhtbEhhc2hTY2FuRnVsbChzY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYUVsZW1lbnREdW1wLCBvdXRwdXQpOwp9CiNlbmRpZiAvKiBMSUJYTUxfT1VUUFVUX0VOQUJMRUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCVV0aWxpdGllcwkJCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFHZXRQcm9wTm9kZToKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUgCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFNlZWtzIGFuIGF0dHJpYnV0ZSB3aXRoIGEgbmFtZSBvZiBAbmFtZSBpbgogKiBubyBuYW1lc3BhY2UuCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBvciBOVUxMIGlmIG5vdCBwcmVzZW50LiAKICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlKHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqbmFtZSkgCnsKICAgIHhtbEF0dHJQdHIgcHJvcDsKCiAgICBpZiAoKG5vZGUgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpIAoJcmV0dXJuKE5VTEwpOwogICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChwcm9wLT5ucyA9PSBOVUxMKSAmJiB4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBCQURfQ0FTVCBuYW1lKSkJICAgIAoJICAgIHJldHVybihwcm9wKTsKCXByb3AgPSBwcm9wLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3BOb2RlTnM6CiAqIEBub2RlOiB0aGUgZWxlbWVudCBub2RlIAogKiBAdXJpOiB0aGUgdXJpCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIFNlZWtzIGFuIGF0dHJpYnV0ZSB3aXRoIGEgbG9jYWwgbmFtZSBvZiBAbmFtZSBhbmQKICogYSBuYW1lc3BhY2UgVVJJIG9mIEB1cmkuCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBvciBOVUxMIGlmIG5vdCBwcmVzZW50LiAKICovCnN0YXRpYyB4bWxBdHRyUHRyCnhtbFNjaGVtYUdldFByb3BOb2RlTnMoeG1sTm9kZVB0ciBub2RlLCBjb25zdCBjaGFyICp1cmksIGNvbnN0IGNoYXIgKm5hbWUpIAp7CiAgICB4bWxBdHRyUHRyIHByb3A7CgogICAgaWYgKChub2RlID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKSAKCXJldHVybihOVUxMKTsKICAgIHByb3AgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKHByb3AgIT0gTlVMTCkgewoJaWYgKChwcm9wLT5ucyAhPSBOVUxMKSAmJgoJICAgIHhtbFN0ckVxdWFsKHByb3AtPm5hbWUsIEJBRF9DQVNUIG5hbWUpICYmCgkgICAgeG1sU3RyRXF1YWwocHJvcC0+bnMtPmhyZWYsIEJBRF9DQVNUIHVyaSkpCgkgICAgcmV0dXJuKHByb3ApOwoJcHJvcCA9IHByb3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldE5vZGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICp2YWw7CiAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgogICAgdmFsID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOyAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3A6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBub2RlCiAqIEBuYW1lOiB0aGUgcHJvcGVydHkgbmFtZQogKiAKICogUmVhZCBhIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgaW50ZXJuYWxpemUgdGhlIHN0cmluZwogKgogKiBSZXR1cm5zIHRoZSBzdHJpbmcgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0UHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICB4bWxDaGFyICp2YWw7CiAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgogICAgdmFsID0geG1sR2V0UHJvcChub2RlLCBCQURfQ0FTVCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwogICAgeG1sRnJlZSh2YWwpOwogICAgcmV0dXJuKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFHZXRFbGVtOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKiBAbnM6ICB0aGUgZWxlbWVudCBuYW1lc3BhY2UKICoKICogTG9va3VwIGEgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUdldEVsZW0oeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICAKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfSBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICAqIFRoaXMgb25lIHdhcyByZW1vdmVkLCBzaW5jZSB0b3AgbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbnMgaGF2ZQogICAgICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugc3BlY2lmaWVkIGluIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgPHNjaGVtYT4KICAgICAqIGluZm9ybWF0aW9uIGVsZW1lbnQsIGV2ZW4gaWYgZWxlbWVudEZvcm1EZWZhdWx0IGlzICJ1bnF1YWxpZmllZCIuCiAgICAgKi8KICAgIAogICAgLyogZWxzZSBpZiAoKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkgewogICAgICAgIGlmICh4bWxTdHJFcXVhbChuYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBOVUxMKTsKCWVsc2UKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKChsZXZlbCA9PSAwKSB8fCAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUwpKSkgewogICAgICAgICAgICByZXR1cm4gKHJldCk7Cgl9CiAgICAqLwogICAgCiAgICAvKgogICAgKiBSZW1vdmVkIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQogICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRFbGVtKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UsIGxldmVsICsgMSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFR5cGU6CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcyBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIHR5cGUgbmFtZQogKiBAbnM6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogTG9va3VwIGEgdHlwZSBpbiB0aGUgc2NoZW1hcyBvciB0aGUgcHJlZGVmaW5lZCB0eXBlcwogKgogKiBSZXR1cm5zIHRoZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0VHlwZSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldDsKCiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQogICAgICAgICAgICByZXR1cm4gKHJldCk7CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKHJldCAhPSBOVUxMKQoJcmV0dXJuIChyZXQpOwogICAgLyoKICAgICogUmVtb3ZlZCwgc2luY2UgdGhlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBncmFmdGVkIG9uIHRoZQogICAgKiBtYWluIHNjaGVtYSBvbmx5LiAgICAKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0VHlwZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0ckRlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSkKCXJldHVybiAocmV0KTsgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCwgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEgCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwIAogKgogKiBMb29rdXAgYSBhbiBhdHRyaWJ1dGUgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOyAgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsJCiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwIAogKgogKiBMb29rdXAgYSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIAogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5ncm91cERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCXJldHVybiAocmV0KTsgIAogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQoJICAgIHJldHVybiAocmV0KTsKCWVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBJU19CTEFOS19OT0RFKG4pCQkJCQkJXAogICAgKCgobiktPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKHhtbFNjaGVtYUlzQmxhbmsoKG4pLT5jb250ZW50KSkpCgovKioKICogeG1sU2NoZW1hSXNCbGFuazoKICogQHN0cjogIGEgc3RyaW5nCiAqCiAqIENoZWNrIGlmIGEgc3RyaW5nIGlzIGlnbm9yYWJsZQogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHN0cmluZyBpcyBOVUxMIG9yIG1hZGUgb2YgYmxhbmtzIGNoYXJzLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc0JsYW5rKHhtbENoYXIgKiBzdHIpCnsKICAgIGlmIChzdHIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKDEpOwogICAgd2hpbGUgKCpzdHIgIT0gMCkgewogICAgICAgIGlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKICAgICAgICAgICAgcmV0dXJuICgwKTsKICAgICAgICBzdHIrKzsKICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBpdGVtOiAgdGhlIGl0ZW0KICoKICogQWRkIGEgaXRlbSB0byB0aGUgc2NoZW1hJ3MgbGlzdCBvZiBjdXJyZW50IGl0ZW1zLgogKiBUaGlzIGlzIHVzZWQgaWYgdGhlIHNjaGVtYSB3YXMgYWxyZWFkeSBjb25zdHJ1Y3RlZCBhbmQKICogbmV3IHNjaGVtYXRhIG5lZWQgdG8gYmUgYWRkZWQgdG8gaXQuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNlZWRzIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0pCnsKICAgIHN0YXRpYyBpbnQgZ3Jvd1NpemUgPSAxMDA7CiAgICB4bWxTY2hlbWFBc3NlbWJsZVB0ciBhc3M7CgogICAgYXNzID0gY3R4dC0+YXNzZW1ibGU7CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPCAwKSB7CgkvKiBJZiBkaXNhYmxlZC4gKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPD0gMCkgewoJYXNzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxNYWxsb2MoZ3Jvd1NpemUgKiBzaXplb2YoeG1sU2NoZW1hVHlwZVB0cikpOwoJaWYgKGFzcy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCQkiYWxsb2NhdGluZyBuZXcgaXRlbSBidWZmZXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0JCglhc3MtPnNpemVJdGVtcyA9IGdyb3dTaXplOwogICAgfSBlbHNlIGlmIChhc3MtPnNpemVJdGVtcyA8PSBhc3MtPm5iSXRlbXMpIHsKCWFzcy0+c2l6ZUl0ZW1zICo9IDI7Cglhc3MtPml0ZW1zID0gKHZvaWQgKiopIHhtbFJlYWxsb2MoYXNzLT5pdGVtcywgCgkgICAgYXNzLT5zaXplSXRlbXMgKiBzaXplb2YoeG1sU2NoZW1hVHlwZVB0cikpOwoJaWYgKGFzcy0+aXRlbXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwKCQkiZ3Jvd2luZyBpdGVtIGJ1ZmZlciIsIE5VTEwpOwoJICAgIGFzcy0+c2l6ZUl0ZW1zID0gMDsKCSAgICByZXR1cm4gKC0xKTsKCX0JCiAgICB9CiAgICAvKiBhc3MtPml0ZW1zW2Fzcy0+bmJJdGVtcysrXSA9ICh2b2lkICopIGl0ZW07ICovCiAgICAoKHhtbFNjaGVtYVR5cGVQdHIgKikgYXNzLT5pdGVtcylbYXNzLT5uYkl0ZW1zKytdID0gKHZvaWQgKikgaXRlbTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGROb3RhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgYW5ub3RhdGlvbiBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFBZGROb3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ub3RhRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFOb3RhdGlvblB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFOb3RhdGlvbikpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkIGFubm90YXRpb24iLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5ub3RhRGVjbCwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCS8qCgkqIFRPRE86IFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgc2luY2UgYSB1bmlxdWUgbmFtZSB3aWxsIGJlIGNvbXB1dGVkLgoJKiBJZiBpdCBmYWlscywgdGhlbiBhbiBvdGhlciBpbnRlcm5hbCBlcnJvciBtdXN0IGhhdmUgb2NjdXJlZC4KCSovCgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX05PVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgIkFubm90YXRpb24gZGVjbGFyYXRpb24gJyVzJyBpcyBhbHJlYWR5IGRlY2xhcmVkLlxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIGF0dHJpYnV0ZSAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmF0dHJEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGUpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWVzcGFjZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX0FUVFIsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiQSBnbG9iYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzIGFscmVhZHkgZXhpc3QiLCBuYW1lKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5hdHRyZ3JwRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9CiAgICAgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKQogICAgICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXR0cmlidXRlIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cCkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfQVRUUkdST1VQLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIkEgZ2xvYmFsIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzIGFscmVhZHkgZXhpc3QiLCBuYW1lKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIHR5cGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEVsZW1lbnQgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFBZGRFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSwKCQkgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgZWxlbWVudCAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmVsZW1EZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lc3BhY2UsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCWlmICh0b3BMZXZlbCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfRUxFTUVOVCwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJBIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzICIKCQkiYWxyZWFkeSBleGlzdCIsIG5hbWUpOwogICAgICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgewoJICAgIGNoYXIgYnVmWzMwXTsgCgoJICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjZUNvbnQgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCSAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+ZWxlbURlY2wsIG5hbWUsICh4bWxDaGFyICopIGJ1ZiwKCQluYW1lc3BhY2UsIHJldCk7CgkgICAgaWYgKHZhbCAhPSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBZGRFbGVtZW50LCAiCgkJICAgICJhIGR1YmxpY2F0ZSBlbGVtZW50IGRlY2xhcmF0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyAiCgkJICAgICJjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGhhc2guIiwgbmFtZSk7CgkJeG1sRnJlZShyZXQpOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJfQogICAgICAgIAogICAgfQogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIGl0ZW0KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFBZGRUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSwKCQkgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIHR5cGUgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT50eXBlRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgdHlwZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnJlZGVmID0gTlVMTDsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CQogICAgICAgIGlmIChjdHh0LT5pbmNsdWRlcyA9PSAwKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX1RZUEUsCgkJTlVMTCwgTlVMTCwgbm9kZSwgCgkJIkEgZ2xvYmFsIHR5cGUgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5IGV4aXN0IiwgbmFtZSk7ICAgICAgICAgICAgCSAgICAKCSAgICB4bWxGcmVlKHJldCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciBwcmV2OwoKCSAgICBwcmV2ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKCSAgICBpZiAocHJldiA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZFR5cGUsIG9uIHR5cGUgIgoJCSAgICAiJyVzJy5cbiIsCgkJICAgIG5hbWUsIE5VTEwpOwoJCXhtbEZyZWUocmV0KTsKCQlyZXR1cm4gKE5VTEwpOwoJICAgIH0KCSAgICByZXQtPnJlZGVmID0gcHJldi0+cmVkZWY7CgkgICAgcHJldi0+cmVkZWYgPSByZXQ7Cgl9CiAgICB9CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CiAgICByZXQtPmF0dHJpYnV0ZVVzZXMgPSBOVUxMOwogICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IE5VTEw7CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkJCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQscmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBncm91cCBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hQWRkR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+Z3JvdXBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ncm91cERlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVR5cGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIGdyb3VwIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9CiAgICAgICAgeG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPmdyb3VwRGVjbCwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX0dST1VQLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkEgZ2xvYmFsIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIG5hbWUpOyAgICAKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmROc1B0cgp4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyKSAKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmROcykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJjcmVhdGluZyB3aWxkY2FyZCBuYW1lc3BhY2UgY29uc3RyYWludCIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsgICAgCiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQWRkcyBhIHdpbGRjYXJkLiBJdCBjb3JyZXNwb25kcyB0byBhIAogKiB4c2Q6YW55QXR0cmlidXRlIGFuZCBpcyB1c2VkIGFzIHN0b3JhZ2UgZm9yIG5hbWVzcGFjZSAKICogY29uc3RyYWludHMgb24gYSB4c2Q6YW55LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hQWRkV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciByZXQgPSBOVUxMOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZGluZyB3aWxkY2FyZCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKgkJVXRpbGl0aWVzIGZvciBwYXJzaW5nCQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxHZXRRTmFtZVByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSByZXN1bHQgbmFtZXNwYWNlIGlmIGFueQogKgogKiBFeHRyYWN0IGEgUU5hbWUgQXR0cmlidXRlIHZhbHVlCiAqCiAqIFJldHVybnMgdGhlIE5DTmFtZSBvciBOVUxMIGlmIG5vdCBmb3VuZCwgYW5kIGFsc28gdXBkYXRlIEBuYW1lc3BhY2UKICogICAgd2l0aCB0aGUgbmFtZXNwYWNlIFVSSQogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxHZXRRTmFtZVByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICoqIG5hbWVzcGFjZSkKewogICAgY29uc3QgeG1sQ2hhciAqdmFsOwogICAgeG1sTnNQdHIgbnM7CiAgICBjb25zdCB4bWxDaGFyICpyZXQsICpwcmVmaXg7CiAgICBpbnQgbGVuOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgICpuYW1lc3BhY2UgPSBOVUxMOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKCFzdHJjaHIoKGNoYXIgKikgdmFsLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgMCk7CglpZiAobnMpIHsKCSAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJICAgIHJldHVybiAodmFsKTsKCX0KICAgIH0KICAgIHJldCA9IHhtbFNwbGl0UU5hbWUzKHZhbCwgJmxlbik7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKHZhbCk7CiAgICB9CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHJldCwgLTEpOwogICAgcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIGxlbik7CgogICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CiAgICBpZiAobnMgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1BSRUZJWF9VTkRFRklORUQsIAoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIE5VTEwsIHZhbCwKCSAgICAiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlICIKCSAgICAiZGVjbGFyYXRpb24gaW4gc2NvcGUiLCB2YWwsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBwYXJlbnQgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEB2YWx1ZTogIHRoZSBRTmFtZSB2YWx1ZSAKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgdGhlIGxvY2FsIG5hbWUgYW5kIHRoZSBVUkkgb2YgYSBRTmFtZSB2YWx1ZSBhbmQgdmFsaWRhdGVzIGl0LgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9uIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdAogKiBzaG91bGQgcmVzb2x2ZSB0byBzY2hlbWEgY29tcG9uZW50cy4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnByZWZpeCwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnByZWY7CiAgICB4bWxOc1B0ciBuczsKICAgIGludCBsZW4sIHJldDsKICAgIAogICAgKnVyaSA9IE5VTEw7CiAgICAqbG9jYWwgPSBOVUxMOwogICAgaWYgKHByZWZpeCAhPSAwKQoJKnByZWZpeCA9IE5VTEw7CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPiAwKSB7CQkKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJICAgIG93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIAoJICAgICJRTmFtZSIsIHZhbHVlLCAKCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsJCgkqbG9jYWwgPSB2YWx1ZTsKCXJldHVybiAoY3R4dC0+ZXJyKTsgCiAgICB9IGVsc2UgaWYgKHJldCA8IDApCglyZXR1cm4gKC0xKTsKICAgCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWx1ZSwgJzonKSkgewkKCW5zID0geG1sU2VhcmNoTnMoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQsIDApOwoJaWYgKG5zKQoJICAgICp1cmkgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zLT5ocmVmLCAtMSk7CgllbHNlIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpIHsKCSAgICAvKgoJICAgICogVGhpcyBvbmUgdGFrZXMgY2FyZSBvZiBpbmNsdWRlZCBzY2hlbWFzIHdpdGggbm8KCSAgICAqIHRhcmdldCBuYW1lc3BhY2UuCgkgICAgKi8KCSAgICAqdXJpID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9CQoJKmxvY2FsID0gdmFsdWU7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogQXQgdGhpcyBwb2ludCB4bWxTcGxpdFFOYW1lMyBoYXMgdG8gcmV0dXJuIGEgbG9jYWwgbmFtZS4KICAgICovCiAgICAqbG9jYWwgPSB4bWxTcGxpdFFOYW1lMyh2YWx1ZSwgJmxlbik7CiAgICAqbG9jYWwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsICpsb2NhbCwgLTEpOwogICAgcHJlZiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsdWUsIGxlbik7CiAgICBpZiAocHJlZml4ICE9IDApCgkqcHJlZml4ID0gcHJlZjsKICAgIG5zID0geG1sU2VhcmNoTnMoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQsIHByZWYpOwogICAgaWYgKG5zID09IE5VTEwpIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgb3duZXJEZXMsIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwgIlFOYW1lIiwgdmFsdWUsCgkgICAgIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSAiCgkgICAgImRlY2xhcmF0aW9uIGluIHNjb3BlIiwgdmFsdWUsIE5VTEwpOwoJcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSBlbHNlIHsKICAgICAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyIGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgbm9kZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIHRoZSBRTmFtZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb24gYXR0cmlidXRlIHZhbHVlcyB0aGF0CiAqIHNob3VsZCByZXNvbHZlIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnByZWZpeCwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKGN0eHQsIHNjaGVtYSwgCglvd25lckRlcywgb3duZXJJdGVtLCBhdHRyLCB2YWx1ZSwgdXJpLCBwcmVmaXgsIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0clFOYW1lOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIFFOYW1lIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0clFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCAKCQkJCSAgIHhtbENoYXIgKipvd25lckRlcywKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCQkgICBjb25zdCBjaGFyICpuYW1lLAoJCQkJICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKipwcmVmaXgsCgkJCQkgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUob3duZXJFbGVtLCBuYW1lKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCSpsb2NhbCA9IE5VTEw7CgkqdXJpID0gTlVMTDsKCXJldHVybiAoMCk7ICAgIAogICAgfQogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsIAoJb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwgdXJpLCBwcmVmaXgsIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxHZXRNYXhPY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtYXhPY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNYXhPY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWF4T2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewoJaWYgKG1heCAhPSBVTkJPVU5ERUQpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCS8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCQl2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoZGVmKTsKCX0gZWxzZSAKCSAgICByZXR1cm4gKFVOQk9VTkRFRCk7ICAvKiBlbmNvZGluZyBpdCB3aXRoIC0xIG1pZ2h0IGJlIGFub3RoZXIgb3B0aW9uICovCiAgICB9CgogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKGRlZik7CiAgICB9CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICAvKgogICAgKiBUT0RPOiBSZXN0cmljdCB0aGUgbWF4aW1hbCB2YWx1ZSB0byBJbnRlZ2VyLgogICAgKi8KICAgIGlmICgoKmN1ciAhPSAwKSB8fCAocmV0IDwgbWluKSB8fCAoKG1heCAhPSAtMSkgJiYgKHJldCA+IG1heCkpKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbEdldE1pbk9jY3VyczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBHZXQgdGhlIG1pbk9jY3VycyBwcm9wZXJ0eQogKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGlmIG5vdCBmb3VuZCwgb3IgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50CnhtbEdldE1pbk9jY3Vycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWluT2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICAvKiBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywgKi8KCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgZXhwZWN0ZWQsCgkgICAgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGRlZik7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG93bmVyRGVzOiAgb3duZXIgZGVzaWduYXRpb24KICogQG93bmVySXRlbTogIHRoZSBvd25lciBhcyBhIHNjaGVtYSBpdGVtCiAqIEBub2RlOiB0aGUgbm9kZSBob2xkaW5nIHRoZSB2YWx1ZQogKgogKiBDb252ZXJ0cyBhIGJvb2xlYW4gc3RyaW5nIHZhbHVlIGludG8gMSBvciAwLgogKgogKiBSZXR1cm5zIDAgb3IgMS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAkJCSAgIAoJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbHVlID0gTlVMTDsKICAgIGludCByZXMgPSAwOwogICAKICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CiAgICAvKiAKICAgICogMy4yLjIuMSBMZXhpY2FsIHJlcHJlc2VudGF0aW9uCiAgICAqIEFuIGluc3RhbmNlIG9mIGEgZGF0YXR5cGUgdGhhdCBpcyBkZWZpbmVkIGFzILdib29sZWFutyAKICAgICogY2FuIGhhdmUgdGhlIGZvbGxvd2luZyBsZWdhbCBsaXRlcmFscyB7dHJ1ZSwgZmFsc2UsIDEsIDB9LgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICByZXMgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICJmYWxzZSIpKQogICAgICAgIHJlcyA9IDA7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjEiKSkKCXJlcyA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjAiKSkKICAgICAgICByZXMgPSAwOyAgICAKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckRlcywgb3duZXJJdGVtLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwgCgkgICAgIigxIHwgMCB8IHRydWUgfCBmYWxzZSkiLCBCQURfQ0FTVCB2YWx1ZSwgCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXMpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEV2YWx1YXRlIGlmIGEgYm9vbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqIDEgaWYgZm91bmQgdG8gYmUgdHJ1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRCb29sZWFuUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGludCBkZWYpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoZGVmKTsKICAgIC8qIAogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63IAogICAgKiBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGxlZ2FsIGxpdGVyYWxzIHt0cnVlLCBmYWxzZSwgMSwgMH0uCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMSIpKQoJZGVmID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgIjAiKSkKICAgICAgICBkZWYgPSAwOyAgICAKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckRlcywgb3duZXJJdGVtLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwgCgkgICAgIigxIHwgMCB8IHRydWUgfCBmYWxzZSkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChkZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVNoZW1hIGV4dHJhY3Rpb24gZnJvbSBhbiBJbmZvc2V0CQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgCgkJCQkJCSAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VBbGwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgICAgIGludCB0b3BMZXZlbCk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDaG9pY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSk7CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWU6CiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAYXR0cjogIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUgYmVpbmcgdmFsaWRhdGVkCiAqIEB2YWx1ZTogdGhlIHZhbHVlCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdCAKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAkJCSAgIAoJCQkgICB4bWxBdHRyUHRyIGF0dHIsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIAogICAgaW50IHJldCA9IDA7IAoKICAgIC8qCiAgICAqIE5PVEU6IFNob3VsZCB3ZSBtb3ZlIHRoaXMgdG8geG1sc2NoZW1hdHlwZXMuYz8gSG1tLCBidXQgdGhpcwogICAgKiBvbmUgaXMgcmVhbGx5IG1lYW50IHRvIGJlIHVzZWQgaW50ZXJuYWxseSwgc28gYmV0dGVyIG5vdC4KICAgICovICAgIAogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpIHx8IChhdHRyID09IE5VTEwpKQoJcmV0dXJuICgtMSk7ICAgCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUHZhbHVlQXR0ck5vZGUsIHRoZSBnaXZlbiAiCgkgICAgInR5cGUgJyVzJyBpcyBub3QgYSBidWlsdC1pbiB0eXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfSAgICAKICAgIHN3aXRjaCAodHlwZS0+YnVpbHRJblR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQVNfTkNOQU1FOgoJICAgIHJldCA9IHhtbFZhbGlkYXRlTkNOYW1lKHZhbHVlLCAxKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQVNfUU5BTUU6CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQdmFsdWVBdHRyTm9kZSwgdXNlICIKCQkidGhlIGZ1bmN0aW9uIHhtbFNjaGVtYUV4dHJhY3RTY2hlbWFRTmFtZVByb3B2YWx1ZWlkYXRlZCAiCgkJImZvciBleHRyYWN0aW5nIFFOYW1lIHZhbHVldWVzIGluc3RlYWQuXG4iLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJY2FzZSBYTUxfU0NIRU1BU19BTllVUkk6CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCQl4bWxVUklQdHIgdXJpID0geG1sUGFyc2VVUkkoKGNvbnN0IGNoYXIgKikgdmFsdWUpOwoJCWlmICh1cmkgPT0gTlVMTCkKCQkgICAgcmV0ID0gMTsKCQllbHNlCgkJICAgIHhtbEZyZWVVUkkodXJpKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFTX1RPS0VOOiB7CgkgICAgY29uc3QgeG1sQ2hhciAqY3VyID0gdmFsdWU7CgoJCWlmIChJU19CTEFOS19DSCgqY3VyKSkgewogICAgICAgICAgICAgICAgICAgIHJldCA9IDE7CQkgICAgICAgCgkJfSBlbHNlIHdoaWxlICgqY3VyICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKCpjdXIgPT0gMHhkKSB8fCAoKmN1ciA9PSAweGEpIHx8ICgqY3VyID09IDB4OSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gMTsKCQkJYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgqY3VyID09ICcgJykgewogICAgICAgICAgICAgICAgICAgICAgICBjdXIrKzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgqY3VyID09IDApIHx8ICgqY3VyID09ICcgJykpIHsKCQkJICAgIHJldCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cisrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFTX0xBTkdVQUdFOgoJICAgIGlmICh4bWxDaGVja0xhbmd1YWdlSUQodmFsdWUpICE9IDEpIAoJCXJldCA9IDE7CgkgICAgYnJlYWs7CglkZWZhdWx0OiB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVB2YWx1ZUF0dHJOb2RlLCAiCgkJICAgICJ2YWx1ZWlkYXRpb24gdXNpbmcgdGhlIHR5cGUgJyVzJyBpcyBub3QgaW1wbGVtZW50ZWQgIgoJCSAgICAieWV0LlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9ICAgICAgICAgICAgICAKICAgIC8qCiAgICAqIFRPRE86IFNob3VsZCB3ZSB1c2UgdGhlIFM0UyBlcnJvciBjb2RlcyBpbnN0ZWFkPwogICAgKi8KICAgIGlmIChyZXQgPiAwKSB7IAkKCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CSAgIAoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMiwgCgkJb3duZXJEZXMsIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCXR5cGUsIE5VTEwsIHZhbHVlLCAKCQlOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yKTsKCX0gZWxzZSB7CSAgICAKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsIAoJCW93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCQl0eXBlLCBOVUxMLCB2YWx1ZSwgCgkJTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSk7Cgl9CQogICAgfSAgICAKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZToKICogCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZSBiZWluZyB2YWxpZGF0ZWQKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqIEB2YWx1ZTogdGhlIHJlc3VsdGluZyB2YWx1ZSBpZiBhbnkKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbENoYXIgKipvd25lckRlcywKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCQkJICAgCgkJCSAgIHhtbEF0dHJQdHIgYXR0ciwJCQkgICAKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICBjb25zdCB4bWxDaGFyICoqdmFsdWUpCnsgICAgCiAgICBjb25zdCB4bWxDaGFyICp2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpIHx8IChhdHRyID09IE5VTEwpKQoJcmV0dXJuICgtMSk7ICAgCiAgICAgICAKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJKnZhbHVlID0gdmFsOwoKICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoY3R4dCwgb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwKCXZhbCwgdHlwZSkpOyAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyOgogKiAKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAb3duZXJFbGVtOiB0aGUgb3duZXIgZWxlbWVudCBub2RlCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGJ1aWx0LWluIHR5cGUgdG8gYmUgdmFsaWRhdGVkIGFnYWluc3QKICogQHZhbHVlOiB0aGUgcmVzdWx0aW5nIHZhbHVlIGlmIGFueQogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAkJICAgICAgIAoJCSAgICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCSAgICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkgICAgICAgY29uc3QgY2hhciAqbmFtZSwKCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdmFsdWUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7CglyZXR1cm4gKC0xKTsgICAKICAgIH0KICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgKnZhbHVlID0gTlVMTDsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLCAKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBWYWxBdHRyLCB0aGUgZ2l2ZW4gIgoJICAgICJ0eXBlICclcycgaXMgbm90IGEgYnVpbHQtaW4gdHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgKnZhbHVlID0gTlVMTDsKCXJldHVybiAoMCk7CiAgICB9ICAgIAogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwgCgl0eXBlLCB2YWx1ZSkpOwp9Ci8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJEZWNsczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAdHlwZTogIHRoZSBob3N0aW5nIHR5cGUKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIGF0dHJEZWNscyBkZWNsYXJhdGlvbiBjb3JyZXNwb25kaW5nIHRvCiAqIDwhRU5USVRZICUgYXR0ckRlY2xzICAKICogICAgICAgJygoJWF0dHJpYnV0ZTt8ICVhdHRyaWJ1dGVHcm91cDspKiwoJWFueUF0dHJpYnV0ZTspPyknPgogKi8Kc3RhdGljIHhtbE5vZGVQdHIKeG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGNoaWxkLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBsYXN0YXR0ciwgYXR0cjsKCiAgICBsYXN0YXR0ciA9IE5VTEw7CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSkgewogICAgICAgIGF0dHIgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgewogICAgICAgICAgICBhdHRyID0geG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGVHcm91cCIpKSB7CiAgICAgICAgICAgIGF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9CiAgICAgICAgaWYgKGF0dHIgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdGF0dHIgPT0gTlVMTCkgewoJCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkKCQkgICAgKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgdHlwZSktPmF0dHJpYnV0ZXMgPSBhdHRyOwoJCWVsc2UKICAgICAgICAgICAgICAgIHR5cGUtPmF0dHJpYnV0ZXMgPSBhdHRyOwogICAgICAgICAgICAgICAgbGFzdGF0dHIgPSBhdHRyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdGF0dHItPm5leHQgPSBhdHRyOwogICAgICAgICAgICAgICAgbGFzdGF0dHIgPSBhdHRyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9ICAgIAogICAgcmV0dXJuIChjaGlsZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFubm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYUFubm90UHRyCnhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUFubm90UHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IGJhcmtlZCA9IDA7CgogICAgLyoKICAgICogSU5GTzogUzRTIGNvbXBsZXRlZC4KICAgICovCiAgICAvKgogICAgKiBpZCA9IElECiAgICAqIHthbnkgYXR0cmlidXRlcyB3aXRoIG5vbi1zY2hlbWEgbmFtZXNwYWNlIC4gLiAufT4KICAgICogQ29udGVudDogKGFwcGluZm8gfCBkb2N1bWVudGF0aW9uKSoKICAgICovCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU2NoZW1hTmV3QW5ub3QoY3R4dCwgbm9kZSk7CiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmICgoKGF0dHItPm5zID09IE5VTEwpICYmIAoJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpKSB8fAoJICAgICgoYXR0ci0+bnMgIT0gTlVMTCkgJiYgCgkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpIHsKCSAgICAKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgYXR0cik7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qIFRPRE86IENoZWNrIGlkLiAqLyAgICAKICAgIAogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXBwaW5mbyIpKSB7CgkgICAgLyogVE9ETzogbWFrZSBhdmFpbGFibGUgdGhlIGNvbnRlbnQgb2YgImFwcGluZm8iLiAqLwoJICAgIC8qIAoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJiAKCQkgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNvdXJjZSIpKSkgfHwKCQkgICAgICgoYXR0ci0+bnMgIT0gTlVMTCkgJiYgCgkJICAgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIE5VTEwsIGF0dHIpOwoJCX0KCQlhdHRyID0gYXR0ci0+bmV4dDsKCSAgICB9CgkgICAgeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgY2hpbGQsICJzb3VyY2UiLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCBOVUxMKTsJICAgIAoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImRvY3VtZW50YXRpb24iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJkb2N1bWVudGF0aW9uIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzb3VyY2UiKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykgfHwKCQkJKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJsYW5nIikgJiYKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgWE1MX1hNTF9OQU1FU1BBQ0UpKSkpIHsKCQkJCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkJICAgIH0KCQl9CgkJYXR0ciA9IGF0dHItPm5leHQ7CgkgICAgfQoJICAgIC8qCgkgICAgKiBBdHRyaWJ1dGUgInhtbDpsYW5nIi4KCSAgICAqLwoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZU5zKGNoaWxkLCAoY29uc3QgY2hhciAqKSBYTUxfWE1MX05BTUVTUEFDRSwgImxhbmciKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKQoJCXhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0xBTkdVQUdFKSwgTlVMTCk7CSAgICAKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIHsKCSAgICBpZiAoIWJhcmtlZCkKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqIik7CgkgICAgYmFya2VkID0gMTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUZhY2V0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBGYWNldCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyB0eXBlIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFGYWNldFB0cgp4bWxTY2hlbWFQYXJzZUZhY2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGZhY2V0ID0geG1sU2NoZW1hTmV3RmFjZXQoKTsKICAgIGlmIChmYWNldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBmYWNldCIsIG5vZGUpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBmYWNldC0+bm9kZSA9IG5vZGU7CiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInZhbHVlIik7CiAgICBpZiAodmFsdWUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9GQUNFVF9OT19WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAiRmFjZXQgJXMgaGFzIG5vIHZhbHVlXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5JbmNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWluRXhjbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtYXhFeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAidG90YWxEaWdpdHMiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJmcmFjdGlvbkRpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgInBhdHRlcm4iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImVudW1lcmF0aW9uIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAid2hpdGVTcGFjZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heExlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5MZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg7CiAgICB9IGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gZmFjZXQgdHlwZSAlc1xuIiwgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgZmFjZXQtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIGZhY2V0LT52YWx1ZSA9IHZhbHVlOwogICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsKCWNvbnN0IHhtbENoYXIgKmZpeGVkOwoKCWZpeGVkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKCWlmIChmaXhlZCAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGZpeGVkLCBCQURfQ0FTVCAidHJ1ZSIpKQoJCWZhY2V0LT5maXhlZCA9IDE7Cgl9CiAgICB9ICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgZmFjZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgdW5leHBlY3RlZCBjaGlsZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHdpbGRjOiAgdGhlIHdpbGRjYXJkLCBhbHJlYWR5IGNyZWF0ZWQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgdGhlIGF0dHJpYnV0ZSAicHJvY2Vzc0NvbnRlbnRzIiBhbmQgIm5hbWVzcGFjZSIKICogb2YgYSB4c2Q6YW55QXR0cmlidXRlIGFuZCB4c2Q6YW55LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgMCBpZiBldmVyeXRoaW5nIGdvZXMgZmluZSwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIHNvbWV0aGluZyBpcyBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkYywKCQkJIHhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqcGMsICpucywgKmRpY3Ruc0l0ZW07CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbENoYXIgKm5zSXRlbTsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgdG1wLCBsYXN0TnMgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgCiAgICBwYyA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInByb2Nlc3NDb250ZW50cyIpOwogICAgaWYgKChwYyA9PSBOVUxMKQogICAgICAgIHx8ICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInN0cmljdCIpKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOwogICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInNraXAiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJsYXgiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfTEFYOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1BST0NFU1NDT05URU5UX0NISUxELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgTlVMTCwgIihzdHJpY3QgfCBza2lwIHwgbGF4KSIsIHBjLCAKCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICB3aWxkYy0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDsKCXJldCA9IFhNTF9TQ0hFTUFQX1VOS05PV05fUFJPQ0VTU0NPTlRFTlRfQ0hJTEQ7CiAgICB9CiAgICAvKgogICAgICogQnVpbGQgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cy4KICAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lc3BhY2UiKTsKICAgIG5zID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgaWYgKChucyA9PSBOVUxMKSB8fCAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI2FueSIpKSkKCXdpbGRjLT5hbnkgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI290aGVyIikpIHsKCXdpbGRjLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHdpbGRjLT5uZWdOc1NldCA9PSBOVUxMKSB7CSAgICAJICAgIAoJICAgIHJldHVybiAoLTEpOwoJfQoJd2lsZGMtPm5lZ05zU2V0LT52YWx1ZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOyAKICAgIH0gZWxzZSB7ICAgIAoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyOwoKCWN1ciA9IG5zOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgbnNJdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7ICAgIAkgICAgCgkgICAgaWYgKCh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI290aGVyIikpIHx8CgkJICAgICh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI2FueSIpKSkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9XSUxEQ0FSRF9JTlZBTElEX05TX01FTUJFUiwKCQkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsIAoJCSAgICAiKCgjI2FueSB8ICMjb3RoZXIpIHwgTGlzdCBvZiAoYW55VVJJIHwgIgoJCSAgICAiKCMjdGFyZ2V0TmFtZXNwYWNlIHwgIyNsb2NhbCkpKSIsIAoJCSAgICBuc0l0ZW0sIE5VTEwsIE5VTEwsIE5VTEwpOwoJCXJldCA9IFhNTF9TQ0hFTUFQX1dJTERDQVJEX0lOVkFMSURfTlNfTUVNQkVSOwoJICAgIH0gZWxzZSB7CgkJaWYgKHhtbFN0ckVxdWFsKG5zSXRlbSwgQkFEX0NBU1QgIiMjdGFyZ2V0TmFtZXNwYWNlIikpIHsKCQkgICAgZGljdG5zSXRlbSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNsb2NhbCIpKSB7CgkJICAgIGRpY3Ruc0l0ZW0gPSBOVUxMOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogVmFsaWRhdGUgdGhlIGl0ZW0gKGFueVVSSSkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsIAoJCQluc0l0ZW0sIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSkpOwoJCSAgICBkaWN0bnNJdGVtID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuc0l0ZW0sIC0xKTsKCQl9CgkJLyoKCQkqIEF2b2lkIGR1YmxpY2F0ZSBuYW1lc3BhY2VzLgoJCSovCgkJdG1wID0gd2lsZGMtPm5zU2V0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewoJCSAgICBpZiAoZGljdG5zSXRlbSA9PSB0bXAtPnZhbHVlKQoJCQlicmVhazsKCQkgICAgdG1wID0gdG1wLT5uZXh0OwoJCX0KCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCQl4bWxGcmVlKG5zSXRlbSk7CQkJCgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIHRtcC0+dmFsdWUgPSBkaWN0bnNJdGVtOwoJCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJCSAgICBpZiAod2lsZGMtPm5zU2V0ID09IE5VTEwpIAoJCQl3aWxkYy0+bnNTZXQgPSB0bXA7CgkJICAgIGVsc2UKCQkJbGFzdE5zLT5uZXh0ID0gdG1wOwoJCSAgICBsYXN0TnMgPSB0bXA7CgkJfQoKCSAgICB9CQoJICAgIHhtbEZyZWUobnNJdGVtKTsKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOyAgICAKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwgCgkJCQkgeG1sTm9kZVB0ciBub2RlLAoJCQkJIGludCBtaW5PY2N1cnMsCgkJCQkgaW50IG1heE9jY3VycykgewoKICAgIGlmIChtYXhPY2N1cnMgIT0gVU5CT1VOREVEKSB7CgkvKgoJKiBUT0RPOiBNYWJ5IHdlIHNob3VsZCBiZXR0ZXIgbm90IGNyZWF0ZSB0aGUgcGFydGljbGUsIAoJKiBpZiBtaW4vbWF4IGlzIGludmFsaWQsIHNpbmNlIGl0IGNvdWxkIGNvbmZ1c2UgdGhlIGJ1aWxkIG9mIHRoZSAKCSogY29udGVudCBtb2RlbC4KCSovCgkvKiAKCSogMy45LjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBQYXJ0aWNsZSBDb3JyZWN0CgkqCgkqLwoJaWYgKG1heE9jY3VycyA8IDEpIHsgCgkgICAgLyogCgkgICAgKiAyLjIge21heCBvY2N1cnN9IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzIsCgkJTlVMTCwgaXRlbSwgeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1heE9jY3VycyIpLAoJCSJUaGUgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMSIpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMik7Cgl9IGVsc2UgaWYgKG1pbk9jY3VycyA+IG1heE9jY3VycykgewoJICAgIC8qCgkgICAgKiAyLjEge21pbiBvY2N1cnN9IG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB7bWF4IG9jY3Vyc30uCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzEsIAoJCU5VTEwsIGl0ZW0sIHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtaW5PY2N1cnMiKSwKCQkiVGhlIHZhbHVlIG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUgb2YgJ21heE9jY3VycyciKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzEpOwoJfQogICAgfQkKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQW55IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VBbnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBtYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAKCSIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgbWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAKCSJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIGlmICgobWluT2NjdXJzID09IDApICYmIChtYXhPY2N1cnMgPT0gMCkpCglyZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiYW55ICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWTsgICAgCiAgICAKICAgIHdpbGRjID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCk7CiAgICAvKgogICAgKiBDaGVjayBtaW4vbWF4IHNhbml0eS4KICAgICovCiAgICB0eXBlLT5tYXhPY2N1cnMgPSBtYXhPY2N1cnM7CiAgICB0eXBlLT5taW5PY2N1cnMgPSBtaW5PY2N1cnM7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCB0eXBlLCAKCSAgICBub2RlLCB0eXBlLT5taW5PY2N1cnMsIHR5cGUtPm1heE9jY3Vycyk7ICAgIAogICAgLyoKICAgICogVGhpcyBpcyBub3QgbmljZSwgc2luY2UgaXQgaXMgd29uJ3QgYmUgdXNlZCBhcyBhIGF0dHJpYnV0ZSB3aWxkY2FyZCwKICAgICogYnV0IGJldHRlciB0aGFuIGFkZGluZyBhIGZpZWxkIHRvIHRoZSBzdHJ1Y3R1cmUuCiAgICAqLwogICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB3aWxkYzsKICAgIHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyhjdHh0LCBzY2hlbWEsIHdpbGRjLCBub2RlKTsgICAgCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOyAgICAKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1NFUVVFTkNFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTZXF1ZW5jZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBOb3RhdGlvbiBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYVBhcnNlTm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9OT1RBVElPTl9OT19OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICJOb3RhdGlvbiBoYXMgbm8gbmFtZVxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldCA9IHhtbFNjaGVtYUFkZE5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgbmFtZSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fTk9UQVRJT05fQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIm5vdGF0aW9uICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIG5hbWUsIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBbnlBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyBhIHdpbGRjYXJkIG9yIE5VTEwuCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCSAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZXNwYWNlIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicHJvY2Vzc0NvbnRlbnRzIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgTlVMTCwgYXR0cik7CQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKiByZXQtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsgKi8KICAgIC8qCiAgICAqIFBhcnNlIHRoZSBuYW1lc3BhY2UgbGlzdC4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zKGN0eHQsIHNjaGVtYSwgcmV0LCBub2RlKSAhPSAwKSB7Cgl4bWxTY2hlbWFGcmVlV2lsZGNhcmQocmV0KTsKCXJldHVybiAoTlVMTCk7CiAgICB9ICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqYXR0clZhbHVlOwogICAgeG1sQ2hhciAqcmVwTmFtZSA9IE5VTEw7IC8qIFRoZSByZXBvcnRlZCBkZXNpZ25hdGlvbi4gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHIsIG5hbWVBdHRyOwogICAgaW50IGlzUmVmID0gMDsKCiAgICAvKgogICAgICogTm90ZSB0aGF0IHRoZSB3M2Mgc3BlYyBhc3N1bWVzIHRoZSBzY2hlbWEgdG8gYmUgdmFsaWRhdGVkIHdpdGggc2NoZW1hCiAgICAgKiBmb3Igc2NoZW1hcyBiZWZvcmVoYW5kLgogICAgICoKICAgICAqIDMuMi4zIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgQXR0cmlidXRlIERlY2xhcmF0aW9ucwogICAgICovCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBuYW1lQXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CgogICAgaWYgKChhdHRyID09IE5VTEwpICYmIChuYW1lQXR0ciA9PSBOVUxMKSkgewoJLyogCgkqIDMuMi4zIDogMy4xCgkqIE9uZSBvZiByZWYgb3IgbmFtZSBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aCAKCSovCgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8zXzEsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBOVUxMLCBub2RlLCBOVUxMLCAKCSAgICAiT25lIG9mIHRoZSBhdHRyaWJ1dGVzICdyZWYnIG9yICduYW1lJyBtdXN0IGJlIHByZXNlbnQiKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIE5VTEwsIG5vZGUsIAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCiAgICB9IGVsc2UKCWlzUmVmID0gMTsJCiAgICAKICAgIGlmIChpc1JlZikgewoJY2hhciBidWZbNTBdOyAKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEwsICpyZWZQcmVmaXggPSBOVUxMOyAKCgkvKgoJKiBQYXJzZSBhcyBhdHRyaWJ1dGUgcmVmZXJlbmNlLgoJKi8JCQoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiwgTlVMTCwgYXR0ciwgJnJlZk5zLCAKCSAgICAmcmVmUHJlZml4LCAmcmVmKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCiAgICAgICAgc25wcmludGYoYnVmLCA0OSwgIiNhUmVmICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsJCglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKCWlmIChyZXQgPT0gTlVMTCkgewoJICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShyZXBOYW1lKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTsKCXJldC0+bm9kZSA9IG5vZGU7CglyZXQtPnJlZk5zID0gcmVmTnM7CglyZXQtPnJlZlByZWZpeCA9IHJlZlByZWZpeDsKCXJldC0+cmVmID0gcmVmOwkJCgkvKgoJeG1sU2NoZW1hRm9ybWF0VHlwZVJlcCgmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgTlVMTCwgTlVMTCk7CgkqLwoJaWYgKG5hbWVBdHRyICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18xLCAKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbmFtZUF0dHIsIAoJCSJyZWYiLCAibmFtZSIpOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmb3JtIikpIHsKCQkgICAgLyogCgkJICAgICogMy4yLjMgOiAzLjIKCQkgICAgKiBJZiByZWYgaXMgcHJlc2VudCwgdGhlbiBhbGwgb2YgPHNpbXBsZVR5cGU+LAoJCSAgICAqIGZvcm0gYW5kIHR5cGUgbXVzdCBiZSBhYnNlbnQuIAoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18yLCAmcmVwTmFtZSwgCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJCX0gZWxzZSBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInVzZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmIAoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJiAKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwkJICAgIAoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwkJCgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQkKICAgIH0gZWxzZSB7CiAgICAgICAgY29uc3QgeG1sQ2hhciAqbnMgPSBOVUxMOwoJCgkvKgoJKiBQYXJzZSBhcyBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCgkqLwkJCQoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCAKCSAgICAoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCwgTlVMTCwgbmFtZUF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qCgl4bWxTY2hlbWFGb3JtYXRUeXBlUmVwKCZyZXBOYW1lLCBOVUxMLCB4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIG5hbWUpOwoJKi8KCS8qIAoJKiAzLjIuNiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IHhtbG5zIE5vdCBBbGxvd2VkIAoJKi8KCWlmICh4bWxTdHJFcXVhbChuYW1lLCBCQURfQ0FTVCAieG1sbnMiKSkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX05PX1hNTE5TLCAKCQkmcmVwTmFtZSwgTlVMTCwgKHhtbE5vZGVQdHIpIG5hbWVBdHRyLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAiTkNOYW1lIiwgTlVMTCwKCQkiVGhlIHZhbHVlIG11c3Qgbm90IG1hdGNoICd4bWxucyciLCAKCQlOVUxMLCBOVUxMKTsJICAgIAoJICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShyZXBOYW1lKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQkgICAgCgkvKiAKCSogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UgCgkqLwkKCWlmICh0b3BMZXZlbCkgewoJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgewoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZm9ybSIpOwoJICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAidW5xdWFsaWZpZWQiKSkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwgCgkJCSZyZXBOYW1lLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCU5VTEwsICIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwgCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CQkJCgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKQoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CQkKCX0JCQkJCglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBucywgbm9kZSk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CglyZXQtPm5vZGUgPSBub2RlOwkJCQkKCWlmICh0b3BMZXZlbCkKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMOwoJLyogCgkqIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeHNpOiBOb3QgQWxsb3dlZCAKCSovCQoJaWYgKHhtbFN0ckVxdWFsKHJldC0+dGFyZ2V0TmFtZXNwYWNlLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfTk9fWFNJLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLAoJCSJUaGUgdGFyZ2V0IG5hbWVzcGFjZSBtdXN0IG5vdCBtYXRjaCAnJXMnIiwgCgkJeG1sU2NoZW1hSW5zdGFuY2VOcyk7CSAgICAgICAgCgl9CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLiAKCSovCQoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsJCQoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJiAKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSAmJiAJCQkJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpeGVkIikpICYmCQkgICAgCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSkgewoJCSAgICBpZiAoKHRvcExldmVsKSB8fAkJCQkJCSAgICAJCQoJCSAgICAgICAgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZvcm0iKSkgJiYKCQkJICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInVzZSIpKSkpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwkKCQkgICAgfQoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCXhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCSAgICBub2RlLCAidHlwZSIsICZyZXQtPnR5cGVOcywgTlVMTCwgJnJldC0+dHlwZU5hbWUpOwogICAgfSAgICAKICAgIC8qIFRPRE86IENoZWNrIElELiAqLwogICAgcmV0LT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7ICAKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAiZml4ZWQiLgogICAgKi8KICAgIHJldC0+ZGVmVmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwogICAgaWYgKHJldC0+ZGVmVmFsdWUgIT0gTlVMTCkKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9GSVhFRDsKICAgIC8qIAogICAgKiBBdHRyaWJ1dGUgImRlZmF1bHQiLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJLyogCgkqIDMuMi4zIDogMQoJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJKi8KCWlmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgewoJICAgIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzEsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIsICJkZWZhdWx0IiwgImZpeGVkIik7Cgl9IGVsc2UKCSAgICByZXQtPmRlZlZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkJCiAgICB9ICAgIAogICAgaWYgKHRvcExldmVsID09IDApIHsKCS8qIAoJKiBBdHRyaWJ1dGUgInVzZSIuIAoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidXNlIik7CglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJvcHRpb25hbCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CgkgICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicHJvaGliaXRlZCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRDsKCSAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJyZXF1aXJlZCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQ7CgkgICAgZWxzZQoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfVVNFLCAKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgTlVMTCwgIihvcHRpb25hbCB8IHByb2hpYml0ZWQgfCByZXF1aXJlZCkiLCAKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsJCQkJCgl9IGVsc2UKCSAgICByZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMOwoJLyogCgkqIDMuMi4zIDogMgoJKiBJZiBkZWZhdWx0IGFuZCB1c2UgYXJlIGJvdGggcHJlc2VudCwgdXNlIG11c3QgaGF2ZQoJKiB0aGUgYWN0dWFsIHZhbHVlIG9wdGlvbmFsLgoJKi8KCWlmICgocmV0LT5vY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmIAoJICAgIChyZXQtPmRlZlZhbHVlICE9IE5VTEwpICYmIAoJICAgICgocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpID09IDApKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8yLCAKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCU5VTEwsICIob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIiwgTlVMTCwgCgkJIlRoZSB2YWx1ZSBtdXN0IGJlICdvcHRpb25hbCcgaWYgdGhlIGF0dHJpYnV0ZSAiCgkJIidkZWZhdWx0JyBpcyBwcmVzZW50IGFzIHdlbGwiLCBOVUxMLCBOVUxMKTsJICAgIAoJfQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gICAgCiAgICBpZiAoaXNSZWYpIHsKCWlmIChjaGlsZCAhPSBOVUxMKSB7CSAgICAKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKQoJCS8qIAoJCSogMy4yLjMgOiAzLjIKCQkqIElmIHJlZiBpcyBwcmVzZW50LCB0aGVuIGFsbCBvZiA8c2ltcGxlVHlwZT4sCgkJKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LiAKCQkqLwoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18yLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJICAgICIoYW5ub3RhdGlvbj8pIik7CgkgICAgZWxzZSAKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSAgICAiKGFubm90YXRpb24/KSIpOyAgCgl9CiAgICB9IGVsc2UgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmIChyZXQtPnR5cGVOYW1lICE9IE5VTEwpIHsKCQkvKiAKCQkqIDMuMi4zIDogNAoJCSogdHlwZSBhbmQgPHNpbXBsZVR5cGU+IG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4gCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzQsCgkJICAgICZyZXBOYW1lLCAgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJICAgICJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGU/KSIpOwogICAgfQogICAgLyoKICAgICogQ2xlYW51cC4KICAgICovCiAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJeG1sRnJlZShyZXBOYW1lKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIGludCB0b3BMZXZlbCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBuYW1lQXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZiIpOyAgIAogICAgaWYgKCh0b3BMZXZlbCkgfHwgKGF0dHIgPT0gTlVMTCkpIHsKCS8qCgkqIFBhcnNlIGFzIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLgoJKiBOb3RlIHRoYXQgdGhvc2UgYXJlIGFsbG93ZWQgYXQgdG9wIGxldmVsIG9ubHkuCgkqLwoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIE5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbmFtZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBuYW1lQXR0cik7CgkvKgoJKiBUaGUgbmFtZSBpcyBjcnVjaWFsLCBleGl0IGlmIGludmFsaWQuIAoJKi8KCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCSAgICBOVUxMLCBOVUxMLCBuYW1lQXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBuYW1lLCBub2RlKTsKCWlmIChyZXQgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOwoJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMOwoJcmV0LT5ub2RlID0gbm9kZTsKICAgIH0gZWxzZSB7ICAgIAoJY2hhciBidWZbNTBdOwoJY29uc3QgeG1sQ2hhciAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTCwgKnJlZlByZWZpeDsKCgkvKgoJKiBQYXJzZSBhcyBhbiBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UuCgkqLwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCAKCQlOVUxMLCBOVUxMLCBub2RlLCAicmVmIiwgTlVMTCk7Cgl9CQoJeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgIE5VTEwsIE5VTEwsIGF0dHIsICZyZWZOcywgJnJlZlByZWZpeCwgJnJlZik7CgkgCiAgICAgICAgc25wcmludGYoYnVmLCA0OSwgIiNhR3JSZWYgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCW5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CglpZiAobmFtZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgaW50ZXJuYWwgbmFtZSBmb3IgYW4gIgoJCSJhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UiLCBub2RlKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIG5vZGUpOwoJaWYgKHJldCA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA7CglyZXQtPnJlZiA9IHJlZjsKCXJldC0+cmVmTnMgPSByZWZOczsKCS8qIFRPRE86IElzIEByZWZQcmVmaXggY3VycmVudGx5IHVzZWQ/ICovCglyZXQtPnJlZlByZWZpeCA9IHJlZlByZWZpeDsKCXJldC0+bm9kZSA9IG5vZGU7CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCgodG9wTGV2ZWwgPT0gMCkgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpKSB8fAoJCSAodG9wTGV2ZWwgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSkpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIAoJICAgIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyogVE9ETzogVmFsaWRhdGUgImlkIiA/ICovICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOyAgICAKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAodG9wTGV2ZWwpIHsKCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7IAoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwgCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsIAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0OgogKiBAdmFsdWU6ICB0aGUgdmFsdWUKICogQGZsYWdzOiB0aGUgZmxhZ3MgdG8gYmUgbW9kaWZpZWQKICogQGZsYWdRdWFsaWZpZWQ6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAicXVhbGlmaWVkIgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCAxIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdChjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICBpbnQgKmZsYWdzLAoJCQkgICAgIGludCBmbGFnUXVhbGlmaWVkKQp7CiAgICBpZiAoeG1sU3RyRXF1YWwodmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJaWYgICgoKmZsYWdzICYgZmxhZ1F1YWxpZmllZCkgPT0gMCkKCSAgICAqZmxhZ3MgfD0gZmxhZ1F1YWxpZmllZDsKICAgIH0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHZhbHVlLCBCQURfQ0FTVCAidW5xdWFsaWZpZWQiKSkKCXJldHVybiAoMSk7ICAgIAoJCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsOgogKiBAdmFsdWU6ICB0aGUgdmFsdWUKICogQGZsYWdzOiB0aGUgZmxhZ3MgdG8gYmUgbW9kaWZpZWQKICogQGZsYWdBbGw6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiI2FsbCIKICogQGZsYWdFeHRlbnNpb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiZXh0ZW5zaW9uIgogKiBAZmxhZ1Jlc3RyaWN0aW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInJlc3RyaWN0aW9uIgogKiBAZmxhZ1N1YnN0aXR1dGlvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJzdWJzdGl0dXRpb24iCiAqIEBmbGFnTGlzdDogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJsaXN0IgogKiBAZmxhZ1VuaW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInVuaW9uIgogKgogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgImZpbmFsIiBhbmQgImJsb2NrIi4gVGhlIHZhbHVlCiAqIGlzIGNvbnZlcnRlZCBpbnRvIHRoZSBzcGVjaWZpZWQgZmxhZyB2YWx1ZXMgYW5kIHJldHVybmVkIGluIEBmbGFncy4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgMSBvdGhlcndpc2UuCiAqLwoKc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICBpbnQgKmZsYWdzLAkJCQoJCQkgICAgaW50IGZsYWdBbGwsCgkJCSAgICBpbnQgZmxhZ0V4dGVuc2lvbiwKCQkJICAgIGludCBmbGFnUmVzdHJpY3Rpb24sCgkJCSAgICBpbnQgZmxhZ1N1YnN0aXR1dGlvbiwKCQkJICAgIGludCBmbGFnTGlzdCwKCQkJICAgIGludCBmbGFnVW5pb24pCQkJCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIFRPRE86IFRoaXMgZG9lcyBub3QgY2hlY2sgZm9yIGR1YmxpY2F0ZSBlbnRyaWVzLgogICAgKi8KICAgIGlmICh2YWx1ZSA9PSBOVUxMKQoJcmV0dXJuICgxKTsKICAgIGlmICh4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgIiNhbGwiKSkgewoJaWYgKGZsYWdBbGwgIT0gLTEpCgkgICAgKmZsYWdzIHw9IGZsYWdBbGw7CgllbHNlIHsKCSAgICBpZiAoZmxhZ0V4dGVuc2lvbiAhPSAtMSkgCgkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247IAoJICAgIGlmIChmbGFnUmVzdHJpY3Rpb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnUmVzdHJpY3Rpb247CgkgICAgaWYgKGZsYWdTdWJzdGl0dXRpb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnU3Vic3RpdHV0aW9uOwoJICAgIGlmIChmbGFnTGlzdCAhPSAtMSkgCgkJKmZsYWdzIHw9IGZsYWdMaXN0OwoJICAgIGlmIChmbGFnVW5pb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnVW5pb247Cgl9CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyID0gdmFsdWU7Cgl4bWxDaGFyICppdGVtOwoJCglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBpdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7ICAgIAkgICAgCgkgICAgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJleHRlbnNpb24iKSkgewoJCWlmIChmbGFnRXh0ZW5zaW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ0V4dGVuc2lvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInJlc3RyaWN0aW9uIikpIHsKCQlpZiAoZmxhZ1Jlc3RyaWN0aW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1Jlc3RyaWN0aW9uKSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ1Jlc3RyaWN0aW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJzdWJzdGl0dXRpb24iKSkgewoJCWlmIChmbGFnU3Vic3RpdHV0aW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1N1YnN0aXR1dGlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdTdWJzdGl0dXRpb247CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImxpc3QiKSkgewoJCWlmIChmbGFnTGlzdCAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdMaXN0KSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ0xpc3Q7CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInVuaW9uIikpIHsKCQlpZiAoZmxhZ1VuaW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1VuaW9uKSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ1VuaW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgCgkJcmV0ID0gMTsKCSAgICBpZiAoaXRlbSAhPSBOVUxMKQoJCXhtbEZyZWUoaXRlbSk7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKHJldCA9PSAwKSAmJiAoKmN1ciAhPSAwKSk7IAogICAgfSAgICAKICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBFbGVtZW50IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFQYXJzZUVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUgPSBOVUxMOyAgICAKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZTsKICAgIHhtbENoYXIgKnJlcE5hbWUgPSBOVUxMOwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHIsIG5hbWVBdHRyOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwogICAgaW50IGlzUmVmID0gMDsKCiAgICAvKiAzLjMuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEVsZW1lbnQgRGVjbGFyYXRpb25zICovCiAgICAvKiBUT0RPOiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiAzLjMuNiAqLwogICAKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgIAogICAgbmFtZUF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsgICAKICAgIGlmICgodG9wTGV2ZWwpIHx8IChhdHRyID09IE5VTEwpKSB7CglpZiAobmFtZUF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsCgkJKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wsIE5VTEwsIG5vZGUsCgkJIm5hbWUiLCBOVUxMKTsJICAgIAoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgluYW1lID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIG5hbWVBdHRyKTsJCQogICAgfSBlbHNlIHsKCWlzUmVmID0gMTsKCQogICAgfQogICAgLyogCiAgICAqIC4uLiB1bmxlc3MgbWluT2NjdXJzPW1heE9jY3Vycz0wLCBpbiB3aGljaCBjYXNlIHRoZSBpdGVtIGNvcnJlc3BvbmRzIAogICAgKiB0byBubyBjb21wb25lbnQgYXQgYWxsCiAgICAqIFRPRE86IEl0IG1pZ2h0IGJlIGJldHRlciB0byB2YWxpZGF0ZSB0aGUgZWxlbWVudCwgZXZlbiBpZiBpdCB3b24ndCBiZSAKICAgICogdXNlZC4KICAgICovICAgIAogICAgbWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAibm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICBtYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAiKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIGlmICgobWluT2NjdXJzID09IDApICYmIChtYXhPY2N1cnMgPT0gMCkpCglyZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogSWYgd2UgZ2V0IGEgInJlZiIgYXR0cmlidXRlIG9uIGEgbG9jYWwgPGVsZW1lbnQ+IHdlIHdpbGwgYXNzdW1lIGl0J3MKICAgICogYSByZWZlcmVuY2UgLSBldmVuIGlmIHRoZXJlJ3MgYSAibmFtZSIgYXR0cmlidXRlOyB0aGlzIHNlZW1zIHRvIGJlIG1vcmUgCiAgICAqIHJvYnVzdC4KICAgICovCiAgICBpZiAoaXNSZWYpIHsKCWNoYXIgYnVmWzUwXTsKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEwsICpyZWZQcmVmaXg7CgoJLyoKCSogUGFyc2UgYXMgYSBwYXJ0aWNsZS4KCSovCgl4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiwgCgkgICAgTlVMTCwgYXR0ciwgJnJlZk5zLCAmcmVmUHJlZml4LCAmcmVmKTsJCQkKCSAKICAgICAgICBzbnByaW50ZihidWYsIDQ5LCAiI2VSZWYgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCW5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CglyZXQgPSB4bWxTY2hlbWFBZGRFbGVtZW50KGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSwgMCk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOwoJcmV0LT5ub2RlID0gbm9kZTsgICAgIAkJCglyZXQtPnJlZiA9IHJlZjsKCXJldC0+cmVmTnMgPSByZWZOczsKCXJldC0+cmVmUHJlZml4ID0gcmVmUHJlZml4OwoJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1JFRjsKCS8qIAoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCS8qIAoJKiAzLjMuMyA6IDIuMQoJKiBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGggCgkqLwoJaWYgKG5hbWVBdHRyICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8xLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBuYW1lQXR0ciwKCQkicmVmIiwgIm5hbWUiKTsKCX0KCS8qIDMuMy4zIDogMi4yICovICAgCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKQoJCXsKCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzIsCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyLCAKCQkJIk9ubHkgdGhlIGF0dHJpYnV0ZXMgJ21pbk9jY3VycycsICdtYXhPY2N1cnMnIGFuZCAiCgkJCSInaWQnIGFyZSBhbGxvd2VkIGluIGFkZGl0aW9uIHRvICdyZWYnIik7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CSAgICAgIAogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKm5zID0gTlVMTCwgKmZpeGVkOwoKCS8qCgkqIFBhcnNlIGFzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCgkqLwoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCAKCSAgICAoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNFbGVtRGVjbCwgTlVMTCwgbmFtZUF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKQoJICAgIHJldHVybiAoTlVMTCk7CgkvKiAKCSogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCX0gZWxzZSB7CgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmb3JtIik7CgkgICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJCWF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCQkgICAgbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCQl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLCAKCQkJJnJlcE5hbWUsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkJTlVMTCwgIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLCAKCQkJYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsJCQkKCQl9CgkgICAgfSBlbHNlIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pCgkJbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsJCQoJfQkKCXJldCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgc2NoZW1hLCBuYW1lLCBucywgbm9kZSwgdG9wTGV2ZWwpOwoJaWYgKHJldCA9PSBOVUxMKSB7CgkgICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCQl4bWxGcmVlKHJlcE5hbWUpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDsKCXJldC0+bm9kZSA9IG5vZGU7CQkJCQkKCS8qIAoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgkJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYJCQoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWxsYWJsZSIpKSkgCgkJewkKCQkgICAgaWYgKHRvcExldmVsID09IDApIHsgCQkJCQkJCgkJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSkgCgkJCXsKCQkJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uR3JvdXAiKSkgewoJCQkJLyoKCQkJCSogMy4zLjYgOiAzIElmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gCgkJCQkqIGdyb3VwIGFmZmlsaWF0aW9ufSwgdGhlbiB7c2NvcGV9IG11c3QgYmUgZ2xvYmFsLgoJCQkJKiBUT0RPOiBUaGlzIG9uZSBpcyByZWR1bmRhbnQsIHNpbmNlIHRoZSBTNFMgZG9lcyAKCQkJCSogcHJvaGliaXQgdGhpcyBhdHRyaWJ1dGUgb24gbG9jYWwgZGVjbGFyYXRpb25zIGFscmVhZHk7IAoJCQkJKiBzbyB3aHkgYW4gZXhwbGljaXQgZXJyb3IgY29kZT8gV2VpcmQgc3BlYy4KCQkJCSogVE9ETzogTW92ZSB0aGlzIHRvIHRoZSBwcm9wZXIgY29uc3RyYWludCBsYXllci4KCQkJCSogVE9ETzogT3IgYmV0dGVyIHdhaXQgZm9yIHNwZWMgMS4xIHRvIGNvbWUuCgkJCQkqLwoJCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCQkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzMsCgkJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJCQkgICAgfSBlbHNlIHsKCQkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCQkJICAgIH0KCQkJfQoJCSAgICB9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpICYmIAoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJhYnN0cmFjdCIpKSAmJiAKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uR3JvdXAiKSkpIHsKCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CQkgICAgCgkJICAgIH0KCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJCgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQkJCgkvKgoJKiBFeHRyYWN0L3ZhbGlkYXRlIGF0dHJpYnV0ZXMuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgLyogCgkgICAgKiBQcm9jZXNzIHRvcCBhdHRyaWJ1dGVzIG9mIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9ucyBoZXJlLgoJICAgICovCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTDsKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUw7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsICZyZXBOYW1lLCAKCQkoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCAic3Vic3RpdHV0aW9uR3JvdXAiLCAKCQkmKHJldC0+c3Vic3RHcm91cE5zKSwgTlVMTCwgJihyZXQtPnN1YnN0R3JvdXApKTsKCSAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICAKCQlub2RlLCAiYWJzdHJhY3QiLCAwKSkKCQlyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1Q7IAoJICAgIC8qCgkgICAgKiBBdHRyaWJ1dGUgImZpbmFsIi4KCSAgICAqLwoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsJICAgIAoJICAgIGlmIChhdHRyID09IE5VTEwpIHsKCQlyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfQUJTRU5UOwoJICAgIH0gZWxzZSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkgICAgCgkJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYocmV0LT5mbGFncyksIAoJCSAgICAtMSwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9FWFRFTlNJT04sCgkJICAgIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04sIC0xLCAtMSwgLTEpICE9IDApIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCU5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLCAKCQkJYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9CgkgICAgfQoJfSAgICAKCS8qCgkqIEF0dHJpYnV0ZSAiYmxvY2siLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYmxvY2siKTsJCglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0FCU0VOVDsKCX0gZWxzZSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkgICAgCgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYocmV0LT5mbGFncyksIAoJCS0xLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04sIAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OLCAtMSwgLTEpICE9IDApIHsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8ICIKCQkgICAgInJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkiLCBhdHRyVmFsdWUsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsJCQoJICAgIH0KCX0KCWlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgCgkgICAgbm9kZSwgIm5pbGxhYmxlIiwgMCkpCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFOwkKCgl4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgCgkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIAoJICAgICJ0eXBlIiwgJihyZXQtPm5hbWVkVHlwZU5zKSwgTlVMTCwgJihyZXQtPm5hbWVkVHlwZSkpOwoKCXJldC0+dmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJkZWZhdWx0Iik7ICAgIAoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaXhlZCIpOwkKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICBmaXhlZCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAocmV0LT52YWx1ZSAhPSBOVUxMKSB7CgkJLyogCgkJKiAzLjMuMyA6IDEgCgkJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJCSovCgkJeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzEsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyLAoJCSAgICAiZGVmYXVsdCIsICJmaXhlZCIpOwoJICAgIH0gZWxzZSB7CgkJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEOwoJCXJldC0+dmFsdWUgPSBmaXhlZDsKCSAgICB9Cgl9CQogICAgfSAgICAgCiAgICAvKgogICAgKiBFeHRyYWN0L3ZhbGlkYXRlIGNvbW1vbiBhdHRyaWJ1dGVzLgogICAgKi8gICAgCiAgICAvKiBUT0RPOiBDaGVjayBJRDogKi8KICAgIHJldC0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgcmV0LT5taW5PY2N1cnMgPSBtaW5PY2N1cnM7CiAgICByZXQtPm1heE9jY3VycyA9IG1heE9jY3VyczsgCiAgICBpZiAodG9wTGV2ZWwgIT0gMSkKCXhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIAoJICAgIG5vZGUsIG1pbk9jY3VycywgbWF4T2NjdXJzKTsgICAgCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCXJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGlzUmVmKSB7CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8yLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgCgkJTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKCX0KICAgIH0gZWxzZSB7CQkJCglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleFR5cGUiKSkgewoJICAgIC8qIAoJICAgICogMy4zLjMgOiAzIAoJICAgICogInR5cGUiIGFuZCBlaXRoZXIgPHNpbXBsZVR5cGU+IG9yIDxjb21wbGV4VHlwZT4gYXJlIG11dHVhbGx5CgkgICAgKiBleGNsdXNpdmUgCgkgICAgKi8KCSAgICBpZiAocmV0LT5uYW1lZFR5cGUgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzMsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxjb21wbGV4VHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwkJCgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgLyogCgkgICAgKiAzLjMuMyA6IDMgCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUKCSAgICAqIG11dHVhbGx5IGV4Y2x1c2l2ZSAKCSAgICAqLwoJICAgIGlmIChyZXQtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ3R5cGUnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkIGFyZSAiCgkJICAgICJtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsJCQkJCgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQkKCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAidW5pcXVlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImtleSIpKSB8fCAoSVNfU0NIRU1BKGNoaWxkLCAia2V5cmVmIikpKSB7CgkgICAgVE9ETyBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUpPywgIgoJCSIodW5pcXVlIHwga2V5IHwga2V5cmVmKSopKSIpOwoJfQkJCgogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgLyoKICAgICogQ2xlYW51cC4KICAgICovCiAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJeG1sRnJlZShyZXBOYW1lKTsgICAgCiAgICAvKgogICAgKiBOT1RFOiBFbGVtZW50IERlY2xhcmF0aW9uIFJlcHJlc2VudGF0aW9uIE9LIDQuIHdpbGwgYmUgY2hlY2tlZCBhdCBhIAogICAgKiBkaWZmZXJlbnQgbGF5ZXIuCiAgICAqLwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VVbmlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgVW5pb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVVuaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiN1bmlvbiAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfVU5JT047CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1lbWJlclR5cGVzIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgdHlwZSwgYXR0cik7CQkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQkKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAibWVtYmVyVHlwZXMiLiBUaGlzIGlzIGEgbGlzdCBvZiBRTmFtZXMuCiAgICAqIFRPRE86IFZhbGlkYXRlIHRoZSBRTmFtZXMuCiAgICAqLwogICAgdHlwZS0+YmFzZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm1lbWJlclR5cGVzIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CQogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCS8qIFRPRE86IFRoaW5rIGFib3V0IHRoZSBlcnJvciBjb2RlLiAqLwoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1VOSU9OX0NISUxELCAKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZSopIik7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMaXN0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBMaXN0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VMaXN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjbGlzdCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9MSVNUOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaXRlbVR5cGUiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyoKICAgICogQXR0cmlidXRlICJpdGVtVHlwZSIuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIE5VTEwsCglub2RlLCAiaXRlbVR5cGUiLCAmKHR5cGUtPmJhc2VOcyksIE5VTEwsICYodHlwZS0+YmFzZSkpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSAgICAJCiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCWlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJCU5VTEwsIHR5cGUsIG5vZGUsIAoJCSJUaGUgYXR0cmlidXRlICdpdGVtVHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CSAgICAKCX0gZWxzZSB7CQoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7ICAgICAgICAKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkvKiBUT0RPOiBUaGluayBhYm91dCB0aGUgZXJyb3IgY29kZS4gKi8KCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9MSVNUX0NISUxELCAKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZT8pIik7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTaW1wbGUgVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgb2xkQ3R4dFR5cGUsIG9sZFBhcmVudEl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZSA9IE5VTEw7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgIAogICAgaWYgKHRvcExldmVsKSB7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzU1QsIE5VTEwsIG5vZGUsCgkJIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzU1QsIE5VTEwsIGF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZhdHRyVmFsdWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfQogICAgICAgICAgICAKICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CiAgICAgICAgY2hhciBidWZbNDBdOwoKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjU1QgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgKGNvbnN0IHhtbENoYXIgKilidWYsIE5VTEwsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCQkmZGVzLCB0eXBlLCBhdHRyKTsJCSAgICAKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCQkmZGVzLCB0eXBlLCBhdHRyKTsJCgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQogICAgfSBlbHNlIHsJCQoJLyoKCSogUGFyc2UgYXMgZ2xvYmFsIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqCgkqIE5vdGUgdGhhdCBhdHRyVmFsdWUgaXMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgIm5hbWUiIGhlcmUuCgkqLwkKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgYXR0clZhbHVlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUw7CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZkZXMsIHR5cGUsIGF0dHIpOwkKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgICZkZXMsIHR5cGUsIGF0dHIpOwkKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CgkvKgoJKiBBdHRyaWJ1dGUgImZpbmFsIi4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpbmFsIik7CQoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfREVGQVVMVDsKCX0gZWxzZSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZmluYWwiKTsKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJih0eXBlLT5mbGFncyksIAoJCS0xLCAtMSwgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTiwgLTEsCSAgICAKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTikgIT0gMCkgewoKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkgICAgJmRlcywgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCSAgICBOVUxMLCAiKCNhbGwgfCBMaXN0IG9mIChsaXN0IHwgdW5pb24gfCByZXN0cmljdGlvbikiLCAKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9ICAgIAogICAgLyogVE9ETzogQ2hlY2sgaWQuICovICAgIAogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkQ3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIG9sZFBhcmVudEl0ZW0gPSBjdHh0LT5wYXJlbnRJdGVtOwogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IHR5cGU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBzdWJ0eXBlID0gTlVMTDsgICAgICAgICAKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZXN0cmljdGlvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImxpc3QiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VMaXN0KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInVuaW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlVW5pb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsgICAgCiAgICBpZiAoKGNoaWxkICE9IE5VTEwpIHx8IChzdWJ0eXBlID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwgCgkgICAgJmRlcywgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsIAoJICAgICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGxpc3QgfCB1bmlvbikpIik7CiAgICB9CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gb2xkUGFyZW50SXRlbTsKICAgIGN0eHQtPmN0eHRUeXBlID0gb2xkQ3R4dFR5cGU7CiAgICBGUkVFX0FORF9OVUxMKGRlcykKCiAgICByZXR1cm4gKHR5cGUpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnJlZiA9IE5VTEwsICpyZWZOcyA9IE5VTEw7CiAgICBjaGFyIGJ1ZlsxMDBdOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBUT0RPOiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBldmVuIGlmIG5vIGl0ZW0gaXMgY3JlYXRlZCAKICAgICogKGkuZS4gbWluL21heE9jY3VycyA9PSAwKS4KICAgICovCiAgICBtaW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsICIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgaWYgKChtaW5PY2N1cnMgPT0gMCkgJiYgKG1heE9jY3VycyA9PSAwKSkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQlYTUxfU0NIRU1BUF9HUk9VUF9OT05BTUVfTk9SRUYsCgkJIkdyb3VwIGRlZmluaXRpb24gb3IgcGFydGljbGU6IE9uZSBvZiB0aGUgYXR0cmlidXRlcyBcIm5hbWVcIiAiCgkJIm9yIFwicmVmXCIgbXVzdCBiZSBwcmVzZW50LlxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQoJaWYgKHJlZk5zID09IE5VTEwpCgkgICAgcmVmTnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAiYW5vbmdyb3VwICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKICAgIH0KICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0dST1VQOwogICAgaWYgKHRvcExldmVsKSAKICAgICAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPnJlZiA9IHJlZjsKICAgIHR5cGUtPnJlZk5zID0gcmVmTnM7CiAgICB0eXBlLT5taW5PY2N1cnMgPSBtaW5PY2N1cnM7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSBtYXhPY2N1cnM7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCB0eXBlLAoJbm9kZSwgdHlwZS0+bWluT2NjdXJzLCB0eXBlLT5tYXhPY2N1cnMpOyAgICAKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0dST1VQX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJHcm91cCBkZWZpbml0aW9uIFwiJXNcIiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbGw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEFsbCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQWxsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiYWxsJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQUxMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAxLCAxLCAiKDAgfCAxKSIpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDEsIDEsIDEsICIxIik7ICAgIAoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CgkgICAgaWYgKHN1YnR5cGUtPm1pbk9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNoaWxkLCBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywKCSAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzIChtdXN0IGJlIDAgb3IgMSkuXG4iLAoJCSAgICAgTlVMTCwgTlVMTCk7CgkgICAgaWYgKHN1YnR5cGUtPm1heE9jY3VycyA+IDEpCgkgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUFYT0NDVVJTLAoJICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBtYXhPY2N1cnMgKG11c3QgYmUgMCBvciAxKS5cbiIsCgkJICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9BTExfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIjxhbGw+IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhbnVwRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSByb290IG9mIHRoZSBkb2N1bWVudC4KICoKICogcmVtb3ZlcyB1bndhbnRlZCBub2RlcyBpbiBhIHNjaGVtYXMgZG9jdW1lbnQgdHJlZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYW51cERvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgcm9vdCkKewogICAgeG1sTm9kZVB0ciBkZWxldGUsIGN1cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHJvb3QgPT0gTlVMTCkpIHJldHVybjsKCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICBkZWxldGUgPSBOVUxMOwogICAgY3VyID0gcm9vdDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgewogICAgICAgICAgICBpZiAoSVNfQkxBTktfTk9ERShjdXIpKSB7CiAgICAgICAgICAgICAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIGRlbGV0ZSA9IGN1cjsKICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBTa2lwIHRvIG5leHQgbm9kZQogICAgICAgICAqLwogICAgICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfUkVGX05PREUpICYmCiAgICAgICAgICAgICAgICAoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX05PREUpKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIHNraXBfY2hpbGRyZW46CiAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBkbyB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+cGFyZW50OwogICAgICAgICAgICBpZiAoY3VyID09IE5VTEwpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgaWYgKGN1ciA9PSByb290KSB7CiAgICAgICAgICAgICAgICBjdXIgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICB4bWxGcmVlTm9kZShkZWxldGUpOwogICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICB9Cn0KCgovKioKICogeG1sU2NoZW1hSW1wb3J0U2NoZW1hCiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hTG9jYXRpb246ICBhbiBVUkkgZGVmaW5pbmcgd2hlcmUgdG8gZmluZCB0aGUgaW1wb3J0ZWQgc2NoZW1hCiAqCiAqIGltcG9ydCBhIFhNTCBzY2hlbWEKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8KI2lmIDAKc3RhdGljIHhtbFNjaGVtYUltcG9ydFB0cgp4bWxTY2hlbWFJbXBvcnRTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24pCnsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIG5ld2N0eHQ7CgogICAgbmV3Y3R4dCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChuZXdjdHh0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KG5ld2N0eHQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICAvKiBLZWVwIHRoZSBzYW1lIGRpY3Rpb25uYXJ5IGZvciBwYXJzaW5nLCByZWFsbHkgKi8KICAgIHhtbERpY3RSZWZlcmVuY2UoY3R4dC0+ZGljdCk7CiAgICBuZXdjdHh0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIG5ld2N0eHQtPmluY2x1ZGVzID0gMDsKICAgIG5ld2N0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAobmV3Y3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKCiAgICB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMobmV3Y3R4dCwgY3R4dC0+ZXJyb3IsIGN0eHQtPndhcm5pbmcsCgkgICAgICAgICAgICAgICAgICAgICBjdHh0LT51c2VyRGF0YSk7CgogICAgaW1wb3J0ID0gKHhtbFNjaGVtYUltcG9ydCopIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAoaW1wb3J0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGltcG9ydGVkIHNjaGVtYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld2N0eHQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgbWVtc2V0KGltcG9ydCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKICAgIGltcG9ydC0+c2NoZW1hID0geG1sU2NoZW1hUGFyc2UobmV3Y3R4dCk7CgogICAgaWYgKGltcG9ydC0+c2NoZW1hID09IE5VTEwpIHsKICAgICAgICAvKiBGSVhNRSB1c2UgYW5vdGhlciBlcnJvciBlbnVtIGhlcmUgPyAqLwogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgICAgICAgICAgICJGYWlsZWQgdG8gaW1wb3J0IHNjaGVtYSBmcm9tIGxvY2F0aW9uIFwiJXNcIi5cbiIsCgkJICAgICAgc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld2N0eHQpOwoJLyogVGhlIHNjaGVtYUxvY2F0aW9uIGlzIGhlbGQgYnkgdGhlIGRpY3Rpb25hcnkuCglpZiAoaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHhtbENoYXIgKilpbXBvcnQtPnNjaGVtYUxvY2F0aW9uKTsKCSovCgl4bWxGcmVlKGltcG9ydCk7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChuZXdjdHh0KTsKICAgIHJldHVybiBpbXBvcnQ7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0FUVFIpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSOwoKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OOwogICAgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1QpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVDsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsKCiAgICBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfRVhURU5TSU9OKQoJc2NoZW1hLT5mbGFncyBePSBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX0VYVEVOU0lPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTikKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTjsKICAgIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9TVUJTVElUVVRJT04pCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0JMT0NLX0RFRkFVTFRfU1VCU1RJVFVUSU9OOwp9CgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImVsZW1lbnRGb3JtRGVmYXVsdCIpOyAgICAgCiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgl2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CglpZiAoeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdCh2YWwsICZzY2hlbWEtPmZsYWdzLCAKCSAgICBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgIT0gMCkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX0VMRU1GT1JNREVGQVVMVF9WQUxVRSwKCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgCgkJIihxdWFsaWZpZWQgfCB1bnF1YWxpZmllZCkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQogICAgfQogICAgCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImF0dHJpYnV0ZUZvcm1EZWZhdWx0Iik7ICAgICAKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCWlmICh4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0KHZhbCwgJnNjaGVtYS0+ZmxhZ3MsIAoJICAgIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKSAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfQVRUUkZPUk1ERUZBVUxUX1ZBTFVFLAoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCAKCQkiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CiAgICAKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWxEZWZhdWx0Iik7ICAgIAogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbCh2YWwsICYoc2NoZW1hLT5mbGFncyksIC0xLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OLAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT04sCgkgICAgLTEsCgkgICAgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNULAoJICAgIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT04pICE9IDApIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsCgkJIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIsCgkJdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCX0JICAgIAogICAgfQogICAgCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImJsb2NrRGVmYXVsdCIpOyAgICAgCiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7Cgl2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CglpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKHZhbCwgJihzY2hlbWEtPmZsYWdzKSwgLTEsCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9FWFRFTlNJT04sCgkgICAgWE1MX1NDSEVNQVNfQkxPQ0tfREVGQVVMVF9SRVNUUklDVElPTiwKCSAgICBYTUxfU0NIRU1BU19CTE9DS19ERUZBVUxUX1NVQlNUSVRVVElPTiwgLTEsIC0xKSAhPSAwKSB7CgkgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbiB8IHN1YnN0aXR1dGlvbikpIiwKCQl2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJfQkgICAgCiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMKICogQG5vZGVzOiAgdGhlIGxpc3Qgb2YgdG9wIGxldmVsIG5vZGVzCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGVzKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGVzID09IE5VTEwpKQogICAgICAgIHJldHVybjsKCiAgICBjaGlsZCA9IG5vZGVzOwogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJpbmNsdWRlIikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAicmVkZWZpbmUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImltcG9ydCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VJbXBvcnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgewoJICAgIGN0eHQtPmluY2x1ZGVzKys7CgkgICAgeG1sU2NoZW1hUGFyc2VJbmNsdWRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGN0eHQtPmluY2x1ZGVzLS07Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlZGVmaW5lIikpIHsKCSAgICBUT0RPCgl9CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibm90YXRpb24iKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgTlVMTCwgY2hpbGQsCgkJCSAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0NIRU1BU19DSElMRCwKCQkJICAgIlVuZXhwZWN0ZWQgZWxlbWVudCBcIiVzXCIgYXMgY2hpbGQgb2YgPHNjaGVtYT4uXG4iLAoJCQkgICBjaGlsZC0+bmFtZSwgTlVMTCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCXdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKCSAgICBhbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoc2NoZW1hLT5hbm5vdCA9PSBOVUxMKQoJCXNjaGVtYS0+YW5ub3QgPSBhbm5vdDsKCSAgICBlbHNlCgkJeG1sU2NoZW1hRnJlZUFubm90KGFubm90KTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJbXBvcnRQdHIKeG1sU2NoZW1hQWRkSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgeG1sSGFzaFRhYmxlUHRyICppbXBvcnRzLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hSW1wb3J0UHRyIHJldDsKCiAgICBpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJKmltcG9ydHMgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKCWlmICgqaW1wb3J0cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9GQUlMRURfQlVJTERfSU1QT1JULAoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJIkludGVybmFsIGVycm9yOiBmYWlsZWQgdG8gYnVpbGQgdGhlIGltcG9ydCB0YWJsZSIsCgkJTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KICAgIHJldCA9ICh4bWxTY2hlbWFJbXBvcnQqKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGltcG9ydCBzdHJ1Y3QiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9ICAgCiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAobnNOYW1lID09IE5VTEwpCgluc05hbWUgPSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0U7CiAgICB4bWxIYXNoQWRkRW50cnkoKmltcG9ydHMsIG5zTmFtZSwgcmV0KTsgIAoKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgY29uc3QgeG1sQ2hhciAqbG9jYXRpb24sCgkJCSAgeG1sRG9jUHRyICpkb2MsCgkJCSAgY29uc3QgeG1sQ2hhciAqKnRhcmdldE5hbWVzcGFjZSwKCQkJICBpbnQgYWJzb2x1dGUpCnsKICAgIHhtbFBhcnNlckN0eHRQdHIgcGFyc2VyQ3R4dDsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7CiAgICBjb25zdCB4bWxDaGFyICpuczsKICAgIHhtbE5vZGVQdHIgcm9vdDsKCiAgICAvKgogICAgKiBOT1RFOiBUaGlzIHdpbGwgYmUgdXNlZCBmb3IgPGltcG9ydD4sIDx4c2k6c2NoZW1hTG9jYXRpb24+IGFuZAogICAgKiA8eHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24+LgogICAgKi8KICAgICpkb2MgPSBOVUxMOwogICAgLyoKICAgICogR2l2ZW4gdGhhdCB0aGUgc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gaXMgb25seSBhIGhpbnQsIGl0IGlzIG9wZW4gCiAgICAqIHRvIGFwcGxpY2F0aW9ucyB0byBpZ25vcmUgYWxsIGJ1dCB0aGUgZmlyc3QgPGltcG9ydD4gZm9yIGEgZ2l2ZW4gCiAgICAqIG5hbWVzcGFjZSwgcmVnYXJkbGVzcyBvZiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2Ygc2NoZW1hTG9jYXRpb24sIGJ1dAogICAgKiBzdWNoIGEgc3RyYXRlZ3kgcmlza3MgbWlzc2luZyB1c2VmdWwgaW5mb3JtYXRpb24gd2hlbiBuZXcKICAgICogc2NoZW1hTG9jYXRpb25zIGFyZSBvZmZlcmVkLgogICAgKgogICAgKiBYU1YgKHZlciAyLjUtMikgZG9lcyB1c2UgdGhlIGZpcnN0IDxpbXBvcnQ+IHdoaWNoIHJlc29sdmVzIHRvIGEgdmFsaWQgc2NoZW1hLgogICAgKiBYZXJjZXMtSiAodmVyIDIuNS4xKSBpZ25vcmVzIGFsbCBidXQgdGhlIGZpcnN0IGdpdmVuIDxpbXBvcnQ+IC0gcmVnYXJkbGVzcyBpZgogICAgKiB2YWxpZCBvciBub3QuCiAgICAqIFdlIHdpbGwgZm9sbG93IFhTViBoZXJlLiAKICAgICovCiAgICBpZiAobG9jYXRpb24gPT0gTlVMTCkgewoJLyoKCSogU2NoZW1hIERvY3VtZW50IExvY2F0aW9uIFN0cmF0ZWd5OgoJKgoJKiAzIEJhc2VkIG9uIHRoZSBuYW1lc3BhY2UgbmFtZSwgaWRlbnRpZnkgYW4gZXhpc3Rpbmcgc2NoZW1hIGRvY3VtZW50LAoJKiBlaXRoZXIgYXMgYSByZXNvdXJjZSB3aGljaCBpcyBhbiBYTUwgZG9jdW1lbnQgb3IgYSA8c2NoZW1hPiBlbGVtZW50IAoJKiBpbmZvcm1hdGlvbiBpdGVtLCBpbiBzb21lIGxvY2FsIHNjaGVtYSByZXBvc2l0b3J5OyAKCSoKCSogNSBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIG5hbWVzcGFjZSBuYW1lIHRvIGxvY2F0ZSBzdWNoIGEgcmVzb3VyY2UuIAoJKgoJKiBOT1RFOiBUaG9zZSBzdGF0ZWdpZXMgYXJlIG5vdCBzdXBwb3J0ZWQsIHNvIHdlIHdpbGwgc2tpcC4KCSovCglyZXR1cm4gKDApOwogICAgfQogICAgaWYgKG5zTmFtZSA9PSBOVUxMKSAKCW5zID0gWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFOwogICAgZWxzZQoJbnMgPSBuc05hbWU7CiAgICAKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbnMpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CQoJLyoKCSogVGhlcmUgd2FzIGEgdmFsaWQgcmVzb3VyY2UgZm9yIHRoZSBzcGVjaWZpZWQgbmFtZXNwYWNlIGFscmVhZHkKCSogZGVmaW5lZCwgc28gc2tpcC4KCSogVE9ETzogVGhpcyBtaWdodCBiZSBjaGFuZ2VkIHNvbWVkYXkgdG8gYWxsb3cgaW1wb3J0IG9mCgkqIGNvbXBvbmVudHMgZnJvbSBtdWx0aXBsZSBkb2N1bWVudHMgZm9yIGEgc2luZ2xlIHRhcmdldCBuYW1lc3BhY2UuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0gCiAgIAogICAgLyoKICAgICogU2NoZW1hIERvY3VtZW50IExvY2F0aW9uIFN0cmF0ZWd5OiAKICAgICoKICAgICogMiBCYXNlZCBvbiB0aGUgbG9jYXRpb24gVVJJLCBpZGVudGlmeSBhbiBleGlzdGluZyBzY2hlbWEgZG9jdW1lbnQsIAogICAgKiBlaXRoZXIgYXMgYSByZXNvdXJjZSB3aGljaCBpcyBhbiBYTUwgZG9jdW1lbnQgb3IgYSA8c2NoZW1hPiBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtLCBpbiBzb21lIGxvY2FsIHNjaGVtYSByZXBvc2l0b3J5OyAgIAogICAgKgogICAgKiA0IEF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgbG9jYXRpb24gVVJJLCB0byBsb2NhdGUgYSByZXNvdXJjZSBvbiB0aGUgCiAgICAqIHdlYiB3aGljaCBpcyBvciBjb250YWlucyBvciByZWZlcmVuY2VzIGEgPHNjaGVtYT4gZWxlbWVudDsKICAgICogVE9ETzogSG1tLCBJIGRvbid0IGtub3cgaWYgdGhlIHJlZmVyZW5jZSBzdHVmZiBpbiA0LiB3aWxsIHdvcmsuCiAgICAqCiAgICAqLwogICAgaWYgKChhYnNvbHV0ZSA9PSAwKSAmJiAobm9kZSAhPSBOVUxMKSkgewoJeG1sQ2hhciAqYmFzZSwgKlVSSTsKCgliYXNlID0geG1sTm9kZUdldEJhc2Uobm9kZS0+ZG9jLCBub2RlKTsKCWlmIChiYXNlID09IE5VTEwpIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgbm9kZS0+ZG9jLT5VUkwpOwoJfSBlbHNlIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShsb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmIChVUkkgIT0gTlVMTCkgewoJICAgIGxvY2F0aW9uID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBVUkksIC0xKTsKCSAgICB4bWxGcmVlKFVSSSk7Cgl9CiAgICB9CiAgICBwYXJzZXJDdHh0ID0geG1sTmV3UGFyc2VyQ3R4dCgpOwogICAgaWYgKHBhcnNlckN0eHQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAieG1sU2NoZW1hUGFyc2VJbXBvcnQ6ICIKCSAgICAiYWxsb2NhdGluZyBhIHBhcnNlciBjb250ZXh0IiwgTlVMTCk7CglyZXR1cm4oLTEpOwogICAgfQkJCiAgICAKICAgICpkb2MgPSB4bWxDdHh0UmVhZEZpbGUocGFyc2VyQ3R4dCwgKGNvbnN0IGNoYXIgKikgbG9jYXRpb24sIAoJICAgIE5VTEwsIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CgogICAgLyoKICAgICogMi4xIFRoZSByZWZlcmVudCBpcyAoYSBmcmFnbWVudCBvZikgYSByZXNvdXJjZSB3aGljaCBpcyBhbiAKICAgICogWE1MIGRvY3VtZW50IChzZWUgY2xhdXNlIDEuMSksIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8gCiAgICAqIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluIGEgd2VsbC1mb3JtZWQgaW5mb3JtYXRpb24gCiAgICAqIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyB0byBhIHZhbGlkIHNjaGVtYS4KICAgICogVE9ETzogV2hhdCB0byBkbyB3aXRoIHRoZSAiZnJhZ21lbnQiIHN0dWZmPwogICAgKgogICAgKiAyLjIgVGhlIHJlZmVyZW50IGlzIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluIAogICAgKiBhIHdlbGwtZm9ybWVkIGluZm9ybWF0aW9uIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyAKICAgICogdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIE5PVEU6IDIuMiB3b24ndCBhcHBseSwgc2luY2Ugb25seSBYTUwgZG9jdW1lbnRzIHdpbGwgYmUgcHJvY2Vzc2VkIAogICAgKiBoZXJlLgogICAgKi8gICAgICAgCiAgICBpZiAoKmRvYyA9PSBOVUxMKSB7CQoJeG1sRXJyb3JQdHIgbGVycjsKCS8qCgkqIEl0IGlzICpub3QqIGFuIGVycm9yIGZvciB0aGUgYXBwbGljYXRpb24gc2NoZW1hIHJlZmVyZW5jZSAKCSogc3RyYXRlZ3kgdG8gZmFpbC4KCSogCgkqIElmIHRoZSBkb2MgaXMgTlVMTCBhbmQgdGhlIHBhcnNlciBlcnJvciBpcyBhbiBJTyBlcnJvciB3ZQoJKiB3aWxsIGFzc3VtZSB0aGF0IHRoZSByZXNvdXJjZSBjb3VsZCBub3QgYmUgbG9jYXRlZCBvciBhY2Nlc3NlZC4KCSoKCSogVE9ETzogVHJ5IHRvIGZpbmQgc3BlY2lmaWMgZXJyb3IgY29kZXMgdG8gcmVhY3Qgb25seSBvbgoJKiBsb2NhbGlzYXRpb24gZmFpbHVyZXMuCgkqCgkqIFRPRE8sIEZJWE1FOiBDaGVjayB0aGUgc3BlYzogaXMgYSBuYW1lc3BhY2UgYWRkZWQgdG8gdGhlIGltcG9ydGVkCgkqIG5hbWVzcGFjZXMsIGV2ZW4gaWYgdGhlIHNjaGVtYUxvY2F0aW9uIGRpZCBub3QgcHJvdmlkZQoJKiBhIHJlc291cmNlPyBJIGd1ZXNzIHNvLCBzaW5jZSBvbWl0dGluZyB0aGUgInNjaGVtYUxvY2F0aW9uIgoJKiBhdHRyaWJ1dGUsIGltcG9ydHMgYSBuYW1lc3BhY2UgYXMgd2VsbC4KCSovCglsZXJyID0geG1sR2V0TGFzdEVycm9yKCk7CglpZiAoKGxlcnIgIT0gTlVMTCkgJiYgKGxlcnItPmRvbWFpbiA9PSBYTUxfRlJPTV9JTykpIHsJCgkgICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CgkgICAgcmV0dXJuKDApOwoJfQoKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJGYWlsZWQgdG8gcGFyc2UgdGhlIHJlc291cmNlICclcycgZm9yIGltcG9ydCIsCgkgICAgbG9jYXRpb24pOwoJeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CglyZXR1cm4oWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEpOwogICAgfQogICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CiAgICAKICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudCgqZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIGxvY2F0aW9uKTsJCgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0JCiAgICAKICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CQogICAgCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGEgWE1MIHNjaGVtYSBkb2N1bWVudCIsCgkgICAgbG9jYXRpb24pOwkKCXhtbEZyZWVEb2MoKmRvYyk7CgkqZG9jID0gTlVMTDsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEpOwogICAgfQkKICAgICp0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIHJvb3QsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiBJbXBvcnQgQ29uc3RyYWludHMgYW5kIFNlbWFudGljcwogICAgKi8gICAgCiAgICBpZiAobnNOYW1lID09IE5VTEwpIHsKCWlmICgqdGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIFhNTCBzY2hlbWEgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGV4cGVjdGVkICIKCQkidG8gaGF2ZSBhIHRhcmdldCBuYW1lc3BhY2U7IHRoaXMgZGlmZmVycyBmcm9tICIKCQkiaXRzIHRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJyIsICp0YXJnZXROYW1lc3BhY2UpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMik7Cgl9CiAgICB9IGVsc2UgewoJaWYgKCp0YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgWE1MIHNjaGVtYSB0byBiZSBpbXBvcnRlZCBpcyBleHBlY3RlZCB0byBoYXZlIGEgdGFyZ2V0ICIKCQkibmFtZXNwYWNlIG9mICclcyciLCBuc05hbWUpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSk7Cgl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCgqdGFyZ2V0TmFtZXNwYWNlLCBuc05hbWUpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18xLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBYTUwgc2NoZW1hIHRvIGJlIGltcG9ydGVkIGlzIGV4cGVjdGVkIHRvIGhhdmUgYSAiCgkJInRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJzsgdGhpcyBkaWZmZXJzIGZyb20gIgoJCSJpdHMgdGFyZ2V0IG5hbWVzcGFjZSBvZiAnJXMnIiwgCgkJbnNOYW1lLCAqdGFyZ2V0TmFtZXNwYWNlLCBOVUxMKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEpOwoJfQogICAgfQoKICAgIGltcG9ydCA9IHhtbFNjaGVtYUFkZEltcG9ydChjdHh0LCAmKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMpLCBuc05hbWUpOwogICAgaWYgKGltcG9ydCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCwJICAgIAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYywgIgoJICAgICJmYWlsZWQgdG8gYnVpbGQgaW1wb3J0IHRhYmxlIiwgTlVMTCk7Cgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBsb2NhdGlvbjsKICAgIGltcG9ydC0+ZG9jID0gKmRvYzsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUltcG9ydDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW1wb3J0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYgCiAqIG5vdCB2YWxpZCBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvci4gCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgIAogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UsICpvbGRUTlMsICp1cmw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sTm9kZVB0ciByb290OwogICAgaW50IGZsYWdzLCByZXQgPSAwOwoKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIE5VTEwsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0JCiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAKCSJuYW1lc3BhY2UiLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCAKCSZuYW1lc3BhY2UpICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCSAgICAKCSAgICBYTUxfU0NIRU1BUF9JTVBPUlRfTkFNRVNQQUNFX05PVF9VUkksIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIAoJICAgIE5VTEwsIG5hbWVzcGFjZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0lNUE9SVF9OQU1FU1BBQ0VfTk9UX1VSSSk7CiAgICB9CgogICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIAoJInNjaGVtYUxvY2F0aW9uIiwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgCgkmc2NoZW1hTG9jYXRpb24pICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCSAgICAKCSAgICBYTUxfU0NIRU1BUF9JTVBPUlRfU0NIRU1BX05PVF9VUkksIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIAoJICAgIE5VTEwsIG5hbWVzcGFjZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0lNUE9SVF9TQ0hFTUFfTk9UX1VSSSk7CiAgICB9ICAgIAogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZSBhbm5vdGF0aW9uIGhlcmUgaXMgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTVBPUlRfQ0hJTEQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIC8qCiAgICAqIEFwcGx5IGFkZGl0aW9uYWwgY29uc3RyYWludHMuCiAgICAqLwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKSB7CgkvKgoJKiAxLjEgSWYgdGhlIG5hbWVzcGFjZSBbYXR0cmlidXRlXSBpcyBwcmVzZW50LCB0aGVuIGl0cyC3YWN0dWFsIHZhbHVltyAKCSogbXVzdCBub3QgbWF0Y2ggdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBlbmNsb3NpbmcgPHNjaGVtYT4ncyAKCSogdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmICh4bWxTdHJFcXVhbChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbmFtZXNwYWNlKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzFfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IG5vdCBtYXRjaCAiCgkJInRoZSB0YXJnZXQgbmFtZXNwYWNlICclcycgb2YgdGhlIGltcG9ydGluZyBzY2hlbWEiLAoJCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMV8xKTsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiAxLjIgSWYgdGhlIG5hbWVzcGFjZSBbYXR0cmlidXRlXSBpcyBub3QgcHJlc2VudCwgdGhlbiB0aGUgZW5jbG9zaW5nIAoJKiA8c2NoZW1hPiBtdXN0IGhhdmUgYSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IGJlIGV4aXN0ZW50IGlmICIKCQkidGhlIGltcG9ydGluZyBzY2hlbWEgaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCU5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIpOwoJfQogICAgfQogICAgLyoKICAgICogTG9jYXRlIGFuZCBhcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKGN0eHQsIHNjaGVtYSwgbm9kZSwgbmFtZXNwYWNlLCAKCXNjaGVtYUxvY2F0aW9uLCAmZG9jLCAmdGFyZ2V0TmFtZXNwYWNlLCAwKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKGRvYyAhPSBOVUxMKQoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCXJldHVybiAocmV0KTsKICAgIH0gZWxzZSBpZiAoZG9jICE9IE5VTEwpIHsgICAgICAgCgkvKgoJKiBTYXZlIGFuZCByZXNldCB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCgl1cmwgPSBjdHh0LT5VUkw7ICAKCS8qIFRPRE86IElzIHVzaW5nIHRoZSBkb2MtPlVSTCBoZXJlIGNvcnJlY3Q/ICovCgljdHh0LT5VUkwgPSBkb2MtPlVSTDsKCWZsYWdzID0gc2NoZW1hLT5mbGFnczsKCW9sZFROUyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJLyoKCSogUGFyc2UgdGhlIHNjaGVtYS4KCSovCglyb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKCXhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMoY3R4dCwgc2NoZW1hLCByb290KTsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChjdHh0LCBzY2hlbWEsIHJvb3QtPmNoaWxkcmVuKTsKCS8qCgkqIFJlc3RvcmUgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJc2NoZW1hLT5mbGFncyA9IGZsYWdzOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBvbGRUTlM7CgljdHh0LT5VUkwgPSB1cmw7CiAgICB9CiAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUluY2x1ZGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEluY2x1ZGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uLCAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZTsKICAgIGludCB3YXNDb252ZXJ0aW5nTnMgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IHNhdmVGbGFnczsKCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIC8qCiAgICAgKiBQcmVsaW1pbmFyeSBzdGVwLCBleHRyYWN0IHRoZSBVUkktUmVmZXJlbmNlIGZvciB0aGUgaW5jbHVkZSBhbmQKICAgICAqIG1ha2UgYW4gVVJJIGZyb20gdGhlIGJhc2UuCiAgICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICB4bWxDaGFyICpiYXNlID0gTlVMTDsKICAgICAgICB4bWxDaGFyICp1cmkgPSBOVUxMOwoKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgTlVMTCwgYXR0ciwKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCAmc2NoZW1hTG9jYXRpb24pICE9IDApCgkgICAgcmV0dXJuICgtMSk7CgliYXNlID0geG1sTm9kZUdldEJhc2Uobm9kZS0+ZG9jLCBub2RlKTsKCWlmIChiYXNlID09IE5VTEwpIHsKCSAgICB1cmkgPSB4bWxCdWlsZFVSSShzY2hlbWFMb2NhdGlvbiwgbm9kZS0+ZG9jLT5VUkwpOwoJfSBlbHNlIHsKCSAgICB1cmkgPSB4bWxCdWlsZFVSSShzY2hlbWFMb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmICh1cmkgIT0gTlVMTCkgewoJICAgIHNjaGVtYUxvY2F0aW9uID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB1cmksIC0xKTsKCSAgICB4bWxGcmVlKHVyaSk7Cgl9CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOQ0xVREVfU0NIRU1BX05PX1VSSSwgCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgInNjaGVtYUxvY2F0aW9uIiwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbnMgaGVyZSBhcmUgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fSU5DTFVERV9DSElMRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaXJzdCBzdGVwIGlzIHRvIHBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBpbnRvIGFuIERPTS9JbmZvc2V0CiAgICAgKi8KICAgIGRvYyA9IHhtbFJlYWRGaWxlKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgIGlmIChkb2MgPT0gTlVMTCkgewoJLyoKCSogVE9ETzogSXQgaXMgbm90IGFuIGVycm9yIGZvciB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIAoJKiBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSB0byBmYWlsIHRvIHJlc29sdmUgaXQgYWxsLCBpbiB3aGljaCAKCSogY2FzZSBubyBjb3JyZXNwb25kaW5nIGluY2x1c2lvbiBpcyBwZXJmb3JtZWQuIAoJKiBTbyBkbyB3ZSBuZWVkIGEgd2FybmluZyByZXBvcnQgaGVyZT8KCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgCgkgICAgIkZhaWxlZCB0byBsb2FkIHRoZSBkb2N1bWVudCAnJXMnIGZvciBpbmNsdXNpb24iLCBzY2hlbWFMb2NhdGlvbik7CglyZXR1cm4oLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGVuIGV4dHJhY3QgdGhlIHJvb3Qgb2YgdGhlIHNjaGVtYQogICAgICovCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGluY2x1ZGVkIGRvY3VtZW50ICclcycgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIHNjaGVtYUxvY2F0aW9uKTsJCQoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIENoZWNrIHRoZSBzY2hlbWFzIHRvcCBsZXZlbCBlbGVtZW50CiAgICAgKi8KICAgIGlmICghSVNfU0NIRU1BKHJvb3QsICJzY2hlbWEiKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGRvY3VtZW50ICclcycgdG8gYmUgaW5jbHVkZWQgaXMgbm90IGEgc2NoZW1hIGRvY3VtZW50IiwgCgkgICAgc2NoZW1hTG9jYXRpb24pOwoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgCiAgICB0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIHJvb3QsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIC8qCiAgICAqIDIuMSBTSUkgaGFzIGEgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLCBhbmQgaXRzILdhY3R1YWwgCiAgICAqIHZhbHVltyBpcyBpZGVudGljYWwgdG8gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0YXJnZXROYW1lc3BhY2UgCiAgICAqIFthdHRyaWJ1dGVdIG9mIFNJSZIgKHdoaWNoIG11c3QgaGF2ZSBzdWNoIGFuIFthdHRyaWJ1dGVdKS4KICAgICovCiAgICBpZiAodGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCWlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRlZCBzY2hlbWEgIgoJCSInJXMnIGhhcyB0byBiZSBhYnNlbnQsIHNpbmNlIHRoZSBpbmNsdWRpbmcgc2NoZW1hICIKCQkiaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLCAKCQlzY2hlbWFMb2NhdGlvbik7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJICAgIHJldHVybiAoLTEpOwoJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwodGFyZ2V0TmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREUsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgJyVzJyBvZiB0aGUgaW5jbHVkZWQgc2NoZW1hICclcycgIgoJCSJkaWZmZXJzIGZyb20gJyVzJyBvZiB0aGUgaW5jbHVkaW5nIHNjaGVtYSIsIAoJCXRhcmdldE5hbWVzcGFjZSwgc2NoZW1hTG9jYXRpb24sIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB4bWxGcmVlRG9jKGRvYyk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9IGVsc2UgaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsgICAgIAkKCWlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSA9PSAwKSB7CgkgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsJICAgIAoJfSBlbHNlCgkgICAgd2FzQ29udmVydGluZ05zID0gMTsKICAgIH0KICAgIC8qCiAgICAgKiByZWdpc3RlciB0aGUgaW5jbHVkZQogICAgICovCiAgICBpbmNsdWRlID0gKHhtbFNjaGVtYUluY2x1ZGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSW5jbHVkZSkpOwogICAgaWYgKGluY2x1ZGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgaW5jbHVkZWQgc2NoZW1hIiwgTlVMTCk7Cgl4bWxGcmVlRG9jKGRvYyk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgbWVtc2V0KGluY2x1ZGUsIDAsIHNpemVvZih4bWxTY2hlbWFJbmNsdWRlKSk7CiAgICBpbmNsdWRlLT5zY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKICAgIGluY2x1ZGUtPmRvYyA9IGRvYzsKICAgIGluY2x1ZGUtPm5leHQgPSBzY2hlbWEtPmluY2x1ZGVzOwogICAgc2NoZW1hLT5pbmNsdWRlcyA9IGluY2x1ZGU7CgogICAgLyoKICAgICAqIHBhcnNlIHRoZSBkZWNsYXJhdGlvbnMgaW4gdGhlIGluY2x1ZGVkIGZpbGUgbGlrZSBpZiB0aGV5CiAgICAgKiB3ZXJlIGluIHRoZSBvcmlnaW5hbCBmaWxlLgogICAgICovICAgIAogICAgLyoKICAgICogVE9ETzogVGhlIGNvbXBsZXRlIHZhbGlkYXRpb24gb2YgdGhlIDxzY2hlbWE+IGVsZW1lbnQgaXMgbm90IGRvbmUuCiAgICAqLwogICAgLyogICAgCiAgICAqIFRoZSBkZWZhdWx0IHZhbHVlcyAoImJsb2NrRGVmYXVsdCIsICJlbGVtZW50Rm9ybURlZmF1bHQiLCBldGMuKQogICAgKiBhcmUgc2V0IHRvIHRoZSB2YWx1ZXMgb2YgdGhlIGluY2x1ZGVkIHNjaGVtYSBhbmQgcmVzdG9yZWQgYWZ0ZXJ3YXJkcy4KICAgICovICAgIAogICAgc2F2ZUZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIHhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMoY3R4dCwgc2NoZW1hLCByb290KTsKICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCByb290LT5jaGlsZHJlbik7CiAgICBzY2hlbWEtPmZsYWdzID0gc2F2ZUZsYWdzOwogICAgLyoKICAgICogUmVtb3ZlIHRoZSBjb252ZXJ0aW5nIGZsYWcuCiAgICAqLwogICAgaWYgKCh3YXNDb252ZXJ0aW5nTnMgPT0gMCkgJiYgCgkoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSkKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlM7CiAgICByZXR1cm4gKDEpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDaG9pY2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENob2ljZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ2hvaWNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiY2hvaWNlICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NIT0lDRTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIHR5cGUsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgdHlwZS0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAibm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAKCSIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKICAgICAgICBzdWJ0eXBlID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbnkoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0KICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkvKiBUT0RPOiBlcnJvciBjb2RlLiAqLwoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0NIT0lDRV9DSElMRCwKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAoZWxlbWVudCB8IGdyb3VwIHwgY2hvaWNlIHwgc2VxdWVuY2UgfCBhbnkpKikiKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2VxdWVuY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiNzZXEgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgIm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgCgkiKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGN0eHQtPmNvbnRhaW5lciA9IChjb25zdCB4bWxDaGFyICopIG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSkgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUFueShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TRVFVRU5DRV9DSElMRCwKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAoZWxlbWVudCB8IGdyb3VwIHwgY2hvaWNlIHwgc2VxdWVuY2UgfCBhbnkpKikiKTsKICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgUmVzdHJpY3Rpb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOyAgICAKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiNyZXN0ciAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT047CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJhc2UiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImJhc2UiLgogICAgKi8KICAgIHR5cGUtPmJhc2UgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgImJhc2UiLCAmKHR5cGUtPmJhc2VOcykpOwogICAgaWYgKCh0eXBlLT5iYXNlID09IE5VTEwpICYmIAoJKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSkgewoJLyogVE9ETzogVGhpbmsgYWJvdXQgdGhlIGVycm9yIGNvZGUuICovCgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRVNUUklDVElPTl9OT05BTUVfTk9SRUYsIAoJICAgIE5VTEwsIHR5cGUsIG5vZGUsICJiYXNlIiwgTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCX0KICAgIH0gZWxzZSBpZiAoY3R4dC0+Y3R4dFR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCQkvKiAKCQkqIHNyYy1yZXN0cmljdGlvbi1iYXNlLW9yLXNpbXBsZVR5cGUKCQkqIEVpdGhlciB0aGUgYmFzZSBbYXR0cmlidXRlXSBvciB0aGUgc2ltcGxlVHlwZSBbY2hpbGRdIG9mIHRoZSAKCQkqIDxyZXN0cmljdGlvbj4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4gCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU1RSSUNUSU9OX0JBU0VfT1JfU0lNUExFVFlQRSwKCQkgICAgTlVMTCwgTlVMTCwgdHlwZS0+bm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICdiYXNlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQlzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCQl0eXBlLT5iYXNlVHlwZSA9IHN1YnR5cGU7CgkgICAgfQkgICAgICAgIAoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0JICAgICAgICAJCiAgICB9CiAgICBpZiAoKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgbGFzdGZhY2V0ID0gTlVMTDsJCgkJCgkvKgoJKiBBZGQgdGhlIGZhY2V0cyB0byB0aGUgcGFyZW50IHNpbXBsZVR5cGUvY29tcGxleFR5cGUuCgkqLwoJLyoKCSogVE9ETzogRGF0YXR5cGVzOiA0LjEuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb24gb2YgCgkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAoJKiAqU2luZ2xlIEZhY2V0IFZhbHVlKgoJKi8KCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAibWluSW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtYXhJbmNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4RXhjbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInRvdGFsRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImZyYWN0aW9uRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInBhdHRlcm4iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZW51bWVyYXRpb24iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAid2hpdGVTcGFjZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJsZW5ndGgiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4TGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkxlbmd0aCIpKSkgewoJICAgIGZhY2V0ID0geG1sU2NoZW1hUGFyc2VGYWNldChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoZmFjZXQgIT0gTlVMTCkgewoJCWlmIChsYXN0ZmFjZXQgPT0gTlVMTCkKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZhY2V0cyA9IGZhY2V0OwkJCQoJCWVsc2UKCQkgICAgbGFzdGZhY2V0LT5uZXh0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCS8qCgkqIENyZWF0ZSBsaW5rcyBmb3IgZGVyaXZhdGlvbiBhbmQgdmFsaWRhdGlvbi4KCSovCSAgICAKCWlmIChsYXN0ZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbmssIGxhc3RGYWNldExpbmsgPSBOVUxMOwoKCSAgICBmYWNldCA9IGN0eHQtPmN0eHRUeXBlLT5mYWNldHM7CgkgICAgZG8gewkJICAgIAoJCWZhY2V0TGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkJaWYgKGZhY2V0TGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJICAgIHhtbEZyZWUoZmFjZXRMaW5rKTsKCQkgICAgcmV0dXJuIChOVUxMKTsKCQl9CQoJCWZhY2V0TGluay0+ZmFjZXQgPSBmYWNldDsKCQlmYWNldExpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0RmFjZXRMaW5rID09IE5VTEwpIAoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmFjZXRTZXQgPSBmYWNldExpbms7CQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQllbHNlCgkJICAgIGxhc3RGYWNldExpbmstPm5leHQgPSBmYWNldExpbms7CgkJbGFzdEZhY2V0TGluayA9IGZhY2V0TGluazsKCQlmYWNldCA9IGZhY2V0LT5uZXh0OwoJICAgIH0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJfQogICAgfSAgICAKICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewoJICAgIGN0eHQtPmN0eHRUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyogVE9ETzogVGhpbmsgYWJvdXQgdGhlIGVycm9yIGNvZGUuICovCglpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9VTktOT1dOX1JFU1RSSUNUSU9OX0NISUxELCAKCQlOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiYW5ub3RhdGlvbj8sIChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKCX0gZWxzZSBpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpIHsKCSAgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfVU5LTk9XTl9SRVNUUklDVElPTl9DSElMRCwgCgkJTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKHNpbXBsZVR5cGU/LCAobWluRXhjbHVzaXZlIHwgbWluSW5jbHVzaXZlIHwgIgoJCSJtYXhFeGNsdXNpdmUgfCBtYXhJbmNsdXNpdmUgfCB0b3RhbERpZ2l0cyB8IGZyYWN0aW9uRGlnaXRzIHwgIgoJCSJsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCAiCgkJInBhdHRlcm4pKik/LCAoKGF0dHJpYnV0ZSB8IGF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSIpOwoJfSBlbHNlIHsKCSAgICAvKiBTaW1wbGUgdHlwZSAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1VOS05PV05fUkVTVFJJQ1RJT05fQ0hJTEQsIAoJCU5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPywgKG1pbkV4Y2x1c2l2ZSB8IG1pbkluY2x1c2l2ZSB8ICIKCQkibWF4RXhjbHVzaXZlIHwgbWF4SW5jbHVzaXZlIHwgdG90YWxEaWdpdHMgfCBmcmFjdGlvbkRpZ2l0cyB8ICIKCQkibGVuZ3RoIHwgbWluTGVuZ3RoIHwgbWF4TGVuZ3RoIHwgZW51bWVyYXRpb24gfCB3aGl0ZVNwYWNlIHwgIgoJCSJwYXR0ZXJuKSopKSIpOwoJfQogICAgfSAgICAgICAKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgRXh0ZW5zaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiZXh0ZW5zaW9uICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOyAgICAKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIHR5cGUtPmJhc2UgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgImJhc2UiLCAmKHR5cGUtPmJhc2VOcykpOwogICAgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9FWFRFTlNJT05fTk9fQkFTRSwKCSAgICAiPGV4dGVuc2lvbj46IFRoZSBhdHRyaWJ1dGUgXCJiYXNlXCIgaXMgbWlzc2luZy5cbiIsIAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgaWYgKChjdHh0LT5jdHh0VHlwZSAhPSBOVUxMKSAmJgoJKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSkgewoJY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewkgICAgCgkgICAgY3R4dC0+Y3R4dFR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gCgkJeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9FWFRFTlNJT05fQ0hJTEQsCgkgICAgIjxleHRlbnNpb24+IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLCB0eXBlLT5uYW1lLAoJICAgIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlQ29udGVudCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBvbGRQYXJlbnRJdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJzaW1wbGVDb250ZW50ICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOyAgICAKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBvbGRQYXJlbnRJdGVtID0gY3R4dC0+cGFyZW50SXRlbTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgc3VidHlwZSA9IE5VTEw7ICAgIAogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZXh0ZW5zaW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0lNUExFQ09OVEVOVF9DSElMRCwKCSAgICAiPHNpbXBsZUNvbnRlbnQ+IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IG9sZFBhcmVudEl0ZW07CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBvbGRQYXJlbnRJdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjQ0MgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDsKICAgIHR5cGUtPm5vZGUgPSBub2RlOyAgICAKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1peGVkIikpKSAKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQkKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIC8qCiAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgJ21peGVkJy4KICAgICovCiAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgTlVMTCwgdHlwZSwgbm9kZSwgIm1peGVkIiwgMCkpICB7CglpZiAoKGN0eHQtPmN0eHRUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpID09IDApCgkgICAgY3R4dC0+Y3R4dFR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQ7CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBvbGRQYXJlbnRJdGVtID0gY3R4dC0+cGFyZW50SXRlbTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CiAgICB9CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gb2xkUGFyZW50SXRlbTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4IFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICphdHRyVmFsdWU7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOyAvKiBUaGUgcmVwb3J0ZWQgZGVzaWduYXRpb24uICovCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoKICAgIGlmICh0b3BMZXZlbCkgewoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIAoJCSh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0NULCBOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0NULCBOVUxMLCBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKHRvcExldmVsID09IDApIHsKICAgICAgICBjaGFyIGJ1Zls0MF07CgoJLyoKCSogUGFyc2UgYXMgbG9jYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjQ1QgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgKGNvbnN0IHhtbENoYXIgKilidWYsIE5VTEwsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOwoJLyoKCSogVE9ETzogV2UgbmVlZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCQogICAgfSBlbHNlIHsJCgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwkKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsJCgkvKiAKCSogU2V0IGRlZmF1bHRzLgoJKi8KCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfREVGQVVMVDsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfREVGQVVMVDsKICAgIH0gCiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSB7CgkJLyoKCQkqIEF0dHJpYnV0ZSAiaWQiLgoJCSovCgkJdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1peGVkIikpIHsKCQkvKgoJCSogQXR0cmlidXRlICJtaXhlZCIuCgkJKi8KCQlpZiAoeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoY3R4dCwgJmRlcywgdHlwZSwgCgkJICAgICh4bWxOb2RlUHRyKSBhdHRyKSkKCQkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsgCQkKCSAgICB9IGVsc2UgaWYgKHRvcExldmVsKSB7CQkKCQkvKgoJCSogQXR0cmlidXRlcyBvZiBnbG9iYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb25zLgoJCSovCgkJaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpIHsKCQkgICAgLyogUGFzcy4gKi8KCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJhYnN0cmFjdCIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJhYnN0cmFjdCIuCgkJICAgICovCgkJICAgIGlmICh4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZShjdHh0LCAmZGVzLCB0eXBlLCAKCQkJKHhtbE5vZGVQdHIpIGF0dHIpKQkJICAgIAoJCQl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImZpbmFsIi4KCQkgICAgKi8KCQkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgCgkJCSh4bWxOb2RlUHRyKSBhdHRyKTsKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsIAoJCQkmKHR5cGUtPmZsYWdzKSwgCgkJCS0xLCAKCQkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04sIAoJCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OLCAKCQkJLTEsIC0xLCAtMSkgIT0gMCkgCgkJICAgIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCQkgICAgJmRlcywgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCQkgICAgTlVMTCwgCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpIiwgCgkJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCSAgICB9CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmxvY2siKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiYmxvY2siLgoJCSAgICAqLwkJCQoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAKCQkJKHhtbE5vZGVQdHIpIGF0dHIpOwkgICAgCgkJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwgCgkJCS0xLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX0VYVEVOU0lPTiwKCQkJWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19SRVNUUklDVElPTiwgCgkJCS0xLCAtMSwgLTEpICE9IDApIHsKCQkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICAmZGVzLCB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkJICAgIE5VTEwsIAoJCQkgICAgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKSAiLCAKCQkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIH0KCQl9IGVsc2UgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSAgICAmZGVzLCB0eXBlLCBhdHRyKTsKCQl9CgkgICAgfSBlbHNlIHsJICAgIAoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICAmZGVzLCB0eXBlLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSZkZXMsIHR5cGUsIGF0dHIpOwkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfSAgICAgICAKICAgIC8qIAogICAgKiBTZXQgYXMgZGVmYXVsdCBmb3IgYXR0cmlidXRlIHdpbGRjYXJkcy4KICAgICogVGhpcyB3aWxsIGJlIG9ubHkgY2hhbmdlZCBpZiBhIGNvbXBsZXggdHlwZQogICAgKiBpbmhlcml0cyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQgZnJvbSBhIGJhc2UgdHlwZS4KICAgICovCiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOyAgICAKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVDb250ZW50IikpIHsKCS8qIAoJKiAzLjQuMyA6IDIuMiAgCgkqIFNwZWNpZnlpbmcgbWl4ZWQ9J3RydWUnIHdoZW4gdGhlIDxzaW1wbGVDb250ZW50PgoJKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4gaGFzIG5vIGVmZmVjdAoJKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4Q29udGVudCIpKSB7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwoJLyoKCSogUGFyc2UgbW9kZWwgZ3JvdXBzLgoJKi8KICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCS8qCgkqIFBhcnNlIGF0dHJpYnV0ZSBkZWNscy9yZWZzLgoJKi8KICAgICAgICBjaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsIHR5cGUpOwoJLyoKCSogUGFyc2UgYXR0cmlidXRlIHdpbGRjYXJkLgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewkgICAgCgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJICAgICZkZXMsIHR5cGUsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChzaW1wbGVDb250ZW50IHwgY29tcGxleENvbnRlbnQgfCAiCgkgICAgIigoZ3JvdXAgfCBhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSk/LCAoKGF0dHJpYnV0ZSB8ICIKCSAgICAiYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpKSkiKTsKICAgIH0KICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIGN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIGRlZmluaXRpb24gZnJvbSBhIG5vZGUgc2V0CiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2VTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdmFsOwogICAgaW50IG5iZXJyb3JzOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIC8qCiAgICAqIFRoaXMgb25lIGlzIGNhbGxlZCBieSB4bWxTY2hlbWFQYXJzZSBvbmx5IGFuZCBpcyB1c2VkIGlmCiAgICAqIHRoZSBzY2hlbWEgdG8gYmUgcGFyc2VkIHdhcyBzcGVjaWZpZWQgdmlhIHRoZSBBUEk7IGkuZS4gbm90CiAgICAqIGF1dG9tYXRpY2FsbHkgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSBkb2N1bWVudC4KICAgICovCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGlmIChJU19TQ0hFTUEobm9kZSwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwoKICAgICAgICBzY2hlbWEgPSB4bWxTY2hlbWFOZXdTY2hlbWEoY3R4dCk7CiAgICAgICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwoJLyoKCSogRGlzYWJsZSBidWlsZCBvZiBsaXN0IG9mIGl0ZW1zLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidGFyZ2V0TmFtZXNwYWNlIik7IAkJCglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZ2YWwpOwoJICAgIC8qCgkgICAgKiBUT0RPOiBTaG91bGQgd2UgcHJvY2VlZCB3aXRoIGFuIGludmFsaWQgdGFyZ2V0IG5hbWVzcGFjZT8KCSAgICAqLwoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCX0gZWxzZSB7CgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBOVUxMOwoJfQoJLyoKCSogQWRkIHRoZSBjdXJyZW50IG5zIG5hbWUgYW5kIGxvY2F0aW9uIHRvIHRoZSBpbXBvcnQgdGFibGU7CgkqIHRoaXMgaXMgbmVlZGVkIHRvIGhhdmUgYSBjb25zaXN0ZW50IG1lY2hhbmlzbSwgcmVnYXJkbGVzcwoJKiBpZiBhbGwgc2NoZW1hdGEgYXJlIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5IGZpcmVkIGJ5IHRoZQoJKiBpbnN0YW5jZSBvciBpZiB0aGUgc2NoZW1hIHRvIGJlIHVzZWQgd2FzIHNwZWNpZmllZCB2aWEKCSogdGhlIEFQSS4KCSovCglpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQoY3R4dCwgJihzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSwKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CglpZiAoaW1wb3J0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkJTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBhcnNlU2NoZW1hLCAiCgkJImZhaWxlZCB0byBhZGQgYW4gaW1wb3J0IGVudHJ5IiwgTlVMTCk7CgkgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwoJICAgIHNjaGVtYSA9IE5VTEw7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCWltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBjdHh0LT5VUkw7CgkvKgoJKiBOT1RFOiBXZSB3b24ndCBzZXQgdGhlIGRvYyBoZXJlLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBmcmVlZAoJKiBpZiB0aGUgaW1wb3J0IHN0cnVjdCBpcyBmcmVlZC4KCSogaW1wb3J0LT5kb2MgPSBjdHh0LT5kb2M7CgkqLwoKCS8qIFRPRE86IENoZWNrIGlkLiAqLwogICAgICAgIHNjaGVtYS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoJeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgInZlcnNpb24iLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19UT0tFTiksICYoc2NoZW1hLT52ZXJzaW9uKSk7CgoJeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyhjdHh0LCBzY2hlbWEsIG5vZGUpOwkKICAgICAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgbm9kZS0+Y2hpbGRyZW4pOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxEb2NQdHIgZG9jOwoKCWRvYyA9IG5vZGUtPmRvYzsKCiAgICAgICAgaWYgKChkb2MgIT0gTlVMTCkgJiYgKGRvYy0+VVJMICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIlRoZSBmaWxlIFwiJXNcIiBpcyBub3QgYSBYTUwgc2NoZW1hLlxuIiwgZG9jLT5VUkwsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiVGhlIGZpbGUgaXMgbm90IGEgWE1MIHNjaGVtYS5cbiIsIE5VTEwsIE5VTEwpOwoJfQoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwogICAgICAgICAgICBzY2hlbWEgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIGlmIChzY2hlbWEgIT0gTlVMTCkKCXNjaGVtYS0+Y291bnRlciA9IGN0eHQtPmNvdW50ZXI7CiAgICBjdHh0LT5uYmVycm9ycyA9IG5iZXJyb3JzOwojaWZkZWYgREVCVUcKICAgIGlmIChzY2hlbWEgPT0gTlVMTCkKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlKCkgZmFpbGVkXG4iKTsKI2VuZGlmCiAgICByZXR1cm4gKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW5nIHVzaW5nIFNjaGVtYXMJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlSZWFkaW5nL1dyaXRpbmcgU2NoZW1hcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZiAwIC8qIFdpbGwgYmUgZW5hYmxlZCBpZiBpdCBpcyBjbGVhciB3aGF0IG9wdGlvbnMgYXJlIG5lZWRlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVBhcnNlckN0eHRTZXRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG9wdGlvbnM6IGEgY29tYmluYXRpb24gb2YgeG1sU2NoZW1hUGFyc2VyT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHBhcnNlLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICAgICBpbnQgb3B0aW9ucykKCQkJCQkKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVBhcnNlT3B0aW9uLgogICAgKi8KICAgIGZvciAoaSA9IDE7IGkgPCAoaW50KSBzaXplb2YoaW50KSAqIDg7IGkrKykgewogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkgewoJICAgIHJldHVybiAoLTEpOyAgIAogICAgICAgIH0JCiAgICB9CiAgICBjdHh0LT5vcHRpb25zID0gb3B0aW9uczsKICAgIHJldHVybiAoMCk7ICAgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHRHZXRPcHRpb25zOgogKiBAY3R4dDogYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQgCiAqCiAqIFJldHVybnMgdGhlIG9wdGlvbiBjb21iaW5hdGlvbiBvZiB0aGUgcGFyc2VyIGNvbnRleHQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlckN0eHRHZXRPcHRpb25zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKCQkJCQkKeyAgICAKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UgCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOyAgICAKfQoKIHZvaWQgKmN1ckl0ZW1zOyAgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IG5iQ3VySXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBzaXplQ3VySXRlbXM7IC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KCiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHQ6CiAqIEBVUkw6ICB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBmaWxlL3Jlc291cmNlIGV4cGVjdGVkCiAqIHRvIGNvbnRhaW4gYW4gWE1MIFNjaGVtYXMgZmlsZS4KICoKICogUmV0dXJucyB0aGUgcGFyc2VyIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld1BhcnNlckN0eHQoY29uc3QgY2hhciAqVVJMKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoVVJMID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIHJldC0+VVJMID0geG1sRGljdExvb2t1cChyZXQtPmRpY3QsIChjb25zdCB4bWxDaGFyICopIFVSTCwgLTEpOwogICAgcmV0LT5pbmNsdWRlcyA9IDA7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqIEBkaWN0OiB0aGUgZGljdGlvbmFyeSB0byBiZSB1c2VkCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KGNvbnN0IGNoYXIgKlVSTCwgeG1sRGljdFB0ciBkaWN0KQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKICAgIC8qCiAgICBpZiAoVVJMID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCSovCgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmRpY3QgPSBkaWN0OwogICAgeG1sRGljdFJlZmVyZW5jZShkaWN0KTsgICAgCiAgICBpZiAoVVJMICE9IE5VTEwpCglyZXQtPlVSTCA9IHhtbERpY3RMb29rdXAoZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0OgogKiBAYnVmZmVyOiAgYSBwb2ludGVyIHRvIGEgY2hhciBhcnJheSBjb250YWluaW5nIHRoZSBzY2hlbWFzCiAqIEBzaXplOiAgdGhlIHNpemUgb2YgdGhlIGFycmF5CiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IG1lbW9yeSBidWZmZXIgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3TWVtUGFyc2VyQ3R4dChjb25zdCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoKGJ1ZmZlciA9PSBOVUxMKSB8fCAoc2l6ZSA8PSAwKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5idWZmZXIgPSBidWZmZXI7CiAgICByZXQtPnNpemUgPSBzaXplOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dDoKICogQGRvYzogIGEgcHJlcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZG9jdW1lbnQuCiAqIE5CLiBUaGUgZG9jdW1lbnQgbWF5IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgcGFyc2luZyBwcm9jZXNzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dCh4bWxEb2NQdHIgZG9jKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoZG9jID09IE5VTEwpCiAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKCQkJICBOVUxMKTsKICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIC8qIFRoZSBhcHBsaWNhdGlvbiBoYXMgcmVzcG9uc2liaWxpdHkgZm9yIHRoZSBkb2N1bWVudCAqLwogICAgcmV0LT5wcmVzZXJ2ZSA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+ZG9jICE9IE5VTEwgJiYgIWN0eHQtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2MoY3R4dC0+ZG9jKTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKSB7Cgl4bWxGcmVlKCh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtcyk7Cgl4bWxGcmVlKGN0eHQtPmFzc2VtYmxlKTsKICAgIH0KICAgIGlmIChjdHh0LT52Y3R4dCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KGN0eHQtPnZjdHh0KTsKICAgIH0KICAgIHhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICoJCQlCdWlsZGluZyB0aGUgY29udGVudCBtb2RlbHMJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbDoKICogQHR5cGU6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lIHdob3NlIGNvbnRlbnQgaXMgYmVpbmcgYnVpbHQKICoKICogR2VuZXJhdGUgdGhlIGF1dG9tYXRhIHNlcXVlbmNlIG5lZWRlZCBmb3IgdGhhdCB0eXBlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkZvdW5kIHVuZXhwZWN0ZWQgdHlwZSA9IE5VTEwgaW4gJXMgY29udGVudCBtb2RlbFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6IHsgICAKCSAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCBlbmQ7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZDsJICAgIAoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbnM7CgoJICAgIHdpbGQgPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZDsKCgkgICAgaWYgKHdpbGQgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsLCAiCgkJICAgICJubyB3aWxkY2FyZCBvbiB4c2Q6YW55LlxuIiwgTlVMTCwgTlVMTCk7CgkJcmV0dXJuOwoJICAgIH0JICAgICAKCSAgICAKCSAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwoJICAgIGVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoJICAgIAoJICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkgewkJCgkJaWYgKHdpbGQtPmFueSA9PSAxKSB7CgkJICAgIC8qCgkJICAgICogV2UgbmVlZCB0byBhZGQgYm90aCB0cmFuc2l0aW9uczoKCQkgICAgKgoJCSAgICAqIDEuIHRoZSB7IioiLCAiKiJ9IGZvciBlbGVtZW50cyBpbiBhIG5hbWVzcGFjZS4KCQkgICAgKi8JCSAgICAKCQkgICAgY3R4dC0+c3RhdGUgPSAKCQkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkgICAgLyoKCQkgICAgKiAyLiB0aGUgeyIqIn0gZm9yIGVsZW1lbnRzIGluIG5vIG5hbWVzcGFjZS4KCQkgICAgKi8KCQkgICAgY3R4dC0+c3RhdGUgPSAKCQkJeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgTlVMTCwgdHlwZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCWN0eHQtPnN0YXRlID0gc3RhcnQ7CgkJCWN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJICAgIGN0eHQtPnN0YXRlLCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgdHlwZSk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CgkJCW5zID0gbnMtPm5leHQ7CgkJICAgIH0gd2hpbGUgKG5zICE9IE5VTEwpOwoKCQl9IGVsc2UgaWYgKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBkZWFkRW5kOwoKCQkgICAgZGVhZEVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoJCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBkZWFkRW5kLCBCQURfQ0FTVCAiKiIsIHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgdHlwZSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQl9CQkKCSAgICB9IGVsc2UgewoJCWludCBjb3VudGVyOwoJCXhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwoJCWludCBtYXhPY2N1cnMgPSAKCQkgICAgdHlwZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/IFVOQk9VTkRFRCA6IHR5cGUtPm1heE9jY3VycyAtIDE7CgkJaW50IG1pbk9jY3VycyA9CgkJICAgIHR5cGUtPm1pbk9jY3VycyA8IDEgPyAwIDogdHlwZS0+bWluT2NjdXJzIC0gMTsKCQkKCQljb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLCBtaW5PY2N1cnMsIG1heE9jY3Vycyk7CgkJaG9wID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CQkKCQlpZiAod2lsZC0+YW55ID09IDEpIHsJCSAgICAKCQkgICAgY3R4dC0+c3RhdGUgPQoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCSAgICBjdHh0LT5zdGF0ZSA9IAoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKCQl9IGVsc2UgaWYgKHdpbGQtPm5zU2V0ICE9IE5VTEwpIHsJCSAgICAKCQkgICAgbnMgPSB3aWxkLT5uc1NldDsKCQkgICAgZG8gewoJCQljdHh0LT5zdGF0ZSA9IAoJCQkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIG5zLT52YWx1ZSwgdHlwZSk7CgkJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CgkJCW5zID0gbnMtPm5leHQ7CgkJICAgIH0gd2hpbGUgKG5zICE9IE5VTEwpOwoKCQl9IGVsc2UgaWYgKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBkZWFkRW5kOwoKCQkgICAgZGVhZEVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoJCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBkZWFkRW5kLCBCQURfQ0FTVCAiKiIsIHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgdHlwZSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgQkFEX0NBU1QgIioiLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKCQl9CQoJCXhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBob3AsIHN0YXJ0LCBjb3VudGVyKTsKCQl4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgaG9wLCBlbmQsIGNvdW50ZXIpOwoJICAgIH0KCSAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKCQl4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwoJICAgIH0JICAgIAkgICAgCQkJCSAgICAgICAgICAgIAoJICAgIGN0eHQtPnN0YXRlID0gZW5kOwogICAgICAgICAgICBicmVhazsKCX0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOnsKCQl4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlOwogICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBwYXJ0aWNsZSwgZWxlbURlY2w7CgoJCS8qCgkJKiBJTVBPUlRBTlQ6IFRoaXMgcHV0cyBlbGVtZW50IGRlY2xhcmF0aW9ucwoJCSogKGFuZCBuZXZlciBlbGVtZW50IGRlY2wuIHJlZmVyZW5jZXMpIGludG8gdGhlCgkJKiBhdXRvbWF0b24uIFRoaXMgaXMgY3J1Y2lhbCBhbmQgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLCAKCQkqIHNpbmNlIHZhbGlkYXRpbmcgZnVuY3Rpb25zIHJlbHkgbm93IG9uIGl0LgoJCSovCgkJcGFydGljbGUgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsKCQlpZiAocGFydGljbGUtPnJlZiAhPSBOVUxMKSB7CgkJICAgIGlmIChwYXJ0aWNsZS0+cmVmRGVjbCA9PSBOVUxMKSB7CgkJCS8qCgkJCSogU2tpcCBjb250ZW50IG1vZGVsIGNyZWF0aW9uIGlmIHRoZSByZWZlcmVuY2UKCQkJKiBkaWQgbm90IHJlc29sdmUgdG8gYSBkZWNsYXJhdGlvbi4KCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0gZWxzZSB7CgkJCS8qCgkJCSogUmVmZXJlbmNlZCBnbG9iYWwgZWxlbWVudCBkZWNsYXJhdGlvbi4KCQkJKi8KCQkJZWxlbURlY2wgPSBwYXJ0aWNsZS0+cmVmRGVjbDsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogQW5vbnltb3VzIGVsZW1lbnQgZGVjbGFyYXRpb24uCgkJICAgICovCgkJICAgIGVsZW1EZWNsID0gcGFydGljbGU7CgkJfQoJCQogICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCgkJCSAgICBvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCgkJCSAgICBwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwgVU5CT1VOREVEKTsgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkJY3R4dC0+c3RhdGUsIE5VTEwsIAoJCQkJZWxlbURlY2wtPm5hbWUsIAoJCQkJZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJCSh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLCBvbGRzdGF0ZSwKCQkJICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLCBOVUxMLAoJCQkJY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgCgkJCWN0eHQtPnN0YXRlID0KCQkJICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCSAgICBjdHh0LT5zdGF0ZSwgTlVMTCwKCQkJICAgIGVsZW1EZWNsLT5uYW1lLCAKCQkJICAgIGVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgYW4gZWxlbSogKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmICgocGFydGljbGUtPm1heE9jY3VycyA+IDEpIHx8IChwYXJ0aWNsZS0+bWluT2NjdXJzID4gMSkpIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKCQkJcGFydGljbGUtPm1pbk9jY3VycyAtIDEsCgkJCXBhcnRpY2xlLT5tYXhPY2N1cnMgLSAxKTsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCWN0eHQtPnN0YXRlLAoJCQlOVUxMLAoJCQllbGVtRGVjbC0+bmFtZSwKCQkJZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsKTsKICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLCBvbGRzdGF0ZSwKCQkJY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLAoJCQlOVUxMLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtPyAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAoJCQkgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgCgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJY3R4dC0+c3RhdGUsCgkJCU5VTEwsCgkJCWVsZW1EZWNsLT5uYW1lLAoJCQllbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wpOwogICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IGFuIGVsZW0/ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCgkJCSAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGVzOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJZiBtYXggYW5kIG1pbiBvY2N1cmFuY2VzIGFyZSBkZWZhdWx0ICgxKSB0aGVuCiAgICAgICAgICAgICAgICAgKiBzaW1wbHkgaXRlcmF0ZSBvdmVyIHRoZSBzdWJ0eXBlcwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoKHR5cGUtPm1pbk9jY3VycyA9PSAxKSAmJiAodHlwZS0+bWF4T2NjdXJzID09IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5PY2N1cnMgLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTkJPVU5ERUQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLCBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIGNvdW50ZXIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgodHlwZS0+bWF4T2NjdXJzID4gMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh0eXBlLT5taW5PY2N1cnMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5taW5PY2N1cnMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bWF4T2NjdXJzIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCiAgICAgICAgICAgICAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGl0ZXJhdGUgb3ZlciB0aGUgc3VidHlwZXMgYW5kIHJlbWVyZ2UgdGhlIGVuZCB3aXRoIGFuCiAgICAgICAgICAgICAgICAgKiBlcHNpbG9uIHRyYW5zaXRpb24KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBlbmQpOwogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBob3A7CiAgICAgICAgICAgICAgICAgICAgaW50IG1heE9jY3VycyA9IHR5cGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwogICAgICAgICAgICAgICAgICAgICAgICBVTkJPVU5ERUQgOiB0eXBlLT5tYXhPY2N1cnMgLSAxOwogICAgICAgICAgICAgICAgICAgIGludCBtaW5PY2N1cnMgPQogICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5taW5PY2N1cnMgPCAxID8gMCA6IHR5cGUtPm1pbk9jY3VycyAtIDE7CgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogdXNlIGEgY291bnRlciB0byBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgdHJhbnN0aW9ucwogICAgICAgICAgICAgICAgICAgICAqIHdoaWNoIHdlbnQgdGhyb3VnaCB0aGUgY2hvaWNlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPQogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heE9jY3Vycyk7CiAgICAgICAgICAgICAgICAgICAgaG9wID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIGhvcCwgc3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIGhvcCwgZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBzdGFydCwgZW5kKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gZW5kOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6ewogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CgoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbTsKICAgICAgICAgICAgICAgIGludCBsYXg7CgogICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgIGlmIChzdWJ0eXBlcyA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKCQkgICAgLyoKCQkgICAgICogdGhlIGZvbGxvd2luZyAnaWYnIHdhcyBuZWVkZWQgdG8gZml4IGJ1ZyAxMzk4OTcKCQkgICAgICogbm90IHF1aXRlIHN1cmUgd2h5IGl0IG9ubHkgbmVlZHMgdG8gYmUgZG9uZSBmb3IKCQkgICAgICogZWxlbWVudHMgd2l0aCBhICdyZWYnLCBidXQgaXQgc2VlbXMgdG8gd29yayBvay4KCQkgICAgICovCgkJICAgIGlmIChzdWJ0eXBlcy0+cmVmICE9IE5VTEwpCgkJICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgIGVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgc3VidHlwZXM7CQkgIAoJCSAgICAvKgoJCSAgICAqIE5PVEU6IFRoZSB7bWF4IG9jY3Vyc30gb2YgYWxsIHRoZSBwYXJ0aWNsZXMgaW4gdGhlIAoJCSAgICAqIHtwYXJ0aWNsZXN9IG9mIHRoZSBncm91cCBtdXN0IGJlIDAgb3IgMS4KCQkgICAgKi8gICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgoZWxlbS0+bWluT2NjdXJzID09IDEpICYmIChlbGVtLT5tYXhPY2N1cnMgPT0gMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdPbmNlVHJhbnMyKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIAoJCQkJCQllbGVtLT5uYW1lLCAKCQkJCQkJZWxlbS0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkJCQkxLCAxLCBzdWJ0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoZWxlbS0+bWluT2NjdXJzID09IDApICYmCgkJCShlbGVtLT5tYXhPY2N1cnMgPT0gMSkpIHsKCQkJCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRUcmFuczIoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIAoJCQkJCQkgZWxlbS0+bmFtZSwKCQkJCQkJIGVsZW0tPnRhcmdldE5hbWVzcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMpOwogICAgICAgICAgICAgICAgICAgIH0KCQkgICAgLyoKCQkgICAgKiBOT1RFOiBpZiBtYXhPY2N1cnMgPT0gMCB0aGVuIG5vIHRyYW5zaXRpb24gd2lsbCBiZQoJCSAgICAqIGNyZWF0ZWQuCgkJICAgICovCiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxheCA9IHR5cGUtPm1pbk9jY3VycyA9PSAwOwogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3QWxsVHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBpZiAodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCQkKCQkvKgoJCSogVE9ETzogQ2lyY3VsYXIgZGVmaW5pdGlvbnMgd2lsbCBiZSBjaGVja2VkIGF0IHRoZQoJCSogY29uc3RyYWludCBsZXZlbC4gU28gcmVtb3ZlIHRoaXMgd2hlbiB0aGUgY29tcGxleCB0eXBlCgkJKiBjb25zdHJhaW50cyBhcmUgaW1wbGVtZW50ZWQuCgkJKi8KCQlpZiAodHlwZS0+cmVjdXJzZSkgeyAKCQkgICAgLyogVE9ETzogQ2hhbmdlIHRoZSBlcnJvciBjb2RlLiAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJICAgIE5VTEwsIHR5cGUsIHR5cGUtPm5vZGUsCQoJCQkgICAgIlRoaXMgaXRlbSBpcyBjaXJjdWxhciIsIE5VTEwpOwkJICAgICAKCQkgICAgcmV0dXJuOyAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHR5cGUtPnJlY3Vyc2UgPSAxOyAKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh0eXBlLT5iYXNlVHlwZSwgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgIAl0eXBlLT5yZWN1cnNlID0gMDsKICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgLyoKCSAgICAqIEhhbmRsZSBtb2RlbCBncm91cCBkZWZpbml0aW9uIHJlZmVyZW5jZXMuIAoJICAgICogTk9URTogdHlwZS0+c3VidHlwZXMgaXMgdGhlIHJlZmVyZW5jZWQgbW9kZWwgZ3JvcCBkZWZpbml0aW9uOwoJICAgICogYW5kIHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyBpcyB0aGUgbW9kZWwgZ3JvdXAgKGkuZS4gPGFsbD4gb3IgCgkgICAgKiA8Y2hvaWNlPiBvciA8c2VxdWVuY2U+KS4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+cmVmICE9IE5VTEwpICYmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCSh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgIT0gTlVMTCkpIHsKCQl4bWxTY2hlbWFUeXBlUHRyIG1vZGVsR3I7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCBlbmQ7CgoJCW1vZGVsR3IgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CQkKICAgICAgICAgICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkgewoJCSAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoJCSAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwobW9kZWxHciwgY3R4dCwgbmFtZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhPY2N1cnMgPSB0eXBlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KCQkJCSAgICBVTkJPVU5ERUQgOiB0eXBlLT5tYXhPY2N1cnMgLSAxOwogICAgICAgICAgICAgICAgICAgIGludCBtaW5PY2N1cnMgPQogICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5taW5PY2N1cnMgPCAxID8gMCA6IHR5cGUtPm1pbk9jY3VycyAtIDE7CgkJICAgIAogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPQogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKICAgICAgICAgICAgICAgICAgICBob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsJCSAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKG1vZGVsR3IsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIGhvcCwgc3RhcnQsCgkJCWNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwKCQkJY291bnRlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKCSAgICB9CgkgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CiAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDoKCSAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGb3VuZCB1bmV4cGVjdGVkIHR5cGUgJWQgaW4gJXMgY29udGVudCBtb2RlbFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnR5cGUsIG5hbWUpOwogICAgICAgICAgICByZXR1cm47CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbDoKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uIChvciByZWZlcmVuY2UpCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICoKICogQnVpbGRzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSBjb21wbGV4IHR5cGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgogICAgaWYgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fCAodHlwZS0+cmVmICE9IE5VTEwpIHx8CgkodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSB8fAoJKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8CgkodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpKQoJcmV0dXJuOwoKI2lmZGVmIERFQlVHX0NPTlRFTlQKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICJCdWlsZGluZyBjb250ZW50IG1vZGVsIGZvciAlc1xuIiwgbmFtZSk7CiNlbmRpZgoKICAgIGN0eHQtPmFtID0geG1sTmV3QXV0b21hdGEoKTsKICAgIGlmIChjdHh0LT5hbSA9PSBOVUxMKSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW5ub3QgY3JlYXRlIGF1dG9tYXRhIGZvciBjb21wbGV4IHRweWUgJXNcbiIsIG5hbWUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YUdldEluaXRTdGF0ZShjdHh0LT5hbSk7CiAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZSwgY3R4dCwgbmFtZSk7CiAgICB4bWxBdXRvbWF0YVNldEZpbmFsU3RhdGUoY3R4dC0+YW0sIGN0eHQtPnN0YXRlKTsKICAgIHR5cGUtPmNvbnRNb2RlbCA9IHhtbEF1dG9tYXRhQ29tcGlsZShjdHh0LT5hbSk7CiAgICBpZiAodHlwZS0+Y29udE1vZGVsID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCAKCSAgICBOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLAkgICAgCgkgICAgIkZhaWxlZCB0byBjb21waWxlIHRoZSBjb250ZW50IG1vZGVsIiwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFJlZ2V4cElzRGV0ZXJtaW5pc3QodHlwZS0+Y29udE1vZGVsKSAhPSAxKSB7CiAgICAgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9OT1RfREVURVJNSU5JU1RJQywKCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfTk9UREVURVJNSU5JU1QsICovCgkgICAgTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwKCSAgICAiVGhlIGNvbnRlbnQgbW9kZWwgaXMgbm90IGRldGVybWluaXN0IiwgTlVMTCk7CiAgICB9IGVsc2UgewojaWZkZWYgREVCVUdfQ09OVEVOVF9SRUdFWFAKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQgbW9kZWwgb2YgJXM6XG4iLCBuYW1lKTsKICAgICAgICB4bWxSZWdleHBQcmludChzdGRlcnIsIHR5cGUtPmNvbnRNb2RlbCk7CiNlbmRpZgogICAgfQogICAgY3R4dC0+c3RhdGUgPSBOVUxMOwogICAgeG1sRnJlZUF1dG9tYXRhKGN0eHQtPmFtKTsKICAgIGN0eHQtPmFtID0gTlVMTDsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2s6CiAqIEBlbGVtOiAgdGhlIHNjaGVtYSBlbGVtZW50IGNvbnRleHQKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIFJlc29sdmVzIHRoZSByZWZlcmVuY2VzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24KICogb3IgcGFydGljbGUsIHdoaWNoIGhhcyBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGFzIGl0J3MKICogdGVybS4gCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrKHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogY29udGV4dCBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpIHx8IAoJKChlbGVtICE9IE5VTEwpICYmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfUkVTT0xWRUQpKSkKICAgICAgICByZXR1cm47CiAgICBlbGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0lOVEVSTkFMX1JFU09MVkVEOwogICAgaWYgKGVsZW0tPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsKCgkvKgoJKiBUT0RPOiBFdmFsdWF0ZSwgd2hhdCBlcnJvcnMgY291bGQgb2NjdXIgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIG5vdAoJKiBmb3VuZC4gSXQgbWlnaHQgYmUgcG9zc2libGUgdGhhdCB0aGUgInR5cGVmaXh1cCIgbWlnaHQgY3Jhc2ggaWYKCSogbm8gcmVmIGRlY2xhcmF0aW9uIHdhcyBmb3VuZC4KCSovCiAgICAgICAgZWxlbURlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKGN0eHQtPnNjaGVtYSwgZWxlbS0+cmVmLCBlbGVtLT5yZWZOcyk7CiAgICAgICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsJICAKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbSwgZWxlbS0+bm9kZSwKCQkicmVmIiwgZWxlbS0+cmVmLCBlbGVtLT5yZWZOcywgCgkJWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQsIE5VTEwpOwogICAgICAgIH0gZWxzZQoJICAgIGVsZW0tPnJlZkRlY2wgPSBlbGVtRGVjbDsJCiAgICB9IGVsc2UgewkKCWlmICgoZWxlbS0+c3VidHlwZXMgPT0gTlVMTCkgJiYgKGVsZW0tPm5hbWVkVHlwZSAhPSBOVUxMKSkgewoJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCSAgICAKCSAgICAvKiAodHlwZSBkZWZpbml0aW9uKSAuLi4gb3RoZXJ3aXNlIHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyAKCSAgICAqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdHlwZSBbYXR0cmlidXRlXSAuLi4KCSAgICAqLwkgICAgCSAgICAKCSAgICB0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGVsZW0tPm5hbWVkVHlwZSwKCQllbGVtLT5uYW1lZFR5cGVOcyk7CSAgICAKCSAgICBpZiAodHlwZSA9PSBOVUxMKSB7CQoJCXhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW0sIGVsZW0tPm5vZGUsCgkJICAgICJ0eXBlIiwgZWxlbS0+bmFtZWRUeXBlLCBlbGVtLT5uYW1lZFR5cGVOcywKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7CgkgICAgfSBlbHNlCgkJZWxlbS0+c3VidHlwZXMgPSB0eXBlOwoJfQoJaWYgKGVsZW0tPnN1YnN0R3JvdXAgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgc3Vic3RIZWFkOwoJICAgIAoJICAgIC8qCgkgICAgKiBGSVhNRSBUT0RPOiBEbyB3ZSBuZWVkIGEgbmV3IGZpZWxkIGluIF94bWxTY2hlbWFFbGVtZW50IGZvciAKCSAgICAqIHN1YnN0aXR1dGlvbkdyb3VwPwoJICAgICovCgkgICAgc3Vic3RIZWFkID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGVsZW0tPnN1YnN0R3JvdXAsIAoJCWVsZW0tPnN1YnN0R3JvdXBOcyk7CSAgICAKCSAgICBpZiAoc3Vic3RIZWFkID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJICAgIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtLCBOVUxMLAoJCSAgICAic3Vic3RpdHV0aW9uR3JvdXAiLCBlbGVtLT5zdWJzdEdyb3VwLCBlbGVtLT5zdWJzdEdyb3VwTnMsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCXhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2soc3Vic3RIZWFkLCBjdHh0LCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkvKgoJCSogKHR5cGUgZGVmaW5pdGlvbikuLi5vdGhlcndpc2UgdGhlIHt0eXBlIGRlZmluaXRpb259IG9mIHRoZSAKCQkqIGVsZW1lbnQgZGVjbGFyYXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgCgkJKiB0aGUgc3Vic3RpdHV0aW9uR3JvdXAgW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQKCQkqLwoJCWlmIChlbGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSAKCQkgICAgZWxlbS0+c3VidHlwZXMgPSBzdWJzdEhlYWQtPnN1YnR5cGVzOwoJICAgIH0KCX0KCWlmICgoZWxlbS0+c3VidHlwZXMgPT0gTlVMTCkgJiYgKGVsZW0tPm5hbWVkVHlwZSA9PSBOVUxMKSAmJgoJICAgIChlbGVtLT5zdWJzdEdyb3VwID09IE5VTEwpKQoJICAgIGVsZW0tPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXA6CiAqIEB0eXBlOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeHVwIG9mIHRoZSBpdGVtVHlwZSByZWZlcmVuY2Ugb2YgdGhlIGxpc3QgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBhcnNlTGlzdFJlZkZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7ICAgIAogICAgCiAgICBpZiAoKCh0eXBlLT5iYXNlID09IE5VTEwpICYmIAoJICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSkgfHwKCSgodHlwZS0+YmFzZSAhPSBOVUxMKSAmJgoJICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSkpIHsJCgkvKgoJKiBzcmMtbGlzdC1pdGVtVHlwZS1vci1zaW1wbGVUeXBlCgkqIEVpdGhlciB0aGUgaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb3IgdGhlIDxzaW1wbGVUeXBlPiBbY2hpbGRdIG9mIAoJKiB0aGUgPGxpc3Q+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguIAoJKi8KCS8qCgkqIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgcGFyc2UgZnVuY3Rpb24uCgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19MSVNUX0lURU1UWVBFX09SX1NJTVBMRVRZUEUsCgkgICAgTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwgCgkgICAgIlRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgImFyZSBtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsJCiAgICB9IGVsc2UgaWYgKHR5cGUtPmJhc2UhPSBOVUxMKSB7ICAgICAgICAJCiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZSwgdHlwZS0+YmFzZU5zKTsKICAgICAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAkgICAgCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwKCQkiaXRlbVR5cGUiLCB0eXBlLT5iYXNlLCB0eXBlLT5iYXNlTnMsCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7CiAgICAgICAgfQogICAgfSAgICAgICAgICAgICAgIAogICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCSh0eXBlLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKQoJeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlVW5pb25SZWZDaGVjazoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIENoZWNrcyBhbmQgYnVpbGRzIHRoZSBtZW1iZXJUeXBlcyBvZiB0aGUgdW5pb24gdHlwZS4KICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgCiAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBsaW5rLCBsYXN0TGluayA9IE5VTEwsIHByZXZMaW5rLCBzdWJMaW5rLCBuZXdMaW5rOwogICAgeG1sU2NoZW1hVHlwZVB0ciBtZW1iZXJUeXBlLCBjdHh0VHlwZTsKCiAgICAvKiAxIElmIHRoZSA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiBbRGVmaW5pdGlvbjpdICAKICAgICogZGVmaW5lIHRoZSBleHBsaWNpdCBtZW1iZXJzIGFzIHRoZSB0eXBlIGRlZmluaXRpb25zILdyZXNvbHZlZLcgCiAgICAqIHRvIGJ5IHRoZSBpdGVtcyBpbiB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdLCAKICAgICogaWYgYW55LCBmb2xsb3dlZCBieSB0aGUgdHlwZSBkZWZpbml0aW9ucyBjb3JyZXNwb25kaW5nIHRvIHRoZSAKICAgICogPHNpbXBsZVR5cGU+cyBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8dW5pb24+LCBpZiBhbnkuIAogICAgKi8gICAKCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfVU5JT04pCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBpZiAoY3R4dC0+Y3R4dFR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrLCBubyBwYXJlbnQgdHlwZSAiCgkgICAgImF2YWlsYWJsZSIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBzcmMtdW5pb24tbWVtYmVyVHlwZXMtb3Itc2ltcGxlVHlwZXMKICAgICogRWl0aGVyIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBvZiB0aGUgPHVuaW9uPiBlbGVtZW50IG11c3QgCiAgICAqIGJlIG5vbi1lbXB0eSBvciB0aGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSBzaW1wbGVUeXBlIFtjaGlsZF0uIAogICAgKi8KICAgIGlmICgodHlwZS0+YmFzZSA9PSBOVUxMKSAmJiAKCSh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TUkNfVU5JT05fTUVNQkVSVFlQRVNfT1JfU0lNUExFVFlQRVMsCgkgICAgTlVMTCwgTlVMTCwgdHlwZS0+bm9kZSwJCgkgICAgIkVpdGhlciB0aGUgYXR0cmlidXRlICdtZW1iZXJUeXBlcycgbXVzdCBiZSBub24tZW1wdHkgIgoJICAgICJvciB0aGVyZSBtdXN0IGJlIGF0IGxlYXN0IG9uZSA8c2ltcGxlVHlwZT4gY2hpbGQiLCBOVUxMKTsKICAgIH0gCgkKICAgIGN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7Cgl4bWxBdHRyUHRyIGF0dHI7Cgljb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXA7Cgljb25zdCB4bWxDaGFyICpsb2NhbE5hbWUsICp1cmk7CgoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKHR5cGUtPm5vZGUsICJtZW1iZXJUeXBlcyIpOwoJY3VyID0gdHlwZS0+YmFzZTsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWUoY3R4dCwgY3R4dC0+c2NoZW1hLCBOVUxMLCAKCQlOVUxMLCBhdHRyLCBCQURfQ0FTVCB0bXAsICZ1cmksIE5VTEwsICZsb2NhbE5hbWUpOwkgICAKCSAgICBtZW1iZXJUeXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGxvY2FsTmFtZSwgdXJpKTsKCSAgICBpZiAobWVtYmVyVHlwZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fTUVNQkVSX1RZUEUsCgkJICAgIE5VTEwsIE5VTEwsIHR5cGUtPm5vZGUsICJtZW1iZXJUeXBlcyIsIGxvY2FsTmFtZSwgdXJpLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCWlmIChtZW1iZXJUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChtZW1iZXJUeXBlLCBjdHh0LCBOVUxMKTsJICAgIAoJCWxpbmsgPSAoeG1sU2NoZW1hVHlwZUxpbmtQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZUxpbmspKTsKCQlpZiAobGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCBOVUxMKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCWxpbmstPnR5cGUgPSBtZW1iZXJUeXBlOwoJCWxpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0TGluayA9PSBOVUxMKQoJCSAgICBjdHh0VHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rOwkJICAgIAoJCWVsc2UgCgkJICAgIGxhc3RMaW5rLT5uZXh0ID0gbGluazsKCQlsYXN0TGluayA9IGxpbms7CSAgICAKCSAgICB9CgkgICAgeG1sRnJlZSh0bXApOwoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7IAogICAgfQogICAgLyoKICAgICogQWRkIGxvY2FsIHNpbXBsZSB0eXBlcywKICAgICovICAgIAogICAgbWVtYmVyVHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgd2hpbGUgKG1lbWJlclR5cGUgIT0gTlVMTCkgewoJaWYgKG1lbWJlclR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChtZW1iZXJUeXBlLCBjdHh0LCBOVUxMKTsJICAgIAoJbGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJaWYgKGxpbmsgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCWxpbmstPnR5cGUgPSBtZW1iZXJUeXBlOwoJbGluay0+bmV4dCA9IE5VTEw7CglpZiAobGFzdExpbmsgPT0gTlVMTCkKCSAgICBjdHh0VHlwZS0+bWVtYmVyVHlwZXMgPSBsaW5rOwkJICAgIAoJZWxzZSAKCSAgICBsYXN0TGluay0+bmV4dCA9IGxpbms7CglsYXN0TGluayA9IGxpbms7CgltZW1iZXJUeXBlID0gbWVtYmVyVHlwZS0+bmV4dDsKICAgIH0gICAgCiAgICAvKgogICAgKiBUaGUgYWN0dWFsIHZhbHVlIGlzIHRoZW4gZm9ybWVkIGJ5IHJlcGxhY2luZyBhbnkgdW5pb24gdHlwZSAKICAgICogZGVmaW5pdGlvbiBpbiB0aGUgt2V4cGxpY2l0IG1lbWJlcnO3IHdpdGggdGhlIG1lbWJlcnMgb2YgdGhlaXIgCiAgICAqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLgogICAgKi8KICAgIGxpbmsgPSBjdHh0VHlwZS0+bWVtYmVyVHlwZXM7CiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7CglpZiAobGluay0+dHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCSAgICBzdWJMaW5rID0gbGluay0+dHlwZS0+bWVtYmVyVHlwZXM7CSAgICAKCSAgICBpZiAoc3ViTGluayAhPSBOVUxMKSB7CQkKCQlsaW5rLT50eXBlID0gc3ViTGluay0+dHlwZTsKCQlpZiAoc3ViTGluay0+bmV4dCAhPSBOVUxMKSB7CgkJICAgIGxhc3RMaW5rID0gbGluay0+bmV4dDsKCQkgICAgc3ViTGluayA9IHN1YkxpbmstPm5leHQ7CQkKCQkgICAgcHJldkxpbmsgPSBsaW5rOwoJCSAgICB3aGlsZSAoc3ViTGluayAhPSBOVUxMKSB7CQkgICAgCgkJCW5ld0xpbmsgPSAoeG1sU2NoZW1hVHlwZUxpbmtQdHIpIAoJCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJCQlpZiAobmV3TGluayA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgdHlwZSBsaW5rIiwgCgkJCQlOVUxMKTsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9CgkJCW5ld0xpbmstPnR5cGUgPSBtZW1iZXJUeXBlOwkgICAgCgkJCXByZXZMaW5rLT5uZXh0ID0gbmV3TGluazsKCQkJcHJldkxpbmsgPSBuZXdMaW5rOwoJCQluZXdMaW5rLT5uZXh0ID0gbGFzdExpbms7CgkJCQoJCQlzdWJMaW5rID0gc3ViTGluay0+bmV4dDsKCQkgICAgfQoJCX0KCSAgICB9Cgl9CglsaW5rID0gbGluay0+bmV4dDsKICAgIH0gICAgCgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVmaW5pdGlvbgogKiBAdmFsVHlwZTogdGhlIHZhbHVlIHR5cGUKICogCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBoYXMgdGhlIGdpdmVuIHZhbHVlIHR5cGUsIG9yCiAqIGlzIGRlcml2ZWQgZnJvbSBzdWNoIGEgdHlwZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgaW50IHZhbFR5cGUpCnsKICAgIC8qIFRPRE86IENoZWNrIGlmIHRoaXMgd29ya3MgaW4gZXZlcnkgY2FzZS4gKi8KICAgIGlmICgodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkJKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpIHsKCQlpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gdmFsVHlwZSkKCQkJcmV0dXJuKDEpOwogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUpIHsKCWlmICgoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgdHlwZSktPnN1YnR5cGVzICE9IE5VTEwpIAoJICAgIHJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoY3R4dCwgCgkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHR5cGUpLT5zdWJ0eXBlcywgdmFsVHlwZSkpOwogICAgfSBlbHNlIGlmICgodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHx8CgkodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OKSkgewoJaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIAoJICAgIHJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoY3R4dCwgdHlwZS0+YmFzZVR5cGUsIAoJCXZhbFR5cGUpKTsKICAgIH0gZWxzZSBpZiAoKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpICYmCgkoKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB8fAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB8fAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSkgewoJcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCB0eXBlLT5zdWJ0eXBlcywgCgkgICAgdmFsVHlwZSkpOwogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZVR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZ2l2ZW4gdHlwZSBvcgogKiBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAY3VyOiB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGxpc3QKICogQGxhc3RVc2U6IHRoZSB0b3Agb2YgdGhlIGF0dHJpYnV0ZSB1c2UgbGlzdAogKgogKiBCdWlsZHMgdGhlIGF0dHJpYnV0ZSB1c2VzIGxpc3Qgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogVGhpcyBvbmUgaXMgc3VwcG9zZWQgdG8gYmUgY2FsbGVkIGJ5IAogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24gb25seS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgY3VyLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKnVzZXMsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqbGFzdFVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciB0bXA7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCWlmIChjdXItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgLyogCgkgICAgICogVzNDOiAiMiBUaGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwcyC3cmVzb2x2ZWS3IAoJICAgICAqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVlt3Mgb2YgdGhlIHJlZiBbYXR0cmlidXRlXSBvZiB0aGUgCgkgICAgICogPGF0dHJpYnV0ZUdyb3VwPiBbY2hpbGRyZW5dLCBpZiBhbnkuIgoJICAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCAKCQkoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBjdXIpLT5hdHRyaWJ1dGVzLCB1c2VzLCAKCQlsYXN0VXNlKSA9PSAtMSkgewoJCXJldHVybiAoLTEpOwkgICAgCgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKiBXM0M6ICIxIFRoZSBzZXQgb2YgYXR0cmlidXRlIHVzZXMgY29ycmVzcG9uZGluZyB0byB0aGUgCgkgICAgICogPGF0dHJpYnV0ZT4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8JICAgIAkgICAgCgkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlTGluaykpOwoJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcC0+YXR0ciA9IGN1cjsKCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJICAgIGlmICgqdXNlcyA9PSBOVUxMKQoJCSp1c2VzID0gdG1wOwkJICAgIAoJICAgIGVsc2UgCgkJKCpsYXN0VXNlKS0+bmV4dCA9IHRtcDsKCSAgICAqbGFzdFVzZSA9IHRtcDsJICAgIAoJfQkKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0JCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVzdDogIHRoZSBkZXN0aW5hdGlvbiB3aWxkY2FyZAogKiBAc291cmNlOiB0aGUgc291cmNlIHdpbGRjYXJkCiAqCiAqIENsb25lcyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHNvdXJjZQogKiBhbmQgYXNzaWduZXMgdGhlbSB0byBkZXN0LgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpkZXN0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHNvdXJjZSkJCQkJICAgIAp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgdG1wLCBsYXN0OwoKICAgIGlmICgoc291cmNlID09IE5VTEwpIHx8ICgqZGVzdCA9PSBOVUxMKSkKCXJldHVybigtMSk7ICAgIAogICAgKCpkZXN0KS0+YW55ID0gc291cmNlLT5hbnk7CiAgICBjdXIgPSBzb3VyY2UtPm5zU2V0OwogICAgbGFzdCA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHRtcCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7Cgl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCWlmIChsYXN0ID09IE5VTEwpCgkgICAgKCpkZXN0KS0+bnNTZXQgPSB0bXA7CgllbHNlIAoJICAgIGxhc3QtPm5leHQgPSB0bXA7CglsYXN0ID0gdG1wOwoJY3VyID0gY3VyLT5uZXh0OwogICAgfSAgICAKICAgIGlmICgoKmRlc3QpLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoKCpkZXN0KS0+bmVnTnNTZXQpOwkgICAKICAgIGlmIChzb3VyY2UtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSgqZGVzdCktPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAoKCpkZXN0KS0+bmVnTnNTZXQgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJKCpkZXN0KS0+bmVnTnNTZXQtPnZhbHVlID0gc291cmNlLT5uZWdOc1NldC0+dmFsdWU7CSAgICAKICAgIH0gZWxzZQoJKCpkZXN0KS0+bmVnTnNTZXQgPSBOVUxMOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hVW5pb25XaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBVbmlvbnMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIHVuaW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlIAogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoJCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJICAgIAoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoJCQoJCS8qIAoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4gCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQkgICAgICAgIAogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZQogICAgKi8KICAgIGlmIChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpIHsJCglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLCAKICAgICogdGhlbiB0aGUgdW5pb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CQkKCWludCBmb3VuZDsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc3RhcnQ7CgkKCWN1ciA9IGN1cldpbGQtPm5zU2V0OwoJc3RhcnQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBzdGFydDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAodG1wID09IE5VTEwpIAoJCSAgICByZXR1cm4gKC0xKTsKCQl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCQl0bXAtPm5leHQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwkJICAgIAkJICAgIAoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSB0bXA7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyoKICAgICogNCBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IHZhbHVlcyAobmFtZXNwYWNlIG5hbWVzIAogICAgKiBvciC3YWJzZW50tyksIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoKCXJldHVybigwKTsKICAgIH0KICAgIC8qIAogICAgICogNS4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWludCBuc0ZvdW5kLCBhYnNlbnRGb3VuZCA9IDA7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uZWdOc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQ7Cgl9Cgluc0ZvdW5kID0gMDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIAoJCWFic2VudEZvdW5kID0gMTsKCSAgICBlbHNlIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKQoJCW5zRm91bmQgPSAxOwoJICAgIGlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKQoJCWJyZWFrOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgoJaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyBib3RoIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgYW5kILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLyAgICAKCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9IGVsc2UgaWYgKG5zRm91bmQgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKiAKCSAgICAqIDUuMiBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIG5hbWUgCgkgICAgKiBidXQgbm90ILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QgCgkgICAgKiBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjMgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3IGJ1dCBub3QgdGhlIG5lZ2F0ZWQgCgkgICAgKiBuYW1lc3BhY2UgbmFtZSwgdGhlbiB0aGUgdW5pb24gaXMgbm90IGV4cHJlc3NpYmxlLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIAoJCVhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSwKCQkiVGhlIHVuaW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZS5cbiIsCgkJTlVMTCwgTlVMTCk7CQoJICAgIHJldHVybihYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUpOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjQgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKiAKICAgICAqIDYuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7Cgl9CQoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCS8qCgkJKiA2LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSAKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQkJCglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IAoJICAgICogYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICgwKTsKCn0KCi8qKgogKiB4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBJbnRlcnNlY3RzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyBpbnRlcnNlY3Rpb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgcHJldiwgIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZSAKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCQoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCSAgICAKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCQkKCQkvKiAKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuIAoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsJCSAgICAKCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwkgICAgCglyZXR1cm4oMCk7CiAgICB9CSAgICAgICAgICAgIAogICAgLyoKICAgICogMyBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSB2YWx1ZSAoYSBuYW1lc3BhY2UgCiAgICAqIG5hbWUgb3Igt2Fic2VudLcpIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciAKICAgICogt2Fic2VudLcpLCB0aGVuIHRoYXQgc2V0LCBtaW51cyB0aGUgbmVnYXRlZCB2YWx1ZSBpZiBpdCB3YXMgaW4gCiAgICAqIHRoZSBzZXQsIG1pbnVzILdhYnNlbnS3IGlmIGl0IHdhcyBpbiB0aGUgc2V0LCBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7Cgljb25zdCB4bWxDaGFyICpuZWc7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpIHsKCSAgICBuZWcgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIG5lZyA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCS8qCgkqIFJlbW92ZSBhYnNlbnQgYW5kIG5lZ2F0ZWQuCgkqLwoJcHJldiA9IE5VTEw7CgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCWlmIChwcmV2ID09IE5VTEwpIAoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UgCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCWlmIChuZWcgIT0gTlVMTCkgewoJICAgIHByZXYgPSBOVUxMOwoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gbmVnKSB7CgkJICAgIGlmIChwcmV2ID09IE5VTEwpIAoJCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCSAgICBlbHNlIAoJCQlwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCSAgICB4bWxGcmVlKGN1cik7CgkJICAgIGJyZWFrOwoJCX0KCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9CgoJcmV0dXJuKDApOwogICAgfQkgICAgICAgIAogICAgLyoKICAgICogNCBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3KSwgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsJCQoJaW50IGZvdW5kOwoJCgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJcHJldiA9IE5VTEw7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZSAKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl0bXAgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWN1ciA9IHRtcDsJCQoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyogNSBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IG5hbWVzcGFjZSBuYW1lcywgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBpcyBub3QgZXhwcmVzc2libGUKICAgICovCSAgICAKICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkpIHsKCgl4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSwKCSAgICAiVGhlIGludGVyc2VjdGlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGUuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwkKCXJldHVybihYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFKTsKICAgIH0JCSAgICAKICAgIC8qIAogICAgKiA2IElmIHRoZSBvbmUgaXMgYSBuZWdhdGlvbiBvZiBhIG5hbWVzcGFjZSBuYW1lIGFuZCB0aGUgb3RoZXIgCiAgICAqIGlzIGEgbmVnYXRpb24gb2Ygt2Fic2VudLcsIHRoZW4gdGhlIG9uZSB3aGljaCBpcyB0aGUgbmVnYXRpb24gCiAgICAqIG9mIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSkgewkKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gIGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsgCiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHdpbGRBOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEB3aWxkQjogdGhlIHNlY29uZCB3aWxkY2FyZCAKICoKICogUmV0dXJucyAxIGlmIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludCBvZiBAd2lsZEEgaXMgYW4gaW50ZW5zaW9uYWwgCiAqIHN1YnNldCBvZiBAd2lsZEIsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRBLAoJCQkJICAgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZEIpCnsgICAgCgogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBXaWxkY2FyZCBTdWJzZXQgCiAgICAqLwogICAgLyoKICAgICogMSBzdXBlciBtdXN0IGJlIGFueS4gCiAgICAqLwogICAgaWYgKHdpbGRCLT5hbnkpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogMi4xIHN1YiBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3Igt2Fic2VudLcuCiAgICAqIDIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIHRoZSBzYW1lIHZhbHVlLgogICAgKi8KICAgIGlmICgod2lsZEEtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEItPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEEtPm5lZ05zU2V0LT52YWx1ZSA9PSB3aWxkQS0+bmVnTnNTZXQtPnZhbHVlKSkKCXJldHVybiAoMSk7ICAgIAogICAgLyogCiAgICAqIDMuMSBzdWIgbXVzdCBiZSBhIHNldCB3aG9zZSBtZW1iZXJzIGFyZSBlaXRoZXIgbmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3LiAKICAgICovCiAgICBpZiAod2lsZEEtPm5zU2V0ICE9IE5VTEwpIHsKCS8qCgkqIDMuMi4xIHN1cGVyIG11c3QgYmUgdGhlIHNhbWUgc2V0IG9yIGEgc3VwZXJzZXQgdGhlcmVvZi4gCgkqLwoJaWYgKHdpbGRCLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckI7CgkgICAgaW50IGZvdW5kID0gMDsKCSAgICAKCSAgICBjdXIgPSB3aWxkQS0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWN1ckIgPSB3aWxkQi0+bnNTZXQ7CgkJd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQlmb3VuZCA9IDE7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGN1ckIgPSBjdXJCLT5uZXh0OwoJCX0KCQlpZiAoIWZvdW5kKQoJCSAgICByZXR1cm4gKDApOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGZvdW5kKQoJCXJldHVybiAoMSk7IAoJfSBlbHNlIGlmICh3aWxkQi0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoJICAgIC8qCgkgICAgKiAzLjIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgCgkgICAgKiC3YWJzZW50tyBhbmQgdGhhdCB2YWx1ZSBtdXN0IG5vdCBiZSBpbiBzdWIncyBzZXQuIAoJICAgICovCgkgICAgY3VyID0gd2lsZEEtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewkJCgkJaWYgKGN1ci0+dmFsdWUgPT0gd2lsZEItPm5lZ05zU2V0LT52YWx1ZSkKCQkgICAgcmV0dXJuICgwKTsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfSAgCgkgICAgcmV0dXJuICgxKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAYXR0cnM6IHRoZSBhdHRyaWJ1dGUgbGlzdCAKICogQGNvbXBsZXRlV2lsZDogdGhlIHJlc3VsdGluZyBjb21wbGV0ZSB3aWxkY2FyZAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkJICAgIAoJCQkJICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzLAoJCQkJICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmNvbXBsZXRlV2lsZCkJCQkJCnsgICAgICAgIAogICAgd2hpbGUgKGF0dHJzICE9IE5VTEwpIHsKCWlmIChhdHRycy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncm91cDsKCgkgICAgZ3JvdXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGF0dHJzOwoJICAgIC8qCgkgICAgKiBIYW5kbGUgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMuCgkgICAgKi8KCSAgICBpZiAoZ3JvdXAtPnJlZiAhPSBOVUxMKSB7CgkJaWYgKGdyb3VwLT5yZWZJdGVtID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBUT0RPOiBTaG91bGQgd2UgcmFpc2UgYSB3YXJuaW5nIGhlcmU/CgkJICAgICovCgkJICAgIC8qCgkJICAgICogVGhlIHJlZmVyZW5jZWQgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gY291bGQgbm90CgkJICAgICogYmUgcmVzb2x2ZWQgYmVmb3JlaGFuZCwgc28gc2tpcC4KCQkgICAgKi8KCQkgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlCgkJICAgIGdyb3VwID0gZ3JvdXAtPnJlZkl0ZW07CgkgICAgfQkgICAgCgkgICAgLyoKCSAgICAqIEZvciBldmVyeSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiwgYW4gaW50ZXJzZWN0ZWQgd2lsZGNhcmQgCgkgICAgKiB3aWxsIGJlIGNyZWF0ZWQgKGFzc3VtZWQgdGhhdCBhIHdpbGRjYXJkIGV4aXN0cyBvbiB0aGUgCgkgICAgKiBwYXJ0aWN1bGFyIGF0dHIuIGdyLiBkZWYuIG9yIG9uIGFueSBjb250YWluZWQgYXR0ci4gZ3IuIGRlZiAKCSAgICAqIGF0IGFsbCkuCgkgICAgKiBUaGUgZmxhZyBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCBlbnN1cmVzCgkgICAgKiB0aGF0IHRoZSBpbnRlcnNlY3Rpb24gd2lsbCBiZSBwZXJmb3JtZWQgb25seSBvbmNlLgoJICAgICovCgkgICAgaWYgKChncm91cC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCkgPT0gMCkgewoJCWlmIChncm91cC0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCgkJCWdyb3VwLT5hdHRyaWJ1dGVzLCAmZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkJcmV0dXJuICgtMSk7CgkJfQoJCWdyb3VwLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRDsKCSAgICB9CQkKCSAgICBpZiAoZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsJCQoJCWlmICgqY29tcGxldGVXaWxkID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBDb3B5IHRoZSBmaXJzdCBlbmNvdW50ZXJlZCB3aWxkY2FyZCBhcyBjb250ZXh0LCBleGNlcHQgZm9yIHRoZSBhbm5vdGF0aW9uLgoJCSAgICAqLwoJCSAgICAqY29tcGxldGVXaWxkID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCk7CgkJICAgICgqY29tcGxldGVXaWxkKS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOwkgICAKCQkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsIAoJCQljb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPnByb2Nlc3NDb250ZW50cyA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzOwoJCSAgICAvKgoJCSAgICAqIEFsdGhvdWdoIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCBtaWdodCBub3QgY29ycmVzcG9uZCB0byBhbnkKCQkgICAgKiBub2RlIGluIHRoZSBzY2hlbWEsIHdlIHdpbGwgc2F2ZSB0aGlzIGNvbnRleHQgbm9kZS4KCQkgICAgKiBUT0RPOiBIbW0sIGlzIHRoaXMgc2FuZT8KCQkgICAgKi8KCQkgICAgKCpjb21wbGV0ZVdpbGQpLT5ub2RlID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5ub2RlOyAgCgkJICAgIAoJCX0gZWxzZSBpZiAoeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKGN0eHQsICpjb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKCpjb21wbGV0ZVdpbGQpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCSAgICB9Cgl9CglhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgfQogICAJCSAgICAgICAgICAgICAgICAgCiAgICByZXR1cm4gKDApOyAgIAp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJCSAgICAgaW50ICpmaXhlZCwKCQkJCSAgICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlLAoJCQkJICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKewogICAgKmZpeGVkID0gMDsKICAgICp2YWx1ZSA9IE5VTEw7CiAgICBpZiAodmFsICE9IDApIAoJKnZhbCA9IE5VTEw7CgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlID09IE5VTEwpCglpdGVtID0gaXRlbS0+cmVmRGVjbDsKCiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJKnZhbHVlID0gaXRlbS0+ZGVmVmFsdWU7CglpZiAodmFsICE9IDApCgkgICAgKnZhbCA9IGl0ZW0tPmRlZlZhbDsKCWlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpCgkgICAgKmZpeGVkID0gMTsKCXJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9Ci8qKgogKiB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROczoKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDEpOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigxKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYgCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsJCgkKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIAogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBjdXIsIGJhc2UsIHRtcCwgaWQgPSBOVUxMLCBwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIAoJbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW55VHlwZTsKICAgIGludCBiYXNlSXNBbnlUeXBlID0gMDsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgZXJyID0gMDsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKiAKICAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIHdpdGggY29tcGxleCBjb250ZW50IFNjaGVtYSBDb21wb25lbnQuCiAgICAgKgogICAgICogQXR0cmlidXRlIHVzZXMuCiAgICAgKiBUT0RPOiBBZGQgY2hlY2tzIGZvciBhYnNlbnQgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGFuZAogICAgICogc2ltcGxlIHR5cGVzLgogICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJCSAgICAgICJhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJ1aWxkZWQuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkJICAgICAgImNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUuXG4iLAoJCSAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlVHlwZSA9PSBhbnlUeXBlKQoJYmFzZUlzQW55VHlwZSA9IDE7CiAgICAvKgogICAgICogSW5oZXJpdCB0aGUgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZS4KICAgICAqLwogICAgLyoKICAgICAqIE5PVEU6IEl0IGlzIGFsbG93ZWQgdG8gImV4dGVuZCIgdGhlIGFueVR5cGUgY29tcGxleCB0eXBlLgogICAgICovCiAgICBpZiAoIWJhc2VJc0FueVR5cGUpIHsKCWlmIChiYXNlVHlwZSAhPSBOVUxMKSB7CgkgICAgZm9yIChjdXIgPSBiYXNlVHlwZS0+YXR0cmlidXRlVXNlczsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyKSAKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCSJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyBvZiBjb21wbGV4VHlwZSIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdG1wOwoJCX0gZWxzZSAKCQkgICAgbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJbGFzdEJhc2VVc2UgPSB0bXA7IAoJICAgIH0KCX0KICAgIH0KICAgIGlmICgodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkoKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8IAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSkgewoJLyogCgkqIHR5cGUgLS0+ICg8c2ltcGxlQ29udGVudD58PGNvbXBsZXhDb250ZW50PikgCgkqICAgICAgICAtLT4gKDxyZXN0cmljdGlvbj58PGV4dGVuc2lvbj4pIC0tPiBhdHRyaWJ1dGVzCgkqLyAKCWF0dHJzID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT5hdHRyaWJ1dGVzOwogICAgfSBlbHNlIHsKCS8qIFNob3J0IGhhbmQgZm9ybSBvZiB0aGUgY29tcGxleFR5cGUuICovCglhdHRycyA9IHR5cGUtPmF0dHJpYnV0ZXM7CiAgICB9CiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlIHdpbGRjYXJkcy4KICAgICovCQogICAgZXJyID0geG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJYXR0cnMsICZ0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCk7ICAgIAogICAgLyoKICAgICogTk9URTogRHVyaW5nIHRoZSBwYXJzZSB0aW1lLCB0aGUgd2lsZGNhcmQgaXMgY3JlYXRlZCBvbiB0aGUgY29tcGxleFR5cGUKICAgICogZGlyZWN0bHksIGlmIGVuY291bnRlcmVkIGluIGEgPHJlc3RyaWN0aW9uPiBvciA8ZXh0ZW5zaW9uPiBlbGVtZW50LgogICAgKi8KICAgIGlmIChlcnIgPT0gLTEpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAiZmFpbGVkIHRvIGJ1aWxkIGFuIGludGVyc2VjdGVkIGF0dHJpYnV0ZSB3aWxkY2FyZC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmIAoJKChiYXNlSXNBbnlUeXBlKSB8fAoJICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgCSAgICAKCSAgKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgkgICAgICAKCSAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkpKSB7CSAgICAKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFVuaW9uIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCB3aXRoIHRoZSBiYXNlIHdpbGRjYXJkLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKGN0eHQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCXJldHVybiAoLTEpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogSnVzdCBpbmhlcml0IHRoZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGlzIGlzIHRoZSBvbmx5IGNhc2Ugd2hlcmUgYW4gYXR0cmlidXRlIAogICAgICAgICAgICAqIHdpbGRjYXJkIGlzIHNoYXJlZC4KICAgICAgICAgICAgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQpCgkJdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEOwoJICAgIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJfQogICAgfQogICAgCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qIAoJICAgICogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpIAkgICAgCgkgICAgKiA0LjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGhhdmUgb25lLiAKCSAgICAqLwoJICAgIGlmIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkgewkgIAoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAoJCSAgICAiVGhlIHR5cGUgaGFzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCwgIgoJCSAgICAiYnV0IHRoZSBiYXNlIHR5cGUgJXMgZG9lcyBub3QgaGF2ZSBvbmUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuICgxKTsKCSAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQoCgkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gMCkgewoJCS8qIDQuMiAqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIgCgkJICAgICJzdWJzZXQgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCSAgICAKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICAvKiA0LjMgVW5sZXNzIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3dXItdHlwZSAKCSAgICAqIGRlZmluaXRpb263LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIAoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9IG11c3QgYmUgaWRlbnRpY2FsIHRvIG9yIAoJICAgICogc3Ryb25nZXIgdGhhbiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUgCgkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlciAKCSAgICAqIHRoYW4gbGF4IGlzIHN0cm9uZ2VyIHRoYW4gc2tpcC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0gYW55VHlwZSkgJiYgCgkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cykpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8zLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCSAgICAiVGhlICdwcm9jZXNzIGNvbnRlbnRzJyBvZiB0aGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIHdlYWtlciB0aGFuICIKCQkgICAgInRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0KCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJLyoKCSogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKQoJKiBBdCB0aGlzIHBvaW50IHRoZSB0eXBlIGFuZCB0aGUgYmFzZSBoYXZlIGJvdGgsIGVpdGhlcgoJKiBubyB3aWxkY2FyZCBvciBhIHdpbGRjYXJkLgoJKi8KCWlmICgoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkgICAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkpIHsKCSAgICAvKiAxLjMgKi8KCSAgICBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCgKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzMsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIgCgkJICAgICJzdXBlcnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkKCQlyZXR1cm4gKDEpOwkJCgkgICAgfQoJfQkJCiAgICB9CQoKICAgIC8qCiAgICAgKiBHYXRoZXIgYXR0cmlidXRlIHVzZXMgZGVmaW5lZCBieSB0aGlzIHR5cGUuCiAgICAgKi8KICAgIGlmIChhdHRycyAhPSBOVUxMKSB7CglpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgYXR0cnMsIAoJICAgICZ1c2VzLCAmbGFzdFVzZSkgPT0gLTEpIHsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCA0LgogICAgICogIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCiAgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4iCiAgICAgKgogICAgICogRm9yICJleHRlbnNpb24iIHRoaXMgaXMgZG9uZSBmdXJ0aGVyIGRvd24uCiAgICAgKi8KICAgIGlmICgodXNlcyAhPSBOVUxMKSAmJiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgljdXIgPSB1c2VzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgdG1wID0gY3VyLT5uZXh0OwoJICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJICAgICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyICksIAoJCSAgICB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSkpKSB7CgoJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsIAoJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkJCgkJCSJEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSAlcyBzcGVjaWZpZWQiLAoJCQl4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHIsIAoJCQkgICAgeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0ciksIAoJCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkKCQkgICAgKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAgCQkgICAgCgkJICAgIGJyZWFrOwoJCX0KCQl0bXAgPSB0bXAtPm5leHQ7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0JCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CQoJLyoKCSAqIERlcml2ZSBieSByZXN0cmljdGlvbi4KCSAqLwoJaWYgKGJhc2VJc0FueVR5cGUpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKCX0gZWxzZSB7CgkgICAgaW50IGZvdW5kOwoJICAgIGNvbnN0IHhtbENoYXIgKmJFZmZWYWx1ZTsKCSAgICBpbnQgZWZmRml4ZWQ7CgoJICAgIGN1ciA9IHVzZXM7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWJhc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoJCXdoaWxlIChiYXNlICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkgJiYKCQkJeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0cikpKSB7CgkJCQoJCQlmb3VuZCA9IDE7CQkJCgkJCQoJCQlpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJCQkgICAgKGJhc2UtPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMi4xLjEKCQkJICAgICovCQoJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCgkJCQkiVGhlICdvcHRpb25hbCcgdXNlIGlzIGluY29uc2lzdGVudCB3aXRoIGEgbWF0Y2hpbmcgIgoJCQkJIidyZXF1aXJlZCcgdXNlIG9mIHRoZSBiYXNlIHR5cGUiLCBOVUxMKTsJCQkJCgkJCX0gZWxzZSBpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAzIAoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMywgCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCQkJIkEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBmb3IgdGhlICdyZXF1aXJlZCcgIgoJCQkJImF0dHJpYnV0ZSB1c2UgJXMgb2YgdGhlIGJhc2UgdHlwZSBpcyBtaXNzaW5nIiwKCQkJCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgCgkJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0ciksIAoJCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUoYmFzZS0+YXR0cikpKTsJCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJfSBlbHNlIHsKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zIFtEZWZpbml0aW9uOl0gIExldCB0aGUgZWZmZWN0aXZlIHZhbHVlIAoJCQkgICAgKiBjb25zdHJhaW50IG9mIGFuIGF0dHJpYnV0ZSB1c2UgYmUgaXRzIHt2YWx1ZSAKCQkJICAgICogY29uc3RyYWludH0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSBpdHMge2F0dHJpYnV0ZSAKCQkJICAgICogZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9IC4gCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGJhc2UtPmF0dHIsICZlZmZGaXhlZCwgCgkJCQkmYkVmZlZhbHVlLCAwKTsJCQkgICAJCQkJCQkJICAgIAoJCQkgICAgLyoKCQkJICAgICogMi4xLjMgLi4uIG9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZQoJCQkgICAgKgoJCQkgICAgKiAyLjEuMy4xIEIncyC3ZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnS3IGlzIAoJCQkgICAgKiC3YWJzZW50tyBvciBkZWZhdWx0LgoJCQkgICAgKi8KCQkJICAgIGlmICgoYkVmZlZhbHVlICE9IE5VTEwpICYmCgkJCQkoZWZmRml4ZWQgPT0gMSkpIHsKCQkJCWNvbnN0IHhtbENoYXIgKnJFZmZWYWx1ZSA9IE5VTEw7CgoJCQkJeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGJhc2UtPmF0dHIsICZlZmZGaXhlZCwgCgkJCQkgICAgJnJFZmZWYWx1ZSwgMCk7CQoJCQkJLyoKCQkJCSogMi4xLjMuMiBSJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcyAKCQkJCSogZml4ZWQgd2l0aCB0aGUgc2FtZSBzdHJpbmcgYXMgQidzLgoJCQkJKi8KCQkJCWlmICgoZWZmRml4ZWQgPT0gMCkgfHwKCQkJCSAgICAoISB4bWxTdHJFcXVhbChyRWZmVmFsdWUsIGJFZmZWYWx1ZSkpKSB7CgkJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8zLCAKCQkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkKCQkJCQkiVGhlIGVmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJCQkJImF0dHJpYnV0ZSB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggIgoJCQkJCSJpdHMgY29ycmVzcG9uZGVudCBvZiB0aGUgYmFzZSB0eXBlIiwKCQkJCQlOVUxMKTsJCQkJCSAgICAKCQkJCX0KCQkJICAgIH0KCQkJICAgIC8qCgkJCSAgICAqIFRPRE86IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMS4yICh7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCkKCQkJICAgICovCgkJCSAgICAvKgoJCQkgICAgKiBPdmVycmlkZSB0aGUgYXR0cmlidXRlIHVzZS4KCQkJICAgICovCgkJCSAgICBiYXNlLT5hdHRyID0gY3VyLT5hdHRyOwoJCQl9CgkJCQkJCQkJCgkJCWJyZWFrOwoJCSAgICB9CQkJCQoJCSAgICBiYXNlID0gYmFzZS0+bmV4dDsKCQl9CgkJCgkJaWYgKCFmb3VuZCkgewoJCSAgICBpZiAoY3VyLT5hdHRyLT5vY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgewoJCQkvKgoJCQkqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMgoJCQkqLwoJCQlpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkJCSAgICB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCQkJCWN1ci0+YXR0ci0+dGFyZ2V0TmFtZXNwYWNlKSkKCQkJICAgIGZvdW5kID0gMTsKCgkJCWlmICghZm91bmQpIHsKCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMiwgCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkKCQkJCSJOZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkJIm5vciBhIG1hdGNoaW5nIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgZG9lcyBleGlzdCIsCgkJCQlOVUxMKTsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIAoJCQkgICAgKiBBZGQgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqCgkJCSAgICAqIE5vdGUgdGhhdCB0aGlzIG1heSBsZWFkIHRvIGZ1bm55IGRlcml2YXRpb24gZXJyb3IgcmVwb3J0cywgaWYKCQkJICAgICogbXVsdGlwbGUgZXF1YWwgYXR0cmlidXRlIHVzZXMgZXhpc3Q7IGJ1dCB0aGlzIGlzIG5vdAoJCQkgICAgKiBhbGxvd2VkIGFueXdheSwgYW5kIGl0IHdpbGwgYmUgcmVwb3J0ZWQgYmVmb3JlaGFuZC4KCQkJICAgICovCgkJCSAgICB0bXAgPSBjdXI7CgkJCSAgICBpZiAocHJldiAhPSBOVUxMKQoJCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkJICAgIGVsc2UgCgkJCQl1c2VzID0gY3VyLT5uZXh0OwoJCQkgICAgY3VyID0gY3VyLT5uZXh0OyAgICAJCQkKCQkJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJCSAgICB9IGVsc2UgCgkJCQlsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQkJICAgIGxhc3RCYXNlVXNlID0gdG1wOwkJCgkJCSAgICAKCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJICAgIH0KCQl9CQkgICAgCSAgICAKCQlwcmV2ID0gY3VyOwkKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodXNlcyk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsgCgkvKgoJICogVGhlIHNwZWMgYWxsb3dzIG9ubHkgYXBwZW5kaW5nLCBhbmQgbm90IG90aGVyIGtpbmRzIG9mIGV4dGVuc2lvbnMuCgkgKgoJICogVGhpcyBlbnN1cmVzOiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgOiAxLjIgCgkgKi8KCWlmICh1c2VzICE9IE5VTEwpIHsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CgkgICAgfSBlbHNlIAoJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdXNlczsKCX0KICAgIH0gZWxzZSB7CgkvKiAKCSogRGVyaXZlIGltcGxpY2l0ZWx5IGZyb20gdGhlIHVyLXR5cGUuCgkqLwoJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CiAgICB9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuCgkgICAgKgoJICAgICogTm90ZSB0aGF0IHRoaXMgd2FzIGFscmVhZHkgZG9uZSBmb3IgInJlc3RyaWN0aW9uIiBhbmQgdHlwZXMgZGVyaXZlZCBmcm9tCgkgICAgKiB0aGUgdXItdHlwZS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCQkoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciApLCAKCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0cikpKSkgewoKCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwgCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCB0bXAtPmF0dHIsCQkKCQkJICAgICJEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSBzcGVjaWZpZWQiLCBOVUxMKTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgdG1wID0gdG1wLT5uZXh0OwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIDUuIFR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCgkgICAgKiBub3QgaGF2ZSB7dHlwZSBkZWZpbml0aW9ufXMgd2hpY2ggYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuCgkgICAgKi8KCSAgICBpZiAoKGN1ci0+YXR0ci0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkJKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyLCBYTUxfU0NIRU1BU19JRCkpKSB7CgkJaWYgKGlkICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF81LCAKCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAoJCQkiVGhlcmUgbXVzdCBub3QgZXhpc3QgbW9yZSB0aGFuIG9uZSBhdHRyaWJ1dGUgdXNlLCAiCgkJCSJkZWNsYXJlZCBvZiB0eXBlICdJRCcgb3IgZGVyaXZlZCBmcm9tIGl0IiwgCgkJCU5VTEwpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQl9IAoJCWlkID0gY3VyOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVtb3ZlICJwcm9oaWJpdGVkIiBhdHRyaWJ1dGUgdXNlcy4gVGhlIHJlYXNvbiB0aGlzIGlzIGRvbmUgYXQgdGhpcyBsYXRlIAoJICAgICogc3RhZ2UgaXMgdG8gYmUgYWJsZSB0byBjYXRjaCBkdWJsaWNhdGUgYXR0cmlidXRlIHVzZXMuIFNvIHdlIGhhZCB0byBrZWVwCgkgICAgKiBwcm9oaWJpdGVkIHVzZXMgaW4gdGhlIGxpc3QgYXMgd2VsbC4KCSAgICAqLwoJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJdG1wID0gY3VyOwoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCWN1ciA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKHRtcCk7CgkgICAgfSBlbHNlIHsKCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9ICAgIAogICAgfQogICAgLyoJCiAgICAgKiBUT0RPOiBUaGlzIGNoZWNrIHNob3VsZCBiZSByZW1vdmVkIGlmIHdlIGFyZSAxMDAlIHN1cmUgb2YKICAgICAqIHRoZSBiYXNlIHR5cGUgYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBiZWluZyBidWlsdC4KICAgICAqLwogICAgaWYgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoIWJhc2VJc0FueVR5cGUpICYmCgkoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBiYXNlVHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAiYXR0cmlidXRlIHVzZXMgbm90IGJ1aWxkZWQgb24gYmFzZSB0eXBlICclcycuXG4iLAoJICAgIGJhc2VUeXBlLT5uYW1lLCBOVUxMKTsKICAgIH0gICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnM6CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hCiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVmaW5pdGlvbgogKiBAZmluYWw6IHRoZSBmaW5hbAogKgogKiBFdmFsdWF0ZXMgaWYgYSB0eXBlIGRlZmluaXRpb24gY29udGFpbnMgdGhlIGdpdmVuICJmaW5hbCIuCiAqIFRoaXMgZG9lcyB0YWtlICJmaW5hbERlZmF1bHQiIGludG8gYWNjb3VudCBhcyB3ZWxsLgogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgZG9lcyBjb250YWludCB0aGUgZ2l2ZW4gImZpbmFsIiwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgaW50IGZpbmFsKQp7CiAgICBpbnQgdGZpbmFsID0gZmluYWwsIHRmbGFncyA9IHR5cGUtPmZsYWdzOwoKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOyAgICAKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfREVGQVVMVCkgewoJc3dpdGNoIChmaW5hbCkgewoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT046CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT047CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1Q6CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNUOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OOwoJCWJyZWFrOwoJfQoJdGZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIH0KICAgIGlmICh0ZmxhZ3MgJiB0ZmluYWwpIAoJcmV0dXJuICgxKTsKICAgIGVsc2UKCXJldHVybiAoMCk7CiAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzOgogKiBAdHlwZTogIHRoZSBVbmlvbiBTaW1wbGUgVHlwZQogKgogKiBSZXR1cm5zIGEgbGlzdCBvZiBtZW1iZXIgdHlwZXMgb2YgQHR5cGUgaWYgZXhpc3RpbmcsIAogKiByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVMaW5rUHRyCnhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgkgICAgcmV0dXJuICh0eXBlLT5tZW1iZXJUeXBlcyk7CgllbHNlCgkgICAgdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgaXRlbSB0eXBlIGRlZmluaXRpb24gb2YgdGhlIGxpc3Qgc2ltcGxlIHR5cGUuCiAqLyAKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApCglyZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogTm90ZTogSW4gbGlieG1sMiwgdGhlIGJ1aWx0LWluIHR5cGVzIGRvIG5vdCByZWZsZWN0IAogICAgKiB0aGUgZGF0YXR5cGUgaGllcmFyY2h5ICh5ZXQ/KSAtIHdlIGhhdmUgdG8gdHJlYXQgdGhlbQogICAgKiBpbiBhIHNwZWNpYWwgd2F5LgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgCglyZXR1cm4gKHhtbFNjaGVtYUdldEJ1aWx0SW5MaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUpKTsKICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkKCS8qIDEgSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlIHR5cGUgCgkqIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIAoJKiBpdGVtVHlwZSBbYXR0cmlidXRlXSBvZiA8bGlzdD4sIGlmIHByZXNlbnQsIG90aGVyd2lzZSAKCSogdGhlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gCgkqIGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDxsaXN0Pi4KCSovCglyZXR1cm4gKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyk7CiAgICBlbHNlIHsKCS8qIDIgSWYgdGhlIDxyZXN0cmljdGlvbj4gb3B0aW9uIGlzIGNob3NlbiwgdGhlbiB0aGUgCgkqIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkqLyAgICAKCXJldHVybiAoeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlLT5iYXNlVHlwZSkpOwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0s6CiAqIEB0eXBlOiAgdGhlIGRlcml2ZWQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHdoZXRlciBAdHlwZSBjYW4gYmUgdmFsaWRseSAKICogZGVyaXZlZCBmcm9tIEBiYXNlVHlwZS4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIGFuIHBvc2l0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8gCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCQkgICAgIGludCBzdWJzZXQpCnsgICAKICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpCiAgICAqCiAgICAqCiAgICAqIDEgVGhleSBhcmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLgogICAgKiBUT0RPOiBUaGUgaWRlbnR5IGNoZWNrIG1pZ2h0IGhhdmUgdG8gYmUgbW9yZSBjb21wbGV4IHRoYW4gdGhpcy4KICAgICovCiAgICBpZiAodHlwZSA9PSBiYXNlVHlwZSkKCXJldHVybiAoMCk7ICAgIAogICAgLyogCiAgICAqIDIuMSByZXN0cmljdGlvbiBpcyBub3QgaW4gdGhlIHN1YnNldCwgb3IgaW4gdGhlIHtmaW5hbH0KICAgICogb2YgaXRzIG93biB7YmFzZSB0eXBlIGRlZmluaXRpb259OwogICAgKi8KICAgIGlmICgoc3Vic2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikgfHwKCSh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhzY2hlbWEsIAoJICAgIHR5cGUtPmJhc2VUeXBlLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkpIHsKCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8xKTsgCiAgICB9CiAgICAvKiAyLjIgKi8KICAgIGlmICh0eXBlLT5iYXNlVHlwZSA9PSBiYXNlVHlwZSkgewoJLyoKCSogMi4yLjEgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgQi4KCSovCglyZXR1cm4gKDApOwogICAgfSAgIAogICAgLyogCiAgICAqIDIuMi4yIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIG5vdCB0aGUgt3VyLXR5cGUgZGVmaW5pdGlvbrcgCiAgICAqIGFuZCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQsIGFzIGRlZmluZWQgYnkgdGhpcyAKICAgICogY29uc3RyYWludC4gICAgCiAgICAqLwogICAgaWYgKCh0eXBlLT5iYXNlVHlwZSAhPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKSkgJiYKCSh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIGJhc2VUeXBlLCBzdWJzZXQpID09IDApKSB7CglyZXR1cm4gKDApOwkJCiAgICB9IAogICAgLyogCiAgICAqIDIuMi4zIEQncyB7dmFyaWV0eX0gaXMgbGlzdCBvciB1bmlvbiBhbmQgQiBpcyB0aGUgt3NpbXBsZSB1ci10eXBlIAogICAgKiBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB8fAoJKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSkgJiYKCShiYXNlVHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkpIHsKCXJldHVybiAoMCk7CiAgICB9ICAgIAogICAgLyogCiAgICAqIDIuMi40IEIncyB7dmFyaWV0eX0gaXMgdW5pb24gYW5kIEQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIGluIEIncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBzdWJzZXQsIGFzIAogICAgKiBkZWZpbmVkIGJ5IHRoaXMgY29uc3RyYWludC4KICAgICoKICAgICogTk9URTogVGhpcyBzZWVtcyBub3QgdG8gaW52b2x2ZSBidWlsdC1pbiB0eXBlcywgc2luY2UgdGhlcmUgaXMgbm8KICAgICogYnVpbHQtaW4gVW5pb24gU2ltcGxlIFR5cGUuCiAgICAqLwogICAgaWYgKGJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgY3VyOwoKCWN1ciA9IGJhc2VUeXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHNjaGVtYSwgdHlwZSwgCgkJY3VyLT50eXBlLCBzdWJzZXQpID09IDApCgkJcmV0dXJuICgwKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQogICAgfQogICAgCiAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9ERVJJVkVEX09LXzJfMik7Cn0KCgovKioKICogeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHN0LXByb3BzLWNvcnJlY3QuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgcHJvcGVydGllcyBhcmUgY29ycmVjdCwKICogaWYgbm90LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlLCBhbnlTaW1wbGVUeXBlLAoJYW55VHlwZTsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgLyogU1RBVEU6IGVycm9yIGZ1bmNzIGNvbnZlcnRlZC4gKi8KICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICoKICAgICogTk9URTogVGhpcyBpcyBzb21laG93IHJlZHVuZGFudCwgc2luY2Ugd2UgYWN0dWFsbHkgYnVpbHQgYSBzaW1wbGUgdHlwZQogICAgKiB0byBoYXZlIGFsbCB0aGUgbmVlZGVkIGluZm9ybWF0aW9uOyB0aGlzIGFjdHMgYXMgYW4gc2VsZiB0ZXN0LgogICAgKi8KICAgIGFueVNpbXBsZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKICAgIGFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIC8qIAogICAgKiBUT0RPOiAxIFRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG11c3QgYmUgYXMgCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBEYXRhdHlwZSBkZWZpbml0aW9uLCBtb2R1bG8gdGhlIAogICAgKiBpbXBhY3Qgb2YgTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuCiAgICAqLwogICAgLyogQmFzZSB0eXBlOiBJZiB0aGUgZGF0YXR5cGUgaGFzIGJlZW4gt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcgCiAgICAqIHRoZW4gdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gY29tcG9uZW50IGZyb20gd2hpY2ggaXQgaXMgt2Rlcml2ZWS3LCAKICAgICogb3RoZXJ3aXNlIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGZvciBhbnlTaW1wbGVUeXBlICinNC4xLjYpLiAKICAgICovCiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiTm8gYmFzZSB0eXBlIGV4aXN0ZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoKGJhc2VUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpICYmCgkoKGJhc2VUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgfHwKCSAoYmFzZVR5cGUgPT0gYW55VHlwZSkpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJUaGUgYmFzZSB0eXBlICVzIGlzIG5vdCBhIHNpbXBsZSB0eXBlIiwgCgkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgaWYgKChiYXNlVHlwZSAhPSBhbnlTaW1wbGVUeXBlKSAmJgoJKHR5cGUtPnN1YnR5cGVzLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIkEgdHlwZSwgZGVyaXZlZCBieSBsaXN0IG9yIHVuaW9uLCBtdXN0IGhhdmUiCgkgICAgInRoZSBzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uIGFzIGJhc2UgdHlwZSwgbm90ICVzIiwKCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIC8qIAogICAgKiBWYXJpZXR5OiBPbmUgb2Yge2F0b21pYywgbGlzdCwgdW5pb259LiAKICAgICovCiAgICBpZiAoKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmCgkoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSAmJgoJKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlIHZhcmlldHkgaXMgYWJzZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKiBUT0RPOiBGaW5pc2ggdGhpcy4gSG1tLCBpcyB0aGlzIGZpbmlzaGVkPyAqLwoKICAgIC8qCiAgICAqIDIgQWxsIHNpbXBsZSB0eXBlIGRlZmluaXRpb25zIG11c3QgYmUgZGVyaXZlZCB1bHRpbWF0ZWx5IGZyb20gdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbiAoc2+3IGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS4gVGhhdCBpcywgaXQgCiAgICAqIG11c3QgYmUgcG9zc2libGUgdG8gcmVhY2ggYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUgb3IgdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbrcgYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCiAgICAqLyAgICAKICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB3aGlsZSAoKGJhc2VUeXBlICE9IE5VTEwpICYmIChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CglpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgY3R4dCwgIE5VTEwpOwoJaWYgKGJhc2VUeXBlID09IGFueVNpbXBsZVR5cGUpCgkgICAgYnJlYWs7CgllbHNlIGlmIChiYXNlVHlwZSA9PSB0eXBlKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMik7Cgl9CSAgIAoJYmFzZVR5cGUgPSBiYXNlVHlwZS0+YmFzZVR5cGU7CiAgICB9ICAgCiAgICAvKgogICAgKiAzIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgYmFzZVR5cGUsIAoJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzMsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIlRoZSAnZmluYWwnIG9mIGl0cyBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAiCgkgICAgIidyZXN0cmljdGlvbiciLAoJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQkKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8zKTsKICAgIH0gICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBAdHlwZSAoc2ltcGxlVHlwZSkgaXMgZGVyaXZlZCAKICogdmFsaWRseSBieSByZXN0cmljdGlvbi4KICoKICogUmV0dXJucyAtMSBvbiBpbnRlcm5hbCBlcnJvcnMsIDAgaWYgdGhlIHR5cGUgaXMgdmFsaWRseSBkZXJpdmVkLCAKICogYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgLyogU1RBVEU6IGVycm9yIGZ1bmNzIGNvbnZlcnRlZC4gKi8KCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogVGhlIGdpdmVuICIKCSAgICAidHlwZSAnJXMnIGlzIG5vdCBhIHVzZXItZGVyaXZlZCBzaW1wbGVUeXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpIHsKCXhtbFNjaGVtYVR5cGVQdHIgcHJpbWl0aXZlOwoJLyogCgkqIDEuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIGFuIGF0b21pYyBzaW1wbGUgCgkqIHR5cGUgZGVmaW5pdGlvbiBvciBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZS4KCSovCQoJaWYgKCh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgYmFzZSB0eXBlICVzIGlzIG5vdCBhbiBhdG9taWMgc2ltcGxlIHR5cGUiLAoJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xKTsKCX0KCS8qIDEuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIAoJKiByZXN0cmljdGlvbi4KCSovCgkvKiBPUFRJTUlaRSBUT0RPIDogVGhpcyBpcyBhbHJlYWR5IGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tTdFByb3BzQ29ycmVjdCAqLwoJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgZmluYWwgb2YgaXRzIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yKTsKCX0KCQoJLyogCgkqIDEuMy4xIERGIG11c3QgYmUgYW4gYWxsb3dlZCBjb25zdHJhaW5pbmcgZmFjZXQgZm9yIHRoZSB7cHJpbWl0aXZlCgkqIHR5cGUgZGVmaW5pdGlvbn0sIGFzIHNwZWNpZmllZCBpbiB0aGUgYXBwcm9wcmlhdGUgc3Vic2VjdGlvbiBvZiAzLjIgCgkqIFByaW1pdGl2ZSBkYXRhdHlwZXMuCgkqLwoJaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkgICAgaW50IG9rID0gMTsKCSAgICAKCSAgICBwcmltaXRpdmUgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5cGUpOwoJICAgIGlmIChwcmltaXRpdmUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkgICAgWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246IGZhaWxlZCAiCgkJICAgICJ0byBnZXQgcHJpbWl0aXZlIHR5cGUgb2YgdHlwZSAnJXMnLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQkgICAgCgkgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkgICAgZG8gewoJCWlmICh4bWxTY2hlbWFJc0J1aWx0SW5UeXBlRmFjZXQocHJpbWl0aXZlLCBmYWNldC0+dHlwZSkgPT0gMCkgewoJCSAgICBvayA9IDA7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSwKCQkJTlVMTCwgdHlwZSwgcHJpbWl0aXZlLCBmYWNldCk7CQkgICAgCQkgICAgCQkgICAgCgkJfQoJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CSAgICAKCSAgICBpZiAob2sgPT0gMCkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEpOwkgICAgCgl9CgkvKgoJKiBUT0RPOiAxLjMuMiAoZmFjZXQgZGVyaXZhdGlvbikKCSovCiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKCXhtbFNjaGVtYVR5cGVQdHIgaXRlbVR5cGUgPSBOVUxMOwoKCWl0ZW1UeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKTsKCWlmIChpdGVtVHlwZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiAiCgkJImZhaWxlZCB0byBldmFsdWF0ZSB0aGUgaXRlbSB0eXBlIG9mIHR5cGUgJyVzJy5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiAyLjEgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIGF0b21pYyBvciAKCSogdW5pb24gKGluIHdoaWNoIGNhc2UgYWxsIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IAoJKiBtdXN0IGJlIGF0b21pYykuCgkqLwoJaWYgKCgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYgIAoJICAgICgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSkgewkgICAgCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgaXRlbSB0eXBlICVzIG11c3QgaGF2ZSBhIHZhcmlldHkgb2YgYXRvbWljIG9yIHVuaW9uIiwKCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCSAgICAKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCX0gZWxzZSBpZiAoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7CgkgICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCSAgICBtZW1iZXIgPSBpdGVtVHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKChtZW1iZXItPnR5cGUtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJCSJUaGUgaXRlbSB0eXBlIGlzIGEgdW5pb24gdHlwZSwgYnV0IHRoZSAiCgkJCSJtZW1iZXIgdHlwZSAlcyBvZiB0aGlzIGl0ZW0gdHlwZSBpcyBub3QgYXRvbWljIiwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAgCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJfQoJCglpZiAodHlwZS0+YmFzZVR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48bGlzdCAuLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4xIAoJICAgICogMi4zLjEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSAgICAqIGNvbnRhaW4gbGlzdC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIAoJCWl0ZW1UeXBlLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBpdGVtIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAnbGlzdCciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBvbmx5IGNvbnRhaW4gdGhlIHdoaXRlU3BhY2UKCSAgICAqIGZhY2V0IGNvbXBvbmVudC4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIsCgkJCSAgICBOVUxMLCB0eXBlLCBmYWNldCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yKTsKCQkgICAgfQoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJICAgIH0KCSAgICAvKgoJICAgICogVE9ETzogRGF0YXR5cGVzIHN0YXRlczogCgkgICAgKiBBILdsaXN0tyBkYXRhdHlwZSBjYW4gYmUgt2Rlcml2ZWS3IGZyb20gYW4gt2F0b21pY7cgZGF0YXR5cGUgCgkgICAgKiB3aG9zZSC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlIChzdWNoIGFzIHN0cmluZyBvciBhbnlVUkkpb3IgCgkgICAgKiBhILd1bmlvbrcgZGF0YXR5cGUgYW55IG9mIHdob3NlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30ncyAKCSAgICAqILdsZXhpY2FsIHNwYWNltyBhbGxvd3Mgc3BhY2UuCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIFRoaXMgaXMgdGhlIGNhc2UgaWYgd2UgaGF2ZTogPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uIC4uLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4yIAoJICAgICogMi4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgbGlzdC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkJICAgICJUaGUgYmFzZSB0eXBlICVzIG11c3QgYmUgYSBsaXN0IHR5cGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkgICAgKiBjb250YWluIHJlc3RyaWN0aW9uLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkJICAgICJUaGUgZmluYWwgb2YgdGhlIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4yLjMgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgCgkgICAgKiBmcm9tIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBnaXZlbgoJICAgICogdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJICAgICovCgkgICAgewoJCXhtbFNjaGVtYVR5cGVQdHIgYmFzZUl0ZW1UeXBlOwoKCQliYXNlSXRlbVR5cGUgPSB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUtPmJhc2VUeXBlKTsKCQlpZiAoYmFzZUl0ZW1UeXBlID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQlYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCQkieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogIgoJCQkiTGlzdCBzaW1wbGUgdHlwZSAnJXMnOiBGYWlsZWQgdG8gIgoJCQkiZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSBvZiBpdHMgYmFzZSB0eXBlICclcycuXG4iLAoJCQl0eXBlLT5uYW1lLCB0eXBlLT5iYXNlVHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlpZiAoKGl0ZW1UeXBlICE9IGJhc2VJdGVtVHlwZSkgJiYKCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soY3R4dC0+c2NoZW1hLCBpdGVtVHlwZSwKCQkgICAgYmFzZUl0ZW1UeXBlLCAwKSAhPSAwKSkgewoJCSAgICB4bWxDaGFyICpzdHJCSVQgPSBOVUxMLCAqc3RyQlQgPSBOVUxMOwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMywKCQkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJCSJUaGUgaXRlbSB0eXBlICVzIGlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUgIgoJCQkiaXRlbSB0eXBlICVzIG9mIHRoZSBiYXNlIHR5cGUgJXMiLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyQklULCBOVUxMLCBiYXNlSXRlbVR5cGUsIE5VTEwsIDEpLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJCVCwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJJVCkKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCVCkJCSAgICAKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzMpOwoJCX0KCSAgICB9CgkgICAgCgkgICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkJaW50IG9rID0gMTsKCQkvKiAKCQkqIDIuMy4yLjQgT25seSBsZW5ndGgsIG1pbkxlbmd0aCwgbWF4TGVuZ3RoLCB3aGl0ZVNwYWNlLCBwYXR0ZXJuIAoJCSogYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIGFsbG93ZWQgYW1vbmcgdGhlIHtmYWNldHN9LgoJCSovCgkJZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkJZG8gewoJCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJCQkgICAgLyoKCQkJICAgICogVE9ETzogMi41LjEuMiBMaXN0IGRhdGF0eXBlcwoJCQkgICAgKiBUaGUgdmFsdWUgb2Ygt3doaXRlU3BhY2W3IGlzIGZpeGVkIHRvIHRoZSB2YWx1ZSBjb2xsYXBzZS4gCgkJCSAgICAqLwoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCQkgICAgYnJlYWs7CgkJCWRlZmF1bHQ6IHsKCQkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfNCwKCQkJCU5VTEwsIHR5cGUsIGZhY2V0KTsKCQkJICAgIC8qCgkJCSAgICAqIFdlIGNvdWxkIHJldHVybiwgYnV0IGl0J3MgbmljZXIgdG8gcmVwb3J0IGFsbCAKCQkJICAgICogaW52YWxpZCBmYWNldHMuCgkJCSAgICAqLwoJCQkgICAgb2sgPSAwOwkJCSAgICAKCQkJfQoJCSAgICB9CQkgICAgCgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80KTsKCQkvKgoJCSogVE9ETzogMi4zLjIuNSBGb3IgZWFjaCBmYWNldCBpbiB0aGUge2ZhY2V0c30gKGNhbGwgdGhpcyBERiksIGlmIHRoZXJlCgkJKiBpcyBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgaW4gdGhlIHtmYWNldHN9IG9mIHRoZSB7YmFzZSB0eXBlIAoJCSogZGVmaW5pdGlvbn0gKGNhbGwgdGhpcyBCRiksdGhlbiB0aGUgREYncyB7dmFsdWV9IG11c3QgYmUgYSB2YWxpZCAKCQkqIHJlc3RyaWN0aW9uIG9mIEJGJ3Mge3ZhbHVlfSBhcyBkZWZpbmVkIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KCQkqLwoJICAgIH0JICAgIAoJICAgIAoKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCS8qCgkqIDMuMSBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGFsbCBoYXZlIHt2YXJpZXR5fSBvZiAKCSogYXRvbWljIG9yIGxpc3QuCgkqLwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgaWYgKCgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmIAoJCSgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbmVpdGhlciBhbiBhdG9taWMsIG5vciBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfMSk7CgkgICAgfQoJICAgIG1lbWJlciA9IG1lbWJlci0+bmV4dDsKCX0KCS8qCgkqIDMuMy4xIElmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3c2ltcGxlIHVyLXR5cGUgCgkqIGRlZmluaXRpb263IAoJKi8KCWlmICh0eXBlLT5iYXNlVHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkgewoJICAgIC8qCgkgICAgKiAzLjMuMS4xIEFsbCBvZiB0aGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGhhdmUgYSAKCSAgICAqIHtmaW5hbH0gd2hpY2ggZG9lcyBub3QgY29udGFpbiB1bmlvbi4KCSAgICAqLwoJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCWlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIG1lbWJlci0+dHlwZSwgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT04pKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIlRoZSBmaW5hbCBvZiBtZW1iZXIgdHlwZSAlcyBjb250YWlucyAndW5pb24nIiwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBiZSBlbXB0eS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAoJCSAgICAiTm8gZmFjZXRzIGFsbG93ZWQiLCBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzFfMik7CgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogMy4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgdW5pb24uCgkgICAgKi8KCSAgICBpZiAoKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgPT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGJhc2UgdHlwZSAlcyBpcyBub3QgYSB1bmlvbiB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLCAKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzIpOwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuMyBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIsIG11c3QgYmUgdmFsaWRseSAKCSAgICAqIGRlcml2ZWQgZnJvbSB0aGUgY29ycmVzcG9uZGluZyB0eXBlIGRlZmluaXRpb25zIGluIHRoZSB7YmFzZSAKCSAgICAqIHR5cGUgZGVmaW5pdGlvbn0ncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBlbXB0eSBzZXQsIAoJICAgICogYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJICAgICovCgkgICAgewoJCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGJhc2VNZW1iZXI7CgoJCS8qCgkJKiBPUFRJTUlaRTogaWYgdGhlIHR5cGUgaXMgcmVzdHJpY3RpbmcsIGl0IGhhcyBubyBsb2NhbCBkZWZpbmVkIAoJCSogbWVtYmVyIHR5cGVzIGFuZCBpbmhlcml0cyB0aGUgbWVtYmVyIHR5cGVzIG9mIHRoZSBiYXNlIHR5cGU7IAoJCSogdGh1cyBhIGNoZWNrIGZvciBlcXVhbGl0eSBjYW4gYmUgc2tpcHBlZC4KCQkqLwoJCS8qCgkJKiBUT0RPOiBFdmVuIHdvcnNlOiBJIGNhbm5vdCBzZWUgYSBzY2VuYXJpbyB3aGVyZSBhIHJlc3RyaWN0aW5nCgkJKiB1bmlvbiBzaW1wbGUgdHlwZSBjYW4gaGF2ZSBvdGhlciBtZW1iZXIgdHlwZXMgYXMgdGhlIG1lbWJlciAKCQkqIHR5cGVzIG9mIGl0J3MgYmFzZSB0eXBlLiBUaGlzIGNoZWNrIHNlZW1zIG5vdCBuZWNlc3Nhcnkgd2l0aAoJCSogcmVzcGVjdCB0byB0aGUgZGVyaXZhdGlvbiBwcm9jZXNzIGluIGxpYnhtbDIuCgkJKi8KCQlpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkgewoJCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCQkgICAgYmFzZU1lbWJlciA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHR5cGUtPmJhc2VUeXBlKTsKCQkgICAgaWYgKChtZW1iZXIgPT0gTlVMTCkgJiYgKGJhc2VNZW1iZXIgIT0gTlVMTCkpIHsJCSAgIAoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogIgoJCQkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb24gIgoJCQkgICAgIigzLjMuMi4zKSwgdW5pb24gc2ltcGxlIHR5cGUgJyVzJywgdW5lcXVhbCBudW1iZXIgIgoJCQkgICAgIm9mIG1lbWJlciB0eXBlcyBpbiB0aGUgYmFzZSB0eXBlXG4iLAoJCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIH0JCQoJCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQkJaWYgKGJhc2VNZW1iZXIgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCQkiSW50ZXJuYWwgZXJyb3I6ICIKCQkJCSJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uICIKCQkJCSIoMy4zLjIuMyksIHVuaW9uIHNpbXBsZSB0eXBlICclcycsIHVuZXF1YWwgbnVtYmVyICIKCQkJCSJvZiBtZW1iZXIgdHlwZXMgaW4gdGhlIGJhc2UgdHlwZS5cbiIsCgkJCQl0eXBlLT5uYW1lLCBOVUxMKTsKCQkJfQoJCQlpZiAoKG1lbWJlci0+dHlwZSAhPSBiYXNlTWVtYmVyLT50eXBlKSAmJgoJCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soY3R4dC0+c2NoZW1hLCAKCQkJICAgIG1lbWJlci0+dHlwZSwgYmFzZU1lbWJlci0+dHlwZSwgMCkgIT0gMCkpIHsKCQkJICAgIHhtbENoYXIgKnN0ckJNVCA9IE5VTEwsICpzdHJCVCA9IE5VTEw7CgoJCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJCSJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIGl0cyAiCgkJCQkiY29ycmVzcG9uZGluZyBtZW1iZXIgdHlwZSAlcyBvZiB0aGUgYmFzZSB0eXBlICVzIiwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJNVCwgTlVMTCwgYmFzZU1lbWJlci0+dHlwZSwgTlVMTCwgMSksCgkJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJCVCwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCTVQpCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJUKQoJCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzMpOwoJCQl9CQkKCQkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJCQliYXNlTWVtYmVyID0gYmFzZU1lbWJlci0+bmV4dDsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjQgT25seSBwYXR0ZXJuIGFuZCBlbnVtZXJhdGlvbiBmYWNldCBjb21wb25lbnRzIGFyZSAKCSAgICAqIGFsbG93ZWQgYW1vbmcgdGhlIHtmYWNldHN9LgoJICAgICovCSAgICAKCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCQlpbnQgb2sgPSAxOwoKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmICgoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSAmJgoJCQkoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80LAoJCQkJTlVMTCwgdHlwZSwgZmFjZXQpOwkJCQoJCQlvayA9IDA7CQkJICAgIAoJCSAgICB9CQkgICAgCgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80KTsKCQkgICAgCgkgICAgfQoJICAgIC8qCgkgICAgKiBUT0RPOiAzLjMuMi41IChmYWNldCBkZXJpdmF0aW9uKQoJICAgICovCgl9CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIGNyYy1zaW1wbGUtdHlwZSBjb25zdHJhaW50cy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLAogKiBpZiBub3QgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAKICAgIC8qCiAgICAqIE5PVEU6IHNyYy1zaW1wbGUtdHlwZSAyLTQgYXJlIHJlZHVuZGFudCwgc2luY2UgdGhlIGNoZWNrcwogICAgKiB3ZXJlIGFyZSBkb25lIGZvciB0aGUgY29ycmVzcG9uZGluZyA8cmVzdHJpY3Rpb24+LCA8bGlzdD4gYW5kIDx1bmlvbj4KICAgICogZWxlbWVudHMsIGJ1dCBXM0Mgd2FudHMgYSA8c2ltcGxlVHlwZT4gZXJyb3IgYXMgd2VsbCwgc28gaXQgZ2V0cyBvbmUuCiAgICAqIE1hYnkgdGhpcyBjYW4gYmUgc2tpcHBlZCBpbiB0aGUgZnV0dXJlLCBpZiB3ZSBnZXQgc3VyZSBpdCdzIG5vdCBuZWVkZWQuCiAgICAqLwogICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZSwgIgoJCSJubyBzdWJ0eXBlIG9uIHNpbXBsZSB0eXBlICclcycuXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKiAKICAgICogc3JjLXNpbXBsZS10eXBlLjEgVGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgaWYgYW55LAogICAgKiBtdXN0IHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBTaW1wbGUgVHlwZSAKICAgICogRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cyAopzMuMTQuNikuICAgIAogICAgKi8KICAgIGlmICgoeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdChjdHh0LCB0eXBlKSAhPSAwKSB8fAoJKHhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoY3R4dCwgdHlwZSkgIT0gMCkpIHsKCS8qCgkqIFRPRE86IFJlbW92ZWQgdGhpcywgc2luY2UgaXQgZ290IGFubm95aW5nIHRvIGdldCBhbgoJKiBleHRyYSBlcnJvciByZXBvcnQsIGlmIGFueXRoaW5nIGZhaWxlZCB1bnRpbCBub3cuCgkqIEVuYWJsZSB0aGlzIGlmIG5lZWRlZC4KCSovCgkvKgoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgICJTaW1wbGUgdHlwZSAnJXMnIGRvZXMgbm90IHNhdGlzZnkgdGhlIGNvbnN0cmFpbnRzICIKCSAgICAib24gc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJKi8KCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEpOwogICAgfQoKICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHsKCS8qCgkqIHNyYy1zaW1wbGUtdHlwZS4yIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgCgkqIGVpdGhlciBpdCBtdXN0IGhhdmUgYSBiYXNlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyAKCSogW2NoaWxkcmVuXSwgYnV0IG5vdCBib3RoLgoJKi8JCgkvKgoJKiBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMgoJKiBOT1RFOiBUaGlzIHdhcyByZW1vdmVkLCBzaW5jZSB0aGlzIHdpbGwgYmUgYWxyZWFkeSBoYW5kbGVkCgkqIGluIHRoZSBwYXJzZSBmdW5jdGlvbiBmb3IgPHJlc3RyaWN0aW9uPi4gCgkqLwkKICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0xJU1QpIHsKCS8qIHNyYy1zaW1wbGUtdHlwZS4zIElmIHRoZSA8bGlzdD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCBlaXRoZXIgaXQgbXVzdCBoYXZlIAoJKiBhbiBpdGVtVHlwZSBbYXR0cmlidXRlXSBvciBhIDxzaW1wbGVUeXBlPiBhbW9uZyBpdHMgW2NoaWxkcmVuXSwgCgkqIGJ1dCBub3QgYm90aC4KCSogTk9URTogYmFzZVR5cGUgaXMgc2V0IHRvIHRoZSBsb2NhbCBzaW1wbGUgdHlwZSBkZWZpbml0b24sCgkqIGlmIGV4aXN0ZW50LCBhdCBwYXJzZSB0aW1lLiBUaGlzIGlzIGEgaGFjayBhbmQgbm90IG5pY2UuCgkqLwoJLyoKCSogVE9ETzogUmVtb3ZlIHRoaXMsIGFuZCBhZGQgdGhlIGNoZWNrIHRvIHRoZSBwYXJzZSBmdW5jdGlvbiBvZiA8bGlzdD4uCgkqLwoJaWYgKCgodHlwZS0+c3VidHlwZXMtPmJhc2UgPT0gTlVMTCkgJiYgCgkgICAgICh0eXBlLT5iYXNlVHlwZSA9PSBOVUxMKSkgfHwJICAgICAgCgkgICAgKCh0eXBlLT5zdWJ0eXBlcy0+YmFzZSAhPSBOVUxMKSAmJgoJICAgICAodHlwZS0+c3VidHlwZXMtPmJhc2VUeXBlICE9IE5VTEwpKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzMsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCQkibXVzdCBiZSBwcmVzZW50IG9uIHRoZSA8bGlzdD4gY2hpbGQgIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8zKTsKCX0KICAgIAoKICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7Cgl4bWxTY2hlbWFUeXBlUHRyIGFuY2VzdG9yLCBhbnlTaW1wbGVUeXBlOwoKCWFueVNpbXBsZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCgkvKiBzcmMtc2ltcGxlLXR5cGUuNCBDaXJjdWxhciB1bmlvbiB0eXBlIGRlZmluaXRpb24gaXMgZGlzYWxsb3dlZC4gVGhhdCBpcywgaWYgCgkqIHRoZSA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlcmUgbXVzdCBub3QgYmUgYW55IGVudHJpZXMgCgkqIGluIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBhdCBhbnkgZGVwdGggd2hpY2ggcmVzb2x2ZSB0byB0aGUgCgkqIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4uCgkqLwkKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgYW5jZXN0b3IgPSBtZW1iZXItPnR5cGU7CgkgICAgd2hpbGUgKChhbmNlc3RvciAhPSBOVUxMKSAmJiAoYW5jZXN0b3ItPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkgewoJCWlmIChhbmNlc3Rvci0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChhbmNlc3RvciwgY3R4dCwgIE5VTEwpOwoJCWlmIChhbmNlc3RvciA9PSBhbnlTaW1wbGVUeXBlKQoJCSAgICBicmVhazsKCQllbHNlIGlmIChhbmNlc3RvciA9PSB0eXBlKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80LAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfNCk7CgkJfSBlbHNlIGlmIChhbmNlc3Rvci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJCSAgICAvKgoJCSAgICAqIFRPRE8sIEZJWE1FOiBBbHRob3VnaCBhIGxpc3Qgc2ltcGxlIHR5cGUgbXVzdCBub3QgaGF2ZSBhIHVuaW9uIFNUCgkJICAgICogdHlwZSBhcyBpdGVtIHR5cGUsIHdoaWNoIGluIHR1cm4gaGFzIGEgbGlzdCBTVCBhcyBtZW1iZXIgCgkJICAgICogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhpcyBoZXJlIGFzIHdlbGwsIHNpbmNlIHRoaXMgY2hlY2sgCgkJICAgICogd2FzIG5vdCB5ZXQgcGVyZm9ybWVkLgoJCSAgICAqLwoKCQl9CgkJYW5jZXN0b3IgPSBhbmNlc3Rvci0+YmFzZVR5cGU7CgkgICAgfSAgIAoJICAgIG1lbWJlciA9IG1lbWJlci0+bmV4dDsKCX0KICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgojaWYgMCAvKiBOb3QgeWV0IHVzZWQgY29kZSBmb3IgQ1Qgc2NoZW1hIHZhbGlkYXRpb24gKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ1NpbXBsZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSAgICBjb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICBpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldDsKICAgIC8qCiAgICAqIDMuMTQuNCBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKICAgICogVmFsaWRhdGlvbiBSdWxlOiBTdHJpbmcgVmFsaWQKICAgICovCiAgICAvKgogICAgKiAxIEl0IGlzIHNjaGVtYS12YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQgCiAgICAqIGJ5IERhdGF0eXBlIFZhbGlkIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgCglmaXJlRXJyb3JzLCAxLCAxLCAxKTsKICAgIHJldHVybiAocmV0KTsKICAgIC8qCiAgICAqIDIuMSBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVFkgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRZIGdpdmVuIAogICAgKiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNiksIHRoZW4KICAgICogdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkIGVudGl0eSBuYW1lty4KICAgICovCiAgICAvKgogICAgKiAyLjIgSWYgVGhlIGRlZmluaXRpb24gaXMgRU5USVRJRVMgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRJRVMgCiAgICAqIGdpdmVuIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgCiAgICAqIHRoZW4gZXZlcnkgd2hpdGVzcGFjZS1kZWxpbWl0ZWQgc3Vic3RyaW5nIG9mIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZCAKICAgICogZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMyBvdGhlcndpc2Ugbm8gZnVydGhlciBjb25kaXRpb24gYXBwbGllcy4KICAgICovCgogICAgcmV0dXJuICgwKTsKfQojZW5kaWYKCgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CiAgICAgICAgdmN0eHQtPnBjdHh0ID14bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdCgiKiIsIHZjdHh0LT5zY2hlbWEtPmRpY3QpOwoJLyogdmN0eHQtPnBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOyAqLwoJaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycih2Y3R4dCwgTlVMTCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCwgIgoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQuXG4iLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyogVE9ETzogUGFzcyB1c2VyIGRhdGEuICovCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnModmN0eHQtPnBjdHh0LCB2Y3R4dC0+ZXJyb3IsIHZjdHh0LT53YXJuaW5nLCBOVUxMKTsJCiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCWN0eHQtPnZjdHh0ID0geG1sU2NoZW1hTmV3VmFsaWRDdHh0KE5VTEwpOwoJaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQsICIKCQkiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKGN0eHQtPnZjdHh0LCBjdHh0LT5lcnJvciwgY3R4dC0+d2FybmluZywgTlVMTCk7CQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAdmFsdWU6IHRoZSBkZWZhdWx0IHZhbHVlCiAqIEBub2RlOiBhbiBvcHRpb25hbCBub2RlICh0aGUgaG9sZGVyIG9mIHRoZSB2YWx1ZSkKICoKICogQ2hlY2tzIHRoZSAiY29zLXZhbGlkLWRlZmF1bHQiIGNvbnN0cmFpbnRzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgCiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBjb3MtdmFsaWQtZGVmYXVsdDoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKICAgICogRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCB3aXRoIHJlc3BlY3QgdG8gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgaGFzIHRvIHdvcmsgd2l0aG91dCBhIGdpdmVuIG5vZGUgKHRoZSBob2xkZXIgb2YgdGhlCiAgICAqIHZhbHVlKSwgc2luY2UgaXQgc2hvdWxkIHdvcmsgb24gdGhlIGNvbXBvbmVudCwgaS5lLiBhbiB1bmRlcmx5aW5nCiAgICAqIERPTSBtdXN0IG5vdCBiZSBtYW5kYXRvcnkuCiAgICAqLyAgICAgCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8ICh2Y3R4dCA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgbm9kZSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0LCAiCgkgICAgImJhZCBhcmd1bWVudHM6IHRoZSBwYXJzZXIgYW5kL29yIHZhbGlkYXRpb24gY29udGV4dCBpcyAiCgkgICAgIm1pc3NpbmcuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CQogICAgfSAgICAgICAKICAgIGlmIElTX0NPTVBMRVhfVFlQRSh0eXBlKSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIDIuMSBpdHMge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgbWl4ZWQuCgkqLwoJLyogCgkqIFRPRE86IEFkanVzdCB0aGlzIHdoZW4gdGhlIGNvbnRlbnQgdHlwZSB3aWxsIGJlIGNvbXB1dGVkIAoJKiBjb3JyZWN0bHkuIAoJKi8KCWlmICgodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgJiYKCSAgICAodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSAmJgoJICAgICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsIAoJCVhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCXR5cGUsIE5VTEwsIE5VTEwsCgkJIklmIHRoZSB0eXBlIG9mIGEgY29uc3RyYWludCB2YWx1ZSBpcyBjb21wbGV4LCBpdHMgY29udGVudCAiCgkJInR5cGUgbXVzdCBiZSBtaXhlZCBvciBhIHNpbXBsZSB0eXBlIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xKTsKCX0KCWlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHsKCSAgICAvKgoJICAgICogMi4yLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIG1peGVkLCB0aGVuIHRoZSB7Y29udGVudCB0eXBlfSdzIAoJICAgICogcGFydGljbGUgbXVzdCBiZSC3ZW1wdGlhYmxltyBhcyBkZWZpbmVkIGJ5IFBhcnRpY2xlIEVtcHRpYWJsZSAKCSAgICAqICinMy45LjYpLgoJICAgICovCgkgICAgCgkgICAgLyoKCSAgICAqIFVSR0VOVCBUT0RPOiBJbXBsZW1lbnQgdGhpcy4KCSAgICAqLwoJICAgIHJldHVybiAoMCk7Cgl9CiAgICB9CQogICAgLyoKICAgICogMSBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgc3RyaW5nIAogICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKICAgICogVmFsaWQgKKczLjE0LjQpLgogICAgKgogICAgKiBBTkQKICAgICoKICAgICogMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCiAgICAqIHN0cmluZyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKICAgICogYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgogICAgKi8gICAgCiAgICB2Y3R4dC0+bm9kZSA9IG5vZGU7CiAgICB2Y3R4dC0+Y3VyID0gTlVMTDsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCB0eXBlLCB2YWx1ZSwgMSwgMSwgMSwgMCk7CiAgICAvKiByZXQgPSB4bWxTY2hlbWFDaGVja0NWQ1NpbXBsZVR5cGUodmN0eHQsIGVsZW1EZWNsLT52YWx1ZSwgdHlwZURlZiwgMCk7ICovICAgCiAgICBpZiAocmV0IDwgMCkgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgbm9kZSwKCS8qIE5PVE5JQ0U6IGVycm9yIGNvZGU6IFRoaXMgZnVuY3Rpb24gd2lsbCBiZSB1c2VkIGR1cmluZwoJKiBzY2hlbWEgY29uc3RydWN0aW9uIGFuZCB4c2k6dHlwZSB2YWxpZGF0aW9uLgoJKi8KCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJIndoaWxlIHZhbGlkYXRpbmcgYSB2YWx1ZSBjb25zdGFpbnQgdmFsdWUuXG4iLAoJTlVMTCwgTlVMTCk7CgogICAgfSAgICAgCSAgICAKICAgIHJldHVybiAocmV0KTsKfQoKI2lmIDAgLyogTm90IHlldCB1c2VkIGNvZGUgZm9yIENUIHNjaGVtYSB2YWxpZGF0aW9uICovCi8qKgogKiB4bWxTY2hlbWFHZXRTVENvbnRlbnRPZkNUOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICoKICogUmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBmb3IgdGhlIGNvbnRlbnQgb2YKICogdGhlIGNvbXBsZXggdHlwZS4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFNUQ29udGVudE9mQ1QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb3JpZyA9IHR5cGUsIGFueVR5cGU7CgogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgd2hpbGUgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlICE9IGFueVR5cGUpICYmIAoJKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKSB7CglpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKQoJICAgIHJldHVybih0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJTlVMTCwgb3JpZywgTlVMTCwKCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0U1RDb250ZW50VHlwZU9mQ1QsICIKCSJubyBzaW1wbGUgdHlwZSBmb3IgdGhlIGNvbnRlbnQgb2YgY29tcGxleCB0eXBlICclcycgY291bGQgYmUgIgoJImNvbXB1dGVkIiwgb3JpZy0+bmFtZSk7CiAgICByZXR1cm4gKE5VTEwpOwp9CgoKCgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgLyogCiAgICAqIDEgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwgCiAgICAqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHMsICIKCSAgICAidGhlIGNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKGJhc2UtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCS8qCgkqIDEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSogY29udGFpbiBleHRlbnNpb24uCgkqLwoJaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04pIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImNvbnRhaW5zIGV4dGVuc2lvbiIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KCS8qCgkqIDEuMiBJdHMge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSB7YXR0cmlidXRlIHVzZXN9IAoJKiBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmLCB0aGF0IGlzLCBmb3IgZXZlcnkgYXR0cmlidXRlIAoJKiB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0sIHRoZXJlIAoJKiBtdXN0IGJlIGFuIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGNvbXBsZXggCgkqIHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIHRoZSBzYW1lIAoJKiB7bmFtZX0sIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge3R5cGUgZGVmaW5pdGlvbn0gYXMgaXRzIGF0dHJpYnV0ZSAKCSogZGVjbGFyYXRpb24KCSoKCSogTk9URTogVGhpcyB3aWxsIGJlIGFscmVhZHkgc2F0aXNmaWVkIGJ5IHRoZSB3YXkgdGhlIGF0dHJpYnV0ZSB1c2VzCgkqIGFyZSBleHRlbmRlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgdGhpcyBjaGVjawoJKiBpcyBub3QgbmVlZGVkLgoJKi8KCgkvKgoJKiAxLjMgSWYgaXQgaGFzIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gCgkqIG11c3QgYWxzbyBoYXZlIG9uZSwgYW5kIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgCgkqIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUgY29tcGxleCAKCSogdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9LCAKCSogYXMgZGVmaW5lZCBieSBXaWxkY2FyZCBTdWJzZXQgKKczLjEwLjYpLgoJKgoJKiBUaGlzIGlzIGFscmVhZHkgY2hlY2tlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgCgkqIHRoaXMgY2hlY2sgaXMgbm90IG5lZWRlZC4KCSovCgkKCS8qCgkqIDEuNCBPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqCgkqIDEuNC4xIFRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBhbmQgdGhlIAoJKiB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmIG11c3QgYmUgdGhlIHNhbWUgCgkqIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KCSovCgoKCQogICAgfSBlbHNlIHsKCS8qCgkqIDIgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAKCSogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJLyoKCSogMi4xIFRoZSB7Y29udGVudCB0eXBlfSBtdXN0IGJlIHRoZSBzYW1lIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwoJLyoKCSogMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gCgkqIGV4dGVuc2lvbgoJKi8KICAgIH0KCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNDVCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgY29udGVudDsKICAgIGludCBPSyA9IDA7CgogICAgLyoKICAgICogVE9ETzogQWRqdXN0IHRoZSBlcnJvciBjb2RlcyBoZXJlLCBhcyBJIHVzZWQKICAgICogWE1MX1NDSEVNQVBfU1JDX0NUXzEgb25seSB5ZXQuCiAgICAqLwogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAogICAgKiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSwogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIE5VTEwsIHR5cGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja1NSQ0NULCAnJXMnLCBubyBiYXNlIHR5cGUiLCAKCSAgICB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgCiAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewoJaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCSAgICBpZiBJU19DT01QTEVYX1RZUEUoYmFzZSkgewoJCS8qCgkJKiAxIElmIHRoZSA8Y29tcGxleENvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlIHR5cGUgZGVmaW5pdGlvbgoJCSogt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gCgkJKiBtdXN0IGJlIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb247CgkJKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGJhc2UgdHlwZSBpcyBub3QgYSBjb21wbGV4IHR5cGUiLCBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgewoKCSAgICBpZiBJU19TSU1QTEVfVFlQRShiYXNlKSB7CgkJaWYgKHR5cGUtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCQkgICAgLyogCgkJICAgICogMi4xLjMgb25seSBpZiB0aGUgPGV4dGVuc2lvbj4gYWx0ZXJuYXRpdmUgaXMgYWxzbyAKCQkgICAgKiBjaG9zZW4sIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCQkgICAgKi8KCQkgICAgLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzFfMy4gKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90IHJlc3RyaWN0ICIKCQkJImFuIG90aGVyIHNpbXBsZSB0eXBlIiwKCQkJTlVMTCk7CgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCX0KCQlPSyA9IDE7CgoJICAgIH0gZWxzZSB7IC8qIGlmIElTX1NJTVBMRV9UWVBFKGJhc2UpICovCgkJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkJICAgIC8qCgkJICAgICogMi4xLjIgb25seSBpZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBhbHNvIAoJCSAgICAqIGNob3NlbiwgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfSAKCQkgICAgKiBpcyBtaXhlZCBhbmQgYSBwYXJ0aWNsZSBlbXB0eWFibGUuCgkJICAgICovCQoJCSAgICAvKgoJCSAgICAqIEZJWE1FIFRPRE86IENoZWNrIGZvciAqZW1waWFibGUgcGFydGljbGUqIGlzIG1pc3NpbmcuIAoJCSAgICAqLwoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYgCgkJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pID09IDApIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90ICIKCQkJICAgICJleHRlbmQgYW4gb3RoZXIgY29tcGxleCB0eXBlIHdoaWNoIGhhcyBhICIKCQkJICAgICJjb250ZW50IHR5cGUgb2Y6ICdtaXhlZCcgYW5kIGVtcHRpYWJsZSBwYXJ0aWNsZSIsCgkJCSAgICBOVUxMKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBOT1RFOiBUaGlzIHdpbGwgYmUgZmlyZWQgYXMgd2VsbCwgaWYgdGhlIGJhc2UgdHlwZQoJCSAgICAqIGlzIConYW55VHlwZScqLgoJCSAgICAqIE5PVEU6IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyB3aWxsIGJlIHRoZSAKCQkgICAgKiA8cmVzdHJpY3Rpb24+IGl0ZW0uCgkJICAgICovCgkJICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgewoJCQkvKiBZZXMsIHRoaXMgaXMgcGFyYW5vaWQgcHJvZ3JhbW1pbmcuICovCgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkgICAgIiclcycsIDxzaW1wbGVDb250ZW50PiBoYXMgbm8gPHJlc3RyaWN0aW9uPiIsIAoJCQkgICAgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogMi4yIElmIGNsYXVzZSAyLjEuMiBhYm92ZSBpcyBzYXRpc2ZpZWQsIHRoZW4gdGhlcmUgCgkJICAgICogbXVzdCBiZSBhIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiAKCQkgICAgKiA8cmVzdHJpY3Rpb24+LgoJCSAgICAqLwogICAgCQkgICAgaWYgKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+dHlwZSAhPQoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkJCS8qIFRPRE86IENoYW5nZSBlcnJvciBjb2RlIHRvIC4uLl9TUkNfQ1RfMl8yLiAqLwoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSA8c2ltcGxlVHlwZT4gaXMgZXhwZWN0ZWQgYW1vbmcgdGhlIGNoaWxkcmVuICIKCQkJICAgICJvZiA8cmVzdHJpY3Rpb24+IiwgTlVMTCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCSAgICB9IAoJCSAgICBPSyA9IDE7CgkJfSBlbHNlIHsgLyogaWYgKGJhc2UtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSovCgkJICAgIC8qCgkJICAgICogMi4xLjEgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfSBpcyBhIAoJCSAgICAqIHNpbXBsZSB0eXBlIGRlZmluaXRpb247CgkJICAgICovCgkJICAgIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90ICIKCQkJICAgICJiZSBkZXJpdmVkIGZyb20gdGhlIGNvbXBsZXggdHlwZSAnJXMnIiwgCgkJCSAgICBiYXNlLT5uYW1lKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0KCQkgICAgY29udGVudCA9IGJhc2UtPmNvbnRlbnRUeXBlRGVmOwoJCSAgICBpZiAoY29udGVudCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkgICAgIiclcycsIGJhc2UgdHlwZSBoYXMgbm8gY29udGVudCB0eXBlIiwgCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgaWYgKGNvbnRlbnQtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW5ub3QgIgoJCQkgICAgImJlIGRlcml2ZWQgZnJvbSB0aGUgY29tcGxleCB0eXBlICclcyciLCAKCQkJICAgIGJhc2UtPm5hbWUpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQkgICAgfQoJCX0KCSAgICB9IAoJfSAJICAgIAkKICAgIH0KICAgIC8qCiAgICAqIFRPRE86IDMgVGhlIGNvcnJlc3BvbmRpbmcgY29tcGxleCB0eXBlIGRlZmluaXRpb24gY29tcG9uZW50IG11c3QgCiAgICAqIHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgCiAgICAqIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjQuNik7CiAgICAqCiAgICAqIFRPRE86IDQgSWYgY2xhdXNlIDIuMi4xIG9yIGNsYXVzZSAyLjIuMiBpbiB0aGUgY29ycmVzcG9uZGVuY2Ugc3BlY2lmaWNhdGlvbiAKICAgICogYWJvdmUgZm9yIHthdHRyaWJ1dGUgd2lsZGNhcmR9IGlzIHNhdGlzZmllZCwgdGhlIGludGVuc2lvbmFsIAogICAgKiBpbnRlcnNlY3Rpb24gbXVzdCBiZSBleHByZXNzaWJsZSwgYXMgZGVmaW5lZCBpbiBBdHRyaWJ1dGUgV2lsZGNhcmQgCiAgICAqIEludGVyc2VjdGlvbiAopzMuMTAuNikuCiAgICAqLwoKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFHcm91cERlZkZpeHVwOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hR3JvdXBEZWZGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIGdyb3VwLAoJCSAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgZ3JvdXAtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgaWYgKChncm91cC0+cmVmICE9IE5VTEwpICYmIChncm91cC0+c3VidHlwZXMgPT0gTlVMTCkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgZ3JvdXBEZWY7CgkvKgoJKiBSZXNvbHZlIHRoZSByZWZlcmVuY2UuCgkqLwoJZ3JvdXBEZWYgPSB4bWxTY2hlbWFHZXRHcm91cChjdHh0LT5zY2hlbWEsIGdyb3VwLT5yZWYsCgkgICAgZ3JvdXAtPnJlZk5zKTsKCWlmIChncm91cERlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCAKCQlOVUxMLCBncm91cCwgTlVMTCwKCQkicmVmIiwgZ3JvdXAtPnJlZiwgZ3JvdXAtPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfR1JPVVAsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCWdyb3VwLT5zdWJ0eXBlcyA9IGdyb3VwRGVmOwogICAgfQkJCn0KCiNpZiAwIC8qIEVuYWJsZSB3aGVuIHRoZSBjb250ZW50IHR5cGUgd2lsbCBiZSBjb21wdXRlZC4gKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDb21wdXRlQ29udGVudFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgcmVzID0gTlVMTDsKCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkgICAgInRoZSBjb21wbGV4IHR5cGUgJyVzJyBoYXMgbm8gYmFzZSB0eXBlIiwgdHlwZS0+bmFtZSk7CglyZXR1cm4gKC0xKTsKICAgIH0gICAKICAgIGlmIChJU19BTllUWVBFKGJhc2UpIHx8ICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBzdGFydDsKCS8qCgkqIEVmZmVjdGl2ZSAnbWl4ZWQnLgoJKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwoJLyoKCSogRWZmZWN0aXZlIGNvbnRlbnQuCgkqLwoJaWYgKElTX0FOWVRZUEUoYmFzZSkpIAoJICAgIHN0YXJ0ID0gdHlwZTsKCWVsc2UKCSAgICBzdGFydCA9IHR5cGUtPnN1YnR5cGVzOwoJIAogICAgfSBlbHNlIHsgLyogaWYgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCAqLwoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlQ29udGVudEl0ZW07CgoJLyoKCSogQ29tcGxleCB0eXBlIHdpdGggc2ltcGxlIGNvbnRlbnQuCgkqLwoJaWYgSVNfQ09NUExFWF9UWVBFKGJhc2UpIHsKCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CQoJCS8qCgkJKiBTdW1tYXJ5OiBhIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbiAqcmVzdHJpY3QqCgkJKiBhIGNvbXBsZXggdHlwZSB3aXRoIHRoZSBmb2xsb3dpbmcgY29udGVudCB0eXBlOgoJCSogMS4gJ21peGVkJyBhbmQgYW4gZW1wdGlhYmxlIHBhcnRpY2xlCgkJKiAyLiBzaW1wbGUgdHlwZQoJCSovCgkJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgewoJCSAgICAvKgoJCSAgICAqIDIgaWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBiYXNlIHR5cGUgaXMgbWl4ZWQgYW5kIGEgCgkJICAgICogcGFydGljbGUgd2hpY2ggaXMgt2VtcHRpYWJsZbcsIAoJCSAgICAqIFsuLi5dIAoJCSAgICAqIHRoZW4gc3RhcnRpbmcgZnJvbSB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKCQkgICAgKiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gCgkJICAgICogb2YgPHJlc3RyaWN0aW9uPiAoKip3aGljaCBtdXN0IGJlIHByZXNlbnQqKikKCQkgICAgKgoJCSAgICAqIEZJWE1FIFRPRE86IEhhbmRsZSAiZW1wdGlhYmxlIHBhcnRpY2xlIi4KCQkgICAgKi8KCQkgICAgcmVzID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzOwoJCSAgICBpZiAocmVzID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkgICAgIkNUICclcycgKHJlc3RyaWN0aW5nKTogPHNpbXBsZUNvbnRlbnQ+IGhhcyBubyAiCgkJCSAgICAiPHJlc3RyaWN0aW9uPiIsCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCgkJICAgIHJlcy0+c3VidHlwZXM7CgkJICAgIGlmIChyZXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSAgICAiQ1QgJyVzJyAocmVzdHJpY3RpbmcpOiA8cmVzdHJpY3Rpb24+IGhhcyBubyAiCgkJCSAgICAibWFuZGF0b3J5IDxzaW1wbGVUeXBlPiIsCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBiYXNlQ29udGVudEl0ZW0gPSBiYXNlLT5jb250ZW50VHlwZURlZjsKCQkgICAgaWYgKGJhc2VDb250ZW50SXRlbSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJICAgICJDVCAnJXMnIChyZXN0cmljdGluZyksIHRoZSBiYXNlIHR5cGUgaGFzIG5vICIKCQkJICAgICJjb250ZW50IHR5cGUiLCB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgaWYgSVNfU0lNUExFX1RZUEUoYmFzZUNvbnRlbnRJdGVtKSB7CgkJCS8qCgkJCSogMSBJZiB0aGUgYmFzZSB0eXBlIGlzIGEgY29tcGxleCB0eXBlIHdob3NlIG93biAKCQkgICAgCSoge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBhbmQgdGhlIDxyZXN0cmljdGlvbj4gCgkJCSogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuCgkJCSovCgkJCS8qIHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyB3aWxsIGJlIHRoZSByZXN0cmljdGlvbiBpdGVtLiovCgkJCXJlcyA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlczsKCQkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCQkiQ1QgJyVzJyAocmVzdHJpY3RpbmcpOiA8c2ltcGxlVHlwZT4gaGFzIG5vICIKCQkJCSI8cmVzdHJpY3Rpb24+IiwgdHlwZS0+bmFtZSk7CgkJCSAgICByZXR1cm4gKC0xKTsKCQkJfQoJCQkvKgoJCQkqIDEuMSB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSAKCQkJKiA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPHJlc3RyaWN0aW9uPmlmIAoJCQkqIHRoZXJlIGlzIG9uZTsKCQkJKi8KCQkJcmVzID0gcmVzLT5zdWJ0eXBlczsKCQkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJCSAgICAvKgoJCQkgICAgKiAxLjIgb3RoZXJ3aXNlIHRoZSB7Y29udGVudCB0eXBlfSAKCQkJICAgICogb2YgdGhlIGJhc2UgdHlwZSAuCgkJCSAgICAqLwoJCQkgICAgcmVzID0gYmFzZUNvbnRlbnRJdGVtOwoJCQl9CgkJICAgIH0KCQl9CgkJLyoKCQkqIFNQRUNJQUwgVE9ETzogSWYgKnJlc3RyaWN0aW5nKiB0aGUgc3BlYyB3YW50cyB1cyB0byAKCQkqIGNyZWF0ZSBhbiAqYWRkaXRpb25hbCogc2ltcGxlIHR5cGUgd2hpY2ggcmVzdHJpY3RzIHRoZSAKCQkqIGxvY2F0ZWQgc2ltcGxlIHR5cGU7IHdlIHdvbid0IGRvIHRoaXMgeWV0LCBhbmQgbG9vayBob3cgCgkJKiBmYXIgd2UgZ2V0IHdpdGggaXQuCgkJKi8KCSAgICB9IGVsc2UgeyAvKiBpZiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OICovCgkJLyoKCQkqIFN1bW1hcnk6IGEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2FuICpleHRlbmQqCgkJKiBvbmx5IGEgY29tcGxleCBiYXNlIHdpdGggYSBzaW1wbGUgdHlwZSBhcyBjb250ZW50LgoJCSovCQkKCQkvKgoJCSogMyBJZiB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgCgkJKiB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gaXMgYSBjb21wbGV4IHR5cGUgCgkJKiBkZWZpbml0aW9uICh3aG9zZSBvd24ge2NvbnRlbnQgdHlwZX0gKm11c3QgYmUqIGEgc2ltcGxlIAoJCSogdHlwZSBkZWZpbml0aW9uLCBzZWUgYmVsb3cpIGFuZCB0aGUgKjxleHRlbnNpb24+KiAKCQkqIGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhhdCAKCQkqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uOwoJCSovCgkJcmVzID0gYmFzZS0+Y29udGVudFR5cGVEZWY7CgkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJIkNUICclcycgKGV4dGVuZGluZyksIHRoZSBiYXNlIHR5cGUgaGFzIG5vIGNvbnRlbnQgIgoJCQkidHlwZSIsIHR5cGUtPm5hbWUpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCQlpZiAoISBJU19TSU1QTEVfVFlQRShyZXMpKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJIkNUICclcycgKGV4dGVuZGluZyksIHRoZSBjb250ZW50IHR5cGUgb2YgdGhlICIKCQkJImJhc2UgaXMgbm90IGEgc2ltcGxlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkgICAgfQkgICAgCQoJfSBlbHNlIC8qIGlmIElTX0NPTVBMRVhfVFlQRShiYXNlKSAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkgICAgLyoKCSAgICAqIDQgb3RoZXJ3aXNlICh0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlIAoJICAgICogt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gaXMgYSBzaW1wbGUgdHlwZSAKCSAgICAqIGRlZmluaXRpb24gYW5kIHRoZSA8ZXh0ZW5zaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4pLCAKCSAgICAqIHRoZW4gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJICAgICovCgkgICAgcmVzID0gYmFzZTsKCX0JCgl0eXBlLT5jb250ZW50VHlwZURlZiA9IHJlczsKCWlmIChyZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkiJyVzJywgdGhlIGNvbnRlbnQgdHlwZSBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCIsIAoJCXR5cGUtPm5hbWUpOwoJICAgIHJldHVybiAoLTEpOwoJfQoKICAgIH0KICAgIAp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaXh1cDoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGU7CgogICAgaWYgKGl0ZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICAvKgogICAgKiBEbyBub3QgYWxsb3cgdGhlIGZvbGxvd2luZyB0eXBlcyB0byBiZSB0eXBlZml4ZWQsIHByaW9yIHRvCiAgICAqIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5jdHh0VHlwZSA9PSBOVUxMKSB7Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgkgICAgCgkJcmV0dXJuOwoJICAgIGRlZmF1bHQ6CgkgICAgICAgIGJyZWFrOwoJfQogICAgfQogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gaXRlbS0+bmFtZTsKICAgIGlmIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewogICAgICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDp7CQkgICAgCgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkJCWlmIChpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsCgkJCQlOVUxMKTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOyAqLwoJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOnsKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlID0gTlVMTDsKCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5mbGFncyB8PSAKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTjsKCQkgICAgaWYgKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpCgkJCWJhc2UgPSBpdGVtLT5iYXNlVHlwZTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpdGVtLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCQkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIAoJCQkJTlVMTCwgTlVMTCwgCgkJCQkoeG1sTm9kZVB0cikgeG1sU2NoZW1hR2V0UHJvcE5vZGUoaXRlbS0+bm9kZSwgImJhc2UiKSwKCQkJCSJiYXNlIiwgaXRlbS0+YmFzZSwgaXRlbS0+YmFzZU5zLAoJCQkJWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7CQkJICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IAoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQkJCQogICAgICAgICAgICAgICAgICAgIH0JCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5iYXNlVHlwZSA9IGJhc2U7CgkJICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJCQkvKgoJCQkqIENvbXBsZXhUeXBlIHJlc3RyaWN0aW9uLgoJCQkqLwkJCQoJCQkvKgoJCQkqIENvbnRlbnQgdHlwZS4KCQkJKi8KCQkJaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpCgkJCSAgICAvKiAxLjEuMSAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJCWVsc2UgaWYgKChpdGVtLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCQkJICAgICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwpCgkJCSAgICB8fCAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQoJCQkgICAgLyogMS4xLjIgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpCgkJCSAgICAmJiAoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpKQoJCQkgICAgLyogMS4xLjMgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIHsKCQkJICAgIC8qIDEuMiBhbmQgMi5YIGFyZSBhcHBsaWVkIGF0IHRoZSBvdGhlciBsYXllciAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPQoJCQkJWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCQl9CgkJICAgIH0gZWxzZSB7CQoJCQkvKgoJCQkqIFNpbXBsZVR5cGUgcmVzdHJpY3Rpb24uCgkJCSovCgkJCS8qIFRPRE86IE5vdGhpbmc/ICovCgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOnsKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hQ29udGVudFR5cGUgZXhwbGljaXRDb250ZW50VHlwZTsKCQkgICAgCgkJICAgIC8qCgkJICAgICogQW4gZXh0ZW5zaW9uIGRvZXMgZXhpc3Qgb24gYSBjb21wbGV4VHlwZSBvbmx5LgoJCSAgICAqLwoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmxhZ3MgfD0gCgkJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OOwoJCSAgICBpZiAoaXRlbS0+cmVjdXJzZSkgewoJCQkvKiBUT0RPOiBUaGUgd29yZCAicmVjdXJzaXZlIiBzaG91bGQgYmUgY2hhbmdlZCB0byAiY2lyY3VsYXIiIGhlcmUuICovCgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLAoJCQkgICAgTlVMTCwgaXRlbSwgaXRlbS0+bm9kZSwJCgkJCSAgICAiVGhpcyBpdGVtIGlzIGNpcmN1bGFyIiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKCQkgICAgfQoJCSAgICBpZiAoaXRlbS0+YmFzZSAhPSBOVUxMKSB7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW0tPmJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmJhc2VOcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCAKCQkJCU5VTEwsIGl0ZW0sIGl0ZW0tPm5vZGUsCgkJCQkiYmFzZSIsIGl0ZW0tPmJhc2UsIGl0ZW0tPmJhc2VOcywKCQkJCVhNTF9TQ0hFTUFfVFlQRV9CQVNJQywgInR5cGUgZGVmaW5pdGlvbiIpOwkJCQkgICAKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICBpdGVtLT5yZWN1cnNlID0gMTsKCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlLCBjdHh0LCBOVUxMKTsKCQkJICAgIGl0ZW0tPnJlY3Vyc2UgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCS8qCgkJCSogVGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIAoJCQkqIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXQoJCQkqLwoJCQljdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoJCQkvKgoJCQkqIFRPRE86IFRoaXMgb25lIGlzIHN0aWxsIG5lZWRlZCBmb3IgY29tcHV0YXRpb24gb2YKCQkJKiB0aGUgY29udGVudCBtb2RlbCBieSB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwuCgkJCSogVHJ5IHRvIGdldCByaWQgb2YgaXQuCgkJCSovCgkJCWl0ZW0tPmJhc2VUeXBlID0gYmFzZTsJCQkKICAgICAgICAgICAgICAgICAgICB9CgkJICAgIGlmICgoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCQkJKGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CSAgICAKCQkgICAgCgkJICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQkvKiAxLjEuMSAqLwoJCQlleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCSAgICBlbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpICYmCgkJCSgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0FMTCkKCQkJfHwgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCVhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQoJCQkvKiAxLjEuMiAqLwoJCQlleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCSAgICBlbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkKCQkJJiYgKGl0ZW0tPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCQkJLyogMS4xLjMgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgaWYgKGJhc2UgIT0gTlVMTCkgewoJCQkvKiBJdCB3aWxsIGJlIHJlcG9ydGVkIGxhdGVyLCBpZiB0aGUgYmFzZSBpcyBtaXNzaW5nLiAqLwkJCSAgICAKCQkJaWYgKGV4cGxpY2l0Q29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJCSAgICAvKiAyLjEgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gYmFzZS0+Y29udGVudFR5cGU7CgkJCX0gZWxzZSBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCQkgICAgLyogMi4yIGltYml0YWJsZSAhICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0gZWxzZSB7CgkJCSAgICAvKiAyLjMgaW1iaXRhYmxlIHBhcmVpbCAhICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0KCQkgICAgfQkJICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOnsKCQkgICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBpdGVtOwoJCSAgICAvKgoJCSAgICAqIFN0YXJ0IHdpdGggYW4gZW1wdHkgY29udGVudC10eXBlIHR5cGUuCgkJICAgICovCgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCgkJICAgIGlmICgoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkgfHwgCgkJCSgoaXRlbS0+c3VidHlwZXMtPnR5cGUgIT0gCgkJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgJiYgCgkJCShpdGVtLT5zdWJ0eXBlcy0+dHlwZSAhPSAKCQkJWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkpKSB7CgkJCS8qIAoJCQkqIFRoaXMgY2FzZSBpcyB1bmRlcnN0b29kIGFzIHNob3J0aGFuZCBmb3IgY29tcGxleCAKCQkJKiBjb250ZW50IHJlc3RyaWN0aW5nIHRoZSB1ci10eXBlIGRlZmluaXRpb24sIGFuZCAKCQkJKiB0aGUgZGV0YWlscyBvZiB0aGUgbWFwcGluZ3Mgc2hvdWxkIGJlIG1vZGlmaWVkIGFzIAoJCQkqIG5lY2Vzc2FyeS4KCQkJKi8JCQkKCQkJaXRlbS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCQkJaXRlbS0+ZmxhZ3MgfD0gCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoJCQkvKgoJCQkqIEFzc3VtZSB0aGF0IHdlIGluaGVyaXQgdGhlIGNvbnRlbnQtdHlwZSB0eXBlIAoJCQkqIGZyb20gJ2FueVR5cGUnLCB3aGljaCBpcyAnbWl4ZWQnIGFuZCBhIHBhcnRpY2xlCgkJCSogZW1wdGlhYmxlLgoJCQkqLwoJCQlpdGVtLT5jb250ZW50VHlwZSA9IGl0ZW0tPmJhc2VUeXBlLT5jb250ZW50VHlwZTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIEZpeHVwIHRoZSBzdWIgY29tcG9uZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCQkoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09CgkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewkJCSAgICAKCQkJeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQkgICAgfQkKCQkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewoJCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsJCQkKCQkgICAgfSBlbHNlIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkJCS8qCgkJCSogVXNlIHRoZSBjb250ZW50LXR5cGUgdHlwZSBvZiB0aGUgbW9kZWwgZ3JvdXBzCgkJCSogZGVmaW5lZCwgaWYgJ21peGVkJyBpcyBub3Qgc2V0LiBJZiAnbWl4ZWQnIGlzIHNldAoJCQkqIGl0IHdpbGwgZXhwYW5kIHRoZSBjb250ZW50LXR5cGUgYnkgYWxsb3dpbmcgY2hhcmFjdGVyCgkJCSogY29udGVudCB0byBhcHBlYXIuCgkJCSovCgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJICAgIGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKCQkgICAgfQoJCSAgICB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oY3R4dCwgaXRlbSk7CgkJICAgIGN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDp7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkvKiAKCQkJICogUmVtb3ZlZCBkdWUgdG8gaW1wbGVtZW50YXRpb24gb2YgdGhlIGJ1aWxkIG9mIGF0dHJpYnV0ZSB1c2VzLiAKCQkJICovCgkJCS8qCgkJCWlmIChpdGVtLT5hdHRyaWJ1dGVzID09IE5VTEwpCgkJCSAgICBpdGVtLT5hdHRyaWJ1dGVzID0KCQkJICAgICAgICBpdGVtLT5zdWJ0eXBlcy0+YXR0cmlidXRlczsKCQkJKi8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCS8qCgkJKiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnQKCQkqCgkJKi8KCQljdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwkJCgkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWlmIChpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJICAgIGN0eHQtPmN0eHRUeXBlID0gaXRlbTsKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQl9CgkJLyogRml4dXAgYmFzZSB0eXBlICovCQkKCQlpZiAoKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpICYmIAoJCSAgICAoaXRlbS0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlID09CgkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewoJCSAgICAvKiBPUFRJTUlaRTogQWN0dWFsbHkgdGhpcyBvbmUgd2lsbCBuZXZlciBieSBoaXQsIHNpbmNlCgkJICAgICogdGhlIGJhc2UgdHlwZSBpcyBhbHJlYWR5IHR5cGUtZml4ZWQgaW4gPHJlc3RyaWN0aW9uPi4KCQkgICAgKi8KCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBpdGVtOwoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+YmFzZVR5cGUsIGN0eHQsIE5VTEwpOwoJCX0KCQkvKiBCYXNlIHR5cGU6IAoJCSogMiBJZiB0aGUgPGxpc3Q+IG9yIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCAKCQkqIHRoZW4gdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4KCQkqLwoJCWlmIChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewoJCSAgICBpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVDsJCSAgICAKCQl9IGVsc2UgaWYgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9VTklPTikgewoJCSAgICBpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CgkJfSBlbHNlIGlmIChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHsKCQkgICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0LCBjdXIsIGxhc3QgPSBOVUxMOwoJCSAgICAJCSAgICAJICAgIAkJICAgCgkJICAgIC8qIAoJCSAgICAqIFZhcmlldHkKCQkgICAgKiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlIAoJCSAgICAqIHt2YXJpZXR5fSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KCQkgICAgKi8JCgkJICAgIGlmIChpdGVtLT5iYXNlVHlwZSAhPSBOVUxMKSB7CgkJCWlmIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpCgkJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDOwoJCQllbHNlIGlmIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CgkJCWVsc2UgaWYgKGl0ZW0tPmJhc2VUeXBlLT5mbGFncyAmIAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OOwkJICAgIAkJICAgIAkJICAgCgkJCS8qCgkJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBSZXN0cmljdGlvbiAKCQkJKiAoRmFjZXRzKQoJCQkqIE5PVEU6IFNhdGlzZmFjdGlvbiBvZiAxIGFuZCAyIGFyaXNlIGZyb20gdGhlIGZpeHVwIAoJCQkqIGFwcGxpZWQgYmVmb3JlaGFuZC4KCQkJKgkJCSAgICAKCQkJKiAzIFRoZSB7ZmFjZXRzfSBvZiBSIGFyZSB0aGUgdW5pb24gb2YgUyBhbmQgdGhlIHtmYWNldHN9IAoJCQkqIG9mIEIsIGVsaW1pbmF0aW5nIGR1cGxpY2F0ZXMuIFRvIGVsaW1pbmF0ZSBkdXBsaWNhdGVzLCAKCQkJKiB3aGVuIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBvY2N1cnMgaW4gYm90aCBTIGFuZCB0aGUgCgkJCSoge2ZhY2V0c30gb2YgQiwgdGhlIG9uZSBpbiB0aGUge2ZhY2V0c30gb2YgQiBpcyBub3QgCgkJCSogaW5jbHVkZWQsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBlbnVtZXJhdGlvbiBhbmQgcGF0dGVybiAKCQkJKiBmYWNldHMsIGZvciB3aGljaCBtdWx0aXBsZSBvY2N1cnJlbmNlcyB3aXRoIGRpc3RpbmN0IHZhbHVlcyAKCQkJKiBhcmUgYWxsb3dlZC4KCQkJKi8KCQkJaWYgKGl0ZW0tPmJhc2VUeXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CgkJCSAgICBsYXN0ID0gaXRlbS0+ZmFjZXRTZXQ7CgkJCSAgICBpZiAobGFzdCAhPSBOVUxMKQoJCQkJd2hpbGUgKGxhc3QtPm5leHQgIT0gTlVMTCkKCQkJCSAgICBsYXN0ID0gbGFzdC0+bmV4dDsKCQkJCWN1ciA9IGl0ZW0tPmJhc2VUeXBlLT5mYWNldFNldDsKCQkJCWZvciAoOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CgkJCQkgICAgLyogCgkJCQkgICAgKiBCYXNlIHBhdHRlcm5zIHdvbid0IGJlIGFkZCBoZXJlOgoJCQkJICAgICogdGhleSBhcmUgT1JlZCBpbiBhIHR5cGUgYW5kCgkJCQkgICAgKiBBTkRlZCBpbiBkZXJpdmVkIHR5cGVzLiBUaGlzIHdpbGwKCQkJCSAgICAqIGhhcHBlZCBhdCB2YWxpZGF0aW9uIGxldmVsIGJ5CgkJCQkgICAgKiB3YWxraW5nIHRoZSBiYXNlIGF4aXMgb2YgdGhlIHR5cGUuCgkJCQkgICAgKi8KCQkJCSAgICBpZiAoY3VyLT5mYWNldC0+dHlwZSA9PSAKCQkJCQlYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIAoJCQkJCWNvbnRpbnVlOwoJCQkJICAgIGZhY2V0ID0gTlVMTDsKCQkJCSAgICBpZiAoKGl0ZW0tPmZhY2V0U2V0ICE9IE5VTEwpICYmCgkJCQkJKGN1ci0+ZmFjZXQtPnR5cGUgIT0gCgkJCQkJWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSAmJgoJCQkJCShjdXItPmZhY2V0LT50eXBlICE9IAoJCQkJCVhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pKSB7CQkJCQoJCQkJCWZhY2V0ID0gaXRlbS0+ZmFjZXRTZXQ7CgkJCQkJZG8gewoJCQkJCSAgICBpZiAoY3VyLT5mYWNldC0+dHlwZSA9PSAKCQkJCQkJZmFjZXQtPmZhY2V0LT50eXBlKSAKCQkJCQkJYnJlYWs7CgkJCQkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJCQkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJCQkgICAgfQoJCQkJICAgIGlmIChmYWNldCA9PSBOVUxMKSB7CgkJCQkJZmFjZXQgPSAoeG1sU2NoZW1hRmFjZXRMaW5rUHRyKSAKCQkJCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldExpbmspKTsKCQkJCQlpZiAoZmFjZXQgPT0gTlVMTCkgewoJCQkJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsIAoJCQkJCQkiZml4aW5nIHNpbXBsZVR5cGUiLCBOVUxMKTsKCQkJCQkgICAgcmV0dXJuOwoJCQkJCX0KCQkJCQlmYWNldC0+ZmFjZXQgPSBjdXItPmZhY2V0OwoJCQkJCWZhY2V0LT5uZXh0ID0gTlVMTDsKCQkJCQlpZiAobGFzdCA9PSBOVUxMKQoJCQkJCSAgICBpdGVtLT5mYWNldFNldCA9IGZhY2V0OwkJICAgIAoJCQkJCWVsc2UgCgkJCQkJICAgIGxhc3QtPm5leHQgPSBmYWNldDsKCQkJCQlsYXN0ID0gZmFjZXQ7CQkJCQoJCQkJICAgIH0JCQkJICAgIAoJCQkJfQoJCQl9CgkJICAgIH0KCQl9CQoJCS8qCgkJKiBDaGVjayBjb25zdHJhaW50cy4KCQkqLwoJCXhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZShjdHh0LCBpdGVtKTsKCQljdHh0LT5jdHh0VHlwZSA9IGN0eHRUeXBlOwoJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTogICAgICAgICAgICAKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCS8qCgkJKiBUT0RPOiBIYW5kbGluZyB3YXMgbW92ZWQgdG8geG1sU2NoZW1hR3JvdXBEZWZGaXh1cC4KCQkqLwoJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9MSVNUOiAKCQl4bWxTY2hlbWFQYXJzZUxpc3RSZWZGaXh1cChpdGVtLCBjdHh0KTsKCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VOSU9OOgkJCgkJeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrKGl0ZW0sIGN0eHQpOwoJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRkFDRVQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VSOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKQoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQojaWZkZWYgREVCVUdfVFlQRQogICAgaWYgKGl0ZW0tPm5vZGUgIT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiVHlwZSBvZiAlcyA6ICVzOiVkIDoiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5ub2RlLT5kb2MtPlVSTCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2V0TGluZU5vKGl0ZW0tPm5vZGUpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJUeXBlIG9mICVzIDoiLCBuYW1lKTsKICAgIH0KICAgIHN3aXRjaCAoaXRlbS0+Y29udGVudFR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAic2ltcGxlXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZWxlbWVudHNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInVua25vd24gISEhXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiZW1wdHlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZFxuIik7CiAgICAgICAgICAgIGJyZWFrOwoJLyogUmVtb3ZlZCwgc2luY2Ugbm90IHVzZWQuICovCgkvKgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkIG9yIGVsZW1zXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgkqLwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImJhc2ljXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm90IHJlZ2lzdGVyZWQgISEhXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNlbmRpZgp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tGYWNldDoKICogQGZhY2V0OiAgdGhlIGZhY2V0CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dCBvciBOVUxMCiAqIEBuYW1lOiBuYW1lIG9mIHRoZSB0eXBlCiAqCiAqIENoZWNrcyB0aGUgZGVmYXVsdCB2YWx1ZXMgdHlwZXMsIGVzcGVjaWFsbHkgZm9yIGZhY2V0cyAKICoKICogUmV0dXJucyAwIGlmIG9rYXkgb3IgLTEgaW4gY2FlIG9mIGVycm9yCiAqLwppbnQKeG1sU2NoZW1hQ2hlY2tGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9IE5VTEw7CiAgICBpbnQgcmV0ID0gMCwgcmV1c2VWYWxDdHh0ID0gMDsKCiAgICAvKiAKICAgICogVE9ETzogd2lsbCB0aGUgcGFyc2VyIGNvbnRleHQgYmUgZ2l2ZW4gaWYgdXNlZCBmcm9tCiAgICAqIHRoZSByZWxheE5HIG1vZHVsZT8KICAgICovCgogICAgaWYgKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPT0gTlVMTCkgewogICAgICAgIG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPQogICAgICAgICAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OTklOVEVHRVIpOwogICAgfQogICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046IHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBPa2F5IHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBhdCB0aGF0IHBvaW50LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQ7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKCQkvKiA0LjMuNS41IENvbnN0cmFpbnRzIG9uIGVudW1lcmF0aW9uIFNjaGVtYSBDb21wb25lbnRzCgkJKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IGVudW1lcmF0aW9uIHZhbGlkIHJlc3RyaWN0aW9uCgkJKiBJdCBpcyBhbiC3ZXJyb3K3IGlmIGFueSBtZW1iZXIgb2Yge3ZhbHVlfSBpcyBub3QgaW4gdGhlIAoJCSogt3ZhbHVlIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259LiAKCQkqCgkJKiBtaW5JbmNsdXNpdmUsIG1heEluY2x1c2l2ZSwgbWluRXhjbHVzaXZlLCBtYXhFeGNsdXNpdmU6CgkJKiBUaGUgdmFsdWUgt211c3S3IGJlIGluIHRoZSAKCQkqILd2YWx1ZSBzcGFjZbcgb2YgdGhlILdiYXNlIHR5cGW3LiAKCQkqLwoJCS8qCgkJKiBUaGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIHRvIGRlbGl2ZXIgYSBjb21waWxlZCB2YWx1ZQoJCSogb24gdGhlIGZhY2V0LiBJbiBYTUwgU2NoZW1hcyB0aGUgdHlwZSBob2xkaW5nIGEgZmFjZXQsIAoJCSogY2Fubm90IGJlIGEgYnVpbHQtaW4gdHlwZS4gVGh1cyB0byBlbnN1cmUgdGhhdCBvdGhlciBBUEkKCQkqIGNhbGxzIChyZWxheG5nKSBkbyB3b3JrLCBpZiB0aGUgZ2l2ZW4gdHlwZSBpcyBhIGJ1aWx0LWluIAoJCSogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZSAqaXMKCQkqIGFscmVhZHkqIHRoZSBiYXNlIHR5cGUuCQkKCQkqLwoJCWlmICh0eXBlRGVjbC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCQkgICAgYmFzZSA9IHR5cGVEZWNsLT5iYXNlVHlwZTsKCQkgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJICAgICJ0aGUgdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUuXG4iLAoJCQkgICAgdHlwZURlY2wtPm5hbWUsIE5VTEwpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQkJCgkJfSBlbHNlCgkJICAgIGJhc2UgPSB0eXBlRGVjbDsKCQkvKgoJCSogVGhpcyBhdm9pZHMgcGVyc2V2ZXJhdGl2ZSBjcmVhdGlvbiBvZiB0aGUgCgkJKiB2YWxpZGF0aW9uIGNvbnRleHQgaWYgYSBwYXJzZXIgY29udGV4dCBpcwoJCSogdXNlZC4KCQkqLwoJCWlmIChjdHh0ICE9IE5VTEwpIHsKCQkgICAgcmV1c2VWYWxDdHh0ID0gMTsKCQkgICAgaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCQkJaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkKCQkJICAgIHJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIHZjdHh0ID0gY3R4dC0+dmN0eHQ7CgkJfSBlbHNlIHsKCQkgICAgdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CgkJICAgIGlmICh2Y3R4dCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIgoJCQkgICAgImNyZWF0aW5nIGEgbmV3IHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJCSAgICBOVUxMLCBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CQoJCSAgICB9CgkJfQoJICAgICAgICAgICAgICAgIAoJCXZjdHh0LT5ub2RlID0gZmFjZXQtPm5vZGU7CgkJdmN0eHQtPmN1ciA9IE5VTEw7CgkJLyoKCQkqIE5PVEU6IFRoaXMgY2FsbCBkb2VzIG5vdCBjaGVjayB0aGUgY29udGVudCBub2RlcywgCgkJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldCAKCQkqIGRlZmluaXRpb24sICpub3QqIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgKnZhbHVlKiAKCQkqIG9mIHRoZSBmYWNldC4KCQkqLwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCBiYXNlLCAKCQkgICAgZmFjZXQtPnZhbHVlLCAwLCAxLCAxLCAwKTsKCQlmYWNldC0+dmFsID0gdmN0eHQtPnZhbHVlOwoJCXZjdHh0LT52YWx1ZSA9IE5VTEw7CQkKICAgICAgICAgICAgICAgIGlmIChyZXQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVQsIAoJCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnJXMnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUsIAoJCQkgICAgQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLCAKCQkJICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgTlVMTCwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlICclcycgbmFtZSBvZiB0aGUgIgoJCQkiZmFjZXQgJyVzJyBhZ2FpbnN0IHRoZSBiYXNlIHR5cGUgJyVzJy5cbiIsCgkJCWZhY2V0LT52YWx1ZSwgCgkJCUJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCQkJYmFzZS0+bmFtZSwgTlVMTCwgTlVMTCk7IAoJCSAgICByZXQgPSAtMTsKCQl9ICAgCgkJaWYgKHJldXNlVmFsQ3R4dCA9PSAwKQoJCSAgICB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGZhY2V0LT5yZWdleHAgPSB4bWxSZWdleHBDb21waWxlKGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgIGlmIChmYWNldC0+cmVnZXhwID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9SRUdFWFBfSU5WQUxJRCwKCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCSAgICAiZmFjZXQgJ3BhdHRlcm4nIGlzIG5vdCB2YWxpZC5cbiIsCgkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOnsKICAgICAgICAgICAgICAgIGludCB0bXA7CgogICAgICAgICAgICAgICAgdG1wID0KICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldC0+dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKGZhY2V0LT52YWwpKTsKICAgICAgICAgICAgICAgIGlmICh0bXAgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIC8qIGVycm9yIGNvZGUgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgZmFjZXQtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLAoJCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnJXMnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUsIAoJCQkgICAgQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTp7CiAgICAgICAgICAgICAgICBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicHJlc2VydmUiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInJlcGxhY2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUkVQTEFDRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAiY29sbGFwc2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfV0hJVEVfU1BBQ0UsCgkJCSAgICAiVHlwZSBkZWZpbml0aW9uICclcyc6IFRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJCSAgICAiZmFjZXQgJ3doaXRlU3BhY2UnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tEZWZhdWx0czoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIENoZWNrcyB0aGUgZGVmYXVsdCB2YWx1ZXMgdHlwZXMsIGVzcGVjaWFsbHkgZm9yIGZhY2V0cyAKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSB0eXBlRGVjbC0+bmFtZTsgCiAgICAvKgogICAgKiBOT1RFOiBJdCBpcyBpbnRlbmRlZCB0byB1c2UgdGhlIGZhY2V0cyBsaXN0LCBpbnN0ZWFkCiAgICAqIG9mIGZhY2V0U2V0LgogICAgKi8KICAgIGlmICh0eXBlRGVjbC0+ZmFjZXRzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0ID0gdHlwZURlY2wtPmZhY2V0czsKCQoJd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDaGVja0ZhY2V0KGZhY2V0LCB0eXBlRGVjbCwgY3R4dCwgbmFtZSk7CgkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCX0KICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZjoKICogQGN0eHRHcjogdGhlIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBsaXN0OiB0aGUgbGlzdCBvZiBtb2RlbCBncm91cHMgdG8gYmUgcHJvY2Vzc2VkCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIGNpcmN1bGFyIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKHhtbFNjaGVtYVR5cGVQdHIgY3R4dEdyRGVmLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgZ3IpCnsgICAgCiAgICB4bWxTY2hlbWFUeXBlUHRyIGNpcmMgPSBOVUxMOwogICAgaW50IG1hcmtlZDsKICAgIC8qCiAgICAqIFdlIHdpbGwgc2VhcmNoIGZvciBhbiBtb2RlbCBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogICAgKi8gICAgICAgIAogICAgd2hpbGUgKGdyICE9IE5VTEwpIHsKCWlmICgoKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpIHx8CgkgICAgIChnci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8CgkgICAgIChnci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSkgJiYKCSAgICAoZ3ItPnN1YnR5cGVzICE9IE5VTEwpKSB7CQkgCgkgICAgbWFya2VkID0gMDsKCSAgICBpZiAoKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgJiYKCQkoZ3ItPnJlZiAhPSBOVUxMKSkgewoJCWlmIChnci0+c3VidHlwZXMgPT0gY3R4dEdyRGVmKQoJCSAgICByZXR1cm4gKGdyKTsKCQllbHNlIGlmIChnci0+c3VidHlwZXMtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEKSB7CgkJICAgIGdyID0gZ3ItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogTWFyayB0byBhdm9pZCBpbmZpbml0ZSByZWN1cnNpb24gb24KCQkgICAgKiBjaXJjdWxhciByZWZlcmVuY2VzIG5vdCB5ZXQgZXhhbWluZWQuCgkJICAgICovCgkJICAgIGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CgkJICAgIG1hcmtlZCA9IDE7CgkJfSAKCQlpZiAoZ3ItPnN1YnR5cGVzLT5zdWJ0eXBlcyAhPSBOVUxMKQoJCSAgICBjaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoY3R4dEdyRGVmLCAKCQkJZ3ItPnN1YnR5cGVzLT5zdWJ0eXBlcyk7CgkJICAgIC8qCgkJICAgICogVW5tYXJrIHRoZSB2aXNpdGVkIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCgkJKi8KCQlpZiAobWFya2VkKQoJCSAgICBnci0+c3VidHlwZXMtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwoJCWlmIChjaXJjICE9IE5VTEwpCgkJICAgIHJldHVybiAoY2lyYyk7CgkgICAgfSBlbHNlIHsKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoY3R4dEdyRGVmLCAKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGdyLT5zdWJ0eXBlcyk7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCSAgICB9CgoJfQoJZ3IgPSBnci0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXI6CiAqIGF0dHJHcjogIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIHRvIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKHhtbFNjaGVtYVR5cGVQdHIgbW9kZWxHckRlZiwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBNb2RlbCBHcm91cCBDb3JyZWN0CiAgICAqIDIgQ2lyY3VsYXIgZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCB3aXRoaW4gdGhlIHtwYXJ0aWNsZXN9IAogICAgKiBvZiBhIGdyb3VwIHRoZXJlIG11c3Qgbm90IGJlIGF0IGFueSBkZXB0aCBhIHBhcnRpY2xlIHdob3NlIHt0ZXJtfSAKICAgICogaXMgdGhlIGdyb3VwIGl0c2VsZi4KICAgICovCiAgICAvKgogICAgKiBOT1RFOiAiZ3ItPnN1YnR5cGVzIiBob2xkcyB0aGUgcmVmZXJlbmNlZCBncm91cC4KICAgICovCiAgICBpZiAoKG1vZGVsR3JEZWYtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB8fCAKCSgobW9kZWxHckRlZi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgPT0gMCkgfHwKCShtb2RlbEdyRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCXJldHVybjsKICAgIGVsc2UgewoJeG1sU2NoZW1hVHlwZVB0ciBjaXJjOwoKCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihtb2RlbEdyRGVmLCBtb2RlbEdyRGVmLT5zdWJ0eXBlcyk7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX01HX1BST1BTX0NPUlJFQ1RfMiwKCQlOVUxMLCBOVUxMLCBjaXJjLT5ub2RlLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gJyVzJyAiCgkJImRlZmluZWQiLCBtb2RlbEdyRGVmLT5uYW1lKTsKCSAgICAvKgoJICAgICogTk9URTogV2Ugd2lsbCBjdXQgdGhlIHJlZmVyZW5jZSB0byBhdm9pZCBmdXJ0aGVyCgkgICAgKiBjb25mdXNpb24gb2YgdGhlIHByb2Nlc3Nvci4KCSAgICAqIFRPRE86IFNQRUM6IERvZXMgdGhlIHNwZWMgZGVmaW5lIGhvdyB0byBwcm9jZXNzIGhlcmU/CgkgICAgKi8KCSAgICBjaXJjLT5zdWJ0eXBlcyA9IE5VTEw7Cgl9CiAgICB9Cn0KCgovKioKICogeG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZjoKICogQGN0eHRHcjogdGhlIHNlYXJjaGVkIGF0dHJpYnV0ZSBncm91cAogKiBAYXR0cjogdGhlIGN1cnJlbnQgYXR0cmlidXRlIGxpc3QgdG8gYmUgcHJvY2Vzc2VkCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tTUkNBdHRyaWJ1dGVHcm91cENpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIGNpcmN1bGFyIGF0dHJpYnV0ZSBncm91IHJlZmVyZW5jZSwgb3RoZXJ3aXNlIE5VTEwuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjdHh0R3IsCgkJCSAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsgICAgCiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjaXJjID0gTlVMTCwgZ3I7CiAgICBpbnQgbWFya2VkOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBhdHRyaWJ1dGUgZ3JvdXAuCiAgICAqLyAgICAJCiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgltYXJrZWQgPSAwOwoJaWYgKGF0dHItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgZ3IgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGF0dHI7CgkgICAgaWYgKGdyLT5yZWZJdGVtICE9IE5VTEwpICB7CgkJaWYgKGdyLT5yZWZJdGVtID09IGN0eHRHcikKCQkgICAgcmV0dXJuIChncik7CgkJZWxzZSBpZiAoZ3ItPnJlZkl0ZW0tPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQpIHsKCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogTWFyayBhcyB2aXNpdGVkIHRvIGF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbiBvbgoJCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkgICAgKi8KCQkgICAgZ3ItPnJlZkl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkJICAgIG1hcmtlZCA9IDE7CgkJfQoJICAgIH0KCSAgICBpZiAoZ3ItPmF0dHJpYnV0ZXMgIT0gTlVMTCkKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihjdHh0R3IsIGdyLT5hdHRyaWJ1dGVzKTsKCSAgICAvKgoJICAgICogVW5tYXJrIHRoZSB2aXNpdGVkIGdyb3VwJ3MgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChtYXJrZWQpCgkJZ3ItPnJlZkl0ZW0tPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkgICAgaWYgKGNpcmMgIT0gTlVMTCkKCQlyZXR1cm4gKGNpcmMpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgkJCQkKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDQXR0cmlidXRlR3JvdXBDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIG9mIGF0dHJpYnV0ZSBncm91cHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyLAoJCQkJCXhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkJY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKeyAgICAKICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiAKICAgICogQXR0cmlidXRlIEdyb3VwIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sKICAgICogMyBDaXJjdWxhciBncm91cCByZWZlcmVuY2UgaXMgZGlzYWxsb3dlZCBvdXRzaWRlIDxyZWRlZmluZT4uIAogICAgKiBUaGF0IGlzLCB1bmxlc3MgdGhpcyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBwYXJlbnQgaXMgCiAgICAqIDxyZWRlZmluZT4sIHRoZW4gYW1vbmcgdGhlIFtjaGlsZHJlbl0sIGlmIGFueSwgdGhlcmUgbXVzdCAKICAgICogbm90IGJlIGFuIDxhdHRyaWJ1dGVHcm91cD4gd2l0aCByZWYgW2F0dHJpYnV0ZV0gd2hpY2ggcmVzb2x2ZXMgCiAgICAqIHRvIHRoZSBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIDxhdHRyaWJ1dGVHcm91cD4uIEluZGlyZWN0IAogICAgKiBjaXJjdWxhcml0eSBpcyBhbHNvIHJ1bGVkIG91dC4gVGhhdCBpcywgd2hlbiBRTmFtZSByZXNvbHV0aW9uIAogICAgKiAoU2NoZW1hIERvY3VtZW50KSAopzMuMTUuMykgaXMgYXBwbGllZCB0byBhILdRTmFtZbcgYXJpc2luZyBmcm9tIAogICAgKiBhbnkgPGF0dHJpYnV0ZUdyb3VwPnMgd2l0aCBhIHJlZiBbYXR0cmlidXRlXSBhbW9uZyB0aGUgW2NoaWxkcmVuXSwgCiAgICAqIGl0IG11c3Qgbm90IGJlIHRoZSBjYXNlIHRoYXQgYSC3UU5hbWW3IGlzIGVuY291bnRlcmVkIGF0IGFueSBkZXB0aCAKICAgICogd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4KICAgICovCiAgICAvKgogICAgKiBPbmx5IGdsb2JhbCBjb21wb25lbnRzIGNhbiBiZSByZWZlcmVuY2VkLgogICAgKi8KICAgIGlmICgoKGF0dHJHci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSA9PSAwKSB8fCAKCShhdHRyR3ItPmF0dHJpYnV0ZXMgPT0gTlVMTCkpCglyZXR1cm47CiAgICBlbHNlIHsKCXhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNBdHRyR3JSZWYoYXR0ckdyLCBhdHRyR3ItPmF0dHJpYnV0ZXMpOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBSZXBvcnQgdGhlIHJlZmVyZW5jZWQgYXR0ciBncm91cCBhcyBRTmFtZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFX0dST1VQXzMsCgkJTlVMTCwgTlVMTCwgY2lyYy0+bm9kZSwKCQkiQ2lyY3VsYXIgcmVmZXJlbmNlIHRvIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgJyVzJyAiCgkJImRlZmluZWQiLCBhdHRyR3ItPm5hbWUpOwoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLgoJICAgICogQkFEU1BFQzogVGhlIHNwZWMgc2hvdWxkIGRlZmluZSBob3cgdG8gcHJvY2VzcyBpbiB0aGlzIGNhc2UuCgkgICAgKi8KCSAgICBjaXJjLT5hdHRyaWJ1dGVzID0gTlVMTDsKCSAgICBjaXJjLT5yZWZJdGVtID0gTlVMTDsKCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJHcnBGaXh1cDoKICogQGF0dHJncnBEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJHcnBGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyZ3JwLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0cmdycC0+bmFtZTsKICAgIGlmIChhdHRyZ3JwLT5hdHRyaWJ1dGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJncnAtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmVmOwoKICAgICAgICByZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChjdHh0LT5zY2hlbWEsIGF0dHJncnAtPnJlZiwgCgkgICAgYXR0cmdycC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgYXR0cmdycCwgYXR0cmdycC0+bm9kZSwKCQkicmVmIiwgYXR0cmdycC0+cmVmLCBhdHRyZ3JwLT5yZWZOcywgCgkJWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCWF0dHJncnAtPnJlZkl0ZW0gPSByZWY7CgkvKgoJKiBDaGVjayBmb3Igc2VsZiByZWZlcmVuY2UhCgkqLwogICAgICAgIHhtbFNjaGVtYUF0dHJHcnBGaXh1cChyZWYsIGN0eHQsIE5VTEwpOwogICAgICAgIGF0dHJncnAtPmF0dHJpYnV0ZXMgPSByZWYtPmF0dHJpYnV0ZXM7CglhdHRyZ3JwLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHJlZi0+YXR0cmlidXRlV2lsZGNhcmQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyQ2hlY2tWYWxDb25zdHI6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZS4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0cih4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CgogICAgLyoKICAgICogYS1wcm9wcy1jb3JyZWN0CiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogQXR0cmlidXRlIERlY2xhcmF0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKgogICAgKiAyIGlmIHRoZXJlIGlzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGUgY2Fub25pY2FsIGxleGljYWwgCiAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGl0cyB2YWx1ZSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IAogICAgKiB0byB0aGUge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLiAKICAgICovCgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpIHsKCWludCByZXQ7Cgl4bWxOb2RlUHRyIG5vZGU7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGl0ZW0tPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIsICIKCQkidHlwZSBpcyBtaXNzaW5nLi4uIHNraXBwaW5nIHZhbGlkYXRpb24gb2YgIgoJCSJ2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoKCS8qCgkqIFRPRE86IFRyeSB0byBhdm9pZCBjcmVhdGluZyBhIG5ldyBjb250ZXh0LgoJKiBUT0RPOiBUaGlzIGFsbCBpcyBub3QgdmVyeSBwZXJmb3JtYW50LgoJKi8KCXR5cGUgPSBpdGVtLT5zdWJ0eXBlczsKCS8qCgkqIEVuc3VyZSB0aGVyZSdzIHZhbGlkYXRpb24gY29udGV4dC4KCSovCglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIGl0ZW0tPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgIgoJCSAgICAiY3JlYXRpbmcgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQkgICAgTlVMTCwgTlVMTCk7CgkJcmV0dXJuOwoJICAgIH0KCX0KCglpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKQoJICAgIG5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChpdGVtLT5ub2RlLCBCQURfQ0FTVCAiZml4ZWQiKTsKCWVsc2UKCSAgICBub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoaXRlbS0+bm9kZSwgQkFEX0NBU1QgImRlZmF1bHQiKTsKCWN0eHQtPnZjdHh0LT5ub2RlID0gbm9kZTsKCWN0eHQtPnZjdHh0LT5jdXIgPSBOVUxMOwoJLyoKCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCAKCSogc2luY2UgdGhleSBhcmUgbm90IGF2YWlsYWJsZToKCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldCAKCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqIAoJKiBvZiB0aGUgZmFjZXQuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dC0+dmN0eHQsIHR5cGUsIAoJICAgIGl0ZW0tPmRlZlZhbHVlLCAwLCAxLCAxLCAwKTsKCWlmIChyZXQgPT0gMCkgewoJICAgIC8qCgkgICAgKiBTdG9yZSB0aGUgY29tcHV0ZWQgdmFsdWUuCgkgICAgKi8KICAgIAkgICAgaXRlbS0+ZGVmVmFsID0gY3R4dC0+dmN0eHQtPnZhbHVlOwoJICAgIGN0eHQtPnZjdHh0LT52YWx1ZSA9IE5VTEw7CQoJfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkgICAgaWYgKGN0eHQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9BX1BST1BTX0NPUlJFQ1RfMiwgCgkJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJCSAgICB0eXBlLCBOVUxMLCBpdGVtLT5kZWZWYWx1ZSwKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXR0ckNoZWNrVmFsQ29uc3RyLCAiCgkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgIgoJCSJhdHRyaWJ1dGUgZGVjbC91c2UgYWdhaW5zdCB0aGUgdHlwZSAnJXMnIiwKCQl0eXBlLT5uYW1lKTsgCSAgICAKCX0JICAgCQogICAgfSAgICAKfQoKI2lmIDAgLyogTm90IHVzZWQgeWV0LiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVkZWNsKQp7CiAgICAvKgogICAgKiBUT0RPOiAxIFRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIGFzIAogICAgKiBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gVGhlIEVsZW1lbnQgRGVjbGFyYXRpb24gU2NoZW1hIAogICAgKiBDb21wb25lbnQgKKczLjMuMSksIG1vZHVsbyB0aGUgaW1wYWN0IG9mIE1pc3NpbmcgU3ViLWNvbXBvbmVudHMgKKc1LjMpLgogICAgKi8KICAgIC8qCiAgICAqIDIgSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKICAgICogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlIAogICAgKiBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4KICAgICoKICAgICogTk9URTogVGhpcyBpcyBkb25lIGluIHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ci4KICAgICovCiAgICAvKgogICAgKiAzIElmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCAKICAgICogdGhlbiB7c2NvcGV9IG11c3QgYmUgZ2xvYmFsLgogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hUGFyc2VFbGVtZW50LgogICAgKiBUT0RPOiBNb3ZlIGl0IHRvIHRoaXMgbGF5ZXIgaGVyZS4KICAgICovCiAgICAvKgogICAgKiBUT0RPOiA0IElmIHRoZXJlIGlzIGEge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIHRoZSB7dHlwZSBkZWZpbml0aW9ufSAKICAgICogb2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUge3R5cGUgCiAgICAqIGRlZmluaXRpb259IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgZ2l2ZW4gdGhlIHZhbHVlIAogICAgKiBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCAKICAgICogYWZmaWxpYXRpb259LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkgKKczLjQuNikgCiAgICAqIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgY29tcGxleCkgb3IgYXMgZGVmaW5lZCBpbiAKICAgICogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSAoaWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzIAogICAgKiBzaW1wbGUpLiAKICAgICovCiAgICAvKgogICAgKiBUT0RPOiA1IElmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvciB7dHlwZSBkZWZpbml0aW9ufSdzIHtjb250ZW50IHR5cGV9IAogICAgKiBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQgdGhlbiB0aGVyZSBtdXN0IG5vdCBiZSBhIHt2YWx1ZSBjb25zdHJhaW50fS4KICAgICogTm90ZTogVGhlIHVzZSBvZiBJRCBhcyBhIHR5cGUgZGVmaW5pdGlvbiBmb3IgZWxlbWVudHMgZ29lcyBiZXlvbmQgCiAgICAqIFhNTCAxLjAsIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBpZiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBpcyBkZXNpcmVkCiAgICAqLwogICAgLyoKICAgICogVE9ETzogNiBDaXJjdWxhciBzdWJzdGl0dXRpb24gZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCBpdCBtdXN0IG5vdCAKICAgICogYmUgcG9zc2libGUgdG8gcmV0dXJuIHRvIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgCiAgICAqIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSBwcm9wZXJ0eS4KICAgICovCn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyOgogKiBAaXRlbTogIGFuIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uL3BhcnRpY2xlCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIAogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIGNvbnN0cmFpbnRzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0cih4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wsCgkJCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKeyAgIAogICAgaWYgKGRlY2wtPnZhbHVlICE9IE5VTEwpIHsKCWludCByZXQ7Cgl4bWxOb2RlUHRyIG5vZGUgPSBOVUxMOwoJeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCS8qCgkqIDIgSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlIAoJKiBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4KCSovICAgIAoJaWYgKGRlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGRlY2wtPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHIsICIKCQkidHlwZSBpcyBtaXNzaW5nLi4uIHNraXBwaW5nIHZhbGlkYXRpb24gb2YgIgoJCSJ0aGUgdmFsdWUgY29uc3RyYWludCIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCS8qCgkqIEVuc3VyZSB0aGVyZSdzIGEgdmFsaWRhdGlvbiBjb250ZXh0LgoJKi8KCWlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpCgkgICAgcmV0dXJuOwoKCXR5cGUgPSBkZWNsLT5zdWJ0eXBlczsKCglpZiAoZGVjbC0+bm9kZSAhPSBOVUxMKSB7CgkgICAgaWYgKGRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkKCQlub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoZGVjbC0+bm9kZSwgQkFEX0NBU1QgImZpeGVkIik7CgkgICAgZWxzZQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChkZWNsLT5ub2RlLCBCQURfQ0FTVCAiZGVmYXVsdCIpOwoJfQoJY3R4dC0+dmN0eHQtPm5vZGUgPSBub2RlOwoJY3R4dC0+dmN0eHQtPmN1ciA9IE5VTEw7CglyZXQgPSB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdChjdHh0LCBjdHh0LT52Y3R4dCwgdHlwZSwgZGVjbC0+dmFsdWUsIAoJICAgIG5vZGUpOwoJaWYgKHJldCA9PSAwKSB7CgkgICAgLyoKCSAgICAqIENvbnN1bWUgdGhlIGNvbXB1dGVkIHZhbHVlLgoJICAgICovCiAgICAJICAgIGRlY2wtPmRlZlZhbCA9IGN0eHQtPnZjdHh0LT52YWx1ZTsKCSAgICBjdHh0LT52Y3R4dC0+dmFsdWUgPSBOVUxMOwkKCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUVsZW1DaGVja1ZhbENvbnN0ciwgIgoJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgdGhlICIKCQkiZWxlbWVudCBkZWNsYXJhdGlvbiAnJXMnIiwKCQlkZWNsLT5uYW1lKTsgCSAgICAKCX0JICAgCQogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJGaXh1cDoKICogQGl0ZW06ICBhbiBzY2hlbWEgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZS4KICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMvdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgLyogCiAgICAqIFRPRE86IElmIGluY2x1ZGluZyB0aGlzIGlzIGRvbmUgdHdpY2UgKCEpIGZvciBldmVyeSBhdHRyaWJ1dGUuCiAgICAqICAgICAgIC0+IEhtbSwgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCBkb25lLgogICAgKi8KICAgIC8qCiAgICAqIFRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBbY2hpbGRyZW5dLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlIHNpbXBsZSAKICAgICogdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlIAogICAgKiBbYXR0cmlidXRlXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuCiAgICAqLwogICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9JTlRFUk5BTF9SRVNPTFZFRCkKCXJldHVybjsKICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfSU5URVJOQUxfUkVTT0xWRUQ7CiAgICBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoaXRlbS0+dHlwZU5hbWUgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCgl0eXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW0tPnR5cGVOYW1lLAoJICAgIGl0ZW0tPnR5cGVOcyk7CglpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKCEgSVNfU0lNUExFX1RZUEUodHlwZSkpKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIGl0ZW0tPm5vZGUsCgkJInR5cGUiLCBpdGVtLT50eXBlTmFtZSwgaXRlbS0+dHlwZU5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKCX0gZWxzZQoJICAgIGl0ZW0tPnN1YnR5cGVzID0gdHlwZTsKCQogICAgfSBlbHNlIGlmIChpdGVtLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwoKCS8qCgkqIFdlIGhhdmUgYW4gYXR0cmlidXRlIHVzZSBoZXJlOyBhc3NpZ24gdGhlIHJlZmVyZW5jZWQgCgkqIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KCSovCgkvKgoJKiBUT0RPOiBFdmFsdWF0ZSwgd2hhdCBlcnJvcnMgY291bGQgb2NjdXIgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIG5vdAoJKiBmb3VuZC4gSXQgbWlnaHQgYmUgcG9zc2libGUgdGhhdCB0aGUgInR5cGVmaXh1cCIgbWlnaHQgY3Jhc2ggaWYKCSogbm8gcmVmIGRlY2xhcmF0aW9uIHdhcyBmb3VuZC4KCSovCglkZWNsID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgaXRlbS0+cmVmLCBpdGVtLT5yZWZOcyk7CiAgICAgICAgaWYgKGRlY2wgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJICAgIAlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgaXRlbS0+bm9kZSwKCQkicmVmIiwgaXRlbS0+cmVmLCBpdGVtLT5yZWZOcywgCgkJWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CglpdGVtLT5yZWZEZWNsID0gZGVjbDsKICAgICAgICB4bWxTY2hlbWFBdHRyRml4dXAoZGVjbCwgY3R4dCwgTlVMTCk7CgkKICAgICAgICBpdGVtLT5zdWJ0eXBlcyA9IGRlY2wtPnN1YnR5cGVzOwoJLyoKCSogQXR0cmlidXRlIFVzZSBDb3JyZWN0CgkqIGF1LXByb3BzLWNvcnJlY3QuMjogSWYgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyBhIGZpeGVkIAoJKiB7dmFsdWUgY29uc3RyYWludH0sIHRoZW4gaWYgdGhlIGF0dHJpYnV0ZSB1c2UgaXRzZWxmIGhhcyBhIAoJKiB7dmFsdWUgY29uc3RyYWludH0sIGl0IG11c3QgYWxzbyBiZSBmaXhlZCBhbmQgaXRzIHZhbHVlIG11c3QgbWF0Y2ggCgkqIHRoYXQgb2YgdGhlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9LgoJKi8KCWlmICgoZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSAmJiAKCSAgICAoaXRlbS0+ZGVmVmFsdWUgIT0gTlVMTCkpIHsKCSAgICBpZiAoKChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpID09IDApIHx8CgkJKCF4bWxTdHJFcXVhbChpdGVtLT5kZWZWYWx1ZSwgZGVjbC0+ZGVmVmFsdWUpKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQVVfUFJPUFNfQ09SUkVDVF8yLCAKCQkgICAgTlVMTCwgTlVMTCwgaXRlbS0+bm9kZSwgCgkJICAgICJUaGUgdmFsdWUgY29uc3RyYWludCBtdXN0IGJlIGZpeGVkICIKCQkgICAgImFuZCBtYXRjaCB0aGUgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgIgoJCSAgICAiZGVjbGFyYXRpb25zJ3MgdmFsdWUgY29uc3RyYWludCAnJXMnIiwKCQkgICAgZGVjbC0+ZGVmVmFsdWUpOwoJICAgIH0KCSAgICAvKgoJICAgICogRlVUVVJFOiBPbmUgc2hvdWxkIGNoYW5nZSB0aGUgdmFsdWVzIG9mIHRoZSBhdHRyLiB1c2UKCSAgICAqIGlmIGV2ZXIgdmFsaWRhdGlvbiBzaG91bGQgYmUgYXR0ZW1wdGVkIGV2ZW4gaWYgdGhlCgkgICAgKiBzY2hlbWEgaXRzZWxmIHdhcyBub3QgZnVsbHkgdmFsaWQuCgkgICAgKi8KCX0KICAgIH0gZWxzZSB7CglpdGVtLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOyAgICAgICAgCiAgICB9CQp9CgovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQgPSBOVUxMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBwcmVzZXJ2ZSA9IDA7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYSAKICAgICogdGhlIEFQSTsgaS5lLiBub3QgYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KCiAgICB4bWxTY2hlbWFJbml0VHlwZXMoKTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgY3R4dC0+Y291bnRlciA9IDA7CiAgICBjdHh0LT5jb250YWluZXIgPSBOVUxMOwoKICAgIC8qCiAgICAgKiBGaXJzdCBzdGVwIGlzIHRvIHBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBpbnRvIGFuIERPTS9JbmZvc2V0CiAgICAgKi8KICAgIGlmIChjdHh0LT5VUkwgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IHhtbFJlYWRGaWxlKChjb25zdCBjaGFyICopIGN0eHQtPlVSTCwgTlVMTCwgCgkgICAgICAgICAgICAgICAgICBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgICAgIGlmIChkb2MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkJICBYTUxfU0NIRU1BUF9GQUlMRURfTE9BRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBsb2FkICclcycuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPlVSTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChjdHh0LT5idWZmZXIgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IHhtbFJlYWRNZW1vcnkoY3R4dC0+YnVmZmVyLCBjdHh0LT5zaXplLCBOVUxMLCBOVUxMLAoJICAgICAgICAgICAgICAgICAgICBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgICAgIGlmIChkb2MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkJICBYTUxfU0NIRU1BUF9GQUlMRURfUEFSU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgcGFyc2UuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBkb2MtPlVSTCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIpOwogICAgICAgIGN0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiLCAtMSk7CiAgICB9IGVsc2UgaWYgKGN0eHQtPmRvYyAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0gY3R4dC0+ZG9jOwoJcHJlc2VydmUgPSAxOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RISU5HX1RPX1BBUlNFLAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlLlxuIiwKCQkgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGVuIGV4dHJhY3QgdGhlIHJvb3QgYW5kIFNjaGVtYSBwYXJzZSBpdAogICAgICovCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkJICAgICAgIlRoZSBzY2hlbWEgaGFzIG5vIGRvY3VtZW50IGVsZW1lbnQuXG4iLCBOVUxMLCBOVUxMKTsKCWlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBUaGVuIGRvIHRoZSBwYXJzaW5nIGZvciBnb29kCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlU2NoZW1hKGN0eHQsIHJvb3QpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5kb2MgPSBkb2M7CiAgICByZXQtPnByZXNlcnZlID0gcHJlc2VydmU7CiAgICBjdHh0LT5zY2hlbWEgPSByZXQ7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gTlVMTDsKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCBhdHRyaWJ1dGVzIGRlY2xhcmF0aW9ucwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF0dHJGaXh1cCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZ3JvdXAgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckdycEZpeHVwLAogICAgICAgICAgICAgICAgY3R4dCk7CgogICAgLyoKICAgICogQ2hlY2sgYXR0cmlidXRlIGdyb3VwcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIAoJeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVHcm91cENpcmN1bGFyLCBjdHh0KTsKCiAgICAvKgogICAgKiBUaGVuIGZpeHVwIGFsbCBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4KICAgICovICAgIAogICAgeG1sSGFzaFNjYW4ocmV0LT5ncm91cERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hR3JvdXBEZWZGaXh1cCwgY3R4dCk7CiAgICAKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVGaXh1cCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gZml4IHJlZmVyZW5jZXMgb2YgZWxlbWVudCBkZWNsYXJhdGlvbjsgYXBwbHkgY29uc3RyYWludHMuCiAgICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbkZ1bGwocmV0LT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrLCBjdHh0KTsKCiAgICAgLyoKICAgICogQ2hlY2sgbW9kZWwgZ3JvdXBzIGRlZm5pdGlvbnMgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5ncm91cERlY2wsICh4bWxIYXNoU2Nhbm5lcikgCgl4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGJ1aWxkIHRoZSBjb250ZW50IG1vZGVsIGZvciBhbGwgY29tcGxleCB0eXBlcwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLAogICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gY2hlY2sgdGhlIGRlZmF1bHRzIHBhcnQgb2YgdGhlIHR5cGUgbGlrZSBmYWNldHMgdmFsdWVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cywKICAgICAgICAgICAgICAgIGN0eHQpOwoKICAgIC8qCiAgICAqIFZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMvdXNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgY3R4dCk7CgogICAgLyoKICAgICogVmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgZWxlbWVudCBkZWNsYXJhdGlvbnMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5lbGVtRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHIsIGN0eHQpOwoKCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYUZyZWUocmV0KTsKICAgICAgICByZXQgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGNhbGxiYWNrCiAqIEB3YXJuOiAgdGhlIHdhcm5pbmcgY2FsbGJhY2sKICogQGN0eDogIGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcwogKgogKiBTZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9ucyB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+dXNlckRhdGEgPSBjdHg7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBYTWwtU2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnI6IHRoZSBlcnJvciBjYWxsYmFjayByZXN1bHQKICogQHdhcm46IHRoZSB3YXJuaW5nIGNhbGxiYWNrIHJlc3VsdAogKiBAY3R4OiBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MgcmVzdWx0CiAqCiAqIEdldCB0aGUgY2FsbGJhY2sgaW5mb3JtYXRpb24gdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHBhcnNlciBjb250ZXh0CiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBmYWlsdXJlLCAwIG90aGVyd2lzZQogKi8KaW50IAp4bWxTY2hlbWFHZXRQYXJzZXJFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJCQkJIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkJCQkJIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgKiB3YXJuLCB2b2lkICoqY3R4KQp7CglpZiAoY3R4dCA9PSBOVUxMKQoJCXJldHVybigtMSk7CglpZiAoZXJyICE9IE5VTEwpCgkJKmVyciA9IGN0eHQtPmVycm9yOwoJaWYgKHdhcm4gIT0gTlVMTCkKCQkqd2FybiA9IGN0eHQtPndhcm5pbmc7CglpZiAoY3R4ICE9IE5VTEwpCgkJKmN0eCA9IGN0eHQtPnVzZXJEYXRhOwoJcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmc6CiAqIEB0eXBlOiAgdGhlIGZhY2V0IHR5cGUKICoKICogQ29udmVydCB0aGUgeG1sU2NoZW1hVHlwZVR5cGUgdG8gYSBjaGFyIHN0cmluZy4KICoKICogUmV0dXJucyB0aGUgY2hhciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZhY2V0IHR5cGUgaWYgdGhlCiAqICAgICB0eXBlIGlzIGEgZmFjZXQgYW5kIGFuICJJbnRlcm5hbCBFcnJvciIgc3RyaW5nIG90aGVyd2lzZS4KICovCnN0YXRpYyBjb25zdCBjaGFyICoKeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSkKewogICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIHJldHVybiAoInBhdHRlcm4iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtYXhFeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtYXhJbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtaW5FeGNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICByZXR1cm4gKCJtaW5JbmNsdXNpdmUiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgcmV0dXJuICgid2hpdGVTcGFjZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgcmV0dXJuICgiZW51bWVyYXRpb24iKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJsZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJtYXhMZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgogICAgICAgICAgICByZXR1cm4gKCJtaW5MZW5ndGgiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoInRvdGFsRGlnaXRzIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICByZXR1cm4gKCJmcmFjdGlvbkRpZ2l0cyIpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuICgiSW50ZXJuYWwgRXJyb3IiKTsKfQoKc3RhdGljIHhtbENoYXIgKgp4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZShjb25zdCB4bWxDaGFyICp2YWx1ZSkgewogICAgY29uc3QgeG1sQ2hhciAqY3VyID0gdmFsdWU7ICAgIAogICAgeG1sQ2hhciAqcmV0ID0gTlVMTCwgKm1jdXI7IAoKICAgIGlmICh2YWx1ZSA9PSBOVUxMKSAKCXJldHVybihOVUxMKTsKICAgIAogICAgd2hpbGUgKCgqY3VyICE9IDApICYmIAoJKCgoKmN1cikgIT0gMHhkKSAmJiAoKCpjdXIpICE9IDB4OSkgJiYgKCgqY3VyKSAhPSAweGEpKSkgewoJY3VyKys7CiAgICB9CiAgICBpZiAoKmN1ciA9PSAwKQoJcmV0dXJuIChOVUxMKTsKICAgIHJldCA9IHhtbFN0cmR1cCh2YWx1ZSk7CiAgICAvKiBUT0RPIEZJWE1FOiBJIGd1ZXNzIGdjYyB3aWxsIGJhcmsgYXQgdGhpcy4gKi8KICAgIG1jdXIgPSAoeG1sQ2hhciAqKSAgKHJldCArIChjdXIgLSB2YWx1ZSkpOwogICAgZG8gewoJaWYgKCAoKCptY3VyKSA9PSAweGQpIHx8ICgoKm1jdXIpID09IDB4OSkgfHwgKCgqbWN1cikgPT0gMHhhKSApCgkgICAgKm1jdXIgPSAnICc7CgltY3VyKys7CiAgICB9IHdoaWxlICgqbWN1ciAhPSAwKTsJICAgIAogICAgcmV0dXJuKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFuYzsKCiAgICAvKiAKICAgICogVGhlIG5vcm1hbGl6YXRpb24gdHlwZSBjYW4gYmUgY2hhbmdlZCBvbmx5IGZvciB0eXBlcyB3aGljaCBhcmUgZGVyaXZlZCAKICAgICogZnJvbSB4c2Q6c3RyaW5nLgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpICYmCiAgICAgICAgICAgICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19OT1JNU1RSSU5HKSkKCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1BSRVNFUlZFKTsKCWVsc2UgewoJICAgIC8qCgkgICAgKiBGb3IgYWxsILdhdG9taWO3IGRhdGF0eXBlcyBvdGhlciB0aGFuIHN0cmluZyAoYW5kIHR5cGVzILdkZXJpdmVktyAKCSAgICAqIGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBpdCkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2UgaXMgZml4ZWQgdG8gCgkgICAgKiBjb2xsYXBzZQoJICAgICovCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKTsKCX0JCSAgIAkgICAgCiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKCS8qCgkqIEZvciBsaXN0IHR5cGVzIHRoZSBmYWNldCAid2hpdGVTcGFjZSIgaXMgZml4ZWQgdG8gImNvbGxhcHNlIi4gCgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSk7CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7CglyZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hVHlwZVB0ciBhbnlTVDsKCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBsaW47CgoJLyoKCSogQXRvbWljIHR5cGVzLgoJKi8KCWFueVNUID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CglhbmMgPSB0eXBlLT5iYXNlVHlwZTsKCWRvIHsKCSAgICAvKgoJICAgICogRm9yIGFsbCC3YXRvbWljtyBkYXRhdHlwZXMgb3RoZXIgdGhhbiBzdHJpbmcgKGFuZCB0eXBlcyC3ZGVyaXZlZLcgCgkgICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvIAoJICAgICogY29sbGFwc2UKCSAgICAqLwoJICAgIGlmICgoYW5jLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYKCQkoYW5jLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpKSB7CgkJCgkJbGluID0gdHlwZS0+ZmFjZXRTZXQ7CgkJZG8gewoJCSAgICBpZiAobGluLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQkJaWYgKGxpbi0+ZmFjZXQtPndoaXRlc3BhY2UgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSkgewoJCQkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKTsgIAoJCQl9IGVsc2UgaWYgKGxpbi0+ZmFjZXQtPndoaXRlc3BhY2UgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFKSB7IAoJCQkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1JFUExBQ0UpOwoJCQl9IGVsc2UKCQkJICAgIHJldHVybihYTUxfU0NIRU1BU19WQUxfV1RTUF9QUkVTRVJWRSk7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGxpbiA9IGxpbi0+bmV4dDsKCQl9IHdoaWxlIChsaW4gIT0gTlVMTCk7CQoJCWJyZWFrOwoJICAgIH0KCSAgICBhbmMgPSBhbmMtPmJhc2VUeXBlOwoJfSB3aGlsZSAoYW5jICE9IGFueVNUKTsKCXJldHVybiAoWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpOwkKICAgIH0gIAogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGhvbGRpbmcgdGhlIGZhY2V0cwogKiBAZmFjZXRzOiAgdGhlIGxpc3Qgb2YgZmFjZXRzIHRvIGNoZWNrCiAqIEB2YWx1ZTogIHRoZSBsZXhpY2FsIHJlcHIgb2YgdGhlIHZhbHVlIHRvIHZhbGlkYXRlCiAqIEB2YWw6ICB0aGUgcHJlY29tcHV0ZWQgdmFsdWUKICogQGZpcmVFcnJvcnM6ICBpZiAwLCBvbmx5IGludGVybmFsIGVycm9ycyB3aWxsIGJlIGZpcmVkOwogKgkJIG90aGVyd2lzZSBhbGwgZXJyb3JzIHdpbGwgYmUgZmlyZWQuCiAqCiAqIENoZWNrIGEgdmFsdWUgYWdhaW5zdCBhbGwgZmFjZXQgY29uZGl0aW9ucwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJCXVuc2lnbmVkIGxvbmcgbGVuZ3RoLAoJCQkJaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hVHlwZVB0ciAgYmlUeXBlOyAvKiBUaGUgYnVpbGQtaW4gdHlwZS4gKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbms7CiAgICBpbnQgcmV0RmFjZXQ7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCiNpZmRlZiBERUJVR19VTklPTl9WQUxJREFUSU9OCiAgICBwcmludGYoIkZhY2V0cyBvZiB0eXBlOiAnJXMnXG4iLCAoY29uc3QgY2hhciAqKSB0eXBlLT5uYW1lKTsKICAgIHByaW50ZigiICBmaXJlRXJyb3JzOiAlZFxuIiwgZmlyZUVycm9ycyk7CiNlbmRpZgogICAgICAgIAogICAgbm9kZSA9IGN0eHQtPm5vZGU7CiAgICAvKgogICAgKiBOT1RFOiBEbyBub3QganVtcCBhd2F5LCBpZiB0aGUgZmFjZXRTZXQgb2YgdGhlIGdpdmVuIHR5cGUgaXMKICAgICogZW1wdHk6IHVudGlsIG5vdywgInBhdHRlcm4iIGZhY2V0cyBvZiB0aGUgKmJhc2UgdHlwZXMqIG5lZWQgdG8KICAgICogYmUgY2hlY2tlZCBhcyB3ZWxsLgogICAgKi8KICAgIGJpVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgd2hpbGUgKChiaVR5cGUgIT0gTlVMTCkgJiYgKGJpVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJYmlUeXBlID0gYmlUeXBlLT5iYXNlVHlwZTsKICAgIGlmIChiaVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwJCSAgICAKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCSAgICAidGhlIGJhc2UgdHlwZSBheGlzIG9mIHRoZSBnaXZlbiB0eXBlICclcycgZG9lcyBub3QgcmVzb2x2ZSB0byAiCgkgICAgImEgYnVpbHQtaW4gdHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CQoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgCiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7Cgl3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgLyoKCSAgICAqIFNraXAgdGhlIHBhdHRlcm4gIndoaXRlU3BhY2UiOiBpdCBpcyB1c2VkIHRvIAoJICAgICogZm9ybWF0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBiZWZvcmVoYW5kLgoJICAgICovCSAgICAKCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDogCgkJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTGlzdFNpbXBsZVR5cGVGYWNldChmYWNldCwKCQkJICAgIHZhbHVlLCBsZW5ndGgsIDApOwoJCQlsZW4gPSBsZW5ndGg7CgkJICAgIH0gZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxlbmd0aEZhY2V0KGJpVHlwZSwgZmFjZXQsCgkJCSAgICB2YWx1ZSwgY3R4dC0+dmFsdWUsICZsZW4pOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXQsIHZhbHVlLCAKCQkJY3R4dC0+dmFsdWUpOwoJICAgIH0KCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldCBvZiB0eXBlICclcycuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQlicmVhazsKCSAgICB9IGVsc2UgaWYgKChyZXQgPiAwKSAmJiAoZmlyZUVycm9ycykpIHsKCQl4bWxTY2hlbWFWRmFjZXRFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgbGVuLAoJCSAgICB0eXBlLCBmYWNldCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoKCSAgICBmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQ7Cgl9CglpZiAocmV0ID49IDApIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyBlbnVtZXJhdGlvbnMuCgkgICAgKi8KCSAgICByZXRGYWNldCA9IDA7CgkgICAgZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CgkgICAgd2hpbGUgKGZhY2V0TGluayAhPSBOVUxMKSB7CgkJaWYgKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJCSAgICByZXRGYWNldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmlUeXBlLCBmYWNldExpbmstPmZhY2V0LCAKCQkJdmFsdWUsIGN0eHQtPnZhbHVlKTsJCQoJCSAgICBpZiAocmV0RmFjZXQgPD0gMCkKCQkJYnJlYWs7CgkJfQoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHJldEZhY2V0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRDsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwKCQkJdmFsdWUsIDAsIHR5cGUsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0RmFjZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0IG9mIHR5cGUgJyVzJy5cbiIsCgkJICAgIEJBRF9DQVNUICJlbnVtZXJhdGlvbiIsIE5VTEwpOwoJCSAgICByZXQgPSAtMTsJCQoJICAgIH0JCQoJfQogICAgfQogICAgaWYgKHJldCA+PSAwKSB7CgkvKgoJKiBQcm9jZXNzIHBhdHRlcnMuIFBhdHRlcm4gZmFjZXRzIGFyZSBPUmVkIGF0IHR5cGUgbGV2ZWwgCgkqIGFuZCBBTkRlZCBpZiBkZXJpdmVkLiBXYWxrIHRoZSBiYXNlIHR5cGUgYXhpcy4KCSovCgl0bXBUeXBlID0gdHlwZTsKCWZhY2V0ID0gTlVMTDsKCWRvIHsKCSAgICByZXRGYWNldCA9IDA7CgkgICAgZm9yIChmYWNldExpbmsgPSB0bXBUeXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7IAoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikKCQkgICAgY29udGludWU7CgkJcmV0RmFjZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgCgkJICAgIHZhbHVlLCBjdHh0LT52YWx1ZSk7CgkJaWYgKHJldEZhY2V0ID09IDApIAoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXRGYWNldCA8IDApIHsKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJCSJ2YWxpZGF0aW5nICdwYXR0ZXJuJyBmYWNldCAnJXMnIG9mIHR5cGUgJyVzJy5cbiIsCgkJCWZhY2V0TGluay0+ZmFjZXQtPnZhbHVlLCB0bXBUeXBlLT5uYW1lKTsKCQkgICAgcmV0ID0gLTE7CgkJICAgIGJyZWFrOwoJCX0gZWxzZQoJCSAgICAvKiBTYXZlIHRoZSBsYXN0IG5vbi12YWxpZGF0aW5nIGZhY2V0LiAqLwoJCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgfQoJICAgIGlmIChyZXRGYWNldCAhPSAwKQoJCWJyZWFrOwkJICAgIAoJICAgIHRtcFR5cGUgPSB0bXBUeXBlLT5iYXNlVHlwZTsKCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJaWYgKHJldEZhY2V0ID4gMCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19QQVRURVJOX1ZBTElEOwoJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIDAsIHR5cGUsIGZhY2V0LCAKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQogICAgfQkgICAgCiAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU2ltcGxlIHR5cGUgdmFsaWRhdGlvbgkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRE9NIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkJICBpbnQgdmFsU2ltcGxlQ29udGVudCk7CgoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyU3RhdGVzOgogKiBAc3RhdGU6ICBhIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKiBGcmVlIHRoZSBnaXZlbiBsaXN0IG9mIGF0dHJpYnV0ZSBzdGF0ZXMKICoKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoeG1sU2NoZW1hQXR0clN0YXRlUHRyIHN0YXRlKQp7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwogICAgd2hpbGUgKHN0YXRlICE9IE5VTEwpIHsKCXRtcCA9IHN0YXRlOwoJc3RhdGUgPSBzdGF0ZS0+bmV4dDsJCgl4bWxGcmVlKHRtcCk7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBhdHRyczogIGEgbGlzdCBvZiBhdHRyaWJ1dGVzCiAqCiAqIFJlZ2lzdGVyIHRoZSBsaXN0IG9mIGF0dHJpYnV0ZXMgYXMgdGhlIHNldCB0byBiZSB2YWxpZGF0ZWQgb24gdGhhdCBlbGVtZW50CiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxBdHRyUHRyIGF0dHJzKQp7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoKICAgIGN0eHQtPmF0dHIgPSBOVUxMOwogICAgY3R4dC0+YXR0clRvcCA9IE5VTEw7CiAgICB3aGlsZSAoYXR0cnMgIT0gTlVMTCkgewogICAgICAgIGlmICgoYXR0cnMtPm5zICE9IE5VTEwpICYmCiAgICAgICAgICAgICh4bWxTdHJFcXVhbChhdHRycy0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSkgewogICAgICAgICAgICBhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9Cgl0bXAgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKQoJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CglpZiAodG1wID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsICJyZWdpc3RlcmluZyBhdHRyaWJ1dGVzIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl0bXAtPmF0dHIgPSBhdHRyczsKCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV047Cgl0bXAtPm5leHQgPSBOVUxMOwoJdG1wLT5kZWNsID0gTlVMTDsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIAogICAgICAgICAgICBjdHh0LT5hdHRyID0gdG1wOwoJZWxzZQoJICAgIGN0eHQtPmF0dHJUb3AtPm5leHQgPSB0bXA7CgljdHh0LT5hdHRyVG9wID0gdG1wOwogICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgojaWYgMCAvKiBDdXJyZW50bHkgbm90IHVzZWQgKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdAogKiBAbm9kZWxpc3Q6IHRoZSBsaXN0IG9mIG5vZGVzCiAqCiAqIENoZWNrIHRoZSBub2RlIGxpc3QgaXMgb25seSBtYWRlIG9mIHRleHQgbm9kZXMgYW5kIGVudGl0aWVzIHBvaW50aW5nCiAqIHRvIHRleHQgbm9kZXMKICoKICogUmV0dXJucyAxIGlmIHRydWUsIDAgaWYgZmFsc2UgYW5kIC0xIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0KHhtbE5vZGVQdHIgbm9kZWxpc3QpCnsKICAgIHdoaWxlIChub2RlbGlzdCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKG5vZGVsaXN0LT50eXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpIHsKICAgICAgICAgICAgVE9ETyAgICAgICAgICAgICAgICAvKiBpbXBsZW1lbnQgcmVjdXJzaW9uIGluIHRoZSBlbnRpdHkgY29udGVudCAqLwogICAgICAgIH0KICAgICAgICBpZiAoKG5vZGVsaXN0LT50eXBlICE9IFhNTF9URVhUX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ09NTUVOVF9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1BJX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgewogICAgICAgICAgICByZXR1cm4gKDApOwogICAgICAgIH0KICAgICAgICBub2RlbGlzdCA9IG5vZGVsaXN0LT5uZXh0OwogICAgfQogICAgcmV0dXJuICgxKTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBvc3RTY2hlbWFBc3NlbWJsZUZpeHVwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaW50IGksIG5iSXRlbXM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sICppdGVtczsKCgogICAgLyoKICAgICogRHVyaW5nIHRoZSBBc3NlbWJsZSBvZiB0aGUgc2NoZW1hIGN0eHQtPmN1ckl0ZW1zIGhhcwogICAgKiBiZWVuIGZpbGxlZCB3aXRoIHRoZSByZWxldmFudCBuZXcgaXRlbXMuIEZpeCB0aG9zZSB1cC4KICAgICovCiAgICBuYkl0ZW1zID0gY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXM7CiAgICBpdGVtcyA9ICh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtczsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJCXhtbFNjaGVtYUF0dHJGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCXhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2soKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0sIGN0eHQsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQl4bWxTY2hlbWFBdHRyR3JwRml4dXAoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLCAKCQkgICAgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hR3JvdXBEZWZGaXh1cChpdGVtLCBjdHh0LCBOVUxMKTsgICAgICAgICAgICAKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogQ2lyY3VsYXJpdHkgY2hlY2tzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewkgICAgCgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogRml4dXAgZm9yIGFsbCBvdGhlciBpdGVtLiAKICAgICogVE9ETzogSG1tLCBub3Qgc3VyZSBpZiBzdGFydGluZyBmcm9tIGNvbXBsZXgvc2ltcGxlIHR5cGVzLAogICAgKiBhbGwgc3Vic2VxdWVudCBpdGVtcyB3aWxsIGJlIHJlYWNoZWQuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBmYWNldCB2YWx1ZXMuIE5vdGUgdGhhdCBmYWNldHMgYXJlCiAgICAqIGhvbGQgYnkgY29tcGxleCBhbmQgc2ltcGxlIHR5cGUgY29tcG9uZW50cyBvbmx5LgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewkgCgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyhpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogQnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGNvbXBsZXggdHlwZXMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9IAogICAgLyoKICAgICogVmFsaWRhdGUgdmFsdWUgY29udHJhaW50IHZhbHVlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogdGhlIGV4aXN0aW5nIHNjaGVtYQogKiBAbm9kZTogdGhlIG5vZGUgdGhhdCBmaXJlZCB0aGUgYXNzZW1ibGluZwogKiBAbnNOYW1lOiB0aGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIG5ldyBzY2hlbWEKICogQGxvY2F0aW9uOiB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbG9jYXRpb24pCnsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5zLCAqb2xkdG5zOyAKICAgIHhtbERvY1B0ciBkb2MsIG9sZGRvYzsKICAgIGludCBvbGRmbGFncywgcmV0ID0gMDsKICAgIHhtbE5vZGVQdHIgZG9jRWxlbTsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQ7CgogICAgLyoKICAgICogVGhpcyBzaG91bGQgYmUgdXNlZDoKICAgICogMS4gb24gPGltcG9ydD4ocykKICAgICogMi4gaWYgcmVxdWVzdGVkIGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgCiAgICAqIDMuIGlmIHJlcXVlc3RlZCB2aWEgdGhlIEFQSQogICAgKi8KICAgIGlmICgodmN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogQ3JlYXRlIGEgdGVtcG9yYXJ5IHBhcnNlciBjb250ZXh0LgogICAgKi8KICAgIGlmICgodmN0eHQtPnBjdHh0ID09IE5VTEwpICYmCgkoeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHZjdHh0KSA9PSAtMSkpIHsKCXhtbFNjaGVtYVZFcnIodmN0eHQsIG5vZGUsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24sICIKCSAgICAiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHBhcnNlciBjb250ZXh0LlxuIiwgCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsJCQogICAgfSAgICAgICAgICAgIAogICAgcGN0eHQgPSB2Y3R4dC0+cGN0eHQ7CiAgICAvKgogICAgKiBTZXQgdGhlIGNvdW50ZXIgdG8gcHJvZHVjZSB1bmlxdWUgbmFtZXMgZm9yIGFub255bW91cyBpdGVtcy4KICAgICovCiAgICBwY3R4dC0+Y291bnRlciA9IHNjaGVtYS0+Y291bnRlcjsgICAgCiAgICAvKgogICAgKiBBY3F1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYyhwY3R4dCwgc2NoZW1hLCBub2RlLAoJbnNOYW1lLCBsb2NhdGlvbiwgJmRvYywgJnRhcmdldE5zLCAwKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKGRvYyAhPSBOVUxMKQoJICAgIHhtbEZyZWVEb2MoZG9jKTsKICAgIH0gZWxzZSBpZiAoZG9jICE9IE5VTEwpIHsKCWRvY0VsZW0gPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwoJLyoKCSogQ3JlYXRlIG5ldyBhc3NlbWJsZSBpbmZvLgoJKi8KCWlmIChwY3R4dC0+YXNzZW1ibGUgPT0gTlVMTCkgewoJICAgIHBjdHh0LT5hc3NlbWJsZSA9IHhtbFNjaGVtYU5ld0Fzc2VtYmxlKCk7CgkgICAgaWYgKHBjdHh0LT5hc3NlbWJsZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJICAgICJNZW1vcnkgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiwgIgoJCSAgICAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7CgkJeG1sRnJlZURvYyhkb2MpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCX0KCS8qCgkqIFNhdmUgYW5kIHJlc2V0IHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCW9sZGZsYWdzID0gc2NoZW1hLT5mbGFnczsKCW9sZHRucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJb2xkZG9jID0gc2NoZW1hLT5kb2M7CgkKCXhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TnM7CgkvKiBzY2hlbWEtPm5iQ3VySXRlbXMgPSAwOyAqLwoJcGN0eHQtPnNjaGVtYSA9IHNjaGVtYTsKCXBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CglwY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CgkKCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMocGN0eHQsIHNjaGVtYSwgZG9jRWxlbSk7CQkKCXhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwocGN0eHQsIHNjaGVtYSwgZG9jRWxlbS0+Y2hpbGRyZW4pOwoJeG1sU2NoZW1hUG9zdFNjaGVtYUFzc2VtYmxlRml4dXAocGN0eHQpOwoJLyoKCSogU2V0IHRoZSBjb3VudGVyIG9mIGl0ZW1zLgoJKi8KCXNjaGVtYS0+Y291bnRlciA9IHBjdHh0LT5jb3VudGVyOwoJLyoKCSogRnJlZSB0aGUgbGlzdCBvZiBhc3NlbWJsZWQgY29tcG9uZW50cy4KCSovCglwY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXMgPSAwOwoJLyoKCSogUmVzdG9yZSB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCglzY2hlbWEtPmZsYWdzID0gb2xkZmxhZ3M7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IG9sZHRuczsKCXNjaGVtYS0+ZG9jID0gb2xkZG9jOwoJcmV0ID0gcGN0eHQtPmVycjsKICAgIH0gICAgICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHI6CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAeHNpQXR0cjogYW4geHNpIGF0dHJpYnV0ZQogKiBAbm9OYW1lc3BhY2U6IHdoZXRoZXIgYSBzY2hlbWEgd2l0aCBubyB0YXJnZXQgbmFtZXNwYWNlIGlzIGV4cHRlY3RlZAogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZQogKiBvZiBhbiBpbnN0YW5jZS4gSWYgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gaXMgdXNlZCwgQG5vTmFtZXNwYWNlCiAqIG11c3QgYmUgc2V0IHRvIDEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJIHhtbEF0dHJQdHIgeHNpQXR0ciwKCQkJIGludCBub05hbWVzcGFjZSkKewogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBjb25zdCB4bWxDaGFyICpuc25hbWUgPSBOVUxMLCAqbG9jYXRpb247CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IHJldCA9IDA7CiAgICAKICAgIGlmICh4c2lBdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCSAgICBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBQYXJzZSB0aGUgdmFsdWU7IHdlIHdpbGwgYXNzdW1lIGFuIGV2ZW4gbnVtYmVyIG9mIHZhbHVlcwogICAgKiB0byBiZSBnaXZlbiAodGhpcyBpcyBob3cgWGVyY2VzIGFuZCBYU1Ygd29yaykuCiAgICAqLwogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgeHNpQXR0cik7ICAgIAogICAgY3VyID0gdmFsdWU7CiAgICBkbyB7CQoJaWYgKG5vTmFtZXNwYWNlICE9IDEpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgY291bnQrKzsKCSAgICBuc25hbWUgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsJCQoJICAgIGN1ciA9IGVuZDsKCX0KCS8qCgkqIEdldCB0aGUgVVJJLgoJKi8KCXdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCSAgICBjdXIrKzsKCWVuZCA9IGN1cjsKCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJICAgIGVuZCsrOwoJaWYgKGVuZCA9PSBjdXIpCgkgICAgYnJlYWs7Cgljb3VudCsrOwoJbG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsKCWN1ciA9IGVuZDsJCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24odmN0eHQsIHZjdHh0LT5zY2hlbWEsIAoJICAgIHhzaUF0dHItPnBhcmVudCwgbnNuYW1lLCBsb2NhdGlvbik7CglpZiAocmV0ID09IC0xKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJKHhtbE5vZGVQdHIpIHhzaUF0dHIsIE5VTEwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0ciwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYXRhIiwgTlVMTCk7CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSh2YWx1ZSk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9IHdoaWxlICgqY3VyICE9IDApOwogICAgaWYgKHZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKHZhbHVlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtOgogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06IGFuIGVsZW1lbnQgbm9kZSBwb3NzaWJseSBob2xkaW5nIHhzaSBhdHRyaWJ1dGVzCiAqIEBub05hbWVzcGFjZTogd2hldGhlciBhIHNjaGVtYSB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UgaXMgZXhwdGVjdGVkCiAqCiAqIEFzc2VtYmxlcyBhbiBleGlzdGluZyBzY2hlbWEgYnkgYW4gYWRkaXRpb25hbCBzY2hlbWEgdXNpbmcKICogdGhlIHhzaTpzY2hlbWFMb2NhdGlvbiBvciB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGVzCiAqIG9mIHRoZSBnaXZlbiBAZWxlbS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAgCgkJCSB4bWxOb2RlUHRyIGVsZW0pCnsgICAgCiAgICBpbnQgcmV0ID0gMCwgcmV0TnMgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIiwgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CglyZXROcyA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHZjdHh0LCBhdHRyLCAwKTsKCWlmIChyZXROcyA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHZjdHh0LCBhdHRyLCAxKTsKCWlmIChyZXQgPT0gLTEpCgkgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAocmV0TnMgIT0gMCkKCXJldHVybiAocmV0TnMpOwogICAgZWxzZQoJcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCBkZXRlY3RlZCAobWlnaHQgYmUgTlVMTCkKICogQHR5cGU6ICB0aGUgdHlwZQogKgogKiBBIHRyYW5zaXRpb24gaGFzIGJlZW4gbWFkZSBpbiB0aGUgYXV0b21hdGEgYXNzb2NpYXRlZCB0byBhbiBlbGVtZW50CiAqIGNvbnRlbnQgbW9kZWwKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2soeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZSA9IGN0eHQtPm5vZGU7CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2s6ICVzLCAlcywgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmFtZSwgdHlwZS0+bmFtZSwgbm9kZS0+bmFtZSk7CiNlbmRpZgogICAgLyoKICAgICogQHR5cGUtPnR5cGUgd2lsbCBiZSBYTUxfU0NIRU1BX1RZUEVfQU5ZIG9yIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULgogICAgKi8KICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgY3R4dC0+bm9kZSA9IG5vZGU7ICAgIAogICAgY3R4dC0+Y3VyID0gbm9kZS0+Y2hpbGRyZW47CiAgICAvKgogICAgKiBBc3NlbWJsZSBuZXcgc2NoZW1hdGEgdXNpbmcgeHNpLgogICAgKi8KICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewoJaW50IHJldDsKCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbShjdHh0LCBjdHh0LT5ub2RlKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYSBieSB4c2kiLCBOVUxMKTsKCSAgICByZXR1cm47Cgl9CgkvKgoJKiBOT1RFOiBXZSB3b24ndCByZWFjdCBvbiBzY2hlbWEgcGFyc2VyIGVycm9ycyBoZXJlLgoJKiBUT0RPOiBCdXQgYSB3YXJuaW5nIHdvdWxkIGJlIG5pY2UuCgkqLwogICAgfSAgICAKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDogewoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGUgYnVpbGQgb2YgdGhlIGNvbnRlbnQgbW9kZWwgCgkgICAgKiAoeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKSBlbnN1cmVzIHRoYXQgdGhlIGVsZW1lbnQgCgkgICAgKiBkZWNsYXJhdGlvbiAoYW5kIG5vdCBhIHJlZmVyZW5jZSB0byBpdCkgd2lsbCBiZSBnaXZlbi4KCSAgICAqLwoJICAgIGlmICgoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGN0eHQtPnR5cGUpLT5yZWYgIT0gTlVMTCkgewoJCS8qCgkJKiBUaGlzIGlzIHBhcmFub2lkIGNvZGluZyA7LSkuLi4gaXQgc2hvdWxkIG5vdAoJCSogaGFwcGVuIGhlcmUgYW55IG1vcmUuCgkJKi8KCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJICAgIG5vZGUsIE5VTEwsCQkJCQkJCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjaywgIgoJCSAgICAiZWxlbWVudCBkZWNsYXJhdGlvbiAncmVmZXJlbmNlJyBlbmNvdW50ZXJlZCwgIgoJCSAgICAiYnV0IGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gd2FzIGV4cGVjdGVkIiwgCgkJICAgIE5VTEwpOwoJCXJldHVybjsKCSAgICB9CgkgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbihjdHh0LCAKCQkoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZSk7CgkgICAgYnJlYWs7Cgl9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJICAgIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQoY3R4dCwgdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoJZGVmYXVsdDogCgkgICAgYnJlYWs7CiAgICB9CiAgICBjdHh0LT50eXBlID0gb2xkdHlwZTsKICAgIGN0eHQtPm5vZGUgPSBvbGRub2RlOwp9ICAKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHZhbHVlOiB0aGUgdmFsdWUgdG8gYmUgdmFsaWRhdGVkCiAqIEBmaXJlRXJyb3JzOiBzaGFsbCBlcnJvcnMgYmUgcmVwb3J0ZWQ/CiAqIEBhcHBseUZhY2V0czogc2hhbGwgZmFjZXRzIGJlIGFwcGxpZWQ/CiAqIEBub3JtYWxpemU6IHNoYWxsIHRoZSB2YWx1ZSBiZSBub3JtYWxpemVkPwogKiBAY2hlY2tOb2Rlczogc2hhbGwgdGhlIGNvbnRlbnQgbm9kZXMgYmUgY2hlY2tlZD8KICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYnkgdGhlIGdpdmVuIHR5cGUgKHVzZXIgZGVyaXZlZCBvciBidWlsdC1pbikuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSBjb25zdCB4bWxDaGFyICp2YWx1ZSwJCQkJIAoJCQkJIGludCBmaXJlRXJyb3JzLAkJCQkgCgkJCQkgaW50IGFwcGx5RmFjZXRzLAoJCQkJIGludCBub3JtYWxpemUsCgkJCQkgaW50IGNoZWNrTm9kZXMpCnsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGludCByZXQgPSAwOyAgCiAgICB4bWxDaGFyICpub3JtVmFsdWUgPSBOVUxMOwogICAgaW50IHd0c3A7ICAgICAgIAogCiAgICBub2RlID0gY3R4dC0+bm9kZTsKICAgIC8qIFNhdmUgdGhlIGN1cnJlbnQgd2hpdGVzcGFjZSBub3JtYWxpemF0aW9uIHR5cGUuICovCiAgICB3dHNwID0gY3R4dC0+dmFsdWVXUzsKICAgIC8qCiAgICAqIE5vcm1hbGl6ZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKG5vcm1hbGl6ZSAmJiAKCShjdHh0LT52YWx1ZVdTICE9IFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKSkgewoJaW50IG5vcm0gPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0eXBlKTsKCQoJaWYgKChub3JtICE9IC0xKSAmJiAobm9ybSA+IGN0eHQtPnZhbHVlV1MpKSB7CgkgICAgaWYgKG5vcm0gPT0gWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpCgkJbm9ybVZhbHVlID0geG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcodmFsdWUpOwoJICAgIGVsc2UKCQlub3JtVmFsdWUgPSB4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSk7CgkgICAgY3R4dC0+dmFsdWVXUyA9IG5vcm07CgkgICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCXZhbHVlID0gKGNvbnN0IHhtbENoYXIgKikgbm9ybVZhbHVlOwoJfQkJCiAgICB9ICAgIAogICAgLyoKICAgICogVGhlIG5vZGVzIG9mIGEgY29udGVudCBtdXN0IGJlIGNoZWNrZWQgb25seSBvbmNlLAogICAgKiB0aGlzIGlzIG5vdCB3b3JraW5nIHNpbmNlIGxpc3QgdHlwZXMgd2lsbCBmaXJlIHRoaXMKICAgICogbXVsdGlwbGUgdGltZXMuCiAgICAqLwogICAgaWYgKChjaGVja05vZGVzID09IDEpICYmIChjdHh0LT5jdXIgIT0gTlVMTCkpIHsKCXhtbE5vZGVQdHIgY3VyID0gY3R4dC0+Y3VyOwoKCWRvIHsKCSAgICBzd2l0Y2ggKGN1ci0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1RFWFRfTk9ERToKCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CgkgICAgY2FzZSBYTUxfUElfTk9ERToKCSAgICBjYXNlIFhNTF9DT01NRU5UX05PREU6CgkgICAgY2FzZSBYTUxfWElOQ0xVREVfU1RBUlQ6CgkgICAgY2FzZSBYTUxfWElOQ0xVREVfRU5EOgoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX0VOVElUWV9SRUZfTk9ERToKCSAgICBjYXNlIFhNTF9FTlRJVFlfTk9ERToKCQkvKiBUT0RPOiBTY291ciB0aGUgZW50aXRpZXMgZm9yIGlsbGVnYWwgbm9kZXMuICovCgkJVE9ETyBicmVhazsKCSAgICBjYXNlIFhNTF9FTEVNRU5UX05PREU6IHsKCSAgICAvKiBOT1RFOiBDaGFuZ2VkIHRvIGFuIGludGVybmFsIGVycm9yLCBzaW5jZSB0aGUgCgkgICAgKiBleGlzdGVuY2Ugb2YgYW4gZWxlbWVudCBub2RlIHdpbGwgYmUgYWxyZWFkeSBjaGVja2VkIGluCgkgICAgKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUgYW5kIGluCgkgICAgKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeUNvbXBsZXhUeXBlLgoJCSovCgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgIC8qIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElERUxFTSwgKi8KCQkgICAgbm9kZSwgdHlwZSwKCQkgICAgIkVsZW1lbnQgJyVzJyBmb3VuZCBpbiBzaW1wbGUgdHlwZSBjb250ZW50IiwgCgkJICAgIGN1ci0+bmFtZSk7CgkJcmV0dXJuIChYTUxfU0NIRU1BVl9JTlRFUk5BTCk7CgkJCQkgICB9CgkgICAgY2FzZSBYTUxfQVRUUklCVVRFX05PREU6CgkgICAgY2FzZSBYTUxfRE9DVU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9UWVBFX05PREU6CgkgICAgY2FzZSBYTUxfRE9DVU1FTlRfRlJBR19OT0RFOgoJICAgIGNhc2UgWE1MX05PVEFUSU9OX05PREU6CgkgICAgY2FzZSBYTUxfSFRNTF9ET0NVTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX0RURF9OT0RFOgoJICAgIGNhc2UgWE1MX0VMRU1FTlRfREVDTDoKCSAgICBjYXNlIFhNTF9BVFRSSUJVVEVfREVDTDoKCSAgICBjYXNlIFhNTF9FTlRJVFlfREVDTDoKCSAgICBjYXNlIFhNTF9OQU1FU1BBQ0VfREVDTDoKI2lmZGVmIExJQlhNTF9ET0NCX0VOQUJMRUQKCSAgICBjYXNlIFhNTF9ET0NCX0RPQ1VNRU5UX05PREU6IAojZW5kaWYJCSAgICAJCSAgICAJCSAgICAKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgLyogWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLCAqLwoJCSAgICBub2RlLCBOVUxMLAoJCSAgICAiTm9kZSBvZiB1bmV4cGVjdGVkIHR5cGUgZm91bmQgaW4gc2ltcGxlIHR5cGUgY29udGVudCIsCgkJICAgIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVZfSU5URVJOQUwpOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9IHdoaWxlIChjdXIgIT0gTlVMTCk7CiAgICB9CgogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCXhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgYW55VHlwZTsKCglhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CgoJYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwoJd2hpbGUgKChiYXNlICE9IE5VTEwpICYmIAoJICAgIChiYXNlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpICYmCgkgICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJICAgIChiYXNlICE9IGFueVR5cGUpKSB7CgkgICAgYmFzZSA9IGJhc2UtPmJhc2VUeXBlOwoJfQoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgYmFzZSwgdmFsdWUsIDEsIDAsIDEsIDApOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBjb21wbGV4IHR5cGUgJyVzJ1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAoKHJldCA9PSAwKSAmJiAoYXBwbHlGYWNldHMpICYmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSkgewoJICAgIC8qIAoJICAgICogQ2hlY2sgZmFjZXRzLgoJICAgICovCSAgICAKCSAgICAvKgoJICAgICogVGhpcyBpcyBzb21laG93IG5vdCBuaWNlLCBzaW5jZSBpZiBhbiBlcnJvciBvY2N1cnMKCSAgICAqIHRoZSByZXBvcnRlZCB0eXBlIHdpbGwgYmUgdGhlIGNvbXBsZXggdHlwZTsgdGhlIHNwZWMKCSAgICAqIHdhbnRzIGEgc2ltcGxlIHR5cGUgdG8gYmUgY3JlYXRlZCBvbiB0aGUgY29tcGxleCB0eXBlCgkgICAgKiBpZiBpdCBoYXMgYSBzaW1wbGUgY29udGVudC4gRm9yIG5vdyB3ZSBoYXZlIHRvIGxpdmUgd2l0aAoJICAgICogaXQuCgkgICAgKi8KCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCAwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIGNvbXBsZXggdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkJaWYgKGZpcmVFcnJvcnMpIAoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCSAgICB9CQoJfQkKICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCglpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CgkgICAgY3R4dC0+dmFsdWUgPSBOVUxMOwoJfQoJLyoKCSogU1RSRUFNLVJFQUQtQ0hJTERSRU4uCgkqLwkgICAgCQkKCXJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKHR5cGUsIHZhbHVlLCAmKGN0eHQtPnZhbHVlKSwgbm9kZSk7CglpZiAocmV0ID4gMCkgewkgICAgCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIAoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCSAgICBlbHNlCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwkgICAgCgkgICAgaWYgKGZpcmVFcnJvcnMpCgkJeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7Cgl9IGVsc2UgaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBidWlsdC1pbiB0eXBlICclcydcbiIsIHR5cGUtPm5hbWUsIE5VTEwpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpIHsgICAgICAgIAoJLyogMS4yLjEgaWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgCgkqIGEgbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gCgkqLwkKCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUtPmJhc2VUeXBlLCB2YWx1ZSwgMCwgMCwgMCwgMCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGF0b21pYyBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmIChyZXQgPiAwKSB7CSAgICAKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkgICAgaWYgKGZpcmVFcnJvcnMpCgkJeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CQoJfSBlbHNlIGlmICgoYXBwbHlGYWNldHMpICYmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSkgewoJICAgIC8qIAoJICAgICogQ2hlY2sgZmFjZXRzLgoJICAgICovCSAgICAJICAgIAkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBhdG9taWMgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJCS8qCgkJIERpc2FibGVkLCBzaW5jZSB0aGUgZmFjZXQgdmFsaWRhdGlvbiBhbHJlYWR5IHJlcG9ydHMgZXJyb3JzLgoJCWlmIChmaXJlRXJyb3JzKSAKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBjdHh0LT5jdXIsIHZhbHVlLCB0eXBlKTsKCQkqLwoJICAgIH0JCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKICAgICAgICAKCXhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcDsKCXVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCgkvKiAxLjIuMiBpZiB7dmFyaWV0eX0gaXMgt2xpc3S3IHRoZW4gdGhlIHN0cmluZyBtdXN0IGJlIGEgc2VxdWVuY2UgCgkqIG9mIHdoaXRlIHNwYWNlIHNlcGFyYXRlZCB0b2tlbnMsIGVhY2ggb2Ygd2hpY2ggt21hdGNot2VzIGEgbGl0ZXJhbCAKCSogaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7aXRlbSB0eXBlIGRlZmluaXRpb259IAoJKi8KCQoJdG1wVHlwZSA9IHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZSk7CQoJY3VyID0gdmFsdWU7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBsZW4rKzsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0bXBUeXBlLCB0bXAsIDAsIDEsIDAsIDApOwoJICAgIHhtbEZyZWUodG1wKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgYW4gaXRlbSBvZiBsaXN0IHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwkKCQlicmVhazsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJaWYgKGZpcmVFcnJvcnMpCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJCWJyZWFrOwoJICAgIH0JCgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsKCS8qIAoJKiBDaGVjayBmYWNldHMuCgkqLwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBsaXN0IHNpbXBsZSB0eXBlICclcydcbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7Cgl9IGVsc2UgaWYgKChyZXQgPT0gMCkgJiYgKGFwcGx5RmFjZXRzKSkgewoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIGxlbiwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBsaXN0IHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQkvKgoJCSBEaXNhYmxlZCwgc2luY2UgdGhlIGZhY2V0IHZhbGlkYXRpb24gYWxyZWFkeSByZXBvcnRzIGVycm9ycy4KCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkJKi8KCSAgICB9CSAJICAgCgkgICAKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlckxpbms7CgoJLyoKCSogVE9ETzogRm9yIGFsbCBkYXRhdHlwZXMgt2Rlcml2ZWS3IGJ5ILd1bmlvbrcgIHdoaXRlU3BhY2UgZG9lcyAKCSogbm90IGFwcGx5IGRpcmVjdGx5OyBob3dldmVyLCB0aGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IAoJKiB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZSAKCSogt21lbWJlclR5cGVztyBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuIAoJKgoJKiBUaGlzIG1lYW5zIHRoYXQgdGhlIHZhbHVlIGlzIG5vcm1hbGl6ZWQgYnkgdGhlIGZpcnN0IHZhbGlkYXRpbmcKCSogbWVtYmVyIHR5cGUsIHRoZW4gdGhlIGZhY2V0cyBvZiB0aGUgdW5pb24gdHlwZSBhcmUgYXBwbGllZC4gVGhpcwoJKiBuZWVkcyBjaGFuZ2luZyBvZiB0aGUgdmFsdWUhCgkqLwkKCQoJLyoKCSogMS4yLjMgaWYge3ZhcmlldHl9IGlzILd1bmlvbrcgdGhlbiB0aGUgc3RyaW5nIG11c3Qgt21hdGNotyBhIAoJKiBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2YgYXQgbGVhc3Qgb25lIG1lbWJlciBvZiAKCSoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSAKCSovCiNpZmRlZiBERUJVR19VTklPTl9WQUxJREFUSU9OCglwcmludGYoIlVuaW9uIFNUICAgICA6ICclcydcbiIsIChjb25zdCBjaGFyICopIHR5cGUtPm5hbWUpOwoJcHJpbnRmKCIgIGZpcmVFcnJvcnMgOiAlZFxuIiwgZmlyZUVycm9ycyk7CglwcmludGYoIiAgYXBwbHlGYWNldHM6ICVkXG4iLCBhcHBseUZhY2V0cyk7CiNlbmRpZgoJbWVtYmVyTGluayA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHR5cGUpOwoJaWYgKG1lbWJlckxpbmsgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ1bmlvbiBzaW1wbGUgdHlwZSAnJXMnIGhhcyBubyBtZW1iZXIgdHlwZXNcbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0ID0gLTE7Cgl9IAoJaWYgKHJldCA9PSAwKSB7CgkgICAgd2hpbGUgKG1lbWJlckxpbmsgIT0gTlVMTCkgewoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIG1lbWJlckxpbmstPnR5cGUsIAoJCSAgICB2YWx1ZSwgMCwgMSwgMSwgMCk7CgkJaWYgKChyZXQgPD0gMCkgfHwgKHJldCA9PSAwKSkKCQkgICAgYnJlYWs7CSAgICAKCQltZW1iZXJMaW5rID0gbWVtYmVyTGluay0+bmV4dDsKCSAgICB9ICAgICAKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgbWVtYmVycyBvZiB1bmlvbiBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzM7CgkJaWYgKGZpcmVFcnJvcnMpCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJICAgIH0KCX0KCS8qCgkqIEFwcGx5IGZhY2V0cyAocGF0dGVybiwgZW51bWVyYXRpb24pLgkKCSovCglpZiAoKHJldCA9PSAwKSAmJiAoYXBwbHlGYWNldHMpICYmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSkgewoJICAgIGludCBtd3M7CgkgICAgLyoKCSAgICAqIFRoZSBub3JtYWxpemF0aW9uIGJlaGF2aW9yIG9mILd1bmlvbrcgdHlwZXMgaXMgY29udHJvbGxlZCBieSAKCSAgICAqIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZSC3bWVtYmVyVHlwZXO3IAoJICAgICogYWdhaW5zdCB3aGljaCB0aGUgt3VuaW9utyBpcyBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkLiAKCSAgICAqLwkJICAgIAoJICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInRoZSB2YWx1ZSB3YXMgYWxyZWFkeSBub3JtYWxpemVkIGZvciB0aGUgdW5pb24gc2ltcGxlICIKCQkgICAgInR5cGUgJyVzJy5cbiIsIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0KCSAgICBtd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZShtZW1iZXJMaW5rLT50eXBlKTsKCSAgICBpZiAobXdzID4gY3R4dC0+dmFsdWVXUykgewoJCWlmIChtd3MgPT0gWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpCgkJICAgIG5vcm1WYWx1ZSA9IHhtbFNjaGVtYUNvbGxhcHNlU3RyaW5nKHZhbHVlKTsKCQllbHNlCgkJICAgIG5vcm1WYWx1ZSA9IHhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKHZhbHVlKTsKCQlpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJICAgIHZhbHVlID0gKGNvbnN0IHhtbENoYXIgKikgbm9ybVZhbHVlOwoJICAgIH0KCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiB1bmlvbiBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzM7CgkJLyoKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBjdHh0LT5jdXIsIHZhbHVlLCB0eXBlKTsKCQkqLwoJICAgIH0JCgl9CiAgICB9ICAgICAgICAgICAKICAgIGN0eHQtPnZhbHVlV1MgPSB3dHNwOwogICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJeG1sRnJlZShub3JtVmFsdWUpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgZWxlbWVudCBub2RlIHRvIGJlIHZhbGlkYXRlZC4KICoKICogVmFsaWRhdGUgdGhlIGVsZW1lbnQgYWdhaW5zdCBhIHNpbXBsZSB0eXBlLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sTm9kZVB0ciBjdXI7CiAgICBpbnQgcmV0ID0gMCwgcmV0dmFsID0gMDsKICAgICAgICAKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIE5VTEwsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOyAgICAKICAgIH0KCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogCiAgICAqIGN2Yy10eXBlOiAzLjEuMiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBDaGlsZCBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIGN1ciA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkvKgoJKiBUT0RPOiBFbnRpdGllcywgd2lsbCB0aGV5IHByb2R1Y2UgZWxlbWVudHMgYXMgd2VsbD8KCSovCglpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzIsCgkJbm9kZSwgdHlwZSwJCQoJCSJObyBlbGVtZW50IGNvbnRlbnQgYWxsb3dlZCIsIE5VTEwpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8yOwoJfQoJY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgCiAgICAvKgogICAgKiBjdmMtdHlwZSAzLjEuMToKICAgICoKICAgICogVGhlIGF0dHJpYnV0ZXMgb2YgbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nIHRob3NlIHdob3NlIG5hbWVzcGFjZSBuYW1lIAogICAgKiBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kIHdob3NlIGxvY2FsIAogICAgKiBuYW1lIGlzIG9uZSBvZiB0eXBlLCBuaWwsIHNjaGVtYUxvY2F0aW9uIG9yIG5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBBdHRyaWJ1dGUgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB8fAogICAgICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmlsIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbAogICAgICAgICAgICAgIChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIpKSkpIHsKCSAgICB4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGF0dHIpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8xOwogICAgICAgIH0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogVGhpcyB3aWxsIHNraXAgdmFsaWRhdGlvbiBpZiB0aGUgdHlwZSBpcyAnYW55U2ltcGxlVHlwZScgYW5kCiAgICAqIGlmIHRoZSB2YWx1ZSB3YXMgYWxyZWFkeSB2YWxpZGF0ZWQgKGUuZy4gZGVmYXVsdCB2YWx1ZXMpLgogICAgKi8KICAgIGlmICgodmFsU2ltcGxlQ29udGVudCA9PSAxKSAmJgoJKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgfHwKCSAodHlwZS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpKSB7Cgl4bWxDaGFyICp2YWx1ZTsJCgoJdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKCS8qCgkqIE5PVEU6IFRoaXMgY2FsbCB3aWxsIG5vdCBjaGVjayB0aGUgY29udGVudCBub2Rlcywgc2luY2UKCSogdGhpcyBzaG91bGQgYmUgY2hlY2tlZCBoZXJlIGFscmVhZHkuCgkqLwoJcmV0dmFsID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUsIAoJICAgIDEsIDEsIDEsIDApOwoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgeG1sRnJlZSh2YWx1ZSk7CglpZiAocmV0dmFsICE9IDApCgkgICAgcmV0ID0gcmV0dmFsOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmU6CiAqIEB2YWx1ZTogdGhlIGxleGljYWwgcmVwcmVzYW50YXRpb24gb2YgdGhlIFFOYW1lIHZhbHVlCiAqIEBub2RlOiB0aGUgbm9kZSB0byBzZWFyY2ggZm9yIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgogKiBAbnNOYW1lOiB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBuYW1lIGlmIGZvdW5kCiAqCiAqIENoZWNrcyB0aGF0IGEgdmFsdWUgY29uZm9ybXMgdG8gdGhlIGxleGljYWwgc3BhY2Ugb2YgdGhlIHR5cGUgUU5hbWU7CiAqIGlmIHZhbGlkLCB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgbmFtZSBpcyBzZWFyY2hlZCBhbmQgcmV0dXJlZCAKICogYXMgYSBjb3B5IGluIEBuc05hbWUuIFRoZSBsb2NhbCBuYW1lIGlzIHJldHVybmVkIGluIEBsb2NhbE5hbWUgYXMKICogYSBjb3B5LgogKgogKiBSZXR1cm5zIDAgaWYgdmFsaWQsIDEgaWYgbm90IHZhbGlkIGJ5IHR5cGUsIDIgaWYgbm8gY29ycmVzcG9uZGluZyAKICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHdhcyBmb3VuZCBpbiBzY29wZTsgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciAKICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmUoY29uc3QgeG1sQ2hhciAqdmFsdWUsIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sQ2hhciAqKm5zTmFtZSwgeG1sQ2hhciAqKmxvY2FsTmFtZSkKewogICAgaW50IHJldDsKICAgIHhtbENoYXIgKmxvY2FsID0gTlVMTDsKCiAgICBpZiAoKG5zTmFtZSA9PSBOVUxMKSB8fCAobG9jYWxOYW1lID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQoJcmV0dXJuICgtMSk7ICAKICAgICpuc05hbWUgPSBOVUxMOyAgIAogICAgKmxvY2FsTmFtZSA9IE5VTEw7CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gMCkgewoJeG1sQ2hhciAqcHJlZml4OwoJeG1sTnNQdHIgbnM7CgkKCS8qCgkqIE5PVEU6IHhtbFNwbGl0UU5hbWUyIHdpbGwgcmV0dXJuIGEgZHVwbGljYXRlZAoJKiBzdHJpbmcuCgkqLwoJbG9jYWwgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CglpZiAobG9jYWwgPT0gTlVMTCkKCSAgICBsb2NhbCA9IHhtbFN0cmR1cCh2YWx1ZSk7CglucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKCS8qCiAgICAgICAgKiBBIG5hbWVzcGFjZSBuZWVkIG5vdCB0byBiZSBmb3VuZCBpZiB0aGUgcHJlZml4IGlzIE5VTEwuCgkqLwoJaWYgKG5zICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogSXMgaXQgbmVjZXNzYXJ5IHRvIGR1cGxpY2F0ZSB0aGUgVVJJIGhlcmU/CgkgICAgKi8KCSAgICAqbnNOYW1lID0geG1sU3RyZHVwKG5zLT5ocmVmKTsKCX0gZWxzZSBpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxGcmVlKHByZWZpeCk7IAoJICAgIGlmIChsb2NhbCAhPSBOVUxMKQoJCXhtbEZyZWUobG9jYWwpOwoJICAgIHJldHVybiAoMik7Cgl9CQkKCSpsb2NhbE5hbWUgPSBsb2NhbDsKCWlmIChwcmVmaXggIT0gTlVMTCkKCSAgICB4bWxGcmVlKHByZWZpeCk7ICAgIAogICAgfSBlbHNlCglyZXR1cm4gKDEpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hSGFzRWxlbUNvbnRlbnQ6IAogKiBAbm9kZTogIHRoZSBub2RlCiAqCiAqIFNjb3VycyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gbm9kZSBmb3IgZWxlbWVudAogKiBub2Rlcy4KICoKICogUmV0dXJucyAxIGlmIGFuIGVsZW1lbnQgbm9kZSBpcyBmb3VuZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUhhc0VsZW1Db250ZW50KHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKG5vZGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIHJldHVybiAoMSk7Cglub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KLyoqCiAqIHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50OiAKICogQG5vZGU6ICB0aGUgbm9kZQogKgogKiBTY291cnMgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIG5vZGUgZm9yIGVsZW1lbnQKICogYW5kIGNoYXJhY3RlciBub2Rlcy4KICoKICogUmV0dXJucyAxIGlmIGFuIGVsZW1lbnQgb3IgY2hhcmFjdGVyIG5vZGUgaXMgZm91bmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFIYXNFbGVtT3JDaGFyQ29udGVudCh4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChub2RlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgbm9kZSA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKG5vZGUgIT0gTlVMTCkgewoJc3dpdGNoIChub2RlLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgkKCSAgICAvKiAKCSAgICAqIFRPRE86IEFzayBEYW5pZWwgaWYgdGhlc2UgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkgICAgKi8KCSAgICBjYXNlIFhNTF9URVhUX05PREU6CgkgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgoJICAgIC8qCgkgICAgKiBUT0RPOiBIb3cgWE1MX0VOVElUWV9OT0RFcyBldmFsdWF0ZWQ/CgkgICAgKi8KCSAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CgkgICAgY2FzZSBYTUxfRU5USVRZX05PREU6CgkJcmV0dXJuICgxKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQoJbm9kZSA9IG5vZGUtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IHR5cGUuCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbE5vZGVQdHIgZWxlbTsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hVHlwZVB0ciBhY3R1YWxUeXBlID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIHhtbENoYXIgKmF0dHJWYWx1ZTsgCiAgICBpbnQgbmlsbGVkID0gMCwgZWxlbUhhc0NvbnRlbnQgPSAtMTsKCiAgICAvKiAKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbCwgCiAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZSBhbmQgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LgogICAgKiBOb3RlIHRoYXQgQGVsZW1EZWNsIHdpbGwgYmUgdGhlIGRlY2xhcmF0aW9uIGFuZCBuZXZlciB0aGUKICAgICogcmVmZXJlbmNlIHRvIGEgZGVjbGFyYXRpb24uCiAgICAqLwoKICAgIGlmIChjdHh0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJICAgICJiYWQgYXJndW1lbnRzLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICBlbGVtID0gY3R4dC0+bm9kZTsgICAKCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAxCiAgICAqLwogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzEsIAoJICAgIGVsZW0sIE5VTEwsCgkgICAgIk5vIG1hdGNoaW5nIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDIKICAgICovCiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMiwKCSAgICBlbGVtLCBOVUxMLCAKCSAgICAiVGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gaXMgYWJzdHJhY3QiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAgCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAzCiAgICAqIEhhbmRsZSAneHNpOm5pbCcuCiAgICAqLwogICAgCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJuaWwiLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCWF0dHJWYWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KCh4bWxOb2RlUHRyKSBhdHRyKTsJCgljdHh0LT5ub2RlID0gKHhtbE5vZGVQdHIpIGF0dHI7CgljdHh0LT5jdXIgPSBhdHRyLT5jaGlsZHJlbjsJCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwKCSAgICBCQURfQ0FTVCBhdHRyVmFsdWUsIDEsIDEsIDEsIDEpOwoJY3R4dC0+bm9kZSA9IGVsZW07CgljdHh0LT50eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJInZhbGlkYXRpbmcgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciLCBOVUxMKTsKCSAgICBpZiAoYXR0clZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZShhdHRyVmFsdWUpOwoJICAgIHJldHVybiAoLTEpOwoJfSAKCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgPT0gMCkgewoJLyogCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMSAKCSAgICAqLwoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzEsIAoJCWVsZW0sIE5VTEwsCgkJIlRoZSBlbGVtZW50IGlzIG5vdCAnbmlsbGFibGUnIiwgTlVMTCk7CQoJfSBlbHNlIHsJCSAgICAKCSAgICBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgYXR0clZhbHVlLCBCQURfQ0FTVCAidHJ1ZSIpIHx8CgkJeG1sU3RyRXF1YWwoQkFEX0NBU1QgYXR0clZhbHVlLCBCQURfQ0FTVCAiMSIpKSB7CQkKCQlyZXQgPSAwOwoJCS8qIAoJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjEgCgkJKi8KCQllbGVtSGFzQ29udGVudCA9IHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pOwoJCWlmIChlbGVtSGFzQ29udGVudCA9PSAxKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzEsIAoJCQkvKiBYTUxfU0NIRU1BU19FUlJfTk9URU1QVFksICovCgkJCWVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJIlRoZSAnbmlsbGVkJyBlbGVtZW50IG11c3QgaGF2ZSBubyBjaGFyYWN0ZXIgb3IgIgoJCQkiZWxlbWVudCBjb250ZW50IiwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzE7CgkJfQoJCS8qIAoJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjIgCgkJKi8KCQlpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCgkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCAKCQkJLyogWE1MX1NDSEVNQVNfRVJSX0hBVkVERUZBVUxULCAqLwoJCQllbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSJUaGVyZSBpcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQgZGVmaW5lZCBmb3IgIgoJCQkidGhlICduaWxsZWQnIGVsZW1lbnQiLCBOVUxMKTsJCSAgICAKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMjsKCQl9CgkJaWYgKHJldCA9PSAwKQoJCSAgICBuaWxsZWQgPSAxOwkJCgkgICAgfQoJfQoJaWYgKGF0dHJWYWx1ZSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoYXR0clZhbHVlKTsKICAgIH0KICAgIAoKICAgIGFjdHVhbFR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXM7CiAgICAvKiAKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNCAKICAgICogSGFuZGxlICd4c2k6dHlwZScuCiAgICAqLwogICAgCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJ0eXBlIiwgIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewkKCXhtbENoYXIgKm5zTmFtZSA9IE5VTEwsICpsb2NhbCA9IE5VTEw7CgkKCS8qCgkqIFRPRE86IFdlIHNob3VsZCByZXBvcnQgYSAqd2FybmluZyogdGhhdCB0aGUgdHlwZSB3YXMgb3ZlcnJpZGVuCgkqIGJ5IHRoZSBpbnN0YW5jZS4KCSovCgkKCS8qIAoJKiBjdmMtZWx0ICgzLjMuNCkgOiA0LjEgCgkqLwoJYXR0clZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoKHhtbE5vZGVQdHIpIGF0dHIpOwoJcmV0ID0geG1sU2NoZW1hVmFsUU5hbWVBY3F1aXJlKGF0dHJWYWx1ZSwgYXR0ci0+cGFyZW50LAkKCSAgICAmbnNOYW1lLCAmbG9jYWwpOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJInZhbGlkYXRpbmcgdGhlIGF0dHJpYnV0ZSAneHNpOnR5cGUnIiwgTlVMTCk7OwoJICAgIEZSRUVfQU5EX05VTEwoYXR0clZhbHVlKQoJCUZSRUVfQU5EX05VTEwobnNOYW1lKQoJCUZSRUVfQU5EX05VTEwobG9jYWwpCgkJcmV0dXJuICgtMSk7Cgl9IGVsc2UgaWYgKHJldCA9PSAxKSB7CgkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJKHhtbE5vZGVQdHIpIGF0dHIsIGF0dHJWYWx1ZSwgCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpKTsKCX0gZWxzZSBpZiAocmV0ID09IDIpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyAiCgkJImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHNjb3BlIiwgCgkJYXR0clZhbHVlKTsJICAgIAkgICAgCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA0LjIgCgkgICAgKi8KCSAgICBhY3R1YWxUeXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGxvY2FsLCBuc05hbWUpOwoJICAgIGlmIChhY3R1YWxUeXBlID09IE5VTEwpIHsJICAKCQl4bWxDaGFyICpzdHJBID0gTlVMTDsKCQkKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8yLAoJCSAgICAoeG1sTm9kZVB0cikgYXR0ciwgCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkgICAgIlRoZSB2YWx1ZSAlcyBkb2VzIG5vdCByZXNvbHZlIHRvIGEgdHlwZSAiCgkJICAgICJkZWZpbml0aW9uIiwgCgkJICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIG5zTmFtZSwgbG9jYWwpKTsKCQlGUkVFX0FORF9OVUxMKHN0ckEpOyAgICAKCSAgICB9IGVsc2UgewkJCgkJLyoKCQkqIFVSR0VOVCBUT0RPOiBjdmMtZWx0ICgzLjMuNCkgOiA0LjMgKFR5cGUgRGVyaXZhdGlvbiBPSykKCQkqLwkJCgkgICAgfQoJfQoJRlJFRV9BTkRfTlVMTChhdHRyVmFsdWUpCglGUkVFX0FORF9OVUxMKG5zTmFtZSkKCUZSRUVfQU5EX05VTEwobG9jYWwpCiAgICB9CQkKICAgIC8qIFRPRE86IENoYW5nZSB0aGUgaGFuZGxpbmcgb2YgbWlzc2luZyB0eXBlcyBhY2NvcmRpbmcgdG8KICAgICogdGhlIHNwZWMuCiAgICAqLwogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKICAgIAkgICAgWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSwKICAgIAkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8xKTsKICAgIH0KICAgIAogICAgLyoKICAgICogVE9ETzogU2luY2UgdGhpcyBzaG91bGQgYmUgYWxyZWFkeSBjaGVja2VkIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbiwKICAgICogYW5kIHdlIHdhbnQgdG8gZ2V0IHJpZCBvZiB0aGUgWE1MX1NDSEVNQVNfRVJSLi4uIHR5cGVzLCB0aGUgZXJyb3IgY29kZQogICAgKiBoYXMgYmVlbiBjaGFuZ2VkIHRvIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLgogICAgKi8KICAgIC8qCiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewogICAgICAgIGlmIChkZWNsLT5taW5PY2N1cnMgPiAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLCAKCQkiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlc1xuIiwKCQlub2RlLT5uYW1lLCBkZWNsLT5uYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAKICAgICovCiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IG1hdGNoZXMKICAgICAqIFRPRE8sIEZJWE1FOiBDYW4gdGhpcyBzdGlsbCBoYXBwZW4gaGVyZT8gSXNuJ3QgdGhpcyBhbHJlYWR5IGNoZWNrZWQKICAgICAqIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbj8gICAgICAgICAKICAgIGlmICgheG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIGRlY2wtPm5hbWUpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycjMoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIFhNTF9TQ0hFTUFTX0VSUl9XUk9OR0VMRU0sIAoJICAgICJFbGVtZW50ICVzOiBtaXNzaW5nIGNoaWxkICVzIGZvdW5kICVzXG4iLAoJICAgIG5vZGUtPm5hbWUsIGRlY2wtPm5hbWUsIGNoaWxkLT5uYW1lKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAqLyAgICAKICAgIGlmIChlbGVtSGFzQ29udGVudCA9PSAtMSkKCWVsZW1IYXNDb250ZW50ID0geG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSk7CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1IAogICAgKiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEgCiAgICAqIElmIHRoZSBkZWNsYXJhdGlvbiBoYXMgYSB7dmFsdWUgY29uc3RyYWludH0sIAogICAgKiB0aGUgaXRlbSBoYXMgbmVpdGhlciBlbGVtZW50IG5vciBjaGFyYWN0ZXIgW2NoaWxkcmVuXSBhbmQgCiAgICAqIGNsYXVzZSAzLjIgaGFzIG5vdCBhcHBsaWVkLCB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBpZiAoKGVsZW1IYXNDb250ZW50ID09IDApICYmIChuaWxsZWQgPT0gMCkgJiYgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjEgCgkqIElmIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgaXMgYSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utwoJKiB0aGVuIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9CgkqIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBkZWZhdWx0IGZvciB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIAoJKiBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4gCgkqLwoJLyogCgkqIE5PVEU6ICdsb2NhbCcgYWJvdmUgbWVhbnMgdHlwZXMgYXF1aXJlZCBieSB4c2k6dHlwZS4KCSovCglyZXQgPSAwOwoJaWYgKGFjdHVhbFR5cGUgIT0gZWxlbURlY2wtPnN1YnR5cGVzKSB7CgkgICAgeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KGN0eHQpOwoJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KGN0eHQtPnBjdHh0LCBjdHh0LCBhY3R1YWxUeXBlLCAKCQllbGVtRGVjbC0+dmFsdWUsIE5VTEwpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSAgICBlbGVtLCBhY3R1YWxUeXBlLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkgICAgInZhbGlkYXRpbmcgYSBkZWZhdWx0IHZhbHVlIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjIgCgkqIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gd2l0aCB0aGUgY2Fub25pY2FsIGxleGljYWwgCgkqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgdXNlZCBhcyBpdHMgCgkqILdub3JtYWxpemVkIHZhbHVltyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSAKCSogt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKQoJKiAopzMuMy40KS4KCSovCgkvKgogICAgICAgICogRGlzYWJsZSB2YWxpZGF0aW9uIG9mIHRoZSBzaW1wbGUgY29udGVudCwgc2luY2UgaXQgd2FzIGFscmVhZHkKCSogZG9uZSBhYm92ZS4KCSovCglpZiAocmV0ID09IDApIHsKCSAgICBpZiAoYWN0dWFsVHlwZSAhPSBlbGVtRGVjbC0+c3VidHlwZXMpCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKGN0eHQsIGFjdHVhbFR5cGUsIDApOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgMCk7CgkgICAgY3R4dC0+bm9kZSA9IGVsZW07CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJICAgIGVsZW0sIGFjdHVhbFR5cGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSAgICAidmFsaWRhdGluZyBhZ2FpbnN0IHRoZSB0eXBlIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBQU1ZJOiBDcmVhdGUgYSB0ZXh0IG5vZGUgb24gdGhlIGluc3RhbmNlIGVsZW1lbnQuCgkgICAgKi8KCSAgICBpZiAoY3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSB7CgkJeG1sTm9kZVB0ciB0ZXh0Q2hpbGQ7CgkJCgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChlbGVtRGVjbC0+dmFsdWUpOwoJCWlmICh0ZXh0Q2hpbGQgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJCWVsZW0sIGFjdHVhbFR5cGUsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCQkiY291bGQgbm90IGNyZWF0ZSBhIGRlZmF1bHQgdGV4dCBub2RlIGZvciB0aGUgaW5zdGFuY2UiLCAKCQkJTlVMTCk7CgkJfSBlbHNlCgkJICAgIHhtbEFkZENoaWxkKGVsZW0sIHRleHRDaGlsZCk7CSAgICAKCSAgICB9Cgl9CgogICAgfSBlbHNlIHsJCgkvKgoJKiA1LjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCgkqIHRvIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgCgkqIFZhbGlkIChUeXBlKSAopzMuMy40KS4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgMSk7CgljdHh0LT5ub2RlID0gZWxlbTsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJZWxlbSwgYWN0dWFsVHlwZSwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyBhIGRlZmF1bHQgdmFsdWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIDUuMi4yIElmIHRoZXJlIGlzIGEgZml4ZWQge3ZhbHVlIGNvbnN0cmFpbnR9IGFuZCBjbGF1c2UgMy4yIGhhcyAKCSogbm90IGFwcGxpZWQsIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSovCgoJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSAmJiAobmlsbGVkID09IDApKSB7CgkgICAgLyoKCSAgICAqIDUuMi4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqCgkgICAgKiBUT0RPIFJFRFVOREFOVDogSWYgdGhlIGFjdHVhbCB0eXBlIGV4aXN0cywgdGhlIGFib3ZlIGNhbGwgIHRvIAoJICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlIHdpbGwgYWxyZWFkeSBjaGVjayBmb3IgZWxlbWVudCAKCSAgICAqIG5vZGVzLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUhhc0VsZW1Db250ZW50KGVsZW0pKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8xLCAKCQkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCSAgICAiRWxlbWVudHMgaW4gdGhlIGNvbnRlbnQgYXJlIG5vdCBhbGxvd2VkIGlmIGl0IGlzICIKCQkgICAgImNvbnN0cmFpbmVkIGJ5IGEgZml4ZWQgdmFsdWUiLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiA1LjIuMi4yIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCAKCQkqIGJlIHRydWU6CgkJKi8KCQkKCQlpZiAoYWN0dWFsVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkJICAgIHhtbENoYXIgKnZhbHVlOwoJCSAgICAvKgoJCSAgICAqIDUuMi4yLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlILdhY3R1YWwgdHlwZSAKCQkgICAgKiBkZWZpbml0aW9utyBpcyBtaXhlZCwgdGhlbiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIHRoZSAKCQkgICAgKiBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIAoJCSAgICAqIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCgkJICAgICoKCQkgICAgKiAuLi4gdGhlICppbml0aWFsIHZhbHVlKiBvZiBhbiBlbGVtZW50IGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gaXMgdGhlIHN0cmluZyBjb21wb3NlZCBvZiwgaW4gb3JkZXIsIHRoZSAKCQkgICAgKiBbY2hhcmFjdGVyIGNvZGVdIG9mIGVhY2ggY2hhcmFjdGVyIGluZm9ybWF0aW9uIGl0ZW0gaW4gCgkJICAgICogdGhlIFtjaGlsZHJlbl0gb2YgdGhhdCBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0uCgkJICAgICovCgkJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoZWxlbS0+ZG9jLCBlbGVtLT5jaGlsZHJlbiwgMSk7CgkJICAgIGlmICghIHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBlbGVtRGVjbC0+dmFsdWUpKSB7CgkJCS8qIAoJCQkqIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJCSogVE9ETzogSW1wbGVtZW50IHRoZSBjb25vbmljYWwgc3R1ZmYuCgkJCSovCgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMSwgCgkJCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSAgICAiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBjb25vbmljYWwgIgoJCQkgICAgImxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpeGVkIGNvbnN0cmFpbnQiLCAKCQkJICAgIE5VTEwpOwoJCSAgICB9CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsKCQl9IGVsc2UgaWYgKChhY3R1YWxUeXBlLT5jb250ZW50VHlwZSA9PSAKCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwgCgkJICAgIChhY3R1YWxUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJICAgIHhtbENoYXIgKnZhbHVlOwoKCQkgICAgLyoKCQkgICAgKiA1LjIuMi4yLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSC3YWN0dWFsIHR5cGUgCgkJICAgICogZGVmaW5pdGlvbrcgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSAKCQkgICAgKiAqYWN0dWFsIHZhbHVlKiBvZiB0aGUgaXRlbSBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgCgkJICAgICogbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRPRE86ICphY3R1YWwgdmFsdWUqIGlzIHRoZSBub3JtYWxpemVkIHZhbHVlLCBpbXBsLiB0aGlzLgoJCSAgICAqIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJICAgICogVE9ETzogSW1wbGVtZW50IHRoZSBjb25vbmljYWwgc3R1ZmYuCgkJICAgICogCgkJICAgICovCgkJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoZWxlbS0+ZG9jLCBlbGVtLT5jaGlsZHJlbiwgMSk7CgkJICAgIGlmICghIHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBlbGVtRGVjbC0+dmFsdWUpKSB7CgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMiwgCgkJCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSAgICAiVGhlIG5vcm1hbGl6ZWQgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIGNvbm9uaWNhbCAiCgkJCSAgICAibGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZml4ZWQgY29uc3RyYWludCIsIAoJCQkgICAgTlVMTCk7CgkJICAgIH0KCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOwoJCSAgICAKCQl9CgkJLyoKCQkqIFRPRE86IFdoYXQgaWYgdGhlIGNvbnRlbnQgdHlwZSBpcyBub3QgJ21peGVkJyBvciBzaW1wbGU/CgkJKi8KCgkgICAgfQoJICAgIAoJfQogICAgfQoKICAgIC8qCiAgICAqIFRPRE86IDYgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIGVhY2ggb2YgCiAgICAqIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uc30gYXMgcGVyIElkZW50aXR5LWNvbnN0cmFpbnQgCiAgICAqIFNhdGlzZmllZCAopzMuMTEuNCkuCiAgICAqLwoKICAgIC8qCiAgICAqIFRPRE86IDcgSWYgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyB0aGUgt3ZhbGlkYXRpb24gcm9vdLcsIGl0IG11c3QgYmUgCiAgICAqILd2YWxpZLcgcGVyIFZhbGlkYXRpb24gUm9vdCBWYWxpZCAoSUQvSURSRUYpICinMy4zLjQpLgogICAgKi8KICAgICAgICAgICAgICAgCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBSZXByZXNlbnRzIHRoZSByZWN1cnNpdmUgcG9ydGlvbiBvZiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkLiAKICogTm90IGludGVuZGVkIHRvIGJlIHVzZWQgYnkgb3RoZXIgZnVuY3Rpb25zLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwgCgkJCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgICAgICAKICAgIGNvbnN0IHhtbENoYXIgKnVyaTsKICAgIGludCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBjaGlsZDsKCiAgICBpZiAoY3R4dC0+eHNpQXNzZW1ibGUpIHsJCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbShjdHh0LCBjdHh0LT5ub2RlKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYSBieSB4c2kiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9ICAgIAogICAgaWYgKHdpbGQtPnByb2Nlc3NDb250ZW50cyAhPSBYTUxfU0NIRU1BU19BTllfU0tJUCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKCglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICBkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKCSAgICBub2RlLT5uYW1lLCBub2RlLT5ucy0+aHJlZiwgTlVMTCk7CgllbHNlIAoJICAgIGRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLCBub2RlLT5uYW1lLCBOVUxMLCBOVUxMKTsKCWlmIChkZWNsICE9IE5VTEwpIHsJCSAgICAKCSAgICBjdHh0LT5ub2RlID0gbm9kZTsJCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbihjdHh0LCBkZWNsKTsKCSAgICBpZiAocmV0IDwgMCkgewkJCgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUFueUludGVybmFsLCAiCgkJICAgICJ2YWxpZGF0aW5nIGFuIGVsZW1lbnQgaW4gdGhlIGNvbnRleHQgb2YgYSB3aWxkY2FyZC4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApCgkJcmV0dXJuIChyZXQpOwoJfSBlbHNlIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgPT0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkgewoJICAgIC8qIFRPRE86IENoYW5nZSB0byBwcm9wZXIgZXJyb3IgY29kZS4gKi8KCSAgICB4bWxTY2hlbWFWV2lsZGNhcmRFcnIoY3R4dCwgWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xLAoJCW5vZGUsIHdpbGQsICJObyBtYXRjaGluZyBnbG9iYWwgZGVjbGFyYXRpb24gYXZhaWxhYmxlIik7CgkgICAgcmV0dXJuIChjdHh0LT5lcnIpOwoJfQogICAgfQogICAgaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsJICAgCgljaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwoJZG8gewoJICAgIGlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkJaWYgKGNoaWxkLT5ucyAhPSBOVUxMKQoJCSAgICB1cmkgPSBjaGlsZC0+bnMtPmhyZWY7CgkJZWxzZQoJCSAgICB1cmkgPSBOVUxMOwoJCWlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh3aWxkLCB1cmkpID09IDApIHsKCQkgICAgLyogVE9ETzogZXJyb3IgY29kZS4gKi8KCQkgICAgeG1sU2NoZW1hVldpbGRjYXJkRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwKCQkJY2hpbGQsIHdpbGQsIAoJCQkiVGhlIG5hbWVzcGFjZSBvZiB0aGUgZWxlbWVudCBpcyBub3QgYWxsb3dlZCIpOwoJCSAgICByZXR1cm4gKGN0eHQtPmVycik7ICAKCQl9CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsKGN0eHQsIAoJCSAgICB3aWxkLCBjaGlsZCk7CgkJaWYgKHJldCAhPSAwKQoJCSAgICByZXR1cm4gKHJldCk7CQkKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gd2hpbGUgIChjaGlsZCAhPSBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRDb250QnlXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgICAgIAogICAgaWYgKCh0eXBlID09IE5VTEwpIHx8ICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9BTlkpIHx8CgkoY3R4dC0+bm9kZSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBjdHh0LT5ub2RlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldHVybih4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoY3R4dCwgCgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIGN0eHQtPm5vZGUpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQW55VHlwZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY3VycmVudCBlbGVtZW50CiAqCiAqIFRoaXMgb25lIHZhbGlkYXRlcyB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IG9mIHRoZSB0eXBlCiAqICdhbnlUeXBlJy4gVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIG9mICdhbnlUeXBlJyBpcyAibGF4IiwgCiAqIHRodXMgZWxlbWVudHMgaW4gdGhlIHN1YnRyZWUgd2lsbCBiZSB2YWxpZGF0ZWQsIGlmIGEgY29ycmVzcG9uZGluZwogKiBkZWNsYXJhdGlvbiBpbiB0aGUgc2NoZW1hIGV4aXN0cy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGFuZCBpdHMgc3VidHJlZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOwogICAgeG1sTm9kZVB0ciB0b3AsIGN1cjsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbDsKICAgIGludCBza2lwQ29udGVudCwgcmV0OwoKICAgIGlmICgodHlwZSA9PSBOVUxMKSB8fCAoY3R4dC0+bm9kZSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwoKICAgIGlmIChjdHh0LT5ub2RlLT5jaGlsZHJlbiA9PSBOVUxMKSAKCXJldHVybiAoMCk7CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICB0b3AgPSBjdHh0LT5ub2RlOyAgICAgICAgCiAgICAvKgogICAgKiBTVFJFQU06IENoaWxkIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgY3VyID0gY3R4dC0+bm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXNraXBDb250ZW50ID0gMDsKCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJICAgIC8qCgkgICAgKiBUaGUgcHJvY2VzcyBjb250ZW50cyBvZiB0aGUgd2lsZGNhcmQgaXMgImxheCIsIHRodXMKCSAgICAqIHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIGVsZW1lbnQgaWYgYSBkZWNsYXJhdGlvbgoJICAgICogZXhpc3RzLgoJICAgICovCQkKCSAgICBpZiAoY3VyLT5ucyAhPSBOVUxMKQoJCWRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAoJCSAgICBjdXItPm5hbWUsIGN1ci0+bnMtPmhyZWYsIE5VTEwpOwoJICAgIGVsc2UgCgkJZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsIGN1ci0+bmFtZSwgTlVMTCwgTlVMTCk7CSAgICAKCSAgICBpZiAoZGVjbCAhPSBOVUxMKSB7CQkgICAgCgkJY3R4dC0+bm9kZSA9IGN1cjsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIGRlY2wpOwoJCWN0eHQtPm5vZGUgPSB0b3A7CgkJaWYgKHJldCA8IDApIHsJCQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN1ciwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBbnlUeXBlQ29udGVudCwgIgoJCQkidmFsaWRhdGluZyBhbiBlbGVtZW50IGluIHRoZSBjb250ZXh0IG9mIGEgd2lsZGNhcmQuIiwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIHJldHVybiAocmV0KTsKCQl9IGVsc2UgaWYgKHJldCA+IDApCgkJICAgIHJldHVybiAocmV0KTsKCQlza2lwQ29udGVudCA9IDE7CgkgICAgfQoJfSAgIAoJLyoKCSogQnJvd3NlIHRoZSBmdWxsIHN1YnRyZWUsIGRlZXAgZmlyc3QuCgkqLwogICAgICAgIGlmICgoc2tpcENvbnRlbnQgPT0gMCkgJiYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkpIHsKCSAgICAvKiBkZWVwIGZpcnN0ICovCgkgICAgY3VyID0gY3VyLT5jaGlsZHJlbjsKCX0gZWxzZSBpZiAoKGN1ciAhPSB0b3ApICYmIChjdXItPm5leHQgIT0gTlVMTCkpIHsKCSAgICAvKiB0aGVuIHNpYmxpbmdzICovCgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfSBlbHNlIGlmIChjdXIgIT0gdG9wKSB7CgkgICAgLyogZ28gdXAgdG8gcGFyZW50cy0+bmV4dCBpZiBuZWVkZWQgKi8KCSAgICB3aGlsZSAoY3VyICE9IHRvcCkgewoJICAgICAgICBpZiAoY3VyLT5wYXJlbnQgIT0gTlVMTCkKCQkgICAgY3VyID0gY3VyLT5wYXJlbnQ7CgkJaWYgKChjdXIgIT0gdG9wKSAmJiAoY3VyLT5uZXh0ICE9IE5VTEwpKSB7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQkgICAgYnJlYWs7CgkJfQoJCWlmIChjdXItPnBhcmVudCA9PSBOVUxMKSB7CgkJICAgIGN1ciA9IE5VTEw7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9CgkgICAgLyogZXhpdCBjb25kaXRpb24gKi8KCSAgICBpZiAoY3VyID09IHRvcCkgCgkgICAgICAgIGN1ciA9IE5VTEw7Cgl9IGVsc2UKCSAgICBicmVhazsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGV4cGVjdGVkIHRvIGJlIGEgY29tcGxleCB0eXBlIHR5cGUKICogeG1sc2NoZW1hLTEuaHRtbCNjdmMtY29tcGxleC10eXBlCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqIE5vdGUgb24gcmVwb3J0ZWQgZXJyb3JzOiBBbHRob3VnaCBpdCBtaWdodCBiZSBuaWNlIHRvIHJlcG9ydAogKiB0aGUgbmFtZSBvZiB0aGUgc2ltcGxlL2NvbXBsZXggdHlwZSwgdXNlZCB0byB2YWxpZGF0ZSB0aGUgY29udGVudAogKiBvZiBhIG5vZGUsIGl0IGlzIHF1aXRlIHVubmVjZXNzYXJ5OiBmb3IgZ2xvYmFsIGRlZmluZWQgdHlwZXMKICogdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQgaXMgZXF1YWwgdG8gdGhlIE5DTmFtZSBvZiB0aGUgdHlwZSwKICogZm9yIGxvY2FsIGRlZmluZWQgdHlwZXMgaXQgbWFrZXMgbm8gc2Vuc2UgdG8gb3V0cHV0IHRoZSBpbnRlcm5hbAogKiBjb21wdXRlZCBuYW1lIG9mIHRoZSB0eXBlLiBUT0RPOiBJbnN0ZWFkLCBvbmUgc2hvdWxkIGF0dGFjaCB0aGUgCiAqIHN0cnVjdCBvZiB0aGUgdHlwZSBpbnZvbHZlZCB0byB0aGUgZXJyb3IgaGFuZGxlciAtIHRoaXMgYWxsb3dzCiAqIHRoZSByZXBvcnQgb2YgYW55IGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYnkgdGhlIHVzZXIuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJICAgICAgaW50IHZhbFNpbXBsZUNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb2xkdHlwZTsgICAgCiAgICB4bWxOb2RlUHRyIGVsZW0sIGNoaWxkOwogICAgaW50IHJldCA9IDA7CiAgICBjb25zdCB4bWxDaGFyICpuc1VyaTsgICAgCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cnMgPSBOVUxMLCBhdHRyVG9wID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKQoJcmV0dXJuICgtMSk7CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIGVsZW0gPSBjdHh0LT5ub2RlOwoKICAgIC8qCiAgICAqIFZlcmlmeSB0aGUgYXR0cmlidXRlcwogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IFRoaXMgImF0dHJUb3AiIHRoaW5nIGlzIG5vdCBuZWVkZWQgYW55IG1vcmUuCiAgICAqLyAgCiAgICAvKiBOT1RFOiByZW1vdmVkLCBzaW5jZSBhIGNoZWNrIGZvciBhYnN0cmFjdCBpcwogICAgKiBkb25lIGluIHRoZSBjdmMtdHlwZSBjb25zdHJhaW50LgogICAgKgogICAgKgogICAgKiBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUKSB7CiAgICAqCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKICAgICoJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMSwKICAgICoJICAgIGVsZW0sIHR5cGUsIAogICAgKgkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzdHJhY3QiKTsKICAgICoJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzEpOwogICAgKn0KICAgICovCiAgICAKICAgIGF0dHJzID0gY3R4dC0+YXR0cjsgICAgCiAgICBhdHRyVG9wID0gY3R4dC0+YXR0clRvcDsgICAKICAgIC8qCiAgICAqIFNUUkVBTTogQXR0cmlidXRlIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKGN0eHQsIGVsZW0tPnByb3BlcnRpZXMpOyAgICAgCiAgICB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgZWxlbSwgdHlwZSk7CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGN0eHQtPmF0dHIgPSBhdHRyczsgICAgCiAgICBjdHh0LT5hdHRyVG9wID0gYXR0clRvcDsgICAgCgogICAgLyoKICAgICogVE9ETzogVGhpcyBvbmUgY3JlYXRlcyBhIHJlZ2V4cCBldmVuIGlmIG5vIGNvbnRlbnQKICAgICogbW9kZWwgd2FzIGRlZmluZWQuIFNvbWVob3cgLT5jb250TW9kZWwgaXMgYWx3YXlzIG5vdCBOVUxMCiAgICAqIGZvciBjb21wbGV4IHR5cGVzLCBldmVuIGlmIHRoZXkgYXJlIGVtcHR5LgogICAgKiBUT0RPOiBDaGVjayBpZiB0aGUgb2JvdmUgc3RpbGwgb2NjdXJzLgogICAgKi8gICAgICAgICAgICAgIAogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6IHsKCSAgICAvKgoJICAgICogMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gCgkgICAgKiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCgkgICAgKi8KCSAgICAvKgoJICAgICogVE9ETzogSXMgdGhlIGVudGl0eSBzdHVmZiBjb3JyZWN0PwoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pID09IDEpIHsJICAgIAkgICAgCgkJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMSwKCQkgICAgZWxlbSwgdHlwZSwgCgkJICAgICJDaGFyYWN0ZXIgb3IgZWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZW1wdHkiKTsKICAgICAgICAgICAgfQkgCiAgICAgICAgICAgIGJyZWFrOwoJfQoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CgkgICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAKCQkodHlwZS0+YmFzZVR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSB7CgkJLyoKCQkqIFRoZSB0eXBlIGhhcyAnYW55VHlwZScgYXMgaXRzIGJhc2UgYW5kIG5vIGNvbnRlbnQgbW9kZWwKCQkqIGlzIGRlZmluZWQgLT4gdXNlICdhbnlUeXBlJyBhcyB0aGUgdHlwZSB0byB2YWxpZGF0ZQoJCSogYWdhaW5zdC4KCQkqLwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZShjdHh0LCB0eXBlLT5iYXNlVHlwZSk7CgkJLyogVE9ETzogSGFuZGxlIC0xLiAqLwoJCWJyZWFrOwoJICAgIH0KCSAgICAvKiBObyBicmVhayBvbiBwdXJwb3NlLiAqLwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgIHsKCSAgICB4bWxSZWdFeGVjQ3R4dFB0ciBvbGRyZWdleHAgPSBOVUxMOwoJICAgIAoJICAgIC8qCgkgICAgKiBDb250ZW50IG1vZGVsIGNoZWNrIGluaXRpYWxpemF0aW9uLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CQkJCQkKCQlvbGRyZWdleHAgPSBjdHh0LT5yZWdleHA7CgkJY3R4dC0+cmVnZXhwID0geG1sUmVnTmV3RXhlY0N0eHQodHlwZS0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykKCQkgICAgeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjaywgY3R4dCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiPT09PT4gJXNcbiIsIGVsZW0tPm5hbWUpOwojZW5kaWYKCSAgICB9CgkgICAgLyoKCSAgICAqIFNUUkVBTTogQ2hpbGRyZW4gYXJlIHByb2Nlc3NlZC4KCSAgICAqLwoJICAgIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsJCQoJCWlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkJICAgIGlmIChjaGlsZC0+bnMgIT0gTlVMTCkKCQkJbnNVcmkgPSBjaGlsZC0+bnMtPmhyZWY7CgkJICAgIGVsc2UKCQkJbnNVcmkgPSBOVUxMOwoJCSAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZzIoY3R4dC0+cmVnZXhwLAoJCQljaGlsZC0+bmFtZSwgbnNVcmksIGNoaWxkKTsKCQkgICAgLyoKCQkgICAgKiBVUkdFTlQgVE9ETzogQ291bGQgd2UgYW5jaG9yIGFuIGVycm9yIHJlcG9ydAoJCSAgICAqIGhlcmUgdG8gbm90aWZ5IG9mIGludmFsaWQgZWxlbWVudHM/CgkJICAgICovCiNpZmRlZiBERUJVR19BVVRPTUFUQQkJICAgIAoJCSAgICBpZiAocmV0IDwgMCkKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlcyBFcnJvclxuIiwgY2hpbGQtPm5hbWUpOwoJCSAgICBlbHNlCgkJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkiICAtLT4gJXNcbiIsIGNoaWxkLT5uYW1lKTsKI2VuZGlmCgkJfSBlbHNlIGlmICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSAmJiAKCQkgICAgLyogCgkJICAgICogVE9ETzogQXNrIERhbmllbCBpZiB0aGlzIGFyZSBhbGwgY2hhcmFjdGVyIG5vZGVzLgoJCSAgICAqLwoJCSAgICAoKChjaGlsZC0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoIUlTX0JMQU5LX05PREUoY2hpbGQpKSkgfHwKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CQkgICAgCQkgICAgCgkJICAgICAoY2hpbGQtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgfHwJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkpIHsJCSAgICAKCQkgICAgLyogCgkJICAgICogMi4zIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIAoJCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gW2NoaWxkcmVuXSBvdGhlciB0aGFuIHRob3NlIHdob3NlIFtjaGFyYWN0ZXIgCgkJICAgICogY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgCgkJICAgICogRWRpdGlvbildLgoJCSAgICAqLwkJCQoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8zLAoJCQllbGVtLCB0eXBlLCAKCQkJIkNoYXJhY3RlciBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJCSJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZWxlbWVudC1vbmx5Iik7CQkgICAgCgkJICAgIGJyZWFrOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwkJICAgIAoJICAgIH0gICAgCgkgICAgLyoKCSAgICAqIENvbnRlbnQgbW9kZWwgY2hlY2sgZmluYWxpemF0aW9uLgoJICAgICovCiAgICAgICAJICAgIGlmICh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkgewoJCXJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nKGN0eHQtPnJlZ2V4cCwgTlVMTCwgTlVMTCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCSAgICAiPT09PT4gJXMgOiAlZFxuIiwgZWxlbS0+bmFtZSwgcmV0KTsKI2VuZGlmCgkJaWYgKHJldCA9PSAwKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVZfRUxFTUVOVF9DT05URU5ULAoJCQllbGVtLCB0eXBlLCAiVGhlIGVsZW1lbnQgY29udGVudCBpcyBub3QgdmFsaWQiLCBOVUxMKTsKCQl9IGVsc2UgaWYgKHJldCA8IDApIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCWVsZW0sIHR5cGUsICJUaGUgZWxlbWVudCBjb250ZW50IGlzIG5vdCB2YWxpZCIsIE5VTEwpOwojaWZkZWYgREVCVUdfQ09OVEVOVAoJCX0gZWxzZSB7CgkJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIHN1Y2NlZWRlZFxuIiwKCQkJZWxlbS0+bmFtZSk7CgkJICAgIAojZW5kaWYKCQl9CgkJeG1sUmVnRnJlZUV4ZWNDdHh0KGN0eHQtPnJlZ2V4cCk7CgkJY3R4dC0+cmVnZXhwID0gb2xkcmVnZXhwOwoJICAgIH0KCX0KICAgICAgICAgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CgkgICAgLyoKCSAgICAqIElmIHRoZSBzaW1wbGUgY29udGVudCB3YXMgYWxyZWFkeSB2YWxpZGF0ZWQgCgkgICAgKiAoZS5nLiBhIGRlZmF1bHQgdmFsdWUpLCB0aGUgY29udGVudCBuZWVkIG5vdAoJICAgICogdG8gYmUgdmFsaWRhdGVkIGFnYWluLgoJICAgICovCglpZiAodmFsU2ltcGxlQ29udGVudCA9PSAxKSB7CgkgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwoJICAgIC8qCgkgICAgKiBXZSBoaXQgYSBjb21wbGV4VHlwZSB3aXRoIGEgc2ltcGxlQ29udGVudCByZXNvbHZpbmcKCSAgICAqIHRvIGEgdXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluIHNpbXBsZSB0eXBlLgoJICAgICovCgkgICAgLyogCgkgICAgKiAyLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgCgkgICAgKiB0aGVuIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGVsZW1lbnQgCgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0sIGFuZCB0aGUgt25vcm1hbGl6ZWQgdmFsdWW3IAoJICAgICogb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyC3dmFsaWS3IHdpdGggcmVzcGVjdCAKCSAgICAqIHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKCSAgICAqIFZhbGlkICinMy4xNC40KS4KCSAgICAqLwkgIAoJICAgIC8qCgkgICAgKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkgICAgKi8KCSAgICBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOwoJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CgkJLyoKCQkqIFRPRE86IENvdWxkIHRoZSBlbnRpdHkgc3R1ZmYgcHJvZHVjZSBlbGVtZW50cwoJCSogYXMgd2VsbD8KCQkqLwogICAgICAgICAgICAgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAKCQkJIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgYmVjYXVzZSAiCgkJCSJ0aGUgY29udGVudCB0eXBlIGlzIGEgc2ltcGxlIHR5cGUiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJICAgIGJyZWFrOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwkJICAgIAoJICAgIH0JCgkgICAgY3R4dC0+bm9kZSA9IGVsZW07CgkgICAgY3R4dC0+Y3VyID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyoKCQkqIFZhbGlkYXRlIHRoZSBjaGFyYWN0ZXIgY29udGVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCgkJKi8KCQkvKgoJCSogU1RSRUFNOiBDaGlsZHJlbiBhcmUgcHJvY2Vzc2VkLgoJCSovCgkJaWYgKGVsZW0tPmNoaWxkcmVuID09IE5VTEwpCgkJICAgIHZhbHVlID0gTlVMTDsKCQllbHNlCgkJICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoZWxlbSk7IAoJCS8qCgkJKiBVUkdFTlQgVE9ETzogU2hvdWxkIGZhY2V0cyBmb3IgdGhlIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gYmUgCgkJKiBkaXNhYmxlZCwgaWYgdGhlIGRlcml2YXRpb24gb2YgZmFjZXRzIGZvciBjb21wbGV4IHR5cGVzIAoJCSogaXMgaW1wbGVtZW50ZWQ/CgkJKi8KCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIHdvbid0IGNoZWNrIHRoZSBjb3JyZWN0IHR5cGVzIG9mIHRoZQoJCSogY29udGVudCBub2Rlcywgc2luY2UgdGhpcyBzaG91bGQgYmUgZG9uZSBoZXJlLgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUsIDEsIDEsIDEsIDApOwoJCWlmIChyZXQgPiAwKSB7CQoJCSAgICAvKgoJCSAgICAqIE5PVEU6IEFsdGhvdWdoIGFuIGVycm9yIHdpbGwgYmUgcmVwb3J0ZWQgYnkgCgkJICAgICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsIHRoZSBzcGVjIHdhbnRzCgkJICAgICogYSBzcGVjaWZpYyBjb21wbGV4IHR5cGUgZXJyb3IgdG8gYmUgcmVwb3J0ZWQgCgkJICAgICogYWRkaXRpb25hbGx5LgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnLlxuIiwKCQkJZWxlbS0+bmFtZSwgdHlwZS0+bmFtZSk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQkgICAgCgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyogCgkJKiBBcHBseSBmYWNldHMgb2YgdGhlIGNvbXBsZXhUeXBlLiBCZSBzdXJlIHRvIHBhc3MgdGhlIAoJCSogYnVpbHQtaW4gdHlwZSB0byB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLgoJCSovCSAgICAKCQkvKiBVUkdFTlQgVE9ETzogSSBkb24ndCBrbm93IHlldCBpZiB0aGUgZmFjZXRzIG9mIHRoZSBzaW1wbGUgdHlwZQoJCSogYXJlIHVzZWQsIG9yIGlmIHRoZSBmYWNldHMsIGRlZmluZWQgYnkgdGhpcyBjb21wbGV4IHR5cGUsCgkJKiBhcmUgdG8gYmUgdXNlZCBvbmx5LiBUaGlzIGhlcmUgYXBwbGllcyBib3RoIGZhY2V0IHNldHMuCgkJKi8JICAgIAoKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIAoJCSAgICB0eXBlLCB2YWx1ZSwgMCwgMSk7CgkJaWYgKHJldCA+IDApIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMiwKCQkJZWxlbSwgdHlwZSwgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnOyBmYWlsZWQgdG8gIgoJCQkiYXBwbHkgZmFjZXRzLlxuIiwKCQkJdHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCXhtbEZyZWUodmFsdWUpOyAgICAKCSAgICAKCX0KCSAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUT0RPIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5pbXBsZW1lbnRlZCBjb250ZW50IHR5cGUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgbGlzdCBvZiB0eXBlIGRlY2xhcmF0aW9ucwogKgogKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgaW50IHJldDsKCiAgIAogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgTlVMTCwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7ICAgIAogICAgfSAgICAJCiAgICAvKiAKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5ICJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uIi4KICAgICogSXQgd2lsbCBmb3J3YXJkIHRvIHRoZSBwcm9wZXIgdmFsaWRhdGlvbiAKICAgICogcHJvY2VkdXJlcyBmb3IgdGhlIGdpdmVuIHR5cGUuCiAgICAqLyAgICAgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAogICAgCSAgICBYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLAogICAgCSAgICBjdHh0LT5ub2RlLCBOVUxMLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50Iik7CiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8xKTsKICAgIH0KICAgIAogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9BQlNUUkFDVCkgewogICAgCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKICAgIAkgICAgWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMiwKICAgIAkgICAgY3R4dC0+bm9kZSwgdHlwZSwgCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic3RyYWN0Iik7CiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8yKTsKICAgIH0KCiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUoY3R4dCwgdHlwZSwKCQl2YWxTaW1wbGVDb250ZW50KTsKICAgICAgICAgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZShjdHh0LCB0eXBlLAoJCXZhbFNpbXBsZUNvbnRlbnQpOwogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJICAgIGlmICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKQoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZShjdHh0LCB0eXBlKTsKCSAgICBlbHNlCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlKGN0eHQsIHR5cGUsCgkJICAgIHZhbFNpbXBsZUNvbnRlbnQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXQgPSAtMTsKCSAgICBicmVhazsKICAgIH0JCiAgICBpZiAocmV0ID09IC0xKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7Cn0KCgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQXR0ckxvY2FsbHlWYWxpZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsLAoJCQkgICAgICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHN0YXRlLAoJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyKQp7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIGNvbnN0IHhtbENoYXIgKmRlZlZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIGRlZlZhbDsKICAgIGludCBmaXhlZDsKICAgIGludCByZXQ7CgogICAgaWYgKGRlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCXN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQ7CglyZXR1cm4gKFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQpOwogICAgfQogICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhhdHRyLT5kb2MsIGF0dHItPmNoaWxkcmVuLCAxKTsKICAgIGN0eHQtPm5vZGUgPSAoeG1sTm9kZVB0cikgYXR0cjsKICAgIGN0eHQtPmN1ciA9IGF0dHItPmNoaWxkcmVuOwogICAgLyoKICAgICogTk9URTogVGhpcyBjYWxsIGFsc28gY2hlY2tzIHRoZSBjb250ZW50IG5vZGVzIGZvciBjb3JyZWN0IHR5cGUuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgZGVjbC0+c3VidHlwZXMsCgl2YWx1ZSwgMSwgMSwgMSwgMSk7CiAgICAJICAgIAogICAgLyoKICAgICogSGFuZGxlICdmaXhlZCcgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAocmV0ID4gMCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFOwoJLyoKCSogTk9URTogRml4ZWQgdmFsdWUgY29uc3RyYWludHMgd2lsbCBiZSBub3QKCSogYXBwbGllZCBpZiB0aGUgdmFsdWUgd2FzIGludmFsaWQsIGJlY2F1c2U6IAoJKiAxLiBUaGUgdmFsaWRhdGlvbiBwcm9jZXNzIGRvZXMgbm90IHJldHVybiBhIHByZWNvbXB1dGVkIAoJKiAgICB2YWx1ZS4KCSogMi4gQW4gaW52YWxpZCB2YWx1ZSBpbXBsaWVzIGEgdmlvbGF0aW9uIG9mIGEgZml4ZWQgCgkqICAgIHZhbHVlIGNvbnN0cmFpbnQuCgkqLwogICAgfSBlbHNlIGlmIChyZXQgPT0gMCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJaWYgKHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChkZWNsLCAKCSAgICAmZml4ZWQsICZkZWZWYWx1ZSwgJmRlZlZhbCkgJiYgKGZpeGVkID09IDEpKSB7CgkgICAgLyoKCSAgICAqIGN2Yy1hdSA6IEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpCgkgICAgKiBGb3IgYW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gdG8gYmW3dmFsaWS3IAoJICAgICogd2l0aCByZXNwZWN0IHRvIGFuIGF0dHJpYnV0ZSB1c2UgaXRzILdub3JtYWxpemVkIAoJICAgICogdmFsdWW3IG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uCgkgICAgKiBvZiB0aGUgYXR0cmlidXRlIHVzZSdzIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSwgaWYgaXQgCgkgICAgKiBpcyBwcmVzZW50IGFuZCBmaXhlZC4KCSAgICAqLwoJICAgIC8qIAoJICAgICogTk9URTogdGhlIHZhbGlkYXRpb24gY29udGV4dCBob2xkcyBpbiBjdHh0LT52YWx1ZSB0aGUKCSAgICAqIHByZWNvbXB1dGVkIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGU7IHdlbGwgZm9yIHNvbWUgdHlwZXMsCgkgICAgKiBmYWxsYmFjayB0byBzdHJpbmcgY29tcGFyaXNvbiBpZiBubyBjb21wdXRlZCB2YWx1ZSAKCSAgICAqIGV4aXN0cy4KCSAgICAqLwoJICAgIGlmICgoKGN0eHQtPnZhbHVlICE9IE5VTEwpICYmIAoJCSh4bWxTY2hlbWFDb21wYXJlVmFsdWVzKGN0eHQtPnZhbHVlLCBkZWZWYWwpICE9IDApKSB8fAoJCSgoY3R4dC0+dmFsdWUgPT0gTlVMTCkgJiYKCQkoISB4bWxTdHJFcXVhbChkZWZWYWx1ZSwgQkFEX0NBU1QgdmFsdWUpKSkpIHsKCQlzdGF0ZS0+c3RhdGUgPSAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX0ZJWEVEX1ZBTFVFOwkJCQoJICAgIH0KCX0KICAgIH0gIAogICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCXhtbEZyZWUodmFsdWUpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgY29tcGxleFR5cGUgaG9sZGluZyB0aGUgYXR0cmlidXRlIHVzZXMKICoKICogVmFsaWRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgYW4gZWxlbWVudC4KICoKICogMS4gRXhpc3RlbnQsIGludmFsaWQgYXR0cmlidXRlcyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvcm0gCiAqICAgICJwcmVmaXg6bG9jYWxOYW1lIi4gCiAqICAgIFJlYXNvbjogcmVhZGFiaWxpdHkgLSBpdCBpcyBlYXNpZXIgdG8gZmluZCB0aGUgYWN0dWFsIFhNTCAKICogICAgcmVwcmVzZW50YXRpb24gb2YgdGhlIGF0dHJpYnV0ZXMgUU5hbWUuCiAqIDIuIE1pc3NpbmcgYXR0cmlidXRlcyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvcm0gCiAqICAgIHsiVVJJIiwgImxvY2FsTmFtZSJ9LgogKiAgICBUaGlzIGlzIG5lY2Vzc2FyeSwgc2luY2UgdGhlIHRoZSBwcmVmaXggbmVlZCBub3QgdG8gYmUgZGVjbGFyZWQKICogICAgYXQgYWxsLCBhbmQgdGh1cyBpcyBub3QgY29tcHV0YWJsZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5zVVJJOwogICAgaW50IHJldDsKICAgIHhtbEF0dHJQdHIgYXR0cjsgLyogQW4gYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50LiAqLwogICAgY29uc3QgeG1sQ2hhciAqZGVmVmFsdWU7CiAgICB4bWxTY2hlbWFWYWxQdHIgZGVmVmFsOwogICAgaW50IGZpeGVkOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyRGVjbDsKICAgIGludCBmb3VuZDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBjdXJTdGF0ZSwgcmVxQXR0clN0YXRlcyA9IE5VTEwsIHJlcUF0dHJTdGF0ZXNUb3AgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGRlZkF0dHJTdGF0ZXMgPSBOVUxMLCBkZWZBdHRyU3RhdGVzVG9wID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZTsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaW50IHJlZHVuZGFudCA9IDA7CiNlbmRpZgoKICAgICAgCiAgICAvKgogICAgKiBBbGxvdyBhbGwgYXR0cmlidXRlcyBpZiB0aGUgdHlwZSBpcyBhbnlUeXBlLgogICAgKi8KICAgIGlmICh0eXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoJcmV0dXJuICgwKTsKCiAgICBvbGRub2RlID0gY3R4dC0+bm9kZTsKICAgIGlmICh0eXBlICE9IE5VTEwpCglhdHRyVXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKICAgICAgICBmb3VuZCA9IDA7ICAgIAoJYXR0ckRlY2wgPSBhdHRyVXNlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCglwcmludGYoImF0dHIgdXNlIC0gbmFtZTogJXNcbiIsIHhtbFNjaGVtYUdldEF0dHJOYW1lKGF0dHJEZWNsKSk7CglwcmludGYoImF0dHIgdXNlIC0gdXNlOiAlZFxuIiwgYXR0ckRlY2wtPm9jY3Vycyk7CiNlbmRpZgogICAgICAgIGZvciAoY3VyU3RhdGUgPSBjdHh0LT5hdHRyOyBjdXJTdGF0ZSAhPSBOVUxMOyBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0KSB7CQkgICAgCgoJICAgIGlmIChjdXJTdGF0ZS0+ZGVjbCA9PSBhdHRyVXNlLT5hdHRyKSB7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCQlyZWR1bmRhbnQgPSAxOwojZW5kaWYKCSAgICB9CgkgICAgYXR0ciA9IGN1clN0YXRlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJhdHRyIC0gbmFtZTogJXNcbiIsIGF0dHItPm5hbWUpOwoJICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKQoJCXByaW50ZigiYXR0ciAtIG5zOiAlc1xuIiwgYXR0ci0+bnMtPmhyZWYpOwoJICAgIGVsc2UKCQlwcmludGYoImF0dHIgLSBuczogbm9uZVxuIik7CiNlbmRpZgoJICAgIC8qIFRPRE86IENhbiB0aGlzIGV2ZXIgaGFwcGVuPyAqLwogICAgICAgICAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChhdHRyRGVjbC0+cmVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPnJlZikpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGlmICgoYXR0ckRlY2wtPnJlZk5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIGF0dHJEZWNsLT5yZWZOcykpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0ckRlY2wtPnJlZk5zICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPm5hbWUpKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGhhbmRsZSB0aGUgbmFtZXNwYWNlcyBjaGVja3MgaGVyZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAgKiBhY2NlcHQgYW4gdW5xdWFsaWZpZWQgYXR0cmlidXRlIG9ubHkgaWYgdGhlIHRhcmdldAoJCSAgICAgKiBuYW1lc3BhY2Ugb2YgdGhlIGRlY2xhcmF0aW9uIGlzIGFic2VudC4KCQkgICAgICovCgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCgkJCS8qIAoJCQkgKiBUaGlzIGNoZWNrIHdhcyByZW1vdmVkLCBzaW5jZSB0aGUgdGFyZ2V0IG5hbWVzcGFjZQoJCQkgKiB3YXMgZXZhbHVhdGVkIGR1cmluZyBwYXJzaW5nIGFuZCBhbHJlYWR5IHRvb2sKCQkJICogImF0dHJpYnV0ZUZvcm1EZWZhdWx0IiBpbnRvIGFjY291bnQuCgkJCSAqLwoJCSAgICAgICAgLyogKChhdHRyaWJ1dGVzLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfTlNERUZBVUxUKSA9PSAwKSkgKi8KCQkgICAgICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpCgkJICAgICAgICBjb250aW51ZTsKCQkgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICAgICAgICAgICAgICAgICAgIGF0dHItPm5zLT5ocmVmKSkKCQkJY29udGludWU7CgkJfQogICAgICAgICAgICB9CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImZvdW5kXG4iKTsKI2VuZGlmCiAgICAgICAgICAgIGZvdW5kID0gMTsJICAgIAoJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKGN0eHQsIGF0dHJEZWNsLCBjdXJTdGF0ZSwgYXR0cik7CiAgICAgICAgfQogICAgICAgIGlmICghZm91bmQpIHsKCSAgICBpZiAoYXR0ckRlY2wtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkgewoJCXhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgkJCiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCQlwcmludGYoInJlcXVpcmVkIGF0dHIgbm90IGZvdW5kXG4iKTsKI2VuZGlmCgkJLyoKCQkqIEFkZCBhIG5ldyBkdW1teSBhdHRyaWJ1dGUgc3RhdGUuCgkJKi8JCgkJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyIsIE5VTEwpOwoJCSAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfSAgICAgICAgICAgIAoJCXRtcC0+YXR0ciA9IE5VTEw7CgkJdG1wLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORzsKCQl0bXAtPmRlY2wgPSBhdHRyRGVjbDsKCQl0bXAtPm5leHQgPSBOVUxMOwoJCQoJCWlmIChyZXFBdHRyU3RhdGVzID09IE5VTEwpIHsKCQkgICAgcmVxQXR0clN0YXRlcyA9IHRtcDsKCQkgICAgcmVxQXR0clN0YXRlc1RvcCA9IHRtcDsKCQl9IGVsc2UgewoJCSAgICByZXFBdHRyU3RhdGVzVG9wLT5uZXh0ID0gdG1wOwoJCSAgICByZXFBdHRyU3RhdGVzVG9wID0gdG1wOwoJCX0KCSAgICB9IGVsc2UgaWYgKChhdHRyRGVjbC0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJCSAgICAoeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGF0dHJEZWNsLCAKCQkJJmZpeGVkLCAmZGVmVmFsdWUsICZkZWZWYWwpKSkgewoJCXhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgkJLyoKCQkqIEhhbmRsZSBub24gZXhpc3RlbnQgZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGVzLgoJCSovCQoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpIAoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsIAoJCQkicmVnaXN0ZXJpbmcgc2NoZW1hIHNwZWNpZmllZCBhdHRyaWJ1dGVzIiwgTlVMTCk7CgkJICAgIGN0eHQtPm5vZGUgPSBvbGRub2RlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9ICAgICAgICAgICAgCgkJdG1wLT5hdHRyID0gTlVMTDsKCQl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9ERUZBVUxUOwoJCXRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJCXRtcC0+dmFsdWUgPSBkZWZWYWx1ZTsKCQl0bXAtPm5leHQgPSBOVUxMOwoJCQoJCWlmIChkZWZBdHRyU3RhdGVzID09IE5VTEwpIHsKCQkgICAgZGVmQXR0clN0YXRlcyA9IHRtcDsKCQkgICAgZGVmQXR0clN0YXRlcyA9IHRtcDsKCQl9IGVsc2UgewoJCSAgICBkZWZBdHRyU3RhdGVzLT5uZXh0ID0gdG1wOwoJCSAgICBkZWZBdHRyU3RhdGVzVG9wID0gdG1wOwoJCX0JCQkJCgkgICAgfQkJCQoJfQogICAgICAgIGF0dHJVc2UgPSBhdHRyVXNlLT5uZXh0OwogICAgfQogICAgLyoKICAgICAqIEFkZCByZXF1aXJlZCBhdHRyaWJ1dGVzIHRvIHRoZSBhdHRyaWJ1dGUgc3RhdGVzIG9mIHRoZSBjb250ZXh0LgogICAgICovCiAgICBpZiAocmVxQXR0clN0YXRlcyAhPSBOVUxMKSB7CglpZiAoY3R4dC0+YXR0ciA9PSBOVUxMKSB7CgkgICAgY3R4dC0+YXR0ciA9IHJlcUF0dHJTdGF0ZXM7Cgl9IGVsc2UgewkJCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHJlcUF0dHJTdGF0ZXM7Cgl9CgljdHh0LT5hdHRyVG9wID0gcmVxQXR0clN0YXRlc1RvcDsKICAgIH0KICAgIC8qCiAgICAqIFByb2Nlc3Mgd2lsZGNhcmRzLgogICAgKi8KICAgIAogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkgewkKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsJCglwcmludGYoIm1hdGNoaW5nIHdpbGRjYXJkOiBbJWRdIG9mIGNvbXBsZXhUeXBlOiAlc1xuIiwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPm5hbWUpOwoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogbGF4XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc3RyaWN0XG4iKTsKCWVsc2UKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc2tpcFxuIik7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPmFueSkKCSAgICBwcmludGYoInR5cGU6IGFueVxuIik7CgllbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogbmVnYXRlZFxuIik7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkKCQlwcmludGYoIm5zOiAoYWJzZW50KVxuIik7CgkgICAgZWxzZQoJCXByaW50ZigibnM6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBwcmludGYoInR5cGU6IHNldFxuIik7CgkgICAgbnMgPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQ7CgkgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKCQlpZiAobnMtPnZhbHVlID09IE5VTEwpCgkJICAgIHByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCQllbHNlCgkJICAgIHByaW50ZigibnM6ICVzXG4iLCBucy0+dmFsdWUpOwoJCW5zID0gbnMtPm5leHQ7CgkgICAgfQkgICAgCgl9IGVsc2UKCSAgICBwcmludGYoImVtcHR5XG4iKTsKCgojZW5kaWYJCgljdXJTdGF0ZSA9IGN0eHQtPmF0dHI7Cgl3aGlsZSAoY3VyU3RhdGUgIT0gTlVMTCkgewoJICAgIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKSB7CQkKCQlpZiAoY3VyU3RhdGUtPmF0dHItPm5zICE9IE5VTEwpIAoJCSAgICBuc1VSSSA9IGN1clN0YXRlLT5hdHRyLT5ucy0+aHJlZjsKCQllbHNlCgkJICAgIG5zVVJJID0gTlVMTDsJCQoJCWlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJICAgIG5zVVJJKSkgewoJCSAgICAvKgoJCSAgICAqIEhhbmRsZSBwcm9jZXNzQ29udGVudHMuCgkJICAgICovCgkJICAgIGlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX0xBWCkgfHwKCQkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCVhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpKSB7CgkJCQoJCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CQkJCQkJCgkJCWF0dHJEZWNsID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgCgkJCSAgICBhdHRyLT5uYW1lLCBuc1VSSSk7CgkJCWN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCWlmIChhdHRyRGVjbCAhPSBOVUxMKSB7CgkJCSAgICBjdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwoJCQkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKGN0eHQsIGF0dHJEZWNsLCBjdXJTdGF0ZSwgYXR0cik7CQkJICAgIAoJCQl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJCSAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJCX0JCQkJCQkJCQkJCQoJCSAgICB9IGVsc2UKCQkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCX0JCQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgKiBSZXBvcnQgbWlzc2luZyBhbmQgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpIHsKCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlICgoY3VyU3RhdGUgIT0gTlVMTCkgJiYgKGN1clN0YXRlICE9IGN0eHQtPmF0dHJUb3AtPm5leHQpKSB7ICAgIAoJICAgIGlmIChjdXJTdGF0ZS0+c3RhdGUgIT0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEKSB7CgkJYXR0ciA9IGN1clN0YXRlLT5hdHRyOwoJCWlmIChjdXJTdGF0ZS0+ZGVjbCAhPSBOVUxMKSB7CgkJICAgIGlmIChjdXJTdGF0ZS0+ZGVjbC0+cmVmICE9IE5VTEwpCgkJCWF0dHJEZWNsID0gY3VyU3RhdGUtPmRlY2wtPnJlZkRlY2w7CgkJICAgIGVsc2UgCgkJCWF0dHJEZWNsID0gY3VyU3RhdGUtPmRlY2w7CgkJfSBlbHNlCgkJICAgIGF0dHJEZWNsID0gTlVMTDsKCQlpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORykgewoJCSAgICB4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnIoY3R4dCwgZWxlbSwgYXR0ckRlY2wpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IAoJCSAgICBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0FUVFJJQlVURV8yLAoJCQkoeG1sTm9kZVB0cikgYXR0ciwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHJEZWNsLAoJCQkiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiLAoJCQlOVUxMKTsKCQl9IGVsc2UgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX0ZJWEVEX1ZBTFVFKSB7CQkJCgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19BVSwgCgkJCSAgICAoeG1sTm9kZVB0cikgYXR0ciwgKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHJEZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSBkb2VzIG5vdCBtYXRjaCB0aGUgZml4ZWQgdmFsdWUgIgoJCQkgICAgImNvbnN0cmFpbnQiLCBOVUxMKTsKCQl9IGVsc2UgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pIHsKCQkgICAgLyogVE9ETzogInByb2hpYml0ZWQiIHdvbid0IGV2ZXIgYmUgdG91Y2hlZCBoZXJlIS4gCgkJICAgICAgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQpKQoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRPRE86IE9uZSBtaWdodCByZXBvcnQgZGlmZmVyZW50IGVycm9yIG1lc3NhZ2VzIAoJCSAgICAqIGZvciB0aGUgZm9sbG93aW5nIGVycm9ycy4KCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlID09IE5VTEwpIHx8ICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSkgewoJCQl4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8xLCBhdHRyKTsKCQkgICAgfSBlbHNlIHsKCQkJeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMiwgYXR0cik7CgkJICAgIH0KCQl9CgkgICAgfQkKCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwoJfSAgCiAgICB9ICAgIAogICAgCiAgICAvKgogICAgKiBBZGQgbWlzc2luZyBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKGN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURSkgewoJY3VyU3RhdGUgPSBkZWZBdHRyU3RhdGVzOwoJd2hpbGUgKGN1clN0YXRlICE9IE5VTEwpIHsgCgkgICAgYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbDsKCSAgICBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKQoJCWF0dHJEZWNsID0gYXR0ckRlY2wtPnJlZkRlY2w7CgkgICAgLyoKCSAgICAqIFBTVkk6IEFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB0byB0aGUgY3VycmVudCBlbGVtZW50LgoJICAgICovCgkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJCXhtbE5ld1Byb3AoZWxlbSwgYXR0ckRlY2wtPm5hbWUsIGN1clN0YXRlLT52YWx1ZSk7CgkgICAgfSBlbHNlIHsKCQl4bWxOc1B0ciBuczsKCQkKCQlucyA9IHhtbFNlYXJjaE5zQnlIcmVmKGVsZW0tPmRvYywgZWxlbSwgCgkJICAgIGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UpOwoJCWlmIChucyA9PSBOVUxMKSB7CgkJICAgIHhtbENoYXIgcHJlZml4WzEyXTsKCQkgICAgaW50IGNvdW50ZXIgPSAxOwoKCQkgICAgYXR0ciA9IGN1clN0YXRlLT5hdHRyOwoJCSAgICAvKgoJCSAgICAqIENyZWF0ZSBhIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiBvbiB0aGUgdmFsaWRhdGlvbiAKCQkgICAgKiByb290IG5vZGUgaWYgbm8gbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGlzIGluIHNjb3BlLgoJCSAgICAqLwkJICAgIAoJCSAgICBzbnByaW50ZigoY2hhciAqKSBwcmVmaXgsIHNpemVvZihwcmVmaXgpLCAicCIpOwoJCSAgICAvKgoJCSAgICAqIFRoaXMgaXMgc29tZWhvdyBub3QgcGVyZm9ybWFudCwgc2luY2UgdGhlIGFuY2VzdG9yIAoJCSAgICAqIGF4aXMgYmV5b25kIEBlbGVtIHdpbGwgYmUgc2VhcmNoZWQgYXMgd2VsbC4KCQkgICAgKi8KCQkgICAgbnMgPSB4bWxTZWFyY2hOcyhlbGVtLT5kb2MsIGVsZW0sIEJBRF9DQVNUIHByZWZpeCk7CgkJICAgIHdoaWxlIChucyAhPSBOVUxMKSB7CgkJCWlmIChjb3VudGVyID4gMTAwMCkgewoJCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzLCAiCgkJCQkiY291bGQgbm90IGNvbXB1dGUgYSBucyBwcmVmaXggZm9yICIKCQkJCSJkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZSAnJXMnLlxuIiwKCQkJCWF0dHJEZWNsLT5uYW1lLCBOVUxMKTsKCQkJICAgIAoJCQkgICAgYnJlYWs7CgkJCX0KCQkJc25wcmludGYoKGNoYXIgKikgcHJlZml4LCAKCQkJICAgIHNpemVvZihwcmVmaXgpLCAicCVkIiwgY291bnRlcisrKTsKCQkJbnMgPSB4bWxTZWFyY2hOcyhlbGVtLT5kb2MsIGVsZW0sIAoJCQkgICAgQkFEX0NBU1QgcHJlZml4KTsKCQkgICAgfQoJCSAgICBpZiAobnMgPT0gTlVMTCkgewoJCQlucyA9IHhtbE5ld05zKGN0eHQtPnZhbGlkYXRpb25Sb290LCAKCQkJICAgIGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UsIEJBRF9DQVNUIHByZWZpeCk7CgkJCXhtbE5ld05zUHJvcChlbGVtLCBucywgYXR0ckRlY2wtPm5hbWUsIAoJCQkgICAgY3VyU3RhdGUtPnZhbHVlKTsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHhtbE5ld05zUHJvcChlbGVtLCBucywgYXR0ckRlY2wtPm5hbWUsIAoJCQljdXJTdGF0ZS0+dmFsdWUpOwoJCX0KCSAgICB9CgkgICAgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChkZWZBdHRyU3RhdGVzICE9IE5VTEwpIAoJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhkZWZBdHRyU3RhdGVzKTsKCQkKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaWYgKHJlZHVuZGFudCkKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6IHJlZHVuZGFudCBjYWxsIGJ5IHR5cGU6ICVzXG4iLAoJICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUpOwojZW5kaWYKICAgIGN0eHQtPm5vZGUgPSBvbGRub2RlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICoKICogVmFsaWRhdGUgYW4gZWxlbWVudCBpbiBhIHRyZWUKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsgICAgCiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKiAKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQgYW5kCiAgICAqIHhtbFNjaGVtYVZhbGlkYXRlT25lRWxlbWVudC4KICAgICovICAKICAgIGlmIChjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoJLyoKCSogTm8gc2NoZW1hIHdhcyBzcGVjaWZpZWQgYXQgdGltZSBvZiBjcmVhdGlvbiBvZiB0aGUgdmFsaWRhdGlvbgoJKiBjb250ZXh0LiBVc2UgeHNpOnNjaGVtYUxvY2F0aW9uIGFuZCB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbgoJKiBvZiB0aGUgaW5zdGFuY2UgdG8gYnVpbGQgYSBzY2hlbWEuCgkqLwoJaWYgKGN0eHQtPnBjdHh0ID09IE5VTEwpIAoJICAgIGN0eHQtPnBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOwoJaWYgKGN0eHQtPnBjdHh0ID09IE5VTEwpCgkgICAgcmV0dXJuICgtMSk7CgljdHh0LT5zY2hlbWEgPSB4bWxTY2hlbWFOZXdTY2hlbWEoY3R4dC0+cGN0eHQpOwoJaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKQoJICAgIHJldHVybiAoLTEpOwoJLyogVE9ETzogYXNzaWduIHVzZXIgZGF0YS4gKi8KCWN0eHQtPnBjdHh0LT5lcnJvciA9IGN0eHQtPmVycm9yOwoJY3R4dC0+cGN0eHQtPndhcm5pbmcgPSBjdHh0LT53YXJuaW5nOwkKCWN0eHQtPnhzaUFzc2VtYmxlID0gMTsKICAgIH0gZWxzZQoJY3R4dC0+eHNpQXNzZW1ibGUgPSAwOwogICAgLyogY3R4dC0+b3B0aW9ucyB8PSBYTUxfU0NIRU1BX1ZBTF9WQ19JX0NSRUFURTsKICAgICogY3R4dC0+eHNpQXNzZW1ibGUgPSAxOwogICAgKi8KICAgIC8qCiAgICAqIEFzc2VtYmxlIG5ldyBzY2hlbWF0YSB1c2luZyB4c2kuCiAgICAqLwogICAgaWYgKGN0eHQtPnhzaUFzc2VtYmxlKSB7CQoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW0oY3R4dCwgY3R4dC0+bm9kZSk7CglpZiAocmV0ID09IC0xKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQljdHh0LT5ub2RlLCBOVUxMLCAJCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQsICIKCQkiYXNzZW1ibGluZyBzY2hlbWEgYnkgeHNpIiwgTlVMTCk7CSAgICAKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9CiAgICBpZiAocmV0ICE9IC0xKSB7CSAgICAKCWlmIChjdHh0LT5ub2RlLT5ucyAhPSBOVUxMKQoJICAgIGVsZW1EZWNsID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGN0eHQtPm5vZGUtPm5hbWUsIAoJCWN0eHQtPm5vZGUtPm5zLT5ocmVmKTsKCWVsc2UKCSAgICBlbGVtRGVjbCA9IHhtbFNjaGVtYUdldEVsZW0oY3R4dC0+c2NoZW1hLCBjdHh0LT5ub2RlLT5uYW1lLCBOVUxMKTsKCQoJaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwKCQljdHh0LT5ub2RlLCBOVUxMLCAJICAKCQkiTm8gbWF0Y2hpbmcgZ2xvYmFsIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIsIE5VTEwpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfMTsKCX0gZWxzZSB7IAoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZWxlbURlY2wpOyAgICAKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIGN0eHQtPm5vZGUsIE5VTEwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJICAgICJjYWxsaW5nIHZhbGlkYXRpb24gYnkgZGVjbGFyYXRpb24iLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9CiAgICAvKiBjdHh0LT54c2lBc3NlbWJsZSA9IDA7ICovCiAgICBpZiAoY3R4dC0+eHNpQXNzZW1ibGUpIHsKCWlmIChjdHh0LT5zY2hlbWEgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWUoY3R4dC0+c2NoZW1hKTsKCSAgICBjdHh0LT5zY2hlbWEgPSBOVUxMOwoJfQogICAgfQogICAgcmV0dXJuIChyZXQpOyAgIAp9CgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlT25lRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50IG5vZGUKICoKICogVmFsaWRhdGUgYSBicmFuY2ggb2YgYSB0cmVlLCBzdGFydGluZyB3aXRoIHRoZSBnaXZlbiBAZWxlbS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGFuZCBpdHMgc3VidHJlZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciAKICogY29kZSBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpIHx8IChlbGVtLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpKQoJcmV0dXJuICgtMSk7CgogICAgIGlmIChjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJBUEkgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlT25lRWxlbWVudCwgIgoJICAgICJubyBzY2hlbWEgc3BlY2lmaWVkLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBjdHh0LT5kb2MgPSBlbGVtLT5kb2M7CiAgICBjdHh0LT5lcnIgPSAwOwogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgY3R4dC0+bm9kZSA9IGVsZW07CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IGVsZW07CiAgICByZXR1cm4gKHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudChjdHh0KSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvY3VtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKiBAeHNpQXNzZW1ibGU6IHNob3VsZCBzY2hlbWF0YSBiZSBhZGRlZCBpZiByZXF1ZXN0ZWQgYnkgdGhlIGluc3RhbmNlPwogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgICAKICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVZfRE9DVU1FTlRfRUxFTUVOVF9NSVNTSU5HLAoJICAgICh4bWxOb2RlUHRyKSBkb2MsIE5VTEwsCgkgICAgIlRoZSBkb2N1bWVudCBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gICAgCiAgICAvKiBjdHh0LT5vcHRpb25zIHw9IFhNTF9TQ0hFTUFfVkFMX1hTSV9BU1NFTUJMRTsgKi8KICAgIC8qCiAgICAgKiBPa2F5LCBzdGFydCB0aGUgcmVjdXJzaXZlIHZhbGlkYXRpb24KICAgICAqLwogICAgY3R4dC0+bm9kZSA9IHJvb3Q7CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IHJvb3Q7CiAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoY3R4dCk7CgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEKICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsgICAgCiAgICByZXQtPmF0dHJUb3AgPSBOVUxMOwogICAgcmV0LT5hdHRyID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KGN0eHQtPnBjdHh0KTsKICAgIH0KICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRWYWxpZEVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBmdW5jdGlvbgogKiBAd2FybjogdGhlIHdhcm5pbmcgZnVuY3Rpb24KICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0CiAqCiAqIFNldCB0aGUgZXJyb3IgYW5kIHdhcm5pbmcgY2FsbGJhY2sgaW5mb3JtYXRpb25zCiAqLwp2b2lkCnhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKICAgIGlmIChjdHh0LT5wY3R4dCAhPSBOVUxMKQoJeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKGN0eHQtPnBjdHh0LCBlcnIsIHdhcm4sIGN0eCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRWYWxpZEVycm9yczoKICogQGN0eHQ6CWEgWE1MLVNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGZ1bmN0aW9uIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgZnVuY3Rpb24gcmVzdWx0CiAqIEBjdHg6IHRoZSBmdW5jdGlvbnMgY29udGV4dCByZXN1bHQKICoKICogR2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yIGFuZCAwIG90aGVyd2lzZQogKi8KaW50CnhtbFNjaGVtYUdldFZhbGlkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJCQl4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyAqIGVyciwKCQkJCQkJeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuICgtMSk7CglpZiAoZXJyICE9IE5VTEwpCgkJKmVyciA9IGN0eHQtPmVycm9yOwoJaWYgKHdhcm4gIT0gTlVMTCkKCQkqd2FybiA9IGN0eHQtPndhcm5pbmc7CglpZiAoY3R4ICE9IE5VTEwpCgkJKmN0eCA9IGN0eHQtPnVzZXJEYXRhOwoJcmV0dXJuICgwKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHRTZXRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvcHRpb25zOiBhIGNvbWJpbmF0aW9uIG9mIHhtbFNjaGVtYVZhbGlkT3B0aW9uCiAqCiAqIFNldHMgdGhlIG9wdGlvbnMgdG8gYmUgdXNlZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24uCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVNldFZhbGlkT3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJIGludCBvcHRpb25zKQoJCQkJCQp7CiAgICBpbnQgaTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBXQVJOSU5HOiBDaGFuZ2UgdGhlIHN0YXJ0IHZhbHVlIGlmIGFkZGluZyB0byB0aGUKICAgICogeG1sU2NoZW1hVmFsaWRPcHRpb24uCiAgICAqIFRPRE86IElzIHRoZXJlIGFuIG90aGVyLCBtb3JlIGVhc3kgdG8gbWFpbnRhaW4sCiAgICAqIHdheT8KICAgICovCiAgICBmb3IgKGkgPSAxOyBpIDwgKGludCkgc2l6ZW9mKGludCkgKiA4OyBpKyspIHsKICAgICAgICBpZiAob3B0aW9ucyAmIDE8PGkpIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFTZXRWYWxpZE9wdGlvbnMsICIKCQkiaW52YWxpZCBvcHRpb24gYXJndW1lbnQuXG4iLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsgICAKICAgICAgICB9CQogICAgfQogICAgY3R4dC0+b3B0aW9ucyA9IG9wdGlvbnM7CiAgICByZXR1cm4gKDApOyAgICAgIAp9CgovKioKICogeG1sU2NoZW1hR2V0VmFsaWRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0IAogKgogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb2YgdGhlIHZhbGlkYXRpb24gY29udGV4dC4KICovCmludAp4bWxTY2hlbWFWYWxpZEN0eHRHZXRPcHRpb25zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQoJCQkJCQp7ICAgIAogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZSAKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7ICAgIAp9CgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2MoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChkb2MgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgY3R4dC0+ZG9jID0gZG9jOwogICAgY3R4dC0+ZXJyID0gMDsgCiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICAKICAgIC8qCiAgICBpZiAoY3R4dC0+c2NoZW1hID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgTlVMTCwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiQVBJIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZURvYywgIgoJICAgICJubyBzY2hlbWEgc3BlY2lmaWVkIGFuZCBhc3NlbWJsaW5nIG9mIHNjaGVtYXRhICIKCSAgICAidXNpbmcgeHNpOnNjaGVtYUxvY2F0aW9uIGFuZCB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiAiCgkgICAgImlzIG5vdCBlbmFibGVkLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZURvY3VtZW50KGN0eHQsIGRvYyk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGlucHV0OiAgdGhlIGlucHV0IHRvIHVzZSBmb3IgcmVhZGluZyB0aGUgZGF0YQogKiBAZW5jOiAgYW4gb3B0aW9uYWwgZW5jb2RpbmcgaW5mb3JtYXRpb24KICogQHNheDogIGEgU0FYIGhhbmRsZXIgZm9yIHRoZSByZXN1bHRpbmcgZXZlbnRzCiAqIEB1c2VyX2RhdGE6ICB0aGUgY29udGV4dCB0byBwcm92aWRlIHRvIHRoZSBTQVggaGFuZGxlci4KICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dCwgeG1sQ2hhckVuY29kaW5nIGVuYywKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU0FYSGFuZGxlclB0ciBzYXgsIHZvaWQgKnVzZXJfZGF0YSkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChpbnB1dCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKICAgIGN0eHQtPmlucHV0ID0gaW5wdXQ7CiAgICBjdHh0LT5lbmMgPSBlbmM7CiAgICBjdHh0LT5zYXggPSBzYXg7CiAgICBjdHh0LT51c2VyX2RhdGEgPSB1c2VyX2RhdGE7CiAgICBUT0RPIHJldHVybiAoMCk7Cn0KCiNlbmRpZiAvKiBMSUJYTUxfU0NIRU1BU19FTkFCTEVEICovCg==