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+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8sIChyZXN0cmljdGlvbiB8IGV4dGVuc2lvbikpIik7CiAgICB9CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gb2xkUGFyZW50SXRlbTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4IFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICphdHRyVmFsdWU7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOyAvKiBUaGUgcmVwb3J0ZWQgZGVzaWduYXRpb24uICovCiAgICBjaGFyIGJ1Zls0MF07CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKCiAgICBpZiAodG9wTGV2ZWwpIHsKCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwoJaWYgKGF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCAKCQkoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNDVCwgTlVMTCwgbm9kZSwKCQkibmFtZSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9IGVsc2UgaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCAKCSAgICAoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNDVCwgTlVMTCwgYXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfQogICAgICAgICAgICAKICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CgkvKgoJKiBQYXJzZSBhcyBsb2NhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbi4KCSovCiAgICAgICAgc25wcmludGYoYnVmLCAzOSwgIiNDVCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CgluYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7CgkvKgoJKiBUT0RPOiBXZSBuZWVkIHRoZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8JCiAgICB9IGVsc2UgewkKCS8qCgkqIFBhcnNlIGFzIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbi4KCSovCQoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwkKCS8qIAoJKiBTZXQgZGVmYXVsdHMuCgkqLwoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9ERUZBVUxUOwoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9CTE9DS19ERUZBVUxUOwogICAgfSAKICAgIC8qCiAgICAqIEhhbmRsZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpIHsKCQkvKgoJCSogQXR0cmlidXRlICJpZCIuCgkJKi8KCQl0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgIm1peGVkIi4KCQkqLwoJCWlmICh4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZShjdHh0LCAmZGVzLCB0eXBlLCAKCQkgICAgKHhtbE5vZGVQdHIpIGF0dHIpKQoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOyAJCQoJICAgIH0gZWxzZSBpZiAodG9wTGV2ZWwpIHsJCQoJCS8qCgkJKiBBdHRyaWJ1dGVzIG9mIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbnMuCgkJKi8KCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgewoJCSAgICAvKiBQYXNzLiAqLwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImFic3RyYWN0Ii4KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsICZkZXMsIHR5cGUsIAoJCQkoeG1sTm9kZVB0cikgYXR0cikpCQkgICAgCgkJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1Q7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJCSAgICAqLwoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAKCQkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgCgkJCSYodHlwZS0+ZmxhZ3MpLCAKCQkJLTEsIAoJCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTiwgCgkJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04sIAoJCQktMSwgLTEsIC0xKSAhPSAwKSAKCQkgICAgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICAmZGVzLCB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCSAgICBOVUxMLCAKCQkJICAgICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLCAKCQkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIH0KCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJibG9jayIuCgkJICAgICovCQkJCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsIAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CSAgICAKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYodHlwZS0+ZmxhZ3MpLCAKCQkJLTEsCgkJCVhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OLCAKCQkJLTEsIC0xLCAtMSkgIT0gMCkgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJICAgICZkZXMsIHR5cGUsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQkgICAgTlVMTCwgCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpICIsIAoJCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkgICAgfQoJCX0gZWxzZSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkJICAgICZkZXMsIHR5cGUsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgewkgICAgCgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgICZkZXMsIHR5cGUsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJJmRlcywgdHlwZSwgYXR0cik7CQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9ICAgICAgIAogICAgLyogCiAgICAqIFNldCBhcyBkZWZhdWx0IGZvciBhdHRyaWJ1dGUgd2lsZGNhcmRzLgogICAgKiBUaGlzIHdpbGwgYmUgb25seSBjaGFuZ2VkIGlmIGEgY29tcGxleCB0eXBlCiAgICAqIGluaGVyaXRzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCBmcm9tIGEgYmFzZSB0eXBlLgogICAgKi8KICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7ICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZUNvbnRlbnQiKSkgewoJLyogCgkqIDMuNC4zIDogMi4yICAKCSogU3BlY2lmeWluZyBtaXhlZD0ndHJ1ZScgd2hlbiB0aGUgPHNpbXBsZUNvbnRlbnQ+CgkqIGFsdGVybmF0aXZlIGlzIGNob3NlbiBoYXMgbm8gZWZmZWN0CgkqLwoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCSAgICB0eXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOwogICAgICAgIHR5cGUtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhDb250ZW50IikpIHsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CgkvKgoJKiBQYXJzZSBtb2RlbCBncm91cHMuCgkqLwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJLyoKCSogUGFyc2UgYXR0cmlidXRlIGRlY2xzL3JlZnMuCgkqLwogICAgICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CSAgICAKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwgCgkgICAgJmRlcywgdHlwZSwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNpbXBsZUNvbnRlbnQgfCBjb21wbGV4Q29udGVudCB8ICIKCSAgICAiKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICgoYXR0cmlidXRlIHwgIgoJICAgICJhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpKSIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChkZXMpOwogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIGEgbm9kZSBzZXQKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZVNjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUHRyIHNjaGVtYSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVBhcnNlIG9ubHkgYW5kIGlzIHVzZWQgaWYKICAgICogdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgdGhlIEFQSTsgaS5lLiBub3QKICAgICogYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICBuYmVycm9ycyA9IGN0eHQtPm5iZXJyb3JzOwogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgaWYgKElTX1NDSEVNQShub2RlLCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7CgogICAgICAgIHNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0KTsKICAgICAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CgkvKgoJKiBEaXNhYmxlIGJ1aWxkIG9mIGxpc3Qgb2YgaXRlbXMuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsgCQkKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgTlVMTCwgTlVMTCwgYXR0ciwgCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgJnZhbCk7CgkgICAgLyoKCSAgICAqIFRPRE86IFNob3VsZCB3ZSBwcm9jZWVkIHdpdGggYW4gaW52YWxpZCB0YXJnZXQgbmFtZXNwYWNlPwoJICAgICovCgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwoJfSBlbHNlIHsKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IE5VTEw7Cgl9CgkvKgoJKiBBZGQgdGhlIGN1cnJlbnQgbnMgbmFtZSBhbmQgbG9jYXRpb24gdG8gdGhlIGltcG9ydCB0YWJsZTsKCSogdGhpcyBpcyBuZWVkZWQgdG8gaGF2ZSBhIGNvbnNpc3RlbnQgbWVjaGFuaXNtLCByZWdhcmRsZXNzCgkqIGlmIGFsbCBzY2hlbWF0YSBhcmUgY29uc3RydWN0ZWQgZHluYW1pY2FsbHkgZmlyZWQgYnkgdGhlCgkqIGluc3RhbmNlIG9yIGlmIHRoZSBzY2hlbWEgdG8gYmUgdXNlZCB3YXMgc3BlY2lmaWVkIHZpYQoJKiB0aGUgQVBJLgoJKi8KCWltcG9ydCA9IHhtbFNjaGVtYUFkZEltcG9ydChjdHh0LCAmKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMpLAoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCWlmIChpbXBvcnQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfRkFJTEVEX0JVSUxEX0lNUE9SVCwKCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VTY2hlbWEsICIKCQkiZmFpbGVkIHRvIGFkZCBhbiBpbXBvcnQgZW50cnkiLCBOVUxMKTsKCSAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CgkgICAgc2NoZW1hID0gTlVMTDsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiA9IGN0eHQtPlVSTDsKCS8qCgkqIE5PVEU6IFdlIHdvbid0IHNldCB0aGUgZG9jIGhlcmUsIG90aGVyd2lzZSBpdCB3aWxsIGJlIGZyZWVkCgkqIGlmIHRoZSBpbXBvcnQgc3RydWN0IGlzIGZyZWVkLgoJKiBpbXBvcnQtPmRvYyA9IGN0eHQtPmRvYzsKCSovCgoJLyogVE9ETzogQ2hlY2sgaWQuICovCiAgICAgICAgc2NoZW1hLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7Cgl4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAidmVyc2lvbiIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1RPS0VOKSwgJihzY2hlbWEtPnZlcnNpb24pKTsKCgl4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKGN0eHQsIHNjaGVtYSwgbm9kZSk7CQogICAgICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCBub2RlLT5jaGlsZHJlbik7CiAgICB9IGVsc2UgewogICAgICAgIHhtbERvY1B0ciBkb2M7CgoJZG9jID0gbm9kZS0+ZG9jOwoKICAgICAgICBpZiAoKGRvYyAhPSBOVUxMKSAmJiAoZG9jLT5VUkwgIT0gTlVMTCkpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiVGhlIGZpbGUgXCIlc1wiIGlzIG5vdCBhIFhNTCBzY2hlbWEuXG4iLCBkb2MtPlVSTCwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJCSAgICAgICJUaGUgZmlsZSBpcyBub3QgYSBYTUwgc2NoZW1hLlxuIiwgTlVMTCwgTlVMTCk7Cgl9CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CiAgICAgICAgICAgIHNjaGVtYSA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgaWYgKHNjaGVtYSAhPSBOVUxMKQoJc2NoZW1hLT5jb3VudGVyID0gY3R4dC0+Y291bnRlcjsKICAgIGN0eHQtPm5iZXJyb3JzID0gbmJlcnJvcnM7CiNpZmRlZiBERUJVRwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2UoKSBmYWlsZWRcbiIpOwojZW5kaWYKICAgIHJldHVybiAoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpbmcgdXNpbmcgU2NoZW1hcwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVJlYWRpbmcvV3JpdGluZyBTY2hlbWFzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAgLyogV2lsbCBiZSBlbmFibGVkIGlmIGl0IGlzIGNsZWFyIHdoYXQgb3B0aW9ucyBhcmUgbmVlZGVkLiAqLwovKioKICogeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFQYXJzZXJPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgcGFyc2UuCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgIGludCBvcHRpb25zKQoJCQkJCQp7CiAgICBpbnQgaTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBXQVJOSU5HOiBDaGFuZ2UgdGhlIHN0YXJ0IHZhbHVlIGlmIGFkZGluZyB0byB0aGUKICAgICogeG1sU2NoZW1hUGFyc2VPcHRpb24uCiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgcmV0dXJuICgtMSk7ICAgCiAgICAgICAgfQkKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OiBhIHNjaGVtYSBwYXJzZXIgY29udGV4dCAKICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9mIHRoZSBwYXJzZXIgY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQoJCQkJCQp7ICAgIAogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZSAKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7ICAgIAp9Cgogdm9pZCAqY3VySXRlbXM7ICAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgbmJDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IHNpemVDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwoKI2VuZGlmCgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dChjb25zdCBjaGFyICpVUkwpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoY29uc3QgY2hhciAqVVJMLCB4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwogICAgLyoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoJKi8KCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZGljdCA9IGRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKGRpY3QpOyAgICAKICAgIGlmIChVUkwgIT0gTlVMTCkKCXJldC0+VVJMID0geG1sRGljdExvb2t1cChkaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldC0+aW5jbHVkZXMgPSAwOwogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0OgogKiBAZG9jOiAgYSBwcmVwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBkb2N1bWVudC4KICogTkIuIFRoZSBkb2N1bWVudCBtYXkgYmUgbW9kaWZpZWQgZHVyaW5nIHRoZSBwYXJzaW5nIHByb2Nlc3MuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0KHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChkb2MgPT0gTlVMTCkKICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAoJCQkgIE5VTEwpOwogICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgLyogVGhlIGFwcGxpY2F0aW9uIGhhcyByZXNwb25zaWJpbGl0eSBmb3IgdGhlIGRvY3VtZW50ICovCiAgICByZXQtPnByZXNlcnZlID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5kb2MgIT0gTlVMTCAmJiAhY3R4dC0+cHJlc2VydmUpCiAgICAgICAgeG1sRnJlZURvYyhjdHh0LT5kb2MpOwogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpIHsKCXhtbEZyZWUoKHhtbFNjaGVtYVR5cGVQdHIgKikgY3R4dC0+YXNzZW1ibGUtPml0ZW1zKTsKCXhtbEZyZWUoY3R4dC0+YXNzZW1ibGUpOwogICAgfQogICAgaWYgKGN0eHQtPnZjdHh0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWxpZEN0eHQoY3R4dC0+dmN0eHQpOwogICAgfQogICAgeG1sRGljdEZyZWUoY3R4dC0+ZGljdCk7CiAgICB4bWxGcmVlKGN0eHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKgkJCUJ1aWxkaW5nIHRoZSBjb250ZW50IG1vZGVscwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsOgogKiBAdHlwZTogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUgd2hvc2UgY29udGVudCBpcyBiZWluZyBidWlsdAogKgogKiBHZW5lcmF0ZSB0aGUgYXV0b21hdGEgc2VxdWVuY2UgbmVlZGVkIGZvciB0aGF0IHR5cGUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgdW5leHBlY3RlZCB0eXBlID0gTlVMTCBpbiAlcyBjb250ZW50IG1vZGVsXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogeyAgIAoJICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkOwkgICAgCgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsKCgkgICAgd2lsZCA9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoKCSAgICBpZiAod2lsZCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwsICIKCQkgICAgIm5vIHdpbGRjYXJkIG9uIHhzZDphbnkuXG4iLCBOVUxMLCBOVUxMKTsKCQlyZXR1cm47CgkgICAgfQkgICAgIAoJICAgIAoJICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CgkgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkgICAgCgkgICAgaWYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSB7CQkKCQlpZiAod2lsZC0+YW55ID09IDEpIHsKCQkgICAgLyoKCQkgICAgKiBXZSBuZWVkIHRvIGFkZCBib3RoIHRyYW5zaXRpb25zOgoJCSAgICAqCgkJICAgICogMS4gdGhlIHsiKiIsICIqIn0gZm9yIGVsZW1lbnRzIGluIGEgbmFtZXNwYWNlLgoJCSAgICAqLwkJICAgIAoJCSAgICBjdHh0LT5zdGF0ZSA9IAoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBlbmQpOwoJCSAgICAvKgoJCSAgICAqIDIuIHRoZSB7IioifSBmb3IgZWxlbWVudHMgaW4gbm8gbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBjdHh0LT5zdGF0ZSA9IAoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIG5zID0gd2lsZC0+bnNTZXQ7CgkJICAgIGRvIHsKCQkJY3R4dC0+c3RhdGUgPSBzdGFydDsKCQkJY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkgICAgY3R4dC0+c3RhdGUsIE5VTEwsIEJBRF9DQVNUICIqIiwgbnMtPnZhbHVlLCB0eXBlKTsKCQkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGRlYWRFbmQ7CgoJCSAgICBkZWFkRW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIGRlYWRFbmQsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLCB0eXBlKTsKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBlbmQpOwoJCX0JCQoJICAgIH0gZWxzZSB7CgkJaW50IGNvdW50ZXI7CgkJeG1sQXV0b21hdGFTdGF0ZVB0ciBob3A7CgkJaW50IG1heE9jY3VycyA9IAoJCSAgICB0eXBlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8gVU5CT1VOREVEIDogdHlwZS0+bWF4T2NjdXJzIC0gMTsKCQlpbnQgbWluT2NjdXJzID0KCQkgICAgdHlwZS0+bWluT2NjdXJzIDwgMSA/IDAgOiB0eXBlLT5taW5PY2N1cnMgLSAxOwoJCQoJCWNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCQlob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsJCQoJCWlmICh3aWxkLT5hbnkgPT0gMSkgewkJICAgIAoJCSAgICBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIEJBRF9DQVNUICIqIiwgdHlwZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CgkJICAgIGN0eHQtPnN0YXRlID0gCgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIE5VTEwsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewkJICAgIAoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCWN0eHQtPnN0YXRlID0gCgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgbnMtPnZhbHVlLCB0eXBlKTsKCQkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGRlYWRFbmQ7CgoJCSAgICBkZWFkRW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIGRlYWRFbmQsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLCB0eXBlKTsKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCX0JCgkJeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIGhvcCwgc3RhcnQsIGNvdW50ZXIpOwoJCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwgY291bnRlcik7CgkgICAgfQoJICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewoJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CgkgICAgfQkgICAgCSAgICAJCQkJICAgICAgICAgICAgCgkgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6ewoJCXhtbEF1dG9tYXRhU3RhdGVQdHIgb2xkc3RhdGU7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHBhcnRpY2xlLCBlbGVtRGVjbDsKCgkJLyoKCQkqIElNUE9SVEFOVDogVGhpcyBwdXRzIGVsZW1lbnQgZGVjbGFyYXRpb25zCgkJKiAoYW5kIG5ldmVyIGVsZW1lbnQgZGVjbC4gcmVmZXJlbmNlcykgaW50byB0aGUKCQkqIGF1dG9tYXRvbi4gVGhpcyBpcyBjcnVjaWFsIGFuZCBzaG91bGQgbm90IGJlIGNoYW5nZWQsIAoJCSogc2luY2UgdmFsaWRhdGluZyBmdW5jdGlvbnMgcmVseSBub3cgb24gaXQuCgkJKi8KCQlwYXJ0aWNsZSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlOwoJCWlmIChwYXJ0aWNsZS0+cmVmICE9IE5VTEwpIHsKCQkgICAgaWYgKHBhcnRpY2xlLT5yZWZEZWNsID09IE5VTEwpIHsKCQkJLyoKCQkJKiBTa2lwIGNvbnRlbnQgbW9kZWwgY3JlYXRpb24gaWYgdGhlIHJlZmVyZW5jZQoJCQkqIGRpZCBub3QgcmVzb2x2ZSB0byBhIGRlY2xhcmF0aW9uLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBSZWZlcmVuY2VkIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uLgoJCQkqLwoJCQllbGVtRGVjbCA9IHBhcnRpY2xlLT5yZWZEZWNsOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBBbm9ueW1vdXMgZWxlbWVudCBkZWNsYXJhdGlvbi4KCQkgICAgKi8KCQkgICAgZWxlbURlY2wgPSBwYXJ0aWNsZTsKCQl9CgkJCiAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkgewogICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKCQkJICAgIG9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKCQkJICAgIHBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLCBVTkJPVU5ERUQpOyAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQkJICAgIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCQljdHh0LT5zdGF0ZSwgTlVMTCwgCgkJCQllbGVtRGVjbC0+bmFtZSwgCgkJCQllbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsIG9sZHN0YXRlLAoJCQkgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsIE5VTEwsCgkJCQljb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAKCQkJY3R4dC0+c3RhdGUgPQoJCQkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJICAgIGN0eHQtPnN0YXRlLCBOVUxMLAoJCQkgICAgZWxlbURlY2wtPm5hbWUsIAoJCQkgICAgZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJICAgICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtKiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChwYXJ0aWNsZS0+bWF4T2NjdXJzID4gMSkgfHwgKHBhcnRpY2xlLT5taW5PY2N1cnMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAoJCQlwYXJ0aWNsZS0+bWluT2NjdXJzIC0gMSwKCQkJcGFydGljbGUtPm1heE9jY3VycyAtIDEpOwogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJY3R4dC0+c3RhdGUsCgkJCU5VTEwsCgkJCWVsZW1EZWNsLT5uYW1lLAoJCQllbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wpOwogICAgICAgICAgICAgICAgICAgIHRtcCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsIG9sZHN0YXRlLAoJCQljb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsCgkJCU5VTEwsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IGFuIGVsZW0/ICovCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCgkJCSAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQljdHh0LT5zdGF0ZSwKCQkJTlVMTCwKCQkJZWxlbURlY2wtPm5hbWUsCgkJCWVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgYW4gZWxlbT8gKi8KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKCQkJICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIG1heCBhbmQgbWluIG9jY3VyYW5jZXMgYXJlIGRlZmF1bHQgKDEpIHRoZW4KICAgICAgICAgICAgICAgICAqIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgodHlwZS0+bWluT2NjdXJzID09IDEpICYmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbk9jY3VycyAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVOQk9VTkRFRCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0eXBlLT5tYXhPY2N1cnMgPiAxKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGUtPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1pbk9jY3VycyAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5tYXhPY2N1cnMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGVzOwogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaXRlcmF0ZSBvdmVyIHRoZSBzdWJ0eXBlcyBhbmQgcmVtZXJnZSB0aGUgZW5kIHdpdGggYW4KICAgICAgICAgICAgICAgICAqIGVwc2lsb24gdHJhbnNpdGlvbgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWF4T2NjdXJzID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4T2NjdXJzID0gdHlwZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CiAgICAgICAgICAgICAgICAgICAgICAgIFVOQk9VTkRFRCA6IHR5cGUtPm1heE9jY3VycyAtIDE7CiAgICAgICAgICAgICAgICAgICAgaW50IG1pbk9jY3VycyA9CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1pbk9jY3VycyA8IDEgPyAwIDogdHlwZS0+bWluT2NjdXJzIC0gMTsKCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiB1c2UgYSBjb3VudGVyIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB0cmFuc3Rpb25zCiAgICAgICAgICAgICAgICAgICAgICogd2hpY2ggd2VudCB0aHJvdWdoIHRoZSBjaG9pY2UuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY291bnRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwgbWluT2NjdXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4T2NjdXJzKTsKICAgICAgICAgICAgICAgICAgICBob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgaG9wLCBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgaG9wLCBlbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDp7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCgkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtOwogICAgICAgICAgICAgICAgaW50IGxheDsKCiAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgaWYgKHN1YnR5cGVzID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoJCSAgICAvKgoJCSAgICAgKiB0aGUgZm9sbG93aW5nICdpZicgd2FzIG5lZWRlZCB0byBmaXggYnVnIDEzOTg5NwoJCSAgICAgKiBub3QgcXVpdGUgc3VyZSB3aHkgaXQgb25seSBuZWVkcyB0byBiZSBkb25lIGZvcgoJCSAgICAgKiBlbGVtZW50cyB3aXRoIGEgJ3JlZicsIGJ1dCBpdCBzZWVtcyB0byB3b3JrIG9rLgoJCSAgICAgKi8KCQkgICAgaWYgKHN1YnR5cGVzLT5yZWYgIT0gTlVMTCkKCQkgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBzdWJ0eXBlczsJCSAgCgkJICAgIC8qCgkJICAgICogTk9URTogVGhlIHttYXggb2NjdXJzfSBvZiBhbGwgdGhlIHBhcnRpY2xlcyBpbiB0aGUgCgkJICAgICoge3BhcnRpY2xlc30gb2YgdGhlIGdyb3VwIG11c3QgYmUgMCBvciAxLgoJCSAgICAqLyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKChlbGVtLT5taW5PY2N1cnMgPT0gMSkgJiYgKGVsZW0tPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld09uY2VUcmFuczIoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgCgkJCQkJCWVsZW0tPm5hbWUsIAoJCQkJCQllbGVtLT50YXJnZXROYW1lc3BhY2UsCgkJCQkJCTEsIDEsIHN1YnR5cGVzKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChlbGVtLT5taW5PY2N1cnMgPT0gMCkgJiYKCQkJKGVsZW0tPm1heE9jY3VycyA9PSAxKSkgewoJCQkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudFRyYW5zMihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgCgkJCQkJCSBlbGVtLT5uYW1lLAoJCQkJCQkgZWxlbS0+dGFyZ2V0TmFtZXNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfQoJCSAgICAvKgoJCSAgICAqIE5PVEU6IGlmIG1heE9jY3VycyA9PSAwIHRoZW4gbm8gdHJhbnNpdGlvbiB3aWxsIGJlCgkJICAgICogY3JlYXRlZC4KCQkgICAgKi8KICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGF4ID0gdHlwZS0+bWluT2NjdXJzID09IDA7CiAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdBbGxUcmFucyhjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXgpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKICAgICAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZS0+c3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CiAgICAgICAgICAgIGlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGVzOwoJCQoJCS8qCgkJKiBUT0RPOiBDaXJjdWxhciBkZWZpbml0aW9ucyB3aWxsIGJlIGNoZWNrZWQgYXQgdGhlCgkJKiBjb25zdHJhaW50IGxldmVsLiBTbyByZW1vdmUgdGhpcyB3aGVuIHRoZSBjb21wbGV4IHR5cGUKCQkqIGNvbnN0cmFpbnRzIGFyZSBpbXBsZW1lbnRlZC4KCQkqLwoJCWlmICh0eXBlLT5yZWN1cnNlKSB7IAoJCSAgICAvKiBUT0RPOiBDaGFuZ2UgdGhlIGVycm9yIGNvZGUuICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLAoJCQkgICAgTlVMTCwgdHlwZSwgdHlwZS0+bm9kZSwJCgkJCSAgICAiVGhpcyBpdGVtIGlzIGNpcmN1bGFyIiwgTlVMTCk7CQkgICAgIAoJCSAgICByZXR1cm47IAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdHlwZS0+cmVjdXJzZSA9IDE7IAogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPmJhc2VUeXBlLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgCXR5cGUtPnJlY3Vyc2UgPSAwOwogICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZS0+c3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICAvKgoJICAgICogSGFuZGxlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlcy4gCgkgICAgKiBOT1RFOiB0eXBlLT5zdWJ0eXBlcyBpcyB0aGUgcmVmZXJlbmNlZCBtb2RlbCBncm9wIGRlZmluaXRpb247CgkgICAgKiBhbmQgdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzIGlzIHRoZSBtb2RlbCBncm91cCAoaS5lLiA8YWxsPiBvciAKCSAgICAqIDxjaG9pY2U+IG9yIDxzZXF1ZW5jZT4pLgoJICAgICovCgkgICAgaWYgKCh0eXBlLT5yZWYgIT0gTlVMTCkgJiYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyAhPSBOVUxMKSkgewoJCXhtbFNjaGVtYVR5cGVQdHIgbW9kZWxHcjsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCgkJbW9kZWxHciA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsJCQogICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSB7CgkJICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CgkJICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChtb2RlbEdyLCBjdHh0LCBuYW1lKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBob3A7CiAgICAgICAgICAgICAgICAgICAgaW50IG1heE9jY3VycyA9IHR5cGUtPm1heE9jY3VycyA9PSBVTkJPVU5ERUQgPwoJCQkJICAgIFVOQk9VTkRFRCA6IHR5cGUtPm1heE9jY3VycyAtIDE7CiAgICAgICAgICAgICAgICAgICAgaW50IG1pbk9jY3VycyA9CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1pbk9jY3VycyA8IDEgPyAwIDogdHlwZS0+bWluT2NjdXJzIC0gMTsKCQkgICAgCiAgICAgICAgICAgICAgICAgICAgY291bnRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOwogICAgICAgICAgICAgICAgICAgIGhvcCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwkJICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwobW9kZWxHciwgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgaG9wLCBzdGFydCwKCQkJY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIGhvcCwgZW5kLAoJCQljb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgIH0KCSAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDoKICAgICAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZS0+c3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOgoJICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZvdW5kIHVuZXhwZWN0ZWQgdHlwZSAlZCBpbiAlcyBjb250ZW50IG1vZGVsXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHlwZSwgbmFtZSk7CiAgICAgICAgICAgIHJldHVybjsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsOgogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24gKG9yIHJlZmVyZW5jZSkKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKgogKiBCdWlsZHMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIGNvbXBsZXggdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKCiAgICBpZiAoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8ICh0eXBlLT5yZWYgIT0gTlVMTCkgfHwKCSh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpIHx8CgkodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwKCSh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkpCglyZXR1cm47CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgIkJ1aWxkaW5nIGNvbnRlbnQgbW9kZWwgZm9yICVzXG4iLCBuYW1lKTsKI2VuZGlmCgogICAgY3R4dC0+YW0gPSB4bWxOZXdBdXRvbWF0YSgpOwogICAgaWYgKGN0eHQtPmFtID09IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBjcmVhdGUgYXV0b21hdGEgZm9yIGNvbXBsZXggdHB5ZSAlc1xuIiwgbmFtZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3RhcnQgPSBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhR2V0SW5pdFN0YXRlKGN0eHQtPmFtKTsKICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh0eXBlLCBjdHh0LCBuYW1lKTsKICAgIHhtbEF1dG9tYXRhU2V0RmluYWxTdGF0ZShjdHh0LT5hbSwgY3R4dC0+c3RhdGUpOwogICAgdHlwZS0+Y29udE1vZGVsID0geG1sQXV0b21hdGFDb21waWxlKGN0eHQtPmFtKTsKICAgIGlmICh0eXBlLT5jb250TW9kZWwgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsIAoJICAgIE5VTEwsIHR5cGUsIHR5cGUtPm5vZGUsCSAgICAKCSAgICAiRmFpbGVkIHRvIGNvbXBpbGUgdGhlIGNvbnRlbnQgbW9kZWwiLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAoeG1sUmVnZXhwSXNEZXRlcm1pbmlzdCh0eXBlLT5jb250TW9kZWwpICE9IDEpIHsKICAgICAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX05PVF9ERVRFUk1JTklTVElDLAoJICAgIC8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RERVRFUk1JTklTVCwgKi8KCSAgICBOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLAoJICAgICJUaGUgY29udGVudCBtb2RlbCBpcyBub3QgZGV0ZXJtaW5pc3QiLCBOVUxMKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBERUJVR19DT05URU5UX1JFR0VYUAogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudCBtb2RlbCBvZiAlczpcbiIsIG5hbWUpOwogICAgICAgIHhtbFJlZ2V4cFByaW50KHN0ZGVyciwgdHlwZS0+Y29udE1vZGVsKTsKI2VuZGlmCiAgICB9CiAgICBjdHh0LT5zdGF0ZSA9IE5VTEw7CiAgICB4bWxGcmVlQXV0b21hdGEoY3R4dC0+YW0pOwogICAgY3R4dC0+YW0gPSBOVUxMOwp9CgovKioKICogeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjazoKICogQGVsZW06ICB0aGUgc2NoZW1hIGVsZW1lbnQgY29udGV4dAogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogUmVzb2x2ZXMgdGhlIHJlZmVyZW5jZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbgogKiBvciBwYXJ0aWNsZSwgd2hpY2ggaGFzIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gYXMgaXQncwogKiB0ZXJtLiAKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2soeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkgfHwgCgkoKGVsZW0gIT0gTlVMTCkgJiYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9JTlRFUk5BTF9SRVNPTFZFRCkpKQogICAgICAgIHJldHVybjsKICAgIGVsZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fSU5URVJOQUxfUkVTT0xWRUQ7CiAgICBpZiAoZWxlbS0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOwoKCS8qCgkqIFRPRE86IEV2YWx1YXRlLCB3aGF0IGVycm9ycyBjb3VsZCBvY2N1ciBpZiB0aGUgZGVjbGFyYXRpb24gaXMgbm90CgkqIGZvdW5kLiBJdCBtaWdodCBiZSBwb3NzaWJsZSB0aGF0IHRoZSAidHlwZWZpeHVwIiBtaWdodCBjcmFzaCBpZgoJKiBubyByZWYgZGVjbGFyYXRpb24gd2FzIGZvdW5kLgoJKi8KICAgICAgICBlbGVtRGVjbCA9IHhtbFNjaGVtYUdldEVsZW0oY3R4dC0+c2NoZW1hLCBlbGVtLT5yZWYsIGVsZW0tPnJlZk5zKTsKICAgICAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewkgIAoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtLCBlbGVtLT5ub2RlLAoJCSJyZWYiLCBlbGVtLT5yZWYsIGVsZW0tPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCwgTlVMTCk7CiAgICAgICAgfSBlbHNlCgkgICAgZWxlbS0+cmVmRGVjbCA9IGVsZW1EZWNsOwkKICAgIH0gZWxzZSB7CQoJaWYgKChlbGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAoZWxlbS0+bmFtZWRUeXBlICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoJICAgIAoJICAgIC8qICh0eXBlIGRlZmluaXRpb24pIC4uLiBvdGhlcndpc2UgdGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IAoJICAgICogdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlIFthdHRyaWJ1dGVdIC4uLgoJICAgICovCSAgICAJICAgIAoJICAgIHR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgZWxlbS0+bmFtZWRUeXBlLAoJCWVsZW0tPm5hbWVkVHlwZU5zKTsJICAgIAoJICAgIGlmICh0eXBlID09IE5VTEwpIHsJCgkJeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbSwgZWxlbS0+bm9kZSwKCQkgICAgInR5cGUiLCBlbGVtLT5uYW1lZFR5cGUsIGVsZW0tPm5hbWVkVHlwZU5zLAoJCSAgICBYTUxfU0NIRU1BX1RZUEVfQkFTSUMsICJ0eXBlIGRlZmluaXRpb24iKTsKCSAgICB9IGVsc2UKCQllbGVtLT5zdWJ0eXBlcyA9IHR5cGU7Cgl9CglpZiAoZWxlbS0+c3Vic3RHcm91cCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBzdWJzdEhlYWQ7CgkgICAgCgkgICAgLyoKCSAgICAqIEZJWE1FIFRPRE86IERvIHdlIG5lZWQgYSBuZXcgZmllbGQgaW4gX3htbFNjaGVtYUVsZW1lbnQgZm9yIAoJICAgICogc3Vic3RpdHV0aW9uR3JvdXA/CgkgICAgKi8KCSAgICBzdWJzdEhlYWQgPSB4bWxTY2hlbWFHZXRFbGVtKGN0eHQtPnNjaGVtYSwgZWxlbS0+c3Vic3RHcm91cCwgCgkJZWxlbS0+c3Vic3RHcm91cE5zKTsJICAgIAoJICAgIGlmIChzdWJzdEhlYWQgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW0sIE5VTEwsCgkJICAgICJzdWJzdGl0dXRpb25Hcm91cCIsIGVsZW0tPnN1YnN0R3JvdXAsIGVsZW0tPnN1YnN0R3JvdXBOcywKCQkgICAgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjayhzdWJzdEhlYWQsIGN0eHQsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCS8qCgkJKiAodHlwZSBkZWZpbml0aW9uKS4uLm90aGVyd2lzZSB0aGUge3R5cGUgZGVmaW5pdGlvbn0gb2YgdGhlIAoJCSogZWxlbWVudCBkZWNsYXJhdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiAKCQkqIHRoZSBzdWJzdGl0dXRpb25Hcm91cCBbYXR0cmlidXRlXSwgaWYgcHJlc2VudAoJCSovCgkJaWYgKGVsZW0tPnN1YnR5cGVzID09IE5VTEwpIAoJCSAgICBlbGVtLT5zdWJ0eXBlcyA9IHN1YnN0SGVhZC0+c3VidHlwZXM7CgkgICAgfQoJfQoJaWYgKChlbGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAoZWxlbS0+bmFtZWRUeXBlID09IE5VTEwpICYmCgkgICAgKGVsZW0tPnN1YnN0R3JvdXAgPT0gTlVMTCkpCgkgICAgZWxlbS0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxpc3RSZWZGaXh1cDoKICogQHR5cGU6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4dXAgb2YgdGhlIGl0ZW1UeXBlIHJlZmVyZW5jZSBvZiB0aGUgbGlzdCB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsgICAgCiAgICAKICAgIGlmICgoKHR5cGUtPmJhc2UgPT0gTlVMTCkgJiYgCgkgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpKSB8fAoJKCh0eXBlLT5iYXNlICE9IE5VTEwpICYmCgkgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpKSkgewkKCS8qCgkqIHNyYy1saXN0LWl0ZW1UeXBlLW9yLXNpbXBsZVR5cGUKCSogRWl0aGVyIHRoZSBpdGVtVHlwZSBbYXR0cmlidXRlXSBvciB0aGUgPHNpbXBsZVR5cGU+IFtjaGlsZF0gb2YgCgkqIHRoZSA8bGlzdD4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4gCgkqLwoJLyoKCSogVE9ETzogTW92ZSB0aGlzIHRvIHRoZSBwYXJzZSBmdW5jdGlvbi4KCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0xJU1RfSVRFTVRZUEVfT1JfU0lNUExFVFlQRSwKCSAgICBOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLCAKCSAgICAiVGhlIGF0dHJpYnV0ZSAnaXRlbVR5cGUnIGFuZCB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCSAgICAiYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwkKICAgIH0gZWxzZSBpZiAodHlwZS0+YmFzZSE9IE5VTEwpIHsgICAgICAgIAkKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCB0eXBlLT5iYXNlLCB0eXBlLT5iYXNlTnMpOwogICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCSAgICAKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCB0eXBlLCB0eXBlLT5ub2RlLAoJCSJpdGVtVHlwZSIsIHR5cGUtPmJhc2UsIHR5cGUtPmJhc2VOcywKCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFLCBOVUxMKTsKICAgICAgICB9CiAgICB9ICAgICAgICAgICAgICAgCiAgICBpZiAoKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpICYmIAoJKHR5cGUtPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpCgl4bWxTY2hlbWFUeXBlRml4dXAodHlwZS0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIGFuZCBidWlsZHMgdGhlIG1lbWJlclR5cGVzIG9mIHRoZSB1bmlvbiB0eXBlLgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2soeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICAKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmssIGxhc3RMaW5rID0gTlVMTCwgcHJldkxpbmssIHN1YkxpbmssIG5ld0xpbms7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG1lbWJlclR5cGUsIGN0eHRUeXBlOwoKICAgIC8qIDEgSWYgdGhlIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIFtEZWZpbml0aW9uOl0gIAogICAgKiBkZWZpbmUgdGhlIGV4cGxpY2l0IG1lbWJlcnMgYXMgdGhlIHR5cGUgZGVmaW5pdGlvbnMgt3Jlc29sdmVktyAKICAgICogdG8gYnkgdGhlIGl0ZW1zIGluIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0sIAogICAgKiBpZiBhbnksIGZvbGxvd2VkIGJ5IHRoZSB0eXBlIGRlZmluaXRpb25zIGNvcnJlc3BvbmRpbmcgdG8gdGhlIAogICAgKiA8c2ltcGxlVHlwZT5zIGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDx1bmlvbj4sIGlmIGFueS4gCiAgICAqLyAgIAoKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9VTklPTikKICAgICAgICByZXR1cm4gKC0xKTsKICAgIGlmIChjdHh0LT5jdHh0VHlwZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2ssIG5vIHBhcmVudCB0eXBlICIKCSAgICAiYXZhaWxhYmxlIiwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcwogICAgKiBFaXRoZXIgdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIG9mIHRoZSA8dW5pb24+IGVsZW1lbnQgbXVzdCAKICAgICogYmUgbm9uLWVtcHR5IG9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIHNpbXBsZVR5cGUgW2NoaWxkXS4gCiAgICAqLwogICAgaWYgKCh0eXBlLT5iYXNlID09IE5VTEwpICYmIAoJKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19VTklPTl9NRU1CRVJUWVBFU19PUl9TSU1QTEVUWVBFUywKCSAgICBOVUxMLCBOVUxMLCB0eXBlLT5ub2RlLAkKCSAgICAiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ21lbWJlclR5cGVzJyBtdXN0IGJlIG5vbi1lbXB0eSAiCgkgICAgIm9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIDxzaW1wbGVUeXBlPiBjaGlsZCIsIE5VTEwpOwogICAgfSAKCQogICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCXhtbEF0dHJQdHIgYXR0cjsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcDsKCWNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSwgKnVyaTsKCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUodHlwZS0+bm9kZSwgIm1lbWJlclR5cGVzIik7CgljdXIgPSB0eXBlLT5iYXNlOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZShjdHh0LCBjdHh0LT5zY2hlbWEsIE5VTEwsIAoJCU5VTEwsIGF0dHIsIEJBRF9DQVNUIHRtcCwgJnVyaSwgTlVMTCwgJmxvY2FsTmFtZSk7CSAgIAoJICAgIG1lbWJlclR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbG9jYWxOYW1lLCB1cmkpOwoJICAgIGlmIChtZW1iZXJUeXBlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9NRU1CRVJfVFlQRSwKCQkgICAgTlVMTCwgTlVMTCwgdHlwZS0+bm9kZSwgIm1lbWJlclR5cGVzIiwgbG9jYWxOYW1lLCB1cmksCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJaWYgKG1lbWJlclR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSAKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKG1lbWJlclR5cGUsIGN0eHQsIE5VTEwpOwkgICAgCgkJbGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJCWlmIChsaW5rID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CgkJbGluay0+bmV4dCA9IE5VTEw7CgkJaWYgKGxhc3RMaW5rID09IE5VTEwpCgkJICAgIGN0eHRUeXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CQkgICAgCgkJZWxzZSAKCQkgICAgbGFzdExpbmstPm5leHQgPSBsaW5rOwoJCWxhc3RMaW5rID0gbGluazsJICAgIAoJICAgIH0KCSAgICB4bWxGcmVlKHRtcCk7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsgCiAgICB9CiAgICAvKgogICAgKiBBZGQgbG9jYWwgc2ltcGxlIHR5cGVzLAogICAgKi8gICAgCiAgICBtZW1iZXJUeXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICB3aGlsZSAobWVtYmVyVHlwZSAhPSBOVUxMKSB7CglpZiAobWVtYmVyVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pCgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKG1lbWJlclR5cGUsIGN0eHQsIE5VTEwpOwkgICAgCglsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CglsaW5rLT5uZXh0ID0gTlVMTDsKCWlmIChsYXN0TGluayA9PSBOVUxMKQoJICAgIGN0eHRUeXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CQkgICAgCgllbHNlIAoJICAgIGxhc3RMaW5rLT5uZXh0ID0gbGluazsKCWxhc3RMaW5rID0gbGluazsKCW1lbWJlclR5cGUgPSBtZW1iZXJUeXBlLT5uZXh0OwogICAgfSAgICAKICAgIC8qCiAgICAqIFRoZSBhY3R1YWwgdmFsdWUgaXMgdGhlbiBmb3JtZWQgYnkgcmVwbGFjaW5nIGFueSB1bmlvbiB0eXBlIAogICAgKiBkZWZpbml0aW9uIGluIHRoZSC3ZXhwbGljaXQgbWVtYmVyc7cgd2l0aCB0aGUgbWVtYmVycyBvZiB0aGVpciAKICAgICoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIuCiAgICAqLwogICAgbGluayA9IGN0eHRUeXBlLT5tZW1iZXJUeXBlczsKICAgIHdoaWxlIChsaW5rICE9IE5VTEwpIHsKCWlmIChsaW5rLT50eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJICAgIHN1YkxpbmsgPSBsaW5rLT50eXBlLT5tZW1iZXJUeXBlczsJICAgIAoJICAgIGlmIChzdWJMaW5rICE9IE5VTEwpIHsJCQoJCWxpbmstPnR5cGUgPSBzdWJMaW5rLT50eXBlOwoJCWlmIChzdWJMaW5rLT5uZXh0ICE9IE5VTEwpIHsKCQkgICAgbGFzdExpbmsgPSBsaW5rLT5uZXh0OwoJCSAgICBzdWJMaW5rID0gc3ViTGluay0+bmV4dDsJCQoJCSAgICBwcmV2TGluayA9IGxpbms7CgkJICAgIHdoaWxlIChzdWJMaW5rICE9IE5VTEwpIHsJCSAgICAKCQkJbmV3TGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgCgkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CgkJCWlmIChuZXdMaW5rID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCAKCQkJCU5VTEwpOwoJCQkgICAgcmV0dXJuICgtMSk7CgkJCX0KCQkJbmV3TGluay0+dHlwZSA9IG1lbWJlclR5cGU7CSAgICAKCQkJcHJldkxpbmstPm5leHQgPSBuZXdMaW5rOwoJCQlwcmV2TGluayA9IG5ld0xpbms7CgkJCW5ld0xpbmstPm5leHQgPSBsYXN0TGluazsKCQkJCgkJCXN1YkxpbmsgPSBzdWJMaW5rLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCWxpbmsgPSBsaW5rLT5uZXh0OwogICAgfSAgICAKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWxUeXBlOiB0aGUgdmFsdWUgdHlwZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSB0eXBlIGhhcyB0aGUgZ2l2ZW4gdmFsdWUgdHlwZSwgb3IKICogaXMgZGVyaXZlZCBmcm9tIHN1Y2ggYSB0eXBlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgdmFsVHlwZSkKewogICAgLyogVE9ETzogQ2hlY2sgaWYgdGhpcyB3b3JrcyBpbiBldmVyeSBjYXNlLiAqLwogICAgaWYgKCh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYKCQkodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgewoJCWlmICh0eXBlLT5idWlsdEluVHlwZSA9PSB2YWxUeXBlKQoJCQlyZXR1cm4oMSk7CiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURSkgewoJaWYgKCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB0eXBlKS0+c3VidHlwZXMgIT0gTlVMTCkgCgkgICAgcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCAKCQkoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgdHlwZSktPnN1YnR5cGVzLCB2YWxUeXBlKSk7CiAgICB9IGVsc2UgaWYgKCh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgfHwKCSh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT04pKSB7CglpZiAodHlwZS0+YmFzZVR5cGUgIT0gTlVMTCkgCgkgICAgcmV0dXJuKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCB0eXBlLT5iYXNlVHlwZSwgCgkJdmFsVHlwZSkpOwogICAgfSBlbHNlIGlmICgodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCSgodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpKSB7CglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIHR5cGUtPnN1YnR5cGVzLCAKCSAgICB2YWxUeXBlKSk7CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZToKICogQHR5cGU6ICB0aGUgc2ltcGxlVHlwZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIHByaW1pdGl2ZSB0eXBlIG9mIHRoZSBnaXZlbiB0eXBlIG9yCiAqIE5VTEwgaW4gY2FzZSBvZiBlcnJvci4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0JVSUxUSU5fUFJJTUlUSVZFKQoJICAgIHJldHVybiAodHlwZSk7Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CgogICAgcmV0dXJuIChOVUxMKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIEBjdXI6IHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbGlzdAogKiBAbGFzdFVzZTogdGhlIHRvcCBvZiB0aGUgYXR0cmlidXRlIHVzZSBsaXN0CiAqCiAqIEJ1aWxkcyB0aGUgYXR0cmlidXRlIHVzZXMgbGlzdCBvbiB0aGUgZ2l2ZW4gY29tcGxleCB0eXBlLgogKiBUaGlzIG9uZSBpcyBzdXBwb3NlZCB0byBiZSBjYWxsZWQgYnkgCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbiBvbmx5LgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBjdXIsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqdXNlcywKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyICpsYXN0VXNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIHRtcDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJaWYgKGN1ci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICAvKiAKCSAgICAgKiBXM0M6ICIyIFRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXBzILdyZXNvbHZlZLcgCgkgICAgICogdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3cyBvZiB0aGUgcmVmIFthdHRyaWJ1dGVdIG9mIHRoZSAKCSAgICAgKiA8YXR0cmlidXRlR3JvdXA+IFtjaGlsZHJlbl0sIGlmIGFueS4iCgkgICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKGN0eHQsIAoJCSgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGN1ciktPmF0dHJpYnV0ZXMsIHVzZXMsIAoJCWxhc3RVc2UpID09IC0xKSB7CgkJcmV0dXJuICgtMSk7CSAgICAKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qIFczQzogIjEgVGhlIHNldCBvZiBhdHRyaWJ1dGUgdXNlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSAKCSAgICAgKiA8YXR0cmlidXRlPiBbY2hpbGRyZW5dLCBpZiBhbnkuIgoJICAgICAqLwkgICAgCSAgICAKCSAgICB0bXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0cikgCgkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYnVpbGRpbmcgYXR0cmlidXRlIHVzZXMiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgdG1wLT5hdHRyID0gY3VyOwoJICAgIHRtcC0+bmV4dCA9IE5VTEw7CgkgICAgaWYgKCp1c2VzID09IE5VTEwpCgkJKnVzZXMgPSB0bXA7CQkgICAgCgkgICAgZWxzZSAKCQkoKmxhc3RVc2UpLT5uZXh0ID0gdG1wOwoJICAgICpsYXN0VXNlID0gdG1wOwkgICAgCgl9CQoJY3VyID0gY3VyLT5uZXh0OwogICAgfQkKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50czoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBkZXN0OiAgdGhlIGRlc3RpbmF0aW9uIHdpbGRjYXJkCiAqIEBzb3VyY2U6IHRoZSBzb3VyY2Ugd2lsZGNhcmQKICoKICogQ2xvbmVzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2Ygc291cmNlCiAqIGFuZCBhc3NpZ25lcyB0aGVtIHRvIGRlc3QuCiAqIFJldHVybnMgLTEgb24gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmRlc3QsCgkJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgc291cmNlKQkJCQkgICAgCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCB0bXAsIGxhc3Q7CgogICAgaWYgKChzb3VyY2UgPT0gTlVMTCkgfHwgKCpkZXN0ID09IE5VTEwpKQoJcmV0dXJuKC0xKTsgICAgCiAgICAoKmRlc3QpLT5hbnkgPSBzb3VyY2UtPmFueTsKICAgIGN1ciA9IHNvdXJjZS0+bnNTZXQ7CiAgICBsYXN0ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAodG1wID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICAoKmRlc3QpLT5uc1NldCA9IHRtcDsKCWVsc2UgCgkgICAgbGFzdC0+bmV4dCA9IHRtcDsKCWxhc3QgPSB0bXA7CgljdXIgPSBjdXItPm5leHQ7CiAgICB9ICAgIAogICAgaWYgKCgqZGVzdCktPm5lZ05zU2V0ICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCgoKmRlc3QpLT5uZWdOc1NldCk7CSAgIAogICAgaWYgKHNvdXJjZS0+bmVnTnNTZXQgIT0gTlVMTCkgewoJKCpkZXN0KS0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICgoKmRlc3QpLT5uZWdOc1NldCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7CgkoKmRlc3QpLT5uZWdOc1NldC0+dmFsdWUgPSBzb3VyY2UtPm5lZ05zU2V0LT52YWx1ZTsJICAgIAogICAgfSBlbHNlCgkoKmRlc3QpLT5uZWdOc1NldCA9IE5VTEw7CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFVbmlvbldpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQgCiAqCiAqIFVuaW9ucyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgdW5pb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgkKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgkgICAgCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgkJCgkJLyogCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLiAKCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gYW55IG11c3QgYmUgdGhlIHZhbHVlCiAgICAqLwogICAgaWYgKGNvbXBsZXRlV2lsZC0+YW55ICE9IGN1cldpbGQtPmFueSkgewkKCWlmIChjb21wbGV0ZVdpbGQtPmFueSA9PSAwKSB7CgkgICAgY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCXhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIDMgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksIAogICAgKiB0aGVuIHRoZSB1bmlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsJCQoJaW50IGZvdW5kOwoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzdGFydDsKCQoJY3VyID0gY3VyV2lsZC0+bnNTZXQ7CglzdGFydCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IHN0YXJ0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmICh0bXAgPT0gTlVMTCkgCgkJICAgIHJldHVybiAoLTEpOwoJCXRtcC0+dmFsdWUgPSBjdXItPnZhbHVlOwoJCXRtcC0+bmV4dCA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CQkgICAgCQkgICAgCgkJY29tcGxldGVXaWxkLT5uc1NldCA9IHRtcDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKCQkgICAgCQkKCXJldHVybigwKTsKICAgIH0gICAgCiAgICAvKgogICAgKiA0IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgdmFsdWVzIChuYW1lc3BhY2UgbmFtZXMgCiAgICAqIG9yILdhYnNlbnS3KSwgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7Cgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7CgoJcmV0dXJuKDApOwogICAgfQogICAgLyogCiAgICAgKiA1LgogICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7CgoJaW50IG5zRm91bmQsIGFic2VudEZvdW5kID0gMDsKCQoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5lZ05zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICBjdXJCID0gY29tcGxldGVXaWxkLT5uZWdOc1NldDsKCX0KCW5zRm91bmQgPSAwOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgCgkJYWJzZW50Rm91bmQgPSAxOwoJICAgIGVsc2UgaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpCgkJbnNGb3VuZCA9IDE7CgkgICAgaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpCgkJYnJlYWs7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKCglpZiAobnNGb3VuZCAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzIGJvdGggdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIAoJICAgICogbmFtZSBhbmQgt2Fic2VudLcsIHRoZW4gYW55IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovICAgIAoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0gZWxzZSBpZiAobnNGb3VuZCAmJiAoIWFic2VudEZvdW5kKSkgewoJICAgIC8qIAoJICAgICogNS4yIElmIHRoZSBzZXQgUyBpbmNsdWRlcyB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgbmFtZSAKCSAgICAqIGJ1dCBub3Qgt2Fic2VudLcsIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdCAKCSAgICAqIGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMyBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcgYnV0IG5vdCB0aGUgbmVnYXRlZCAKCSAgICAqIG5hbWVzcGFjZSBuYW1lLCB0aGVuIHRoZSB1bmlvbiBpcyBub3QgZXhwcmVzc2libGUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwgCgkJWE1MX1NDSEVNQVBfVU5JT05fTk9UX0VYUFJFU1NJQkxFLAoJCSJUaGUgdW5pb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLlxuIiwKCQlOVUxMLCBOVUxMKTsJCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSk7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKiAKCSAgICAqIDUuNCBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSBlaXRoZXIgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIAoJICAgICogbmFtZSBvciC3YWJzZW50tywgdGhlbiB3aGljaGV2ZXIgb2YgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCAKCSAgICAqIGFuZCBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgfQoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qIAogICAgICogNi4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJfSBlbHNlIHsKCSAgICBjdXIgPSBjdXJXaWxkLT5uc1NldDsKCX0JCgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJLyoKCQkqIDYuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgt2Fic2VudLcsIHRoZW4gYW55IG11c3QgYmUgdGhlIAoJCSogdmFsdWUuCgkJKi8KCQljb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkJfQoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkJfQoJCXJldHVybiAoMCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCQkKCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCSAgICAvKgoJICAgICogNi4yIElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICByZXR1cm4gKDApOwoKfQoKLyoqCiAqIHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBjb21wbGV0ZVdpbGQ6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQGN1cldpbGQ6IHRoZSBzZWNvbmQgd2lsZGNhcmQgCiAqCiAqIEludGVyc2VjdHMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIGludGVyc2VjdGlvbi4KICogUmV0dXJucyBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZSwgLTEgaW4gY2FzZSBvZiBhbgogKiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGNvbXBsZXRlV2lsZCwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIGN1cldpbGQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCLCBwcmV2LCAgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlIAogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoJCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJICAgIAoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoJCQoJCS8qIAoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4gCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQkgICAgICAgIAogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIHRoZSBvdGhlciBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ICE9IGN1cldpbGQtPmFueSkgJiYgKGNvbXBsZXRlV2lsZC0+YW55KSkgewkJICAgIAoJaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsICZjb21wbGV0ZVdpbGQsIGN1cldpbGQpID09IC0xKQoJICAgIHJldHVybigtMSk7CSAgICAKCXJldHVybigwKTsKICAgIH0JICAgICAgICAgICAgCiAgICAvKgogICAgKiAzIElmIGVpdGhlciBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90IGFuZCBhIHZhbHVlIChhIG5hbWVzcGFjZSAKICAgICogbmFtZSBvciC3YWJzZW50tykgYW5kIHRoZSBvdGhlciBpcyBhIHNldCBvZiAobmFtZXNwYWNlIG5hbWVzIG9yIAogICAgKiC3YWJzZW50tyksIHRoZW4gdGhhdCBzZXQsIG1pbnVzIHRoZSBuZWdhdGVkIHZhbHVlIGlmIGl0IHdhcyBpbiAKICAgICogdGhlIHNldCwgbWludXMgt2Fic2VudLcgaWYgaXQgd2FzIGluIHRoZSBzZXQsIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCWNvbnN0IHhtbENoYXIgKm5lZzsKCQoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgewoJICAgIG5lZyA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCQlyZXR1cm4oLTEpOwoJfSBlbHNlCgkgICAgbmVnID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJLyoKCSogUmVtb3ZlIGFic2VudCBhbmQgbmVnYXRlZC4KCSovCglwcmV2ID0gTlVMTDsKCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSB7CgkJaWYgKHByZXYgPT0gTlVMTCkgCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZSAKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKGN1cik7CgkJYnJlYWs7CgkgICAgfQoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQoJaWYgKG5lZyAhPSBOVUxMKSB7CgkgICAgcHJldiA9IE5VTEw7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBuZWcpIHsKCQkgICAgaWYgKHByZXYgPT0gTlVMTCkgCgkJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJICAgIGVsc2UgCgkJCXByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJICAgIHhtbEZyZWUoY3VyKTsKCQkgICAgYnJlYWs7CgkJfQoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0KCglyZXR1cm4oMCk7CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiA0IElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLCAKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIG9mIHRob3NlIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgewkJCglpbnQgZm91bmQ7CgkKCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGZvdW5kID0gMDsKCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJICAgIGZvdW5kID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCWN1ckIgPSBjdXJCLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoIWZvdW5kKSB7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQllbHNlIAoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXRtcCA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKGN1cik7CgkJY3VyID0gdG1wOwkJCgkJY29udGludWU7CgkgICAgfQoJICAgIHByZXYgPSBjdXI7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKCQkgICAgCQkKCXJldHVybigwKTsKICAgIH0gICAgCiAgICAvKiA1IElmIHRoZSB0d28gYXJlIG5lZ2F0aW9ucyBvZiBkaWZmZXJlbnQgbmFtZXNwYWNlIG5hbWVzLCAKICAgICogdGhlbiB0aGUgaW50ZXJzZWN0aW9uIGlzIG5vdCBleHByZXNzaWJsZQogICAgKi8JICAgIAogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSkgewoKCXhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFLAoJICAgICJUaGUgaW50ZXJzZWN0aW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZS5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CQoJcmV0dXJuKFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUpOwogICAgfQkJICAgIAogICAgLyogCiAgICAqIDYgSWYgdGhlIG9uZSBpcyBhIG5lZ2F0aW9uIG9mIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlciAKICAgICogaXMgYSBuZWdhdGlvbiBvZiC3YWJzZW50tywgdGhlbiB0aGUgb25lIHdoaWNoIGlzIHRoZSBuZWdhdGlvbiAKICAgICogb2YgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpKSB7CQoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSAgY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOyAKICAgIH0KICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAd2lsZEE6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQHdpbGRCOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50IG9mIEB3aWxkQSBpcyBhbiBpbnRlbnNpb25hbCAKICogc3Vic2V0IG9mIEB3aWxkQiwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQoeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZEEsCgkJCQkgICAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkQikKeyAgICAKCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFdpbGRjYXJkIFN1YnNldCAKICAgICovCiAgICAvKgogICAgKiAxIHN1cGVyIG11c3QgYmUgYW55LiAKICAgICovCiAgICBpZiAod2lsZEItPmFueSkKCXJldHVybiAoMSk7CiAgICAvKgogICAgKiAyLjEgc3ViIG11c3QgYmUgYSBwYWlyIG9mIG5vdCBhbmQgYSBuYW1lc3BhY2UgbmFtZSBvciC3YWJzZW50ty4KICAgICogMi4yIHN1cGVyIG11c3QgYmUgYSBwYWlyIG9mIG5vdCBhbmQgdGhlIHNhbWUgdmFsdWUuCiAgICAqLwogICAgaWYgKCh3aWxkQS0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCSh3aWxkQi0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCSh3aWxkQS0+bmVnTnNTZXQtPnZhbHVlID09IHdpbGRBLT5uZWdOc1NldC0+dmFsdWUpKQoJcmV0dXJuICgxKTsgICAgCiAgICAvKiAKICAgICogMy4xIHN1YiBtdXN0IGJlIGEgc2V0IHdob3NlIG1lbWJlcnMgYXJlIGVpdGhlciBuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcuIAogICAgKi8KICAgIGlmICh3aWxkQS0+bnNTZXQgIT0gTlVMTCkgewoJLyoKCSogMy4yLjEgc3VwZXIgbXVzdCBiZSB0aGUgc2FtZSBzZXQgb3IgYSBzdXBlcnNldCB0aGVyZW9mLiAKCSovCglpZiAod2lsZEItPm5zU2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQjsKCSAgICBpbnQgZm91bmQgPSAwOwoJICAgIAoJICAgIGN1ciA9IHdpbGRBLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJY3VyQiA9IHdpbGRCLT5uc1NldDsKCQl3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJICAgIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCWZvdW5kID0gMTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgY3VyQiA9IGN1ckItPm5leHQ7CgkJfQoJCWlmICghZm91bmQpCgkJICAgIHJldHVybiAoMCk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoZm91bmQpCgkJcmV0dXJuICgxKTsgCgl9IGVsc2UgaWYgKHdpbGRCLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgkgICAgLyoKCSAgICAqIDMuMi4yIHN1cGVyIG11c3QgYmUgYSBwYWlyIG9mIG5vdCBhbmQgYSBuYW1lc3BhY2UgbmFtZSBvciAKCSAgICAqILdhYnNlbnS3IGFuZCB0aGF0IHZhbHVlIG11c3Qgbm90IGJlIGluIHN1YidzIHNldC4gCgkgICAgKi8KCSAgICBjdXIgPSB3aWxkQS0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CQkKCQlpZiAoY3VyLT52YWx1ZSA9PSB3aWxkQi0+bmVnTnNTZXQtPnZhbHVlKQoJCSAgICByZXR1cm4gKDApOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9ICAKCSAgICByZXR1cm4gKDEpOwoJfQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBhdHRyczogdGhlIGF0dHJpYnV0ZSBsaXN0IAogKiBAY29tcGxldGVXaWxkOiB0aGUgcmVzdWx0aW5nIGNvbXBsZXRlIHdpbGRjYXJkCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAkJCQkgICAgCgkJCQkgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cnMsCgkJCQkgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciAqY29tcGxldGVXaWxkKQkJCQkKeyAgICAgICAgCiAgICB3aGlsZSAoYXR0cnMgIT0gTlVMTCkgewoJaWYgKGF0dHJzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgewoJICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGdyb3VwOwoKCSAgICBncm91cCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgYXR0cnM7CgkgICAgLyoKCSAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgZ3JvdXAgcmVmZXJlbmNlcy4KCSAgICAqLwoJICAgIGlmIChncm91cC0+cmVmICE9IE5VTEwpIHsKCQlpZiAoZ3JvdXAtPnJlZkl0ZW0gPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIFRPRE86IFNob3VsZCB3ZSByYWlzZSBhIHdhcm5pbmcgaGVyZT8KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBUaGUgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBjb3VsZCBub3QKCQkgICAgKiBiZSByZXNvbHZlZCBiZWZvcmVoYW5kLCBzbyBza2lwLgoJCSAgICAqLwoJCSAgICBhdHRycyA9IGF0dHJzLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UKCQkgICAgZ3JvdXAgPSBncm91cC0+cmVmSXRlbTsKCSAgICB9CSAgICAKCSAgICAvKgoJICAgICogRm9yIGV2ZXJ5IGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLCBhbiBpbnRlcnNlY3RlZCB3aWxkY2FyZCAKCSAgICAqIHdpbGwgYmUgY3JlYXRlZCAoYXNzdW1lZCB0aGF0IGEgd2lsZGNhcmQgZXhpc3RzIG9uIHRoZSAKCSAgICAqIHBhcnRpY3VsYXIgYXR0ci4gZ3IuIGRlZi4gb3Igb24gYW55IGNvbnRhaW5lZCBhdHRyLiBnci4gZGVmIAoJICAgICogYXQgYWxsKS4KCSAgICAqIFRoZSBmbGFnIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEIGVuc3VyZXMKCSAgICAqIHRoYXQgdGhlIGludGVyc2VjdGlvbiB3aWxsIGJlIHBlcmZvcm1lZCBvbmx5IG9uY2UuCgkgICAgKi8KCSAgICBpZiAoKGdyb3VwLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEKSA9PSAwKSB7CgkJaWYgKGdyb3VwLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCAKCQkJZ3JvdXAtPmF0dHJpYnV0ZXMsICZncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4gKC0xKTsKCQl9CgkJZ3JvdXAtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEOwoJICAgIH0JCQoJICAgIGlmIChncm91cC0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewkJCgkJaWYgKCpjb21wbGV0ZVdpbGQgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIENvcHkgdGhlIGZpcnN0IGVuY291bnRlcmVkIHdpbGRjYXJkIGFzIGNvbnRleHQsIGV4Y2VwdCBmb3IgdGhlIGFubm90YXRpb24uCgkJICAgICovCgkJICAgICpjb21wbGV0ZVdpbGQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0KTsKCQkgICAgKCpjb21wbGV0ZVdpbGQpLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU7CSAgIAoJCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgCgkJCWNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkJcmV0dXJuICgtMSk7CgkJICAgICgqY29tcGxldGVXaWxkKS0+cHJvY2Vzc0NvbnRlbnRzID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHM7CgkJICAgIC8qCgkJICAgICogQWx0aG91Z2ggdGhlIGNvbXBsZXRlIHdpbGRjYXJkIG1pZ2h0IG5vdCBjb3JyZXNwb25kIHRvIGFueQoJCSAgICAqIG5vZGUgaW4gdGhlIHNjaGVtYSwgd2Ugd2lsbCBzYXZlIHRoaXMgY29udGV4dCBub2RlLgoJCSAgICAqIFRPRE86IEhtbSwgaXMgdGhpcyBzYW5lPwoJCSAgICAqLwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPm5vZGUgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPm5vZGU7ICAKCQkgICAgCgkJfSBlbHNlIGlmICh4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoY3R4dCwgKmNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQoKmNvbXBsZXRlV2lsZCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJICAgIH0KCX0KCWF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgIAkJICAgICAgICAgICAgICAgICAKICAgIHJldHVybiAoMCk7ICAgCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAoJCQkJICAgICBpbnQgKmZpeGVkLAoJCQkJICAgICBjb25zdCB4bWxDaGFyICoqdmFsdWUsCgkJCQkgICAgIHhtbFNjaGVtYVZhbFB0ciAqdmFsKQp7CiAgICAqZml4ZWQgPSAwOwogICAgKnZhbHVlID0gTlVMTDsKICAgIGlmICh2YWwgIT0gMCkgCgkqdmFsID0gTlVMTDsKCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgPT0gTlVMTCkKCWl0ZW0gPSBpdGVtLT5yZWZEZWNsOwoKICAgIGlmIChpdGVtID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGlmIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSB7CgkqdmFsdWUgPSBpdGVtLT5kZWZWYWx1ZTsKCWlmICh2YWwgIT0gMCkKCSAgICAqdmFsID0gaXRlbS0+ZGVmVmFsOwoJaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkKCSAgICAqZml4ZWQgPSAxOwoJcmV0dXJuICgxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KLyoqCiAqIHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zOgogKiBAd2lsZDogIHRoZSB3aWxkY2FyZAogKiBAbnM6ICB0aGUgbmFtZXNwYWNlCiAqIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIGdpdmVuIG5hbWVzcGFjZSBtYXRjaGVzIHRoZSB3aWxkY2FyZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsIGNvbnN0IHhtbENoYXIqIG5zKQp7CiAgICBpZiAod2lsZCA9PSBOVUxMKQoJcmV0dXJuKDApOwoKICAgIGlmICh3aWxkLT5hbnkpCglyZXR1cm4oMSk7CiAgICBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCgljdXIgPSB3aWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChjdXItPnZhbHVlLCBucykpCgkJcmV0dXJuKDEpOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0gZWxzZSBpZiAoKHdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChucyAhPSBOVUxMKSAmJiAKCSgheG1sU3RyRXF1YWwod2lsZC0+bmVnTnNTZXQtPnZhbHVlLCBucykpKQoJcmV0dXJuKDEpOwkKCQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogCiAqCiAqIEJ1aWxkcyB0aGUgd2lsZGNhcmQgYW5kIHRoZSBhdHRyaWJ1dGUgdXNlcyBvbiB0aGUgZ2l2ZW4gY29tcGxleCB0eXBlLgogKiBSZXR1cm5zIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VycywgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGN1ciwgYmFzZSwgdG1wLCBpZCA9IE5VTEwsIHByZXYgPSBOVUxMLCB1c2VzID0gTlVMTCwgCglsYXN0VXNlID0gTlVMTCwgbGFzdEJhc2VVc2UgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzOwogICAgeG1sU2NoZW1hVHlwZVB0ciBhbnlUeXBlOwogICAgaW50IGJhc2VJc0FueVR5cGUgPSAwOwogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKICAgIGludCBlcnIgPSAwOwoKICAgIGFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIC8qIAogICAgICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gd2l0aCBjb21wbGV4IGNvbnRlbnQgU2NoZW1hIENvbXBvbmVudC4KICAgICAqCiAgICAgKiBBdHRyaWJ1dGUgdXNlcy4KICAgICAqIFRPRE86IEFkZCBjaGVja3MgZm9yIGFic2VudCByZWZlcmVuY2VkIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgYW5kCiAgICAgKiBzaW1wbGUgdHlwZXMuCiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkJICAgICAgImF0dHJpYnV0ZSB1c2VzIGFscmVhZHkgYnVpbGRlZC5cbiIsCgkJICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCQkgICAgICAiY29tcGxleCB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2VUeXBlID09IGFueVR5cGUpCgliYXNlSXNBbnlUeXBlID0gMTsKICAgIC8qCiAgICAgKiBJbmhlcml0IHRoZSBhdHRyaWJ1dGUgdXNlcyBvZiB0aGUgYmFzZSB0eXBlLgogICAgICovCiAgICAvKgogICAgICogTk9URTogSXQgaXMgYWxsb3dlZCB0byAiZXh0ZW5kIiB0aGUgYW55VHlwZSBjb21wbGV4IHR5cGUuCiAgICAgKi8KICAgIGlmICghYmFzZUlzQW55VHlwZSkgewoJaWYgKGJhc2VUeXBlICE9IE5VTEwpIHsKCSAgICBmb3IgKGN1ciA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVVc2VzOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CgkJdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCQkJImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIG9mIGNvbXBsZXhUeXBlIiwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQl0bXAtPmF0dHIgPSBjdXItPmF0dHI7CgkJdG1wLT5uZXh0ID0gTlVMTDsKCQlpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJfSBlbHNlIAoJCSAgICBsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQlsYXN0QmFzZVVzZSA9IHRtcDsgCgkgICAgfQoJfQogICAgfQogICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCSgodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgfHwgCgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpKSB7CgkvKiAKCSogdHlwZSAtLT4gKDxzaW1wbGVDb250ZW50Pnw8Y29tcGxleENvbnRlbnQ+KSAKCSogICAgICAgIC0tPiAoPHJlc3RyaWN0aW9uPnw8ZXh0ZW5zaW9uPikgLS0+IGF0dHJpYnV0ZXMKCSovIAoJYXR0cnMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CiAgICB9IGVsc2UgewoJLyogU2hvcnQgaGFuZCBmb3JtIG9mIHRoZSBjb21wbGV4VHlwZS4gKi8KCWF0dHJzID0gdHlwZS0+YXR0cmlidXRlczsKICAgIH0KICAgIC8qCiAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgd2lsZGNhcmRzLgogICAgKi8JCiAgICBlcnIgPSB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCglhdHRycywgJnR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKTsgICAgCiAgICAvKgogICAgKiBOT1RFOiBEdXJpbmcgdGhlIHBhcnNlIHRpbWUsIHRoZSB3aWxkY2FyZCBpcyBjcmVhdGVkIG9uIHRoZSBjb21wbGV4VHlwZQogICAgKiBkaXJlY3RseSwgaWYgZW5jb3VudGVyZWQgaW4gYSA8cmVzdHJpY3Rpb24+IG9yIDxleHRlbnNpb24+IGVsZW1lbnQuCiAgICAqLwogICAgaWYgKGVyciA9PSAtMSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJICAgICJmYWlsZWQgdG8gYnVpbGQgYW4gaW50ZXJzZWN0ZWQgYXR0cmlidXRlIHdpbGRjYXJkLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgJiYgCgkoKGJhc2VJc0FueVR5cGUpIHx8CgkgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAJICAgIAoJICAoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCSAgICAgIAoJICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSkpIHsJICAgIAoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVW5pb24gdGhlIGNvbXBsZXRlIHdpbGRjYXJkIHdpdGggdGhlIGJhc2Ugd2lsZGNhcmQuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoY3R4dCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJcmV0dXJuICgtMSk7Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBKdXN0IGluaGVyaXQgdGhlIHdpbGRjYXJkLgoJICAgICovCgkgICAgLyoKCSAgICAqIE5PVEU6IFRoaXMgaXMgdGhlIG9ubHkgY2FzZSB3aGVyZSBhbiBhdHRyaWJ1dGUgCiAgICAgICAgICAgICogd2lsZGNhcmQgaXMgc2hhcmVkLgogICAgICAgICAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRCkKCQl0eXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSBiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQ7Cgl9CiAgICB9CiAgICAKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyogCgkgICAgKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkgCSAgICAKCSAgICAqIDQuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGFsc28gaGF2ZSBvbmUuIAoJICAgICovCgkgICAgaWYgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CSAgCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCgkJICAgICJUaGUgdHlwZSBoYXMgYW4gYXR0cmlidXRlIHdpbGRjYXJkLCAiCgkJICAgICJidXQgdGhlIGJhc2UgdHlwZSAlcyBkb2VzIG5vdCBoYXZlIG9uZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCgKCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJLyogNC4yICovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIiAKCQkgICAgInN1YnNldCBvZiB0aGUgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJICAgIAoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIC8qIDQuMyBVbmxlc3MgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILd1ci10eXBlIAoJICAgICogZGVmaW5pdGlvbrcsIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgCgkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30gbXVzdCBiZSBpZGVudGljYWwgdG8gb3IgCgkgICAgKiBzdHJvbmdlciB0aGFuIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2F0dHJpYnV0ZSAKCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSwgd2hlcmUgc3RyaWN0IGlzIHN0cm9uZ2VyIAoJICAgICogdGhhbiBsYXggaXMgc3Ryb25nZXIgdGhhbiBza2lwLgoJICAgICovCgkgICAgaWYgKCh0eXBlLT5iYXNlVHlwZSAhPSBhbnlUeXBlKSAmJiAKCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA8IAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzMsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgJ3Byb2Nlc3MgY29udGVudHMnIG9mIHRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgd2Vha2VyIHRoYW4gIgoJCSAgICAidGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkvKgoJKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCgkqIEF0IHRoaXMgcG9pbnQgdGhlIHR5cGUgYW5kIHRoZSBiYXNlIGhhdmUgYm90aCwgZWl0aGVyCgkqIG5vIHdpbGRjYXJkIG9yIGEgd2lsZGNhcmQuCgkqLwoJaWYgKChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCSAgICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSkgewoJICAgIC8qIDEuMyAqLwoJICAgIGlmICh4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIiAKCQkgICAgInN1cGVyc2V0IG9mIHRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQoJCXJldHVybiAoMSk7CQkKCSAgICB9Cgl9CQkKICAgIH0JCgogICAgLyoKICAgICAqIEdhdGhlciBhdHRyaWJ1dGUgdXNlcyBkZWZpbmVkIGJ5IHRoaXMgdHlwZS4KICAgICAqLwogICAgaWYgKGF0dHJzICE9IE5VTEwpIHsKCWlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCBhdHRycywgCgkgICAgJnVzZXMsICZsYXN0VXNlKSA9PSAtMSkgewoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgLyogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0IDQuCiAgICAgKiAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKICAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLiIKICAgICAqCiAgICAgKiBGb3IgImV4dGVuc2lvbiIgdGhpcyBpcyBkb25lIGZ1cnRoZXIgZG93bi4KICAgICAqLwogICAgaWYgKCh1c2VzICE9IE5VTEwpICYmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgPT0gMCkpIHsKCWN1ciA9IHVzZXM7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICB0bXAgPSBjdXItPm5leHQ7CgkgICAgd2hpbGUgKHRtcCAhPSBOVUxMKSB7CSAgICAKCQlpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCSAgICB4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkgICAgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShjdXItPmF0dHIgKSwgCgkJICAgIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwgCgkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwJCQkKCQkJIkR1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlICVzIHNwZWNpZmllZCIsCgkJCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgCgkJCSAgICB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSwgCgkJCSAgICB4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKQoJCSAgICApOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikJCSAgICAJCSAgICAKCQkgICAgYnJlYWs7CgkJfQoJCXRtcCA9IHRtcC0+bmV4dDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfQkKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsJCgkvKgoJICogRGVyaXZlIGJ5IHJlc3RyaWN0aW9uLgoJICovCglpZiAoYmFzZUlzQW55VHlwZSkgewoJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwoJfSBlbHNlIHsKCSAgICBpbnQgZm91bmQ7CgkgICAgY29uc3QgeG1sQ2hhciAqYkVmZlZhbHVlOwoJICAgIGludCBlZmZGaXhlZDsKCgkgICAgY3VyID0gdXNlczsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJYmFzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CgkJd2hpbGUgKGJhc2UgIT0gTlVMTCkgewoJCSAgICBpZiAoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldEF0dHJOYW1lKGJhc2UtPmF0dHIpKSAmJgoJCQl4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShiYXNlLT5hdHRyKSkpIHsKCQkJCgkJCWZvdW5kID0gMTsJCQkKCQkJCgkJCWlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAyLjEuMQoJCQkgICAgKi8JCgkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMSwKCQkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwKCQkJCSJUaGUgJ29wdGlvbmFsJyB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggYSBtYXRjaGluZyAiCgkJCQkiJ3JlcXVpcmVkJyB1c2Ugb2YgdGhlIGJhc2UgdHlwZSIsIE5VTEwpOwkJCQkKCQkJfSBlbHNlIGlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDMgCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8zLCAKCQkJCU5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJCQkiQSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGZvciB0aGUgJ3JlcXVpcmVkJyAiCgkJCQkiYXR0cmlidXRlIHVzZSAlcyBvZiB0aGUgYmFzZSB0eXBlIGlzIG1pc3NpbmciLAoJCQkJeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyLCAKCQkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShiYXNlLT5hdHRyKSwgCgkJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkpOwkKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQl9IGVsc2UgewoJCQkgICAgLyoKCQkJICAgICogMi4xLjMgW0RlZmluaXRpb246XSAgTGV0IHRoZSBlZmZlY3RpdmUgdmFsdWUgCgkJCSAgICAqIGNvbnN0cmFpbnQgb2YgYW4gYXR0cmlidXRlIHVzZSBiZSBpdHMge3ZhbHVlIAoJCQkgICAgKiBjb25zdHJhaW50fSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIGl0cyB7YXR0cmlidXRlIAoJCQkgICAgKiBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0gLiAKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYmFzZS0+YXR0ciwgJmVmZkZpeGVkLCAKCQkJCSZiRWZmVmFsdWUsIDApOwkJCSAgIAkJCQkJCQkgICAgCgkJCSAgICAvKgoJCQkgICAgKiAyLjEuMyAuLi4gb25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlCgkJCSAgICAqCgkJCSAgICAqIDIuMS4zLjEgQidzILdlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludLcgaXMgCgkJCSAgICAqILdhYnNlbnS3IG9yIGRlZmF1bHQuCgkJCSAgICAqLwoJCQkgICAgaWYgKChiRWZmVmFsdWUgIT0gTlVMTCkgJiYKCQkJCShlZmZGaXhlZCA9PSAxKSkgewoJCQkJY29uc3QgeG1sQ2hhciAqckVmZlZhbHVlID0gTlVMTDsKCgkJCQl4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYmFzZS0+YXR0ciwgJmVmZkZpeGVkLCAKCQkJCSAgICAmckVmZlZhbHVlLCAwKTsJCgkJCQkvKgoJCQkJKiAyLjEuMy4yIFIncyC3ZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnS3IGlzIAoJCQkJKiBmaXhlZCB3aXRoIHRoZSBzYW1lIHN0cmluZyBhcyBCJ3MuCgkJCQkqLwoJCQkJaWYgKChlZmZGaXhlZCA9PSAwKSB8fAoJCQkJICAgICghIHhtbFN0ckVxdWFsKHJFZmZWYWx1ZSwgYkVmZlZhbHVlKSkpIHsKCQkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzMsIAoJCQkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwJCQoJCQkJCSJUaGUgZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnQgb2YgdGhlICIKCQkJCQkiYXR0cmlidXRlIHVzZSBpcyBpbmNvbnNpc3RlbnQgd2l0aCAiCgkJCQkJIml0cyBjb3JyZXNwb25kZW50IG9mIHRoZSBiYXNlIHR5cGUiLAoJCQkJCU5VTEwpOwkJCQkJICAgIAoJCQkJfQoJCQkgICAgfQoJCQkgICAgLyoKCQkJICAgICogVE9ETzogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4xLjIgKHt0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkKQoJCQkgICAgKi8KCQkJICAgIC8qCgkJCSAgICAqIE92ZXJyaWRlIHRoZSBhdHRyaWJ1dGUgdXNlLgoJCQkgICAgKi8KCQkJICAgIGJhc2UtPmF0dHIgPSBjdXItPmF0dHI7CgkJCX0KCQkJCQkJCQkKCQkJYnJlYWs7CgkJICAgIH0JCQkJCgkJICAgIGJhc2UgPSBiYXNlLT5uZXh0OwoJCX0KCQkKCQlpZiAoIWZvdW5kKSB7CgkJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJCS8qCgkJCSogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4yCgkJCSovCgkJCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCQkJICAgIHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCQkJY3VyLT5hdHRyLT50YXJnZXROYW1lc3BhY2UpKQoJCQkgICAgZm91bmQgPSAxOwoKCQkJaWYgKCFmb3VuZCkgewoJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8yLCAKCQkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwJCQoJCQkJIk5laXRoZXIgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlLCAiCgkJCQkibm9yIGEgbWF0Y2hpbmcgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZSBkb2VzIGV4aXN0IiwKCQkJCU5VTEwpOwoJCQl9IGVsc2UgewoJCQkgICAgLyogCgkJCSAgICAqIEFkZCB0aGUgYXR0cmlidXRlIHVzZS4KCQkJICAgICoKCQkJICAgICogTm90ZSB0aGF0IHRoaXMgbWF5IGxlYWQgdG8gZnVubnkgZGVyaXZhdGlvbiBlcnJvciByZXBvcnRzLCBpZgoJCQkgICAgKiBtdWx0aXBsZSBlcXVhbCBhdHRyaWJ1dGUgdXNlcyBleGlzdDsgYnV0IHRoaXMgaXMgbm90CgkJCSAgICAqIGFsbG93ZWQgYW55d2F5LCBhbmQgaXQgd2lsbCBiZSByZXBvcnRlZCBiZWZvcmVoYW5kLgoJCQkgICAgKi8KCQkJICAgIHRtcCA9IGN1cjsKCQkJICAgIGlmIChwcmV2ICE9IE5VTEwpCgkJCQlwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCQkgICAgZWxzZSAKCQkJCXVzZXMgPSBjdXItPm5leHQ7CgkJCSAgICBjdXIgPSBjdXItPm5leHQ7ICAgIAkJCQoJCQkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCQkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHRtcDsKCQkJICAgIH0gZWxzZSAKCQkJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdG1wOwoJCQkgICAgbGFzdEJhc2VVc2UgPSB0bXA7CQkKCQkJICAgIAoJCQkgICAgY29udGludWU7CgkJCX0KCQkgICAgfQoJCX0JCSAgICAJICAgIAoJCXByZXYgPSBjdXI7CQoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHVzZXMgIT0gTlVMTCkKCQl4bWxTY2hlbWFGcmVlQXR0cmlidXRlVXNlTGlzdCh1c2VzKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgeyAKCS8qCgkgKiBUaGUgc3BlYyBhbGxvd3Mgb25seSBhcHBlbmRpbmcsIGFuZCBub3Qgb3RoZXIga2luZHMgb2YgZXh0ZW5zaW9ucy4KCSAqCgkgKiBUaGlzIGVuc3VyZXM6IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKSA6IDEuMiAKCSAqLwoJaWYgKHVzZXMgIT0gTlVMTCkgewoJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQl0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKCSAgICB9IGVsc2UgCgkJbGFzdEJhc2VVc2UtPm5leHQgPSB1c2VzOwoJfQogICAgfSBlbHNlIHsKCS8qIAoJKiBEZXJpdmUgaW1wbGljaXRlbHkgZnJvbSB0aGUgdXItdHlwZS4KCSovCgl0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKICAgIH0KICAgIC8qCiAgICAgKiAzLjQuNiAtPiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkgewoJY3VyID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDQuIFR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCgkgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4KCSAgICAqCgkgICAgKiBOb3RlIHRoYXQgdGhpcyB3YXMgYWxyZWFkeSBkb25lIGZvciAicmVzdHJpY3Rpb24iIGFuZCB0eXBlcyBkZXJpdmVkIGZyb20KCSAgICAqIHRoZSB1ci10eXBlLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsKCQl0bXAgPSBjdXItPm5leHQ7CgkJd2hpbGUgKHRtcCAhPSBOVUxMKSB7CSAgICAKCQkgICAgaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJCSh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyICksIAoJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSkpKSB7CgoJCQl4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF80LCAKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIHRtcC0+YXR0ciwJCQoJCQkgICAgIkR1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlIHNwZWNpZmllZCIsIE5VTEwpOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogNS4gVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKCSAgICAqIG5vdCBoYXZlIHt0eXBlIGRlZmluaXRpb259cyB3aGljaCBhcmUgb3IgYXJlIGRlcml2ZWQgZnJvbSBJRC4KCSAgICAqLwoJICAgIGlmICgoY3VyLT5hdHRyLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCQkoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIsIFhNTF9TQ0hFTUFTX0lEKSkpIHsKCQlpZiAoaWQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzUsIAoJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCgkJCSJUaGVyZSBtdXN0IG5vdCBleGlzdCBtb3JlIHRoYW4gb25lIGF0dHJpYnV0ZSB1c2UsICIKCQkJImRlY2xhcmVkIG9mIHR5cGUgJ0lEJyBvciBkZXJpdmVkIGZyb20gaXQiLCAKCQkJTlVMTCk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCX0gCgkJaWQgPSBjdXI7CgkgICAgfQoJICAgIC8qCgkgICAgKiBSZW1vdmUgInByb2hpYml0ZWQiIGF0dHJpYnV0ZSB1c2VzLiBUaGUgcmVhc29uIHRoaXMgaXMgZG9uZSBhdCB0aGlzIGxhdGUgCgkgICAgKiBzdGFnZSBpcyB0byBiZSBhYmxlIHRvIGNhdGNoIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgdXNlcy4gU28gd2UgaGFkIHRvIGtlZXAKCSAgICAqIHByb2hpYml0ZWQgdXNlcyBpbiB0aGUgbGlzdCBhcyB3ZWxsLgoJICAgICovCgkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQl0bXAgPSBjdXI7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IGN1ci0+bmV4dDsKCQllbHNlCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJY3VyID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUodG1wKTsKCSAgICB9IGVsc2UgewoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0gICAgCiAgICB9CiAgICAvKgkKICAgICAqIFRPRE86IFRoaXMgY2hlY2sgc2hvdWxkIGJlIHJlbW92ZWQgaWYgd2UgYXJlIDEwMCUgc3VyZSBvZgogICAgICogdGhlIGJhc2UgdHlwZSBhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJlaW5nIGJ1aWx0LgogICAgICovCiAgICBpZiAoKGJhc2VUeXBlICE9IE5VTEwpICYmICghYmFzZUlzQW55VHlwZSkgJiYKCShiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCShiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIGJhc2VUeXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJICAgICJhdHRyaWJ1dGUgdXNlcyBub3QgYnVpbGRlZCBvbiBiYXNlIHR5cGUgJyVzJy5cbiIsCgkgICAgYmFzZVR5cGUtPm5hbWUsIE5VTEwpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRmluYWxDb250YWluczoKICogQHNjaGVtYTogIHRoZSBzY2hlbWEKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBmaW5hbDogdGhlIGZpbmFsCiAqCiAqIEV2YWx1YXRlcyBpZiBhIHR5cGUgZGVmaW5pdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gImZpbmFsIi4KICogVGhpcyBkb2VzIHRha2UgImZpbmFsRGVmYXVsdCIgaW50byBhY2NvdW50IGFzIHdlbGwuCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBkb2VzIGNvbnRhaW50IHRoZSBnaXZlbiAiZmluYWwiLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgZmluYWwpCnsKICAgIGludCB0ZmluYWwgPSBmaW5hbCwgdGZsYWdzID0gdHlwZS0+ZmxhZ3M7CgogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7ICAgIAogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9ERUZBVUxUKSB7Cglzd2l0Y2ggKGZpbmFsKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT047CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTjsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVDoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1Q7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT047CgkJYnJlYWs7Cgl9Cgl0ZmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwogICAgfQogICAgaWYgKHRmbGFncyAmIHRmaW5hbCkgCglyZXR1cm4gKDEpOwogICAgZWxzZQoJcmV0dXJuICgwKTsKICAgIAp9CgovKioKICogeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXM6CiAqIEB0eXBlOiAgdGhlIFVuaW9uIFNpbXBsZSBUeXBlCiAqCiAqIFJldHVybnMgYSBsaXN0IG9mIG1lbWJlciB0eXBlcyBvZiBAdHlwZSBpZiBleGlzdGluZywgCiAqIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZUxpbmtQdHIKeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CglpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHR5cGUtPm1lbWJlclR5cGVzKTsKCWVsc2UKCSAgICB0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZToKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBpdGVtIHR5cGUgZGVmaW5pdGlvbiBvZiB0aGUgbGlzdCBzaW1wbGUgdHlwZS4KICovIApzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAKICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgPT0gMCkKCXJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBOb3RlOiBJbiBsaWJ4bWwyLCB0aGUgYnVpbHQtaW4gdHlwZXMgZG8gbm90IHJlZmxlY3QgCiAgICAqIHRoZSBkYXRhdHlwZSBoaWVyYXJjaHkgKHlldD8pIC0gd2UgaGF2ZSB0byB0cmVhdCB0aGVtCiAgICAqIGluIGEgc3BlY2lhbCB3YXkuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAKCXJldHVybiAoeG1sU2NoZW1hR2V0QnVpbHRJbkxpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZSkpOwogICAgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9MSVNUKQoJLyogMSBJZiB0aGUgPGxpc3Q+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUgdHlwZSAKCSogZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgCgkqIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9mIDxsaXN0PiwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIAoJKiB0aGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiAKCSogYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPGxpc3Q+LgoJKi8KCXJldHVybiAodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzKTsKICAgIGVsc2UgewoJLyogMiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBvcHRpb24gaXMgY2hvc2VuLCB0aGVuIHRoZSAKCSoge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KCSovICAgIAoJcmV0dXJuICh4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUtPmJhc2VUeXBlKSk7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSzoKICogQHR5cGU6ICB0aGUgZGVyaXZlZCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBiYXNlVHlwZTogIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3Mgd2hldGVyIEB0eXBlIGNhbiBiZSB2YWxpZGx5IAogKiBkZXJpdmVkIGZyb20gQGJhc2VUeXBlLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYW4gcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLyAKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSwKCQkJCSAgICAgaW50IHN1YnNldCkKeyAgIAogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkKICAgICoKICAgICoKICAgICogMSBUaGV5IGFyZSB0aGUgc2FtZSB0eXBlIGRlZmluaXRpb24uCiAgICAqIFRPRE86IFRoZSBpZGVudHkgY2hlY2sgbWlnaHQgaGF2ZSB0byBiZSBtb3JlIGNvbXBsZXggdGhhbiB0aGlzLgogICAgKi8KICAgIGlmICh0eXBlID09IGJhc2VUeXBlKQoJcmV0dXJuICgwKTsgICAgCiAgICAvKiAKICAgICogMi4xIHJlc3RyaWN0aW9uIGlzIG5vdCBpbiB0aGUgc3Vic2V0LCBvciBpbiB0aGUge2ZpbmFsfQogICAgKiBvZiBpdHMgb3duIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn07CiAgICAqLwogICAgaWYgKChzdWJzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSB8fAoJKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHNjaGVtYSwgCgkgICAgdHlwZS0+YmFzZVR5cGUsIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSkgewoJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzEpOyAKICAgIH0KICAgIC8qIDIuMiAqLwogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IGJhc2VUeXBlKSB7CgkvKgoJKiAyLjIuMSBEJ3Mgt2Jhc2UgdHlwZSBkZWZpbml0aW9utyBpcyBCLgoJKi8KCXJldHVybiAoMCk7CiAgICB9ICAgCiAgICAvKiAKICAgICogMi4yLjIgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgbm90IHRoZSC3dXItdHlwZSBkZWZpbml0aW9utyAKICAgICogYW5kIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEIgZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzIAogICAgKiBjb25zdHJhaW50LiAgICAKICAgICovCiAgICBpZiAoKHR5cGUtPmJhc2VUeXBlICE9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSAmJgoJKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soc2NoZW1hLCB0eXBlLT5iYXNlVHlwZSwgYmFzZVR5cGUsIHN1YnNldCkgPT0gMCkpIHsKCXJldHVybiAoMCk7CQkKICAgIH0gCiAgICAvKiAKICAgICogMi4yLjMgRCdzIHt2YXJpZXR5fSBpcyBsaXN0IG9yIHVuaW9uIGFuZCBCIGlzIHRoZSC3c2ltcGxlIHVyLXR5cGUgCiAgICAqIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmICgoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHx8CgkodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pKSAmJgoJKGJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSkgewoJcmV0dXJuICgwKTsKICAgIH0gICAgCiAgICAvKiAKICAgICogMi4yLjQgQidzIHt2YXJpZXR5fSBpcyB1bmlvbiBhbmQgRCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhIHR5cGUgCiAgICAqIGRlZmluaXRpb24gaW4gQidzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIHN1YnNldCwgYXMgCiAgICAqIGRlZmluZWQgYnkgdGhpcyBjb25zdHJhaW50LgogICAgKgogICAgKiBOT1RFOiBUaGlzIHNlZW1zIG5vdCB0byBpbnZvbHZlIGJ1aWx0LWluIHR5cGVzLCBzaW5jZSB0aGVyZSBpcyBubwogICAgKiBidWlsdC1pbiBVbmlvbiBTaW1wbGUgVHlwZS4KICAgICovCiAgICBpZiAoYmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBjdXI7CgoJY3VyID0gYmFzZVR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soc2NoZW1hLCB0eXBlLCAKCQljdXItPnR5cGUsIHN1YnNldCkgPT0gMCkKCQlyZXR1cm4gKDApOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCiAgICB9CiAgICAKICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8yKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3Mgc3QtcHJvcHMtY29ycmVjdC4KICoKICogUmV0dXJucyAwIGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSBjb3JyZWN0LAogKiBpZiBub3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBhbmQgLTEgb24gaW50ZXJuYWwKICogZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGUsIGFueVNpbXBsZVR5cGUsCglhbnlUeXBlOwogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCiAgICAvKiBTVEFURTogZXJyb3IgZnVuY3MgY29udmVydGVkLiAqLwogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIHNvbWVob3cgcmVkdW5kYW50LCBzaW5jZSB3ZSBhY3R1YWxseSBidWlsdCBhIHNpbXBsZSB0eXBlCiAgICAqIHRvIGhhdmUgYWxsIHRoZSBuZWVkZWQgaW5mb3JtYXRpb247IHRoaXMgYWN0cyBhcyBhbiBzZWxmIHRlc3QuCiAgICAqLwogICAgYW55U2ltcGxlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgLyogCiAgICAqIFRPRE86IDEgVGhlIHZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBvZiBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gbXVzdCBiZSBhcyAKICAgICogZGVzY3JpYmVkIGluIHRoZSBwcm9wZXJ0eSB0YWJsZWF1IGluIERhdGF0eXBlIGRlZmluaXRpb24sIG1vZHVsbyB0aGUgCiAgICAqIGltcGFjdCBvZiBNaXNzaW5nIFN1Yi1jb21wb25lbnRzICinNS4zKS4KICAgICovCiAgICAvKiBCYXNlIHR5cGU6IElmIHRoZSBkYXRhdHlwZSBoYXMgYmVlbiC3ZGVyaXZlZLcgYnkgt3Jlc3RyaWN0aW9utyAKICAgICogdGhlbiB0aGUgU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBjb21wb25lbnQgZnJvbSB3aGljaCBpdCBpcyC3ZGVyaXZlZLcsIAogICAgKiBvdGhlcndpc2UgdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gZm9yIGFueVNpbXBsZVR5cGUgKKc0LjEuNikuIAogICAgKi8KICAgIGlmIChiYXNlVHlwZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJObyBiYXNlIHR5cGUgZXhpc3RlbnQiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIGlmICgoYmFzZVR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgJiYKCSgoYmFzZVR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB8fAoJIChiYXNlVHlwZSA9PSBhbnlUeXBlKSkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIlRoZSBiYXNlIHR5cGUgJXMgaXMgbm90IGEgc2ltcGxlIHR5cGUiLCAKCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CglGUkVFX0FORF9OVUxMKHN0cikJCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoKGJhc2VUeXBlICE9IGFueVNpbXBsZVR5cGUpICYmCgkodHlwZS0+c3VidHlwZXMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiQSB0eXBlLCBkZXJpdmVkIGJ5IGxpc3Qgb3IgdW5pb24sIG11c3QgaGF2ZSIKCSAgICAidGhlIHNpbXBsZSB1ci10eXBlIGRlZmluaXRpb24gYXMgYmFzZSB0eXBlLCBub3QgJXMiLAoJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgLyogCiAgICAqIFZhcmlldHk6IE9uZSBvZiB7YXRvbWljLCBsaXN0LCB1bmlvbn0uIAogICAgKi8KICAgIGlmICgoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYKCSgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pID09IDApICYmCgkoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJUaGUgdmFyaWV0eSBpcyBhYnNlbnQiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIC8qIFRPRE86IEZpbmlzaCB0aGlzLiBIbW0sIGlzIHRoaXMgZmluaXNoZWQ/ICovCgogICAgLyoKICAgICogMiBBbGwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMgbXVzdCBiZSBkZXJpdmVkIHVsdGltYXRlbHkgZnJvbSB0aGUgt3NpbXBsZSAKICAgICogdXItdHlwZSBkZWZpbml0aW9uIChzb7cgY2lyY3VsYXIgZGVmaW5pdGlvbnMgYXJlIGRpc2FsbG93ZWQpLiBUaGF0IGlzLCBpdCAKICAgICogbXVzdCBiZSBwb3NzaWJsZSB0byByZWFjaCBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZSBvciB0aGUgt3NpbXBsZSAKICAgICogdXItdHlwZSBkZWZpbml0aW9utyBieSByZXBlYXRlZGx5IGZvbGxvd2luZyB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KICAgICovICAgIAogICAgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIHdoaWxlICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgKGJhc2VUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpIHsKCWlmIChiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pCgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2VUeXBlLCBjdHh0LCAgTlVMTCk7CglpZiAoYmFzZVR5cGUgPT0gYW55U2ltcGxlVHlwZSkKCSAgICBicmVhazsKCWVsc2UgaWYgKGJhc2VUeXBlID09IHR5cGUpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8yKTsKCX0JICAgCgliYXNlVHlwZSA9IGJhc2VUeXBlLT5iYXNlVHlwZTsKICAgIH0gICAKICAgIC8qCiAgICAqIDMgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCBiYXNlVHlwZSwgCglYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMywKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlICdmaW5hbCcgb2YgaXRzIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICIKCSAgICAiJ3Jlc3RyaWN0aW9uJyIsCgkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzMpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgaWYgdGhlIGdpdmVuIEB0eXBlIChzaW1wbGVUeXBlKSBpcyBkZXJpdmVkIAogKiB2YWxpZGx5IGJ5IHJlc3RyaWN0aW9uLgogKgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9ycywgMCBpZiB0aGUgdHlwZSBpcyB2YWxpZGx5IGRlcml2ZWQsIAogKiBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NUUmVzdHJpY3RzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgIAogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKCiAgICAvKiBTVEFURTogZXJyb3IgZnVuY3MgY29udmVydGVkLiAqLwoKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCSAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJICAgICJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiBUaGUgZ2l2ZW4gIgoJICAgICJ0eXBlICclcycgaXMgbm90IGEgdXNlci1kZXJpdmVkIHNpbXBsZVR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgewoJeG1sU2NoZW1hVHlwZVB0ciBwcmltaXRpdmU7CgkvKiAKCSogMS4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgYW4gYXRvbWljIHNpbXBsZSAKCSogdHlwZSBkZWZpbml0aW9uIG9yIGEgYnVpbHQtaW4gcHJpbWl0aXZlIGRhdGF0eXBlLgoJKi8JCglpZiAoKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJIlRoZSBiYXNlIHR5cGUgJXMgaXMgbm90IGFuIGF0b21pYyBzaW1wbGUgdHlwZSIsCgkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzEpOwoJfQoJLyogMS4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gCgkqIHJlc3RyaWN0aW9uLgoJKi8KCS8qIE9QVElNSVpFIFRPRE8gOiBUaGlzIGlzIGFscmVhZHkgZG9uZSBpbiB4bWxTY2hlbWFDaGVja1N0UHJvcHNDb3JyZWN0ICovCglpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCB0eXBlLT5iYXNlVHlwZSwgCgkgICAgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzIsCgkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJIlRoZSBmaW5hbCBvZiBpdHMgYmFzZSB0eXBlICVzIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzIpOwoJfQoJCgkvKiAKCSogMS4zLjEgREYgbXVzdCBiZSBhbiBhbGxvd2VkIGNvbnN0cmFpbmluZyBmYWNldCBmb3IgdGhlIHtwcmltaXRpdmUKCSogdHlwZSBkZWZpbml0aW9ufSwgYXMgc3BlY2lmaWVkIGluIHRoZSBhcHByb3ByaWF0ZSBzdWJzZWN0aW9uIG9mIDMuMiAKCSogUHJpbWl0aXZlIGRhdGF0eXBlcy4KCSovCglpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICBpbnQgb2sgPSAxOwoJICAgIAoJICAgIHByaW1pdGl2ZSA9IHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGUodHlwZSk7CgkgICAgaWYgKHByaW1pdGl2ZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCSAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogZmFpbGVkICIKCQkgICAgInRvIGdldCBwcmltaXRpdmUgdHlwZSBvZiB0eXBlICclcycuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CSAgICAKCSAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKCSAgICBkbyB7CgkJaWYgKHhtbFNjaGVtYUlzQnVpbHRJblR5cGVGYWNldChwcmltaXRpdmUsIGZhY2V0LT50eXBlKSA9PSAwKSB7CgkJICAgIG9rID0gMDsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0VycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfM18xLAoJCQlOVUxMLCB0eXBlLCBwcmltaXRpdmUsIGZhY2V0KTsJCSAgICAJCSAgICAJCSAgICAKCQl9CgkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsJICAgIAoJICAgIGlmIChvayA9PSAwKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSk7CSAgICAKCX0KCS8qCgkqIFRPRE86IDEuMy4yIChmYWNldCBkZXJpdmF0aW9uKQoJKi8KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJeG1sU2NoZW1hVHlwZVB0ciBpdGVtVHlwZSA9IE5VTEw7CgoJaXRlbVR5cGUgPSB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUpOwoJaWYgKGl0ZW1UeXBlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246ICIKCQkiZmFpbGVkIHRvIGV2YWx1YXRlIHRoZSBpdGVtIHR5cGUgb2YgdHlwZSAnJXMnLlxuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIDIuMSBUaGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgYXRvbWljIG9yIAoJKiB1bmlvbiAoaW4gd2hpY2ggY2FzZSBhbGwgdGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gCgkqIG11c3QgYmUgYXRvbWljKS4KCSovCglpZiAoKChpdGVtVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSAmJiAgCgkgICAgKChpdGVtVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pID09IDApKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJIlRoZSBpdGVtIHR5cGUgJXMgbXVzdCBoYXZlIGEgdmFyaWV0eSBvZiBhdG9taWMgb3IgdW5pb24iLAoJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgaXRlbVR5cGUsIE5VTEwsIDEpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikJICAgIAoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJfSBlbHNlIGlmIChpdGVtVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCSAgICB4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7CgoJICAgIG1lbWJlciA9IGl0ZW1UeXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoKG1lbWJlci0+dHlwZS0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAkKCQkJIlRoZSBpdGVtIHR5cGUgaXMgYSB1bmlvbiB0eXBlLCBidXQgdGhlICIKCQkJIm1lbWJlciB0eXBlICVzIG9mIHRoaXMgaXRlbSB0eXBlIGlzIG5vdCBhdG9taWMiLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIG1lbWJlci0+dHlwZSwgTlVMTCwgMSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikJCSAgICAKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSk7CgkJfQoJCW1lbWJlciA9IG1lbWJlci0+bmV4dDsKCSAgICB9Cgl9CgkKCWlmICh0eXBlLT5iYXNlVHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkgewoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxsaXN0IC4uCgkgICAgKi8KCSAgICAvKgoJICAgICogMi4zLjEgCgkgICAgKiAyLjMuMS4xIFRoZSB7ZmluYWx9IG9mIHRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IAoJICAgICogY29udGFpbiBsaXN0LgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgCgkJaXRlbVR5cGUsIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVCkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkJICAgICJUaGUgZmluYWwgb2YgaXRzIGl0ZW0gdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdsaXN0JyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgaXRlbVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMS4yIFRoZSB7ZmFjZXRzfSBtdXN0IG9ubHkgY29udGFpbiB0aGUgd2hpdGVTcGFjZQoJICAgICogZmFjZXQgY29tcG9uZW50LgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkJZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkJZG8gewoJCSAgICBpZiAoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMiwKCQkJICAgIE5VTEwsIHR5cGUsIGZhY2V0KTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIpOwoJCSAgICB9CgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBUT0RPOiBEYXRhdHlwZXMgc3RhdGVzOiAKCSAgICAqIEEgt2xpc3S3IGRhdGF0eXBlIGNhbiBiZSC3ZGVyaXZlZLcgZnJvbSBhbiC3YXRvbWljtyBkYXRhdHlwZSAKCSAgICAqIHdob3NlILdsZXhpY2FsIHNwYWNltyBhbGxvd3Mgc3BhY2UgKHN1Y2ggYXMgc3RyaW5nIG9yIGFueVVSSSlvciAKCSAgICAqIGEgt3VuaW9utyBkYXRhdHlwZSBhbnkgb2Ygd2hvc2Uge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSdzIAoJICAgICogt2xleGljYWwgc3BhY2W3IGFsbG93cyBzcGFjZS4KCSAgICAqLwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48cmVzdHJpY3Rpb24gLi4uCgkgICAgKi8KCSAgICAvKgoJICAgICogMi4zLjIgCgkgICAgKiAyLjMuMi4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiBsaXN0LgoJICAgICovCgkgICAgaWYgKCh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgPT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCQkgICAgIlRoZSBiYXNlIHR5cGUgJXMgbXVzdCBiZSBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4yLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QKCSAgICAqIGNvbnRhaW4gcmVzdHJpY3Rpb24uCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCB0eXBlLT5iYXNlVHlwZSwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCQkgICAgIlRoZSBmaW5hbCBvZiB0aGUgYmFzZSB0eXBlICVzIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzIpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMyBUaGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCAKCSAgICAqIGZyb20gdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0ncyB7aXRlbSB0eXBlIGRlZmluaXRpb259IGdpdmVuCgkgICAgKiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuCgkgICAgKi8KCSAgICB7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlSXRlbVR5cGU7CgoJCWJhc2VJdGVtVHlwZSA9IHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZS0+YmFzZVR5cGUpOwoJCWlmIChiYXNlSXRlbVR5cGUgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCVhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJCSJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiAiCgkJCSJMaXN0IHNpbXBsZSB0eXBlICclcyc6IEZhaWxlZCB0byAiCgkJCSJldmFsdWF0ZSB0aGUgaXRlbSB0eXBlIG9mIGl0cyBiYXNlIHR5cGUgJyVzJy5cbiIsCgkJCXR5cGUtPm5hbWUsIHR5cGUtPmJhc2VUeXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCWlmICgoaXRlbVR5cGUgIT0gYmFzZUl0ZW1UeXBlKSAmJgoJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhjdHh0LT5zY2hlbWEsIGl0ZW1UeXBlLAoJCSAgICBiYXNlSXRlbVR5cGUsIDApICE9IDApKSB7CgkJICAgIHhtbENoYXIgKnN0ckJJVCA9IE5VTEwsICpzdHJCVCA9IE5VTEw7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8zLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAkKCQkJIlRoZSBpdGVtIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSAiCgkJCSJpdGVtIHR5cGUgJXMgb2YgdGhlIGJhc2UgdHlwZSAlcyIsCgkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgaXRlbVR5cGUsIE5VTEwsIDEpLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJCSVQsIE5VTEwsIGJhc2VJdGVtVHlwZSwgTlVMTCwgMSksCgkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJULCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQklUKQoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJUKQkJICAgIAoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMyk7CgkJfQoJICAgIH0KCSAgICAKCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCQlpbnQgb2sgPSAxOwoJCS8qIAoJCSogMi4zLjIuNCBPbmx5IGxlbmd0aCwgbWluTGVuZ3RoLCBtYXhMZW5ndGgsIHdoaXRlU3BhY2UsIHBhdHRlcm4gCgkJKiBhbmQgZW51bWVyYXRpb24gZmFjZXQgY29tcG9uZW50cyBhcmUgYWxsb3dlZCBhbW9uZyB0aGUge2ZhY2V0c30uCgkJKi8KCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJCSAgICAvKgoJCQkgICAgKiBUT0RPOiAyLjUuMS4yIExpc3QgZGF0YXR5cGVzCgkJCSAgICAqIFRoZSB2YWx1ZSBvZiC3d2hpdGVTcGFjZbcgaXMgZml4ZWQgdG8gdGhlIHZhbHVlIGNvbGxhcHNlLiAKCQkJICAgICovCgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJCSAgICBicmVhazsKCQkJZGVmYXVsdDogewoJCQkgICAgeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80LAoJCQkJTlVMTCwgdHlwZSwgZmFjZXQpOwoJCQkgICAgLyoKCQkJICAgICogV2UgY291bGQgcmV0dXJuLCBidXQgaXQncyBuaWNlciB0byByZXBvcnQgYWxsIAoJCQkgICAgKiBpbnZhbGlkIGZhY2V0cy4KCQkJICAgICovCgkJCSAgICBvayA9IDA7CQkJICAgIAoJCQl9CgkJICAgIH0JCSAgICAKCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzQpOwoJCS8qCgkJKiBUT0RPOiAyLjMuMi41IEZvciBlYWNoIGZhY2V0IGluIHRoZSB7ZmFjZXRzfSAoY2FsbCB0aGlzIERGKSwgaWYgdGhlcmUKCQkqIGlzIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBpbiB0aGUge2ZhY2V0c30gb2YgdGhlIHtiYXNlIHR5cGUgCgkJKiBkZWZpbml0aW9ufSAoY2FsbCB0aGlzIEJGKSx0aGVuIHRoZSBERidzIHt2YWx1ZX0gbXVzdCBiZSBhIHZhbGlkIAoJCSogcmVzdHJpY3Rpb24gb2YgQkYncyB7dmFsdWV9IGFzIGRlZmluZWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgoJCSovCgkgICAgfQkgICAgCgkgICAgCgoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJLyoKCSogMy4xIFRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgYWxsIGhhdmUge3ZhcmlldHl9IG9mIAoJKiBhdG9taWMgb3IgbGlzdC4KCSovCgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7CgoJbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7Cgl3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCSAgICBpZiAoKChtZW1iZXItPnR5cGUtPmZsYWdzICYgCgkJWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYgCgkJKChtZW1iZXItPnR5cGUtPmZsYWdzICYgCgkJWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBtZW1iZXIgdHlwZSAlcyBpcyBuZWl0aGVyIGFuIGF0b21pYywgbm9yIGEgbGlzdCB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18xKTsKCSAgICB9CgkgICAgbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJfQoJLyoKCSogMy4zLjEgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILdzaW1wbGUgdXItdHlwZSAKCSogZGVmaW5pdGlvbrcgCgkqLwoJaWYgKHR5cGUtPmJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSB7CgkgICAgLyoKCSAgICAqIDMuMy4xLjEgQWxsIG9mIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgaGF2ZSBhIAoJICAgICoge2ZpbmFsfSB3aGljaCBkb2VzIG5vdCBjb250YWluIHVuaW9uLgoJICAgICovCgkgICAgbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgbWVtYmVyLT50eXBlLCAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTikpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlIGZpbmFsIG9mIG1lbWJlciB0eXBlICVzIGNvbnRhaW5zICd1bmlvbiciLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIG1lbWJlci0+dHlwZSwgTlVMTCwgMSkpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikJCSAgIAoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMS4yIFRoZSB7ZmFjZXRzfSBtdXN0IGJlIGVtcHR5LgoJICAgICovCgkgICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzFfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCgkJICAgICJObyBmYWNldHMgYWxsb3dlZCIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMV8yKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAzLjMuMi4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiB1bmlvbi4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYmFzZSB0eXBlICVzIGlzIG5vdCBhIHVuaW9uIHR5cGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIHJlc3RyaWN0aW9uLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgZmluYWwgb2YgaXRzIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMik7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMi4zIFRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9LCBpbiBvcmRlciwgbXVzdCBiZSB2YWxpZGx5IAoJICAgICogZGVyaXZlZCBmcm9tIHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgZGVmaW5pdGlvbnMgaW4gdGhlIHtiYXNlIAoJICAgICogdHlwZSBkZWZpbml0aW9ufSdzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIGVtcHR5IHNldCwgCgkgICAgKiBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNikuCgkgICAgKi8KCSAgICB7CgkJeG1sU2NoZW1hVHlwZUxpbmtQdHIgYmFzZU1lbWJlcjsKCgkJLyoKCQkqIE9QVElNSVpFOiBpZiB0aGUgdHlwZSBpcyByZXN0cmljdGluZywgaXQgaGFzIG5vIGxvY2FsIGRlZmluZWQgCgkJKiBtZW1iZXIgdHlwZXMgYW5kIGluaGVyaXRzIHRoZSBtZW1iZXIgdHlwZXMgb2YgdGhlIGJhc2UgdHlwZTsgCgkJKiB0aHVzIGEgY2hlY2sgZm9yIGVxdWFsaXR5IGNhbiBiZSBza2lwcGVkLgoJCSovCgkJLyoKCQkqIFRPRE86IEV2ZW4gd29yc2U6IEkgY2Fubm90IHNlZSBhIHNjZW5hcmlvIHdoZXJlIGEgcmVzdHJpY3RpbmcKCQkqIHVuaW9uIHNpbXBsZSB0eXBlIGNhbiBoYXZlIG90aGVyIG1lbWJlciB0eXBlcyBhcyB0aGUgbWVtYmVyIAoJCSogdHlwZXMgb2YgaXQncyBiYXNlIHR5cGUuIFRoaXMgY2hlY2sgc2VlbXMgbm90IG5lY2Vzc2FyeSB3aXRoCgkJKiByZXNwZWN0IHRvIHRoZSBkZXJpdmF0aW9uIHByb2Nlc3MgaW4gbGlieG1sMi4KCQkqLwoJCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKSB7CgkJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJCSAgICBiYXNlTWVtYmVyID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZS0+YmFzZVR5cGUpOwoJCSAgICBpZiAoKG1lbWJlciA9PSBOVUxMKSAmJiAoYmFzZU1lbWJlciAhPSBOVUxMKSkgewkJICAgCgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiAiCgkJCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbiAiCgkJCSAgICAiKDMuMy4yLjMpLCB1bmlvbiBzaW1wbGUgdHlwZSAnJXMnLCB1bmVxdWFsIG51bWJlciAiCgkJCSAgICAib2YgbWVtYmVyIHR5cGVzIGluIHRoZSBiYXNlIHR5cGVcbiIsCgkJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQkgICAgfQkJCgkJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCQlpZiAoYmFzZU1lbWJlciA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogIgoJCQkJInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb24gIgoJCQkJIigzLjMuMi4zKSwgdW5pb24gc2ltcGxlIHR5cGUgJyVzJywgdW5lcXVhbCBudW1iZXIgIgoJCQkJIm9mIG1lbWJlciB0eXBlcyBpbiB0aGUgYmFzZSB0eXBlLlxuIiwKCQkJCXR5cGUtPm5hbWUsIE5VTEwpOwoJCQl9CgkJCWlmICgobWVtYmVyLT50eXBlICE9IGJhc2VNZW1iZXItPnR5cGUpICYmCgkJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhjdHh0LT5zY2hlbWEsIAoJCQkgICAgbWVtYmVyLT50eXBlLCBiYXNlTWVtYmVyLT50eXBlLCAwKSAhPSAwKSkgewoJCQkgICAgeG1sQ2hhciAqc3RyQk1UID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzMsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkJIlRoZSBtZW1iZXIgdHlwZSAlcyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gaXRzICIKCQkJCSJjb3JyZXNwb25kaW5nIG1lbWJlciB0eXBlICVzIG9mIHRoZSBiYXNlIHR5cGUgJXMiLAoJCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpLAoJCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyQk1ULCBOVUxMLCBiYXNlTWVtYmVyLT50eXBlLCBOVUxMLCAxKSwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJULCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJNVCkKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyQlQpCgkJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMyk7CgkJCX0JCQoJCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkJCWJhc2VNZW1iZXIgPSBiYXNlTWVtYmVyLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuNCBPbmx5IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIAoJICAgICogYWxsb3dlZCBhbW9uZyB0aGUge2ZhY2V0c30uCgkgICAgKi8JICAgIAoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQsCgkJCQlOVUxMLCB0eXBlLCBmYWNldCk7CQkJCgkJCW9rID0gMDsJCQkgICAgCgkJICAgIH0JCSAgICAKCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQpOwoJCSAgICAKCSAgICB9CgkgICAgLyoKCSAgICAqIFRPRE86IDMuMy4yLjUgKGZhY2V0IGRlcml2YXRpb24pCgkgICAgKi8KCX0KICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgY3JjLXNpbXBsZS10eXBlIGNvbnN0cmFpbnRzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgIAogICAgLyoKICAgICogTk9URTogc3JjLXNpbXBsZS10eXBlIDItNCBhcmUgcmVkdW5kYW50LCBzaW5jZSB0aGUgY2hlY2tzCiAgICAqIHdlcmUgYXJlIGRvbmUgZm9yIHRoZSBjb3JyZXNwb25kaW5nIDxyZXN0cmljdGlvbj4sIDxsaXN0PiBhbmQgPHVuaW9uPgogICAgKiBlbGVtZW50cywgYnV0IFczQyB3YW50cyBhIDxzaW1wbGVUeXBlPiBlcnJvciBhcyB3ZWxsLCBzbyBpdCBnZXRzIG9uZS4KICAgICogTWFieSB0aGlzIGNhbiBiZSBza2lwcGVkIGluIHRoZSBmdXR1cmUsIGlmIHdlIGdldCBzdXJlIGl0J3Mgbm90IG5lZWRlZC4KICAgICovCiAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlLCAiCgkJIm5vIHN1YnR5cGUgb24gc2ltcGxlIHR5cGUgJyVzJy5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qIAogICAgKiBzcmMtc2ltcGxlLXR5cGUuMSBUaGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCBpZiBhbnksCiAgICAqIG11c3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9ucyBzZXQgb3V0IGluIENvbnN0cmFpbnRzIG9uIFNpbXBsZSBUeXBlIAogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy4xNC42KS4gICAgCiAgICAqLwogICAgaWYgKCh4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KGN0eHQsIHR5cGUpICE9IDApIHx8CgkoeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyhjdHh0LCB0eXBlKSAhPSAwKSkgewoJLyoKCSogVE9ETzogUmVtb3ZlZCB0aGlzLCBzaW5jZSBpdCBnb3QgYW5ub3lpbmcgdG8gZ2V0IGFuCgkqIGV4dHJhIGVycm9yIHJlcG9ydCwgaWYgYW55dGhpbmcgZmFpbGVkIHVudGlsIG5vdy4KCSogRW5hYmxlIHRoaXMgaWYgbmVlZGVkLgoJKi8KCS8qCgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgIlNpbXBsZSB0eXBlICclcycgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY29uc3RyYWludHMgIgoJICAgICJvbiBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucy5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMSk7CiAgICB9CgogICAgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewoJLyoKCSogc3JjLXNpbXBsZS10eXBlLjIgSWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCAKCSogZWl0aGVyIGl0IG11c3QgaGF2ZSBhIGJhc2UgW2F0dHJpYnV0ZV0gb3IgYSA8c2ltcGxlVHlwZT4gYW1vbmcgaXRzIAoJKiBbY2hpbGRyZW5dLCBidXQgbm90IGJvdGguCgkqLwkKCS8qCgkqIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8yCgkqIE5PVEU6IFRoaXMgd2FzIHJlbW92ZWQsIHNpbmNlIHRoaXMgd2lsbCBiZSBhbHJlYWR5IGhhbmRsZWQKCSogaW4gdGhlIHBhcnNlIGZ1bmN0aW9uIGZvciA8cmVzdHJpY3Rpb24+LiAKCSovCQogICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewoJLyogc3JjLXNpbXBsZS10eXBlLjMgSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIGVpdGhlciBpdCBtdXN0IGhhdmUgCgkqIGFuIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyBbY2hpbGRyZW5dLCAKCSogYnV0IG5vdCBib3RoLgoJKiBOT1RFOiBiYXNlVHlwZSBpcyBzZXQgdG8gdGhlIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRvbiwKCSogaWYgZXhpc3RlbnQsIGF0IHBhcnNlIHRpbWUuIFRoaXMgaXMgYSBoYWNrIGFuZCBub3QgbmljZS4KCSovCgkvKgoJKiBUT0RPOiBSZW1vdmUgdGhpcywgYW5kIGFkZCB0aGUgY2hlY2sgdG8gdGhlIHBhcnNlIGZ1bmN0aW9uIG9mIDxsaXN0Pi4KCSovCglpZiAoKCh0eXBlLT5zdWJ0eXBlcy0+YmFzZSA9PSBOVUxMKSAmJiAKCSAgICAgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpKSB8fAkgICAgICAKCSAgICAoKHR5cGUtPnN1YnR5cGVzLT5iYXNlICE9IE5VTEwpICYmCgkgICAgICh0eXBlLT5zdWJ0eXBlcy0+YmFzZVR5cGUgIT0gTlVMTCkpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMywKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJFaXRoZXIgdGhlIGF0dHJpYnV0ZSAnaXRlbVR5cGUnIG9yIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJtdXN0IGJlIHByZXNlbnQgb24gdGhlIDxsaXN0PiBjaGlsZCAiLCBOVUxMKTsJICAgIAoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzMpOwoJfQogICAgCgogICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfVU5JT04pIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcjsKCXhtbFNjaGVtYVR5cGVQdHIgYW5jZXN0b3IsIGFueVNpbXBsZVR5cGU7CgoJYW55U2ltcGxlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoKCS8qIHNyYy1zaW1wbGUtdHlwZS40IENpcmN1bGFyIHVuaW9uIHR5cGUgZGVmaW5pdGlvbiBpcyBkaXNhbGxvd2VkLiBUaGF0IGlzLCBpZiAKCSogdGhlIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVyZSBtdXN0IG5vdCBiZSBhbnkgZW50cmllcyAKCSogaW4gdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIGF0IGFueSBkZXB0aCB3aGljaCByZXNvbHZlIHRvIHRoZSAKCSogY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPi4KCSovCQoJbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7Cgl3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCSAgICBhbmNlc3RvciA9IG1lbWJlci0+dHlwZTsKCSAgICB3aGlsZSAoKGFuY2VzdG9yICE9IE5VTEwpICYmIChhbmNlc3Rvci0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CgkJaWYgKGFuY2VzdG9yLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGFuY2VzdG9yLCBjdHh0LCAgTlVMTCk7CgkJaWYgKGFuY2VzdG9yID09IGFueVNpbXBsZVR5cGUpCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKGFuY2VzdG9yID09IHR5cGUpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzQsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCQl9IGVsc2UgaWYgKGFuY2VzdG9yLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJICAgIC8qCgkJICAgICogVE9ETywgRklYTUU6IEFsdGhvdWdoIGEgbGlzdCBzaW1wbGUgdHlwZSBtdXN0IG5vdCBoYXZlIGEgdW5pb24gU1QKCQkgICAgKiB0eXBlIGFzIGl0ZW0gdHlwZSwgd2hpY2ggaW4gdHVybiBoYXMgYSBsaXN0IFNUIGFzIG1lbWJlciAKCQkgICAgKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGlzIGhlcmUgYXMgd2VsbCwgc2luY2UgdGhpcyBjaGVjayAKCQkgICAgKiB3YXMgbm90IHlldCBwZXJmb3JtZWQuCgkJICAgICovCgoJCX0KCQlhbmNlc3RvciA9IGFuY2VzdG9yLT5iYXNlVHlwZTsKCSAgICB9ICAgCgkgICAgbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIE5vdCB5ZXQgdXNlZCBjb2RlIGZvciBDVCBzY2hlbWEgdmFsaWRhdGlvbiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDU2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgIGludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0OwogICAgLyoKICAgICogMy4xNC40IFNpbXBsZSBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwogICAgKiBWYWxpZGF0aW9uIFJ1bGU6IFN0cmluZyBWYWxpZAogICAgKi8KICAgIC8qCiAgICAqIDEgSXQgaXMgc2NoZW1hLXZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCAKICAgICogYnkgRGF0YXR5cGUgVmFsaWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUsIHZhbHVlLCAKCWZpcmVFcnJvcnMsIDEsIDEsIDEpOwogICAgcmV0dXJuIChyZXQpOwogICAgLyoKICAgICogMi4xIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUWSBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVFkgZ2l2ZW4gCiAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgdGhlbgogICAgKiB0aGUgc3RyaW5nIG11c3QgYmUgYSC3ZGVjbGFyZWQgZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMiBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVElFUyBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVElFUyAKICAgICogZ2l2ZW4gdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLCAKICAgICogdGhlbiBldmVyeSB3aGl0ZXNwYWNlLWRlbGltaXRlZCBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkIAogICAgKiBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4zIG90aGVyd2lzZSBubyBmdXJ0aGVyIGNvbmRpdGlvbiBhcHBsaWVzLgogICAgKi8KCiAgICByZXR1cm4gKDApOwp9CiNlbmRpZgoKCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICBpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKICAgICAgICB2Y3R4dC0+cGN0eHQgPXhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KCIqIiwgdmN0eHQtPnNjaGVtYS0+ZGljdCk7CgkvKiB2Y3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7ICovCglpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCBOVUxMLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0LCAiCgkJImZhaWxlZCB0byBjcmVhdGUgYSB0ZW1wLiBwYXJzZXIgY29udGV4dC5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh2Y3R4dC0+cGN0eHQsIHZjdHh0LT5lcnJvciwgdmN0eHQtPndhcm5pbmcsIE5VTEwpOwkKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICBpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJY3R4dC0+dmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCwgIgoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qIFRPRE86IFBhc3MgdXNlciBkYXRhLiAqLwoJeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoY3R4dC0+dmN0eHQsIGN0eHQtPmVycm9yLCBjdHh0LT53YXJuaW5nLCBOVUxMKTsJCiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWx1ZTogdGhlIGRlZmF1bHQgdmFsdWUKICogQG5vZGU6IGFuIG9wdGlvbmFsIG5vZGUgKHRoZSBob2xkZXIgb2YgdGhlIHZhbHVlKQogKgogKiBDaGVja3MgdGhlICJjb3MtdmFsaWQtZGVmYXVsdCIgY29uc3RyYWludHMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwKICogaWYgbm90LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dCwKCQkJICAgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsgICAKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIGNvcy12YWxpZC1kZWZhdWx0OgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKQogICAgKiBGb3IgYSBzdHJpbmcgdG8gYmUgYSB2YWxpZCBkZWZhdWx0IHdpdGggcmVzcGVjdCB0byBhIHR5cGUgCiAgICAqIGRlZmluaXRpb24gdGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgLyoKICAgICogTk9URTogVGhpcyBoYXMgdG8gd29yayB3aXRob3V0IGEgZ2l2ZW4gbm9kZSAodGhlIGhvbGRlciBvZiB0aGUKICAgICogdmFsdWUpLCBzaW5jZSBpdCBzaG91bGQgd29yayBvbiB0aGUgY29tcG9uZW50LCBpLmUuIGFuIHVuZGVybHlpbmcKICAgICogRE9NIG11c3Qgbm90IGJlIG1hbmRhdG9yeS4KICAgICovICAgICAKICAgIGlmICgocGN0eHQgPT0gTlVMTCkgfHwgKHZjdHh0ID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBub2RlLAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQsICIKCSAgICAiYmFkIGFyZ3VtZW50czogdGhlIHBhcnNlciBhbmQvb3IgdmFsaWRhdGlvbiBjb250ZXh0IGlzICIKCSAgICAibWlzc2luZy5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsJCiAgICB9ICAgICAgIAogICAgaWYgSVNfQ09NUExFWF9UWVBFKHR5cGUpIHsKCS8qCgkqIENvbXBsZXggdHlwZS4KCSoKCSogMi4xIGl0cyB7Y29udGVudCB0eXBlfSBtdXN0IGJlIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBvciBtaXhlZC4KCSovCgkvKiAKCSogVE9ETzogQWRqdXN0IHRoaXMgd2hlbiB0aGUgY29udGVudCB0eXBlIHdpbGwgYmUgY29tcHV0ZWQgCgkqIGNvcnJlY3RseS4gCgkqLwoJaWYgKCh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSAmJgoJICAgICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpICYmCgkgICAgKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihwY3R4dCwgCgkJWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJdHlwZSwgTlVMTCwgTlVMTCwKCQkiSWYgdGhlIHR5cGUgb2YgYSBjb25zdHJhaW50IHZhbHVlIGlzIGNvbXBsZXgsIGl0cyBjb250ZW50ICIKCQkidHlwZSBtdXN0IGJlIG1peGVkIG9yIGEgc2ltcGxlIHR5cGUiLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybihYTUxfU0NIRU1BUF9DT1NfVkFMSURfREVGQVVMVF8yXzEpOwoJfQoJaWYgKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgewoJICAgIC8qCgkgICAgKiAyLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgbWl4ZWQsIHRoZW4gdGhlIHtjb250ZW50IHR5cGV9J3MgCgkgICAgKiBwYXJ0aWNsZSBtdXN0IGJlILdlbXB0aWFibGW3IGFzIGRlZmluZWQgYnkgUGFydGljbGUgRW1wdGlhYmxlIAoJICAgICogKKczLjkuNikuCgkgICAgKi8KCSAgICAKCSAgICAvKgoJICAgICogVVJHRU5UIFRPRE86IEltcGxlbWVudCB0aGlzLgoJICAgICovCgkgICAgcmV0dXJuICgwKTsKCX0KICAgIH0JCiAgICAvKgogICAgKiAxIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBzdHJpbmcgCiAgICAqIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIAogICAgKiBWYWxpZCAopzMuMTQuNCkuCiAgICAqCiAgICAqIEFORAogICAgKgogICAgKiAyLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSAKICAgICogc3RyaW5nIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIAogICAgKiBhcyBkZWZpbmVkIGJ5IFN0cmluZyBWYWxpZCAopzMuMTQuNCkuCiAgICAqLyAgICAKICAgIHZjdHh0LT5ub2RlID0gbm9kZTsKICAgIHZjdHh0LT5jdXIgPSBOVUxMOwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUodmN0eHQsIHR5cGUsIHZhbHVlLCAxLCAxLCAxLCAwKTsKICAgIC8qIHJldCA9IHhtbFNjaGVtYUNoZWNrQ1ZDU2ltcGxlVHlwZSh2Y3R4dCwgZWxlbURlY2wtPnZhbHVlLCB0eXBlRGVmLCAwKTsgKi8gICAKICAgIGlmIChyZXQgPCAwKSB7Cgl4bWxTY2hlbWFQRXJyKHBjdHh0LCBub2RlLAoJLyogTk9UTklDRTogZXJyb3IgY29kZTogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIHVzZWQgZHVyaW5nCgkqIHNjaGVtYSBjb25zdHJ1Y3Rpb24gYW5kIHhzaTp0eXBlIHZhbGlkYXRpb24uCgkqLwoJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0LCAiCgkid2hpbGUgdmFsaWRhdGluZyBhIHZhbHVlIGNvbnN0YWludCB2YWx1ZS5cbiIsCglOVUxMLCBOVUxMKTsKCiAgICB9ICAgICAJICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgojaWYgMCAvKiBOb3QgeWV0IHVzZWQgY29kZSBmb3IgQ1Qgc2NoZW1hIHZhbGlkYXRpb24gKi8KLyoqCiAqIHhtbFNjaGVtYUdldFNUQ29udGVudE9mQ1Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKgogKiBSZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZSB0eXBlIGZvciB0aGUgY29udGVudCBvZgogKiB0aGUgY29tcGxleCB0eXBlLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0U1RDb250ZW50T2ZDVCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvcmlnID0gdHlwZSwgYW55VHlwZTsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICB3aGlsZSAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUgIT0gYW55VHlwZSkgJiYgCgkodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpCgkgICAgcmV0dXJuKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJWE1MX1NDSEVNQVBfSU5URVJOQUwsCglOVUxMLCBvcmlnLCBOVUxMLAoJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRTVENvbnRlbnRUeXBlT2ZDVCwgIgoJIm5vIHNpbXBsZSB0eXBlIGZvciB0aGUgY29udGVudCBvZiBjb21wbGV4IHR5cGUgJyVzJyBjb3VsZCBiZSAiCgkiY29tcHV0ZWQiLCBvcmlnLT5uYW1lKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCgoKCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kczoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsIGEgcG9zaXRpdmUKICogZXJyb3IgY29kZSBpZiBub3QgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3VyZWQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CiAgICAvKiAKICAgICogMSBJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLCAKICAgICogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kcywgIgoJICAgICJ0aGUgY29tcGxleCB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZSIsIHR5cGUtPm5hbWUpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAoYmFzZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJLyoKCSogMS4xIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IAoJKiBjb250YWluIGV4dGVuc2lvbi4KCSovCglpZiAoYmFzZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTikgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiVGhlICdmaW5hbCcgb2YgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uICIKCQkiY29udGFpbnMgZXh0ZW5zaW9uIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzEpOwoJfQoJLyoKCSogMS4yIEl0cyB7YXR0cmlidXRlIHVzZXN9IG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlIHthdHRyaWJ1dGUgdXNlc30gCgkqIG9mIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYsIHRoYXQgaXMsIGZvciBldmVyeSBhdHRyaWJ1dGUgCgkqIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSwgdGhlcmUgCgkqIG11c3QgYmUgYW4gYXR0cmlidXRlIHVzZSBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUgY29tcGxleCAKCSogdHlwZSBkZWZpbml0aW9uIGl0c2VsZiB3aG9zZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBoYXMgdGhlIHNhbWUgCgkqIHtuYW1lfSwge3RhcmdldCBuYW1lc3BhY2V9IGFuZCB7dHlwZSBkZWZpbml0aW9ufSBhcyBpdHMgYXR0cmlidXRlIAoJKiBkZWNsYXJhdGlvbgoJKgoJKiBOT1RFOiBUaGlzIHdpbGwgYmUgYWxyZWFkeSBzYXRpc2ZpZWQgYnkgdGhlIHdheSB0aGUgYXR0cmlidXRlIHVzZXMKCSogYXJlIGV4dGVuZGVkIGluIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjsgdGh1cyB0aGlzIGNoZWNrCgkqIGlzIG5vdCBuZWVkZWQuCgkqLwoKCS8qCgkqIDEuMyBJZiBpdCBoYXMgYW4ge2F0dHJpYnV0ZSB3aWxkY2FyZH0sIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiAKCSogbXVzdCBhbHNvIGhhdmUgb25lLCBhbmQgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSAKCSogd2lsZGNhcmR9J3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSBjb21wbGV4IAoJKiB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0sIAoJKiBhcyBkZWZpbmVkIGJ5IFdpbGRjYXJkIFN1YnNldCAopzMuMTAuNikuCgkqCgkqIFRoaXMgaXMgYWxyZWFkeSBjaGVja2VkIGluIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjsgdGh1cyAKCSogdGhpcyBjaGVjayBpcyBub3QgbmVlZGVkLgoJKi8KCQoJLyoKCSogMS40IE9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSoKCSogMS40LjEgVGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGFuZCB0aGUgCgkqIHtjb250ZW50IHR5cGV9IG9mIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgbXVzdCBiZSB0aGUgc2FtZSAKCSogc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgoJKi8KCgoJCiAgICB9IGVsc2UgewoJLyoKCSogMiBJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIAoJKiB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKCSovCgkvKgoJKiAyLjEgVGhlIHtjb250ZW50IHR5cGV9IG11c3QgYmUgdGhlIHNhbWUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSovCgkvKgoJKiAyLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiAKCSogZXh0ZW5zaW9uCgkqLwogICAgfQoKfQoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NSQ0NUKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlLCBjb250ZW50OwogICAgaW50IE9LID0gMDsKCiAgICAvKgogICAgKiBUT0RPOiBBZGp1c3QgdGhlIGVycm9yIGNvZGVzIGhlcmUsIGFzIEkgdXNlZAogICAgKiBYTUxfU0NIRU1BUF9TUkNfQ1RfMSBvbmx5IHlldC4KICAgICovCiAgICAvKgogICAgKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDogCiAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFJlcHJlc2VudGF0aW9uIE9LCiAgICAqLwogICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDQ1QsICclcycsIG5vIGJhc2UgdHlwZSIsIAoJICAgIHR5cGUtPm5hbWUpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAKICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CglpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJICAgIGlmIElTX0NPTVBMRVhfVFlQRShiYXNlKSB7CgkJLyoKCQkqIDEgSWYgdGhlIDxjb21wbGV4Q29udGVudD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGUgdHlwZSBkZWZpbml0aW9uCgkJKiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXSAKCQkqIG11c3QgYmUgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbjsKCQkqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgYmFzZSB0eXBlIGlzIG5vdCBhIGNvbXBsZXggdHlwZSIsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJICAgIH0KCX0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CgoJICAgIGlmIElTX1NJTVBMRV9UWVBFKGJhc2UpIHsKCQlpZiAodHlwZS0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewoJCSAgICAvKiAKCQkgICAgKiAyLjEuMyBvbmx5IGlmIHRoZSA8ZXh0ZW5zaW9uPiBhbHRlcm5hdGl2ZSBpcyBhbHNvIAoJCSAgICAqIGNob3NlbiwgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJCSAgICAqLwoJCSAgICAvKiBUT0RPOiBDaGFuZ2UgZXJyb3IgY29kZSB0byAuLi5fU1JDX0NUXzJfMV8zLiAqLwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiQSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW5ub3QgcmVzdHJpY3QgIgoJCQkiYW4gb3RoZXIgc2ltcGxlIHR5cGUiLAoJCQlOVUxMKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJfQoJCU9LID0gMTsKCgkgICAgfSBlbHNlIHsgLyogaWYgSVNfU0lNUExFX1RZUEUoYmFzZSkgKi8KCQlpZiAoYmFzZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHsKCQkgICAgLyoKCQkgICAgKiAyLjEuMiBvbmx5IGlmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGFsc28gCgkJICAgICogY2hvc2VuLCBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIHtjb250ZW50IHR5cGV9IAoJCSAgICAqIGlzIG1peGVkIGFuZCBhIHBhcnRpY2xlIGVtcHR5YWJsZS4KCQkgICAgKi8JCgkJICAgIC8qCgkJICAgICogRklYTUUgVE9ETzogQ2hlY2sgZm9yICplbXBpYWJsZSBwYXJ0aWNsZSogaXMgbWlzc2luZy4gCgkJICAgICovCgkJICAgIGlmICgodHlwZS0+ZmxhZ3MgJiAKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgPT0gMCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW5ub3QgIgoJCQkgICAgImV4dGVuZCBhbiBvdGhlciBjb21wbGV4IHR5cGUgd2hpY2ggaGFzIGEgIgoJCQkgICAgImNvbnRlbnQgdHlwZSBvZjogJ21peGVkJyBhbmQgZW1wdGlhYmxlIHBhcnRpY2xlIiwKCQkJICAgIE5VTEwpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIE5PVEU6IFRoaXMgd2lsbCBiZSBmaXJlZCBhcyB3ZWxsLCBpZiB0aGUgYmFzZSB0eXBlCgkJICAgICogaXMgKidhbnlUeXBlJyouCgkJICAgICogTk9URTogdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzIHdpbGwgYmUgdGhlIAoJCSAgICAqIDxyZXN0cmljdGlvbj4gaXRlbS4KCQkgICAgKi8KCQkgICAgaWYgKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CgkJCS8qIFllcywgdGhpcyBpcyBwYXJhbm9pZCBwcm9ncmFtbWluZy4gKi8KCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwgCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja1NSQ0NULCAiCgkJCSAgICAiJyVzJywgPHNpbXBsZUNvbnRlbnQ+IGhhcyBubyA8cmVzdHJpY3Rpb24+IiwgCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiAyLjIgSWYgY2xhdXNlIDIuMS4yIGFib3ZlIGlzIHNhdGlzZmllZCwgdGhlbiB0aGVyZSAKCQkgICAgKiBtdXN0IGJlIGEgPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIAoJCSAgICAqIDxyZXN0cmljdGlvbj4uCgkJICAgICovCiAgICAJCSAgICBpZiAodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT50eXBlICE9CgkJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCQkJLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzIuICovCgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJBIDxzaW1wbGVUeXBlPiBpcyBleHBlY3RlZCBhbW9uZyB0aGUgY2hpbGRyZW4gIgoJCQkgICAgIm9mIDxyZXN0cmljdGlvbj4iLCBOVUxMKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0gCgkJICAgIE9LID0gMTsKCQl9IGVsc2UgeyAvKiBpZiAoYmFzZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKi8KCQkgICAgLyoKCQkgICAgKiAyLjEuMSBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIHtjb250ZW50IHR5cGV9IGlzIGEgCgkJICAgICogc2ltcGxlIHR5cGUgZGVmaW5pdGlvbjsKCQkgICAgKi8KCQkgICAgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUykgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW5ub3QgIgoJCQkgICAgImJlIGRlcml2ZWQgZnJvbSB0aGUgY29tcGxleCB0eXBlICclcyciLCAKCQkJICAgIGJhc2UtPm5hbWUpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQkgICAgfQoJCSAgICBjb250ZW50ID0gYmFzZS0+Y29udGVudFR5cGVEZWY7CgkJICAgIGlmIChjb250ZW50ID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwgCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja1NSQ0NULCAiCgkJCSAgICAiJyVzJywgYmFzZSB0eXBlIGhhcyBubyBjb250ZW50IHR5cGUiLCAKCQkJICAgIHR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICBpZiAoY29udGVudC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJBIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbm5vdCAiCgkJCSAgICAiYmUgZGVyaXZlZCBmcm9tIHRoZSBjb21wbGV4IHR5cGUgJyVzJyIsIAoJCQkgICAgYmFzZS0+bmFtZSk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCSAgICB9CgkJfQoJICAgIH0gCgl9IAkgICAgCQogICAgfQogICAgLyoKICAgICogVE9ETzogMyBUaGUgY29ycmVzcG9uZGluZyBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiBjb21wb25lbnQgbXVzdCAKICAgICogc2F0aXNmeSB0aGUgY29uZGl0aW9ucyBzZXQgb3V0IGluIENvbnN0cmFpbnRzIG9uIENvbXBsZXggVHlwZSAKICAgICogRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cyAopzMuNC42KTsKICAgICoKICAgICogVE9ETzogNCBJZiBjbGF1c2UgMi4yLjEgb3IgY2xhdXNlIDIuMi4yIGluIHRoZSBjb3JyZXNwb25kZW5jZSBzcGVjaWZpY2F0aW9uIAogICAgKiBhYm92ZSBmb3Ige2F0dHJpYnV0ZSB3aWxkY2FyZH0gaXMgc2F0aXNmaWVkLCB0aGUgaW50ZW5zaW9uYWwgCiAgICAqIGludGVyc2VjdGlvbiBtdXN0IGJlIGV4cHJlc3NpYmxlLCBhcyBkZWZpbmVkIGluIEF0dHJpYnV0ZSBXaWxkY2FyZCAKICAgICogSW50ZXJzZWN0aW9uICinMy4xMC42KS4KICAgICovCgp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYUdyb3VwRGVmRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4ZXMgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFHcm91cERlZkZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgZ3JvdXAsCgkJICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsgICAgCiAgICBncm91cC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICBpZiAoKGdyb3VwLT5yZWYgIT0gTlVMTCkgJiYgKGdyb3VwLT5zdWJ0eXBlcyA9PSBOVUxMKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBncm91cERlZjsKCS8qCgkqIFJlc29sdmUgdGhlIHJlZmVyZW5jZS4KCSovCglncm91cERlZiA9IHhtbFNjaGVtYUdldEdyb3VwKGN0eHQtPnNjaGVtYSwgZ3JvdXAtPnJlZiwKCSAgICBncm91cC0+cmVmTnMpOwoJaWYgKGdyb3VwRGVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIAoJCU5VTEwsIGdyb3VwLCBOVUxMLAoJCSJyZWYiLCBncm91cC0+cmVmLCBncm91cC0+cmVmTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9HUk9VUCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoJZ3JvdXAtPnN1YnR5cGVzID0gZ3JvdXBEZWY7CiAgICB9CQkKfQoKI2lmIDAgLyogRW5hYmxlIHdoZW4gdGhlIGNvbnRlbnQgdHlwZSB3aWxsIGJlIGNvbXB1dGVkLiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNvbXB1dGVDb250ZW50VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlLCByZXMgPSBOVUxMOwoKICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCSAgICAidGhlIGNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfSAgIAogICAgaWYgKElTX0FOWVRZUEUoYmFzZSkgfHwgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IAoJICAgIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHN0YXJ0OwoJLyoKCSogRWZmZWN0aXZlICdtaXhlZCcuCgkqLwoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCSAgICAgdHlwZS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CgkvKgoJKiBFZmZlY3RpdmUgY29udGVudC4KCSovCglpZiAoSVNfQU5ZVFlQRShiYXNlKSkgCgkgICAgc3RhcnQgPSB0eXBlOwoJZWxzZQoJICAgIHN0YXJ0ID0gdHlwZS0+c3VidHlwZXM7CgkgCiAgICB9IGVsc2UgeyAvKiBpZiBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UICovCgl4bWxTY2hlbWFUeXBlUHRyIGJhc2VDb250ZW50SXRlbTsKCgkvKgoJKiBDb21wbGV4IHR5cGUgd2l0aCBzaW1wbGUgY29udGVudC4KCSovCglpZiBJU19DT01QTEVYX1RZUEUoYmFzZSkgewoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsJCgkJLyoKCQkqIFN1bW1hcnk6IGEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2FuICpyZXN0cmljdCoKCQkqIGEgY29tcGxleCB0eXBlIHdpdGggdGhlIGZvbGxvd2luZyBjb250ZW50IHR5cGU6CgkJKiAxLiAnbWl4ZWQnIGFuZCBhbiBlbXB0aWFibGUgcGFydGljbGUKCQkqIDIuIHNpbXBsZSB0eXBlCgkJKi8KCQlpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkJICAgIC8qCgkJICAgICogMiBpZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGJhc2UgdHlwZSBpcyBtaXhlZCBhbmQgYSAKCQkgICAgKiBwYXJ0aWNsZSB3aGljaCBpcyC3ZW1wdGlhYmxltywgCgkJICAgICogWy4uLl0gCgkJICAgICogdGhlbiBzdGFydGluZyBmcm9tIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIAoJCSAgICAqIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSAKCQkgICAgKiBvZiA8cmVzdHJpY3Rpb24+ICgqKndoaWNoIG11c3QgYmUgcHJlc2VudCoqKQoJCSAgICAqCgkJICAgICogRklYTUUgVE9ETzogSGFuZGxlICJlbXB0aWFibGUgcGFydGljbGUiLgoJCSAgICAqLwoJCSAgICByZXMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXM7CgkJICAgIGlmIChyZXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSAgICAiQ1QgJyVzJyAocmVzdHJpY3RpbmcpOiA8c2ltcGxlQ29udGVudD4gaGFzIG5vICIKCQkJICAgICI8cmVzdHJpY3Rpb24+IiwKCQkJICAgIHR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoKCQkgICAgcmVzLT5zdWJ0eXBlczsKCQkgICAgaWYgKHJlcyA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJICAgICJDVCAnJXMnIChyZXN0cmljdGluZyk6IDxyZXN0cmljdGlvbj4gaGFzIG5vICIKCQkJICAgICJtYW5kYXRvcnkgPHNpbXBsZVR5cGU+IiwKCQkJICAgIHR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIGJhc2VDb250ZW50SXRlbSA9IGJhc2UtPmNvbnRlbnRUeXBlRGVmOwoJCSAgICBpZiAoYmFzZUNvbnRlbnRJdGVtID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkgICAgIkNUICclcycgKHJlc3RyaWN0aW5nKSwgdGhlIGJhc2UgdHlwZSBoYXMgbm8gIgoJCQkgICAgImNvbnRlbnQgdHlwZSIsIHR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICBpZiBJU19TSU1QTEVfVFlQRShiYXNlQ29udGVudEl0ZW0pIHsKCQkJLyoKCQkJKiAxIElmIHRoZSBiYXNlIHR5cGUgaXMgYSBjb21wbGV4IHR5cGUgd2hvc2Ugb3duIAoJCSAgICAJKiB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGFuZCB0aGUgPHJlc3RyaWN0aW9uPiAKCQkJKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4KCQkJKi8KCQkJLyogdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzIHdpbGwgYmUgdGhlIHJlc3RyaWN0aW9uIGl0ZW0uKi8KCQkJcmVzID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzOwoJCQlpZiAocmVzID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJCSJDVCAnJXMnIChyZXN0cmljdGluZyk6IDxzaW1wbGVUeXBlPiBoYXMgbm8gIgoJCQkJIjxyZXN0cmljdGlvbj4iLCB0eXBlLT5uYW1lKTsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9CgkJCS8qCgkJCSogMS4xIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIAoJCQkqIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8cmVzdHJpY3Rpb24+aWYgCgkJCSogdGhlcmUgaXMgb25lOwoJCQkqLwoJCQlyZXMgPSByZXMtPnN1YnR5cGVzOwoJCQlpZiAocmVzID09IE5VTEwpIHsKCQkJICAgIC8qCgkJCSAgICAqIDEuMiBvdGhlcndpc2UgdGhlIHtjb250ZW50IHR5cGV9IAoJCQkgICAgKiBvZiB0aGUgYmFzZSB0eXBlIC4KCQkJICAgICovCgkJCSAgICByZXMgPSBiYXNlQ29udGVudEl0ZW07CgkJCX0KCQkgICAgfQoJCX0KCQkvKgoJCSogU1BFQ0lBTCBUT0RPOiBJZiAqcmVzdHJpY3RpbmcqIHRoZSBzcGVjIHdhbnRzIHVzIHRvIAoJCSogY3JlYXRlIGFuICphZGRpdGlvbmFsKiBzaW1wbGUgdHlwZSB3aGljaCByZXN0cmljdHMgdGhlIAoJCSogbG9jYXRlZCBzaW1wbGUgdHlwZTsgd2Ugd29uJ3QgZG8gdGhpcyB5ZXQsIGFuZCBsb29rIGhvdyAKCQkqIGZhciB3ZSBnZXQgd2l0aCBpdC4KCQkqLwoJICAgIH0gZWxzZSB7IC8qIGlmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04gKi8KCQkvKgoJCSogU3VtbWFyeTogYSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW4gKmV4dGVuZCoKCQkqIG9ubHkgYSBjb21wbGV4IGJhc2Ugd2l0aCBhIHNpbXBsZSB0eXBlIGFzIGNvbnRlbnQuCgkJKi8JCQoJCS8qCgkJKiAzIElmIHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCAKCQkqIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXSBpcyBhIGNvbXBsZXggdHlwZSAKCQkqIGRlZmluaXRpb24gKHdob3NlIG93biB7Y29udGVudCB0eXBlfSAqbXVzdCBiZSogYSBzaW1wbGUgCgkJKiB0eXBlIGRlZmluaXRpb24sIHNlZSBiZWxvdykgYW5kIHRoZSAqPGV4dGVuc2lvbj4qIAoJCSogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGF0IAoJCSogY29tcGxleCB0eXBlIGRlZmluaXRpb247CgkJKi8KCQlyZXMgPSBiYXNlLT5jb250ZW50VHlwZURlZjsKCQlpZiAocmVzID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkiQ1QgJyVzJyAoZXh0ZW5kaW5nKSwgdGhlIGJhc2UgdHlwZSBoYXMgbm8gY29udGVudCAiCgkJCSJ0eXBlIiwgdHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJCWlmICghIElTX1NJTVBMRV9UWVBFKHJlcykpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkiQ1QgJyVzJyAoZXh0ZW5kaW5nKSwgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGUgIgoJCQkiYmFzZSBpcyBub3QgYSBzaW1wbGUgdHlwZSIsIHR5cGUtPm5hbWUpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCSAgICB9CSAgICAJCgl9IGVsc2UgLyogaWYgSVNfQ09NUExFWF9UWVBFKGJhc2UpICovCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsKCSAgICAvKgoJICAgICogNCBvdGhlcndpc2UgKHRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgCgkgICAgKiC3YWN0dWFsIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXSBpcyBhIHNpbXBsZSB0eXBlIAoJICAgICogZGVmaW5pdGlvbiBhbmQgdGhlIDxleHRlbnNpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiksIAoJICAgICogdGhlbiB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkgICAgKi8KCSAgICByZXMgPSBiYXNlOwoJfQkKCXR5cGUtPmNvbnRlbnRUeXBlRGVmID0gcmVzOwoJaWYgKHJlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCSInJXMnLCB0aGUgY29udGVudCB0eXBlIGNvdWxkIG5vdCBiZSBkZXRlcm1pbmVkIiwgCgkJdHlwZS0+bmFtZSk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgogICAgfQogICAgCn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hVHlwZUZpeHVwOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4ZXMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIHR5cGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXAoeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsKCiAgICBpZiAoaXRlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIC8qCiAgICAqIERvIG5vdCBhbGxvdyB0aGUgZm9sbG93aW5nIHR5cGVzIHRvIGJlIHR5cGVmaXhlZCwgcHJpb3IgdG8KICAgICogdGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlL2NvbXBsZXggdHlwZXMuCiAgICAqLwogICAgaWYgKGN0eHQtPmN0eHRUeXBlID09IE5VTEwpIHsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VTklPTjoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CSAgICAKCQlyZXR1cm47CgkgICAgZGVmYXVsdDoKCSAgICAgICAgYnJlYWs7Cgl9CiAgICB9CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBpdGVtLT5uYW1lOwogICAgaWYgKGl0ZW0tPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CiAgICAgICAgc3dpdGNoIChpdGVtLT50eXBlKSB7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOnsJCSAgICAKCQkgICAgaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpIHsKCQkJaWYgKGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwKCQkJCU5VTEwpOwoJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7ICovCgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSBOVUxMOwoKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZsYWdzIHw9IAoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoJCSAgICBpZiAoaXRlbS0+YmFzZVR5cGUgIT0gTlVMTCkKCQkJYmFzZSA9IGl0ZW0tPmJhc2VUeXBlOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGl0ZW0tPmJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBpdGVtLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5iYXNlTnMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgCgkJCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwgCgkJCQlOVUxMLCBOVUxMLCAKCQkJCSh4bWxOb2RlUHRyKSB4bWxTY2hlbWFHZXRQcm9wTm9kZShpdGVtLT5ub2RlLCAiYmFzZSIpLAoJCQkJImJhc2UiLCBpdGVtLT5iYXNlLCBpdGVtLT5iYXNlTnMsCgkJCQlYTUxfU0NIRU1BX1RZUEVfQkFTSUMsICJ0eXBlIGRlZmluaXRpb24iKTsJCQkgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0gCgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2UsIGN0eHQsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CQkJCiAgICAgICAgICAgICAgICAgICAgfQkKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmJhc2VUeXBlID0gYmFzZTsKCQkgICAgaWYgKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7CgkJCS8qCgkJCSogQ29tcGxleFR5cGUgcmVzdHJpY3Rpb24uCgkJCSovCQkJCgkJCS8qCgkJCSogQ29udGVudCB0eXBlLgoJCQkqLwoJCQlpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkKCQkJICAgIC8qIDEuMS4xICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkJZWxzZSBpZiAoKGl0ZW0tPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJgoJCQkgICAgKChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9UWVBFX0FMTCkKCQkJICAgIHx8IChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkpCgkJCSAgICAvKiAxLjEuMiAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJCWVsc2UgaWYgKChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkKCQkJICAgICYmIChpdGVtLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkpCgkJCSAgICAvKiAxLjEuMyAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJCWVsc2UgewoJCQkgICAgLyogMS4yIGFuZCAyLlggYXJlIGFwcGxpZWQgYXQgdGhlIG90aGVyIGxheWVyICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0KCQkgICAgfSBlbHNlIHsJCgkJCS8qCgkJCSogU2ltcGxlVHlwZSByZXN0cmljdGlvbi4KCQkJKi8KCQkJLyogVE9ETzogTm90aGluZz8gKi8KCQkgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046ewoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSBOVUxMOwoJCSAgICB4bWxTY2hlbWFDb250ZW50VHlwZSBleHBsaWNpdENvbnRlbnRUeXBlOwoJCSAgICAKCQkgICAgLyoKCQkgICAgKiBBbiBleHRlbnNpb24gZG9lcyBleGlzdCBvbiBhIGNvbXBsZXhUeXBlIG9ubHkuCgkJICAgICovCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5mbGFncyB8PSAKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT047CgkJICAgIGlmIChpdGVtLT5yZWN1cnNlKSB7CgkJCS8qIFRPRE86IFRoZSB3b3JkICJyZWN1cnNpdmUiIHNob3VsZCBiZSBjaGFuZ2VkIHRvICJjaXJjdWxhciIgaGVyZS4gKi8KCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9CQVNFX1RZUEUsCgkJCSAgICBOVUxMLCBpdGVtLCBpdGVtLT5ub2RlLAkKCQkJICAgICJUaGlzIGl0ZW0gaXMgY2lyY3VsYXIiLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoJCSAgICB9CgkJICAgIGlmIChpdGVtLT5iYXNlICE9IE5VTEwpIHsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCQkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIAoJCQkJTlVMTCwgaXRlbSwgaXRlbS0+bm9kZSwKCQkJCSJiYXNlIiwgaXRlbS0+YmFzZSwgaXRlbS0+YmFzZU5zLAoJCQkJWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7CQkJCSAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IAoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIGl0ZW0tPnJlY3Vyc2UgPSAxOwoJCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2UsIGN0eHQsIE5VTEwpOwoJCQkgICAgaXRlbS0+cmVjdXJzZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJLyoKCQkJKiBUaGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgCgkJCSogdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdCgkJCSovCgkJCWN0eHQtPmN0eHRUeXBlLT5iYXNlVHlwZSA9IGJhc2U7CgkJCS8qCgkJCSogVE9ETzogVGhpcyBvbmUgaXMgc3RpbGwgbmVlZGVkIGZvciBjb21wdXRhdGlvbiBvZgoJCQkqIHRoZSBjb250ZW50IG1vZGVsIGJ5IHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbC4KCQkJKiBUcnkgdG8gZ2V0IHJpZCBvZiBpdC4KCQkJKi8KCQkJaXRlbS0+YmFzZVR5cGUgPSBiYXNlOwkJCQogICAgICAgICAgICAgICAgICAgIH0KCQkgICAgaWYgKChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCQkoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsJICAgIAoJCSAgICAKCQkgICAgZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkgICAgaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpCgkJCS8qIDEuMS4xICovCgkJCWV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJICAgIGVsc2UgaWYgKChpdGVtLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCQkJKChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfQUxMKQoJCQl8fCAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkpCgkJCS8qIDEuMS4yICovCgkJCWV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJICAgIGVsc2UgaWYgKChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQoJCQkmJiAoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpKQoJCQkvKiAxLjEuMyAqLwoJCQlleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCSAgICBpZiAoYmFzZSAhPSBOVUxMKSB7CgkJCS8qIEl0IHdpbGwgYmUgcmVwb3J0ZWQgbGF0ZXIsIGlmIHRoZSBiYXNlIGlzIG1pc3NpbmcuICovCQkJICAgIAoJCQlpZiAoZXhwbGljaXRDb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkJICAgIC8qIDIuMSAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPSBiYXNlLT5jb250ZW50VHlwZTsKCQkJfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJCSAgICAvKiAyLjIgaW1iaXRhYmxlICEgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIDIuMyBpbWJpdGFibGUgcGFyZWlsICEgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkJfQoJCSAgICB9CQkgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6ewoJCSAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IGl0ZW07CgkJICAgIC8qCgkJICAgICogU3RhcnQgd2l0aCBhbiBlbXB0eSBjb250ZW50LXR5cGUgdHlwZS4KCQkgICAgKi8KCQkgICAgaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpCgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoKCQkgICAgaWYgKChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSB8fCAKCQkJKChpdGVtLT5zdWJ0eXBlcy0+dHlwZSAhPSAKCQkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSAmJiAKCQkJKGl0ZW0tPnN1YnR5cGVzLT50eXBlICE9IAoJCQlYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSkpIHsKCQkJLyogCgkJCSogVGhpcyBjYXNlIGlzIHVuZGVyc3Rvb2QgYXMgc2hvcnRoYW5kIGZvciBjb21wbGV4IAoJCQkqIGNvbnRlbnQgcmVzdHJpY3RpbmcgdGhlIHVyLXR5cGUgZGVmaW5pdGlvbiwgYW5kIAoJCQkqIHRoZSBkZXRhaWxzIG9mIHRoZSBtYXBwaW5ncyBzaG91bGQgYmUgbW9kaWZpZWQgYXMgCgkJCSogbmVjZXNzYXJ5LgoJCQkqLwkJCQoJCQlpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoJCQlpdGVtLT5mbGFncyB8PSAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgkJCS8qCgkJCSogQXNzdW1lIHRoYXQgd2UgaW5oZXJpdCB0aGUgY29udGVudC10eXBlIHR5cGUgCgkJCSogZnJvbSAnYW55VHlwZScsIHdoaWNoIGlzICdtaXhlZCcgYW5kIGEgcGFydGljbGUKCQkJKiBlbXB0aWFibGUuCgkJCSovCgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0gaXRlbS0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogRml4dXAgdGhlIHN1YiBjb21wb25lbnRzLgoJCSAgICAqLwoJCSAgICBpZiAoKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJCShpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0KCQkJWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7CQkJICAgIAoJCQl4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwoJCSAgICB9CQoJCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwkJCQoJCSAgICB9IGVsc2UgaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpIHsKCQkJLyoKCQkJKiBVc2UgdGhlIGNvbnRlbnQtdHlwZSB0eXBlIG9mIHRoZSBtb2RlbCBncm91cHMKCQkJKiBkZWZpbmVkLCBpZiAnbWl4ZWQnIGlzIG5vdCBzZXQuIElmICdtaXhlZCcgaXMgc2V0CgkJCSogaXQgd2lsbCBleHBhbmQgdGhlIGNvbnRlbnQtdHlwZSBieSBhbGxvd2luZyBjaGFyYWN0ZXIKCQkJKiBjb250ZW50IHRvIGFwcGVhci4KCQkJKi8KCQkJaXRlbS0+Y29udGVudFR5cGUgPQoJCQkgICAgaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOwoJCSAgICB9CgkJICAgIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbihjdHh0LCBpdGVtKTsKCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOnsKICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCS8qIAoJCQkgKiBSZW1vdmVkIGR1ZSB0byBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYnVpbGQgb2YgYXR0cmlidXRlIHVzZXMuIAoJCQkgKi8KCQkJLyoKCQkJaWYgKGl0ZW0tPmF0dHJpYnV0ZXMgPT0gTlVMTCkKCQkJICAgIGl0ZW0tPmF0dHJpYnV0ZXMgPQoJCQkgICAgICAgIGl0ZW0tPnN1YnR5cGVzLT5hdHRyaWJ1dGVzOwoJCQkqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJLyoKCQkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudAoJCSoKCQkqLwoJCWN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CQkKCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJaWYgKGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSAKCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBpdGVtOwoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwoJCX0KCQkvKiBGaXh1cCBiYXNlIHR5cGUgKi8JCQoJCWlmICgoaXRlbS0+YmFzZVR5cGUgIT0gTlVMTCkgJiYgCgkJICAgIChpdGVtLT5iYXNlVHlwZS0+Y29udGVudFR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7CgkJICAgIC8qIE9QVElNSVpFOiBBY3R1YWxseSB0aGlzIG9uZSB3aWxsIG5ldmVyIGJ5IGhpdCwgc2luY2UKCQkgICAgKiB0aGUgYmFzZSB0eXBlIGlzIGFscmVhZHkgdHlwZS1maXhlZCBpbiA8cmVzdHJpY3Rpb24+LgoJCSAgICAqLwoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IGl0ZW07CgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5iYXNlVHlwZSwgY3R4dCwgTlVMTCk7CgkJfQoJCS8qIEJhc2UgdHlwZTogCgkJKiAyIElmIHRoZSA8bGlzdD4gb3IgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIAoJCSogdGhlbiB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LgoJCSovCgkJaWYgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9MSVNUKSB7CgkJICAgIGl0ZW0tPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CgkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUOwkJICAgIAoJCX0gZWxzZSBpZiAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB7CgkJICAgIGl0ZW0tPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CgkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsKCQl9IGVsc2UgaWYgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewoJCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXQsIGN1ciwgbGFzdCA9IE5VTEw7CgkJICAgIAkJICAgIAkgICAgCQkgICAKCQkgICAgLyogCgkJICAgICogVmFyaWV0eQoJCSAgICAqIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUgCgkJICAgICoge3ZhcmlldHl9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgoJCSAgICAqLwkKCQkgICAgaWYgKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpIHsKCQkJaWYgKGl0ZW0tPmJhc2VUeXBlLT5mbGFncyAmIAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykKCQkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUM7CgkJCWVsc2UgaWYgKGl0ZW0tPmJhc2VUeXBlLT5mbGFncyAmIAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpCgkJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVDsKCQkJZWxzZSBpZiAoaXRlbS0+YmFzZVR5cGUtPmZsYWdzICYgCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pCgkJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CQkgICAgCQkgICAgCQkgICAKCQkJLyoKCQkJKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFNpbXBsZSBUeXBlIFJlc3RyaWN0aW9uIAoJCQkqIChGYWNldHMpCgkJCSogTk9URTogU2F0aXNmYWN0aW9uIG9mIDEgYW5kIDIgYXJpc2UgZnJvbSB0aGUgZml4dXAgCgkJCSogYXBwbGllZCBiZWZvcmVoYW5kLgoJCQkqCQkJICAgIAoJCQkqIDMgVGhlIHtmYWNldHN9IG9mIFIgYXJlIHRoZSB1bmlvbiBvZiBTIGFuZCB0aGUge2ZhY2V0c30gCgkJCSogb2YgQiwgZWxpbWluYXRpbmcgZHVwbGljYXRlcy4gVG8gZWxpbWluYXRlIGR1cGxpY2F0ZXMsIAoJCQkqIHdoZW4gYSBmYWNldCBvZiB0aGUgc2FtZSBraW5kIG9jY3VycyBpbiBib3RoIFMgYW5kIHRoZSAKCQkJKiB7ZmFjZXRzfSBvZiBCLCB0aGUgb25lIGluIHRoZSB7ZmFjZXRzfSBvZiBCIGlzIG5vdCAKCQkJKiBpbmNsdWRlZCwgd2l0aCB0aGUgZXhjZXB0aW9uIG9mIGVudW1lcmF0aW9uIGFuZCBwYXR0ZXJuIAoJCQkqIGZhY2V0cywgZm9yIHdoaWNoIG11bHRpcGxlIG9jY3VycmVuY2VzIHdpdGggZGlzdGluY3QgdmFsdWVzIAoJCQkqIGFyZSBhbGxvd2VkLgoJCQkqLwoJCQlpZiAoaXRlbS0+YmFzZVR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCQkJICAgIGxhc3QgPSBpdGVtLT5mYWNldFNldDsKCQkJICAgIGlmIChsYXN0ICE9IE5VTEwpCgkJCQl3aGlsZSAobGFzdC0+bmV4dCAhPSBOVUxMKQoJCQkJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwoJCQkJY3VyID0gaXRlbS0+YmFzZVR5cGUtPmZhY2V0U2V0OwoJCQkJZm9yICg7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCQkJCSAgICAvKiAKCQkJCSAgICAqIEJhc2UgcGF0dGVybnMgd29uJ3QgYmUgYWRkIGhlcmU6CgkJCQkgICAgKiB0aGV5IGFyZSBPUmVkIGluIGEgdHlwZSBhbmQKCQkJCSAgICAqIEFORGVkIGluIGRlcml2ZWQgdHlwZXMuIFRoaXMgd2lsbAoJCQkJICAgICogaGFwcGVkIGF0IHZhbGlkYXRpb24gbGV2ZWwgYnkKCQkJCSAgICAqIHdhbGtpbmcgdGhlIGJhc2UgYXhpcyBvZiB0aGUgdHlwZS4KCQkJCSAgICAqLwoJCQkJICAgIGlmIChjdXItPmZhY2V0LT50eXBlID09IAoJCQkJCVhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgCgkJCQkJY29udGludWU7CgkJCQkgICAgZmFjZXQgPSBOVUxMOwoJCQkJICAgIGlmICgoaXRlbS0+ZmFjZXRTZXQgIT0gTlVMTCkgJiYKCQkJCQkoY3VyLT5mYWNldC0+dHlwZSAhPSAKCQkJCQlYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCQkJKGN1ci0+ZmFjZXQtPnR5cGUgIT0gCgkJCQkJWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsJCQkJCgkJCQkJZmFjZXQgPSBpdGVtLT5mYWNldFNldDsKCQkJCQlkbyB7CgkJCQkJICAgIGlmIChjdXItPmZhY2V0LT50eXBlID09IAoJCQkJCQlmYWNldC0+ZmFjZXQtPnR5cGUpIAoJCQkJCQlicmVhazsKCQkJCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQkJCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQkJCSAgICB9CgkJCQkgICAgaWYgKGZhY2V0ID09IE5VTEwpIHsKCQkJCQlmYWNldCA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpIAoJCQkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0TGluaykpOwoJCQkJCWlmIChmYWNldCA9PSBOVUxMKSB7CgkJCQkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCQkJCSJmaXhpbmcgc2ltcGxlVHlwZSIsIE5VTEwpOwoJCQkJCSAgICByZXR1cm47CgkJCQkJfQoJCQkJCWZhY2V0LT5mYWNldCA9IGN1ci0+ZmFjZXQ7CgkJCQkJZmFjZXQtPm5leHQgPSBOVUxMOwoJCQkJCWlmIChsYXN0ID09IE5VTEwpCgkJCQkJICAgIGl0ZW0tPmZhY2V0U2V0ID0gZmFjZXQ7CQkgICAgCgkJCQkJZWxzZSAKCQkJCQkgICAgbGFzdC0+bmV4dCA9IGZhY2V0OwoJCQkJCWxhc3QgPSBmYWNldDsJCQkJCgkJCQkgICAgfQkJCQkgICAgCgkJCQl9CgkJCX0KCQkgICAgfQoJCX0JCgkJLyoKCQkqIENoZWNrIGNvbnN0cmFpbnRzLgoJCSovCgkJeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKGN0eHQsIGl0ZW0pOwoJCWN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOiAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJLyoKCQkqIFRPRE86IEhhbmRsaW5nIHdhcyBtb3ZlZCB0byB4bWxTY2hlbWFHcm91cERlZkZpeHVwLgoJCSovCgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0xJU1Q6IAoJCXhtbFNjaGVtYVBhcnNlTGlzdFJlZkZpeHVwKGl0ZW0sIGN0eHQpOwoJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CQkKCQl4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2soaXRlbSwgY3R4dCk7CgkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9GQUNFVDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiNpZmRlZiBERUJVR19UWVBFCiAgICBpZiAoaXRlbS0+bm9kZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJUeXBlIG9mICVzIDogJXM6JWQgOiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPm5vZGUtPmRvYy0+VVJMLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxHZXRMaW5lTm8oaXRlbS0+bm9kZSkpOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIlR5cGUgb2YgJXMgOiIsIG5hbWUpOwogICAgfQogICAgc3dpdGNoIChpdGVtLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJzaW1wbGVcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbGVtZW50c1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAidW5rbm93biAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbXB0eVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgkvKiBSZW1vdmVkLCBzaW5jZSBub3QgdXNlZC4gKi8KCS8qCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWQgb3IgZWxlbXNcbiIpOwogICAgICAgICAgICBicmVhazsKCSovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0OgogKiBAZmFjZXQ6ICB0aGUgZmFjZXQKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKgogKiBSZXR1cm5zIDAgaWYgb2theSBvciAtMSBpbiBjYWUgb2YgZXJyb3IKICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBub25OZWdhdGl2ZUludGVnZXJUeXBlID0gTlVMTDsKICAgIGludCByZXQgPSAwLCByZXVzZVZhbEN0eHQgPSAwOwoKICAgIC8qIAogICAgKiBUT0RPOiB3aWxsIHRoZSBwYXJzZXIgY29udGV4dCBiZSBnaXZlbiBpZiB1c2VkIGZyb20KICAgICogdGhlIHJlbGF4TkcgbW9kdWxlPwogICAgKi8KCiAgICBpZiAobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9PSBOVUxMKSB7CiAgICAgICAgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9CiAgICAgICAgICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05OSU5URUdFUik7CiAgICB9CiAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjogewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE9rYXkgd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAqIGF0IHRoYXQgcG9pbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CgoJCS8qIDQuMy41LjUgQ29uc3RyYWludHMgb24gZW51bWVyYXRpb24gU2NoZW1hIENvbXBvbmVudHMKCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogZW51bWVyYXRpb24gdmFsaWQgcmVzdHJpY3Rpb24KCQkqIEl0IGlzIGFuILdlcnJvcrcgaWYgYW55IG1lbWJlciBvZiB7dmFsdWV9IGlzIG5vdCBpbiB0aGUgCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uIAoJCSoKCQkqIG1pbkluY2x1c2l2ZSwgbWF4SW5jbHVzaXZlLCBtaW5FeGNsdXNpdmUsIG1heEV4Y2x1c2l2ZToKCQkqIFRoZSB2YWx1ZSC3bXVzdLcgYmUgaW4gdGhlIAoJCSogt3ZhbHVlIHNwYWNltyBvZiB0aGUgt2Jhc2UgdHlwZbcuIAoJCSovCgkJLyoKCQkqIFRoaXMgZnVuY3Rpb24gaXMgaW50ZW5kZWQgdG8gZGVsaXZlciBhIGNvbXBpbGVkIHZhbHVlCgkJKiBvbiB0aGUgZmFjZXQuIEluIFhNTCBTY2hlbWFzIHRoZSB0eXBlIGhvbGRpbmcgYSBmYWNldCwgCgkJKiBjYW5ub3QgYmUgYSBidWlsdC1pbiB0eXBlLiBUaHVzIHRvIGVuc3VyZSB0aGF0IG90aGVyIEFQSQoJCSogY2FsbHMgKHJlbGF4bmcpIGRvIHdvcmssIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGEgYnVpbHQtaW4gCgkJKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlICppcwoJCSogYWxyZWFkeSogdGhlIGJhc2UgdHlwZS4JCQoJCSovCgkJaWYgKHR5cGVEZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCSAgICBiYXNlID0gdHlwZURlY2wtPmJhc2VUeXBlOwoJCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIgoJCQkgICAgInRoZSB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJCSAgICB0eXBlRGVjbC0+bmFtZSwgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CQkKCQl9IGVsc2UKCQkgICAgYmFzZSA9IHR5cGVEZWNsOwoJCS8qCgkJKiBUaGlzIGF2b2lkcyBwZXJzZXZlcmF0aXZlIGNyZWF0aW9uIG9mIHRoZSAKCQkqIHZhbGlkYXRpb24gY29udGV4dCBpZiBhIHBhcnNlciBjb250ZXh0IGlzCgkJKiB1c2VkLgoJCSovCgkJaWYgKGN0eHQgIT0gTlVMTCkgewoJCSAgICByZXVzZVZhbEN0eHQgPSAxOwoJCSAgICBpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJCQlpZiAoeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KGN0eHQpID09IC0xKQoJCQkgICAgcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdmN0eHQgPSBjdHh0LT52Y3R4dDsKCQl9IGVsc2UgewoJCSAgICB2Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKCQkgICAgaWYgKHZjdHh0ID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSAgICAiY3JlYXRpbmcgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQkJICAgIE5VTEwsIE5VTEwpOwoJCQlyZXR1cm4gKC0xKTsJCgkJICAgIH0KCQl9CgkgICAgICAgICAgICAgICAgCgkJdmN0eHQtPm5vZGUgPSBmYWNldC0+bm9kZTsKCQl2Y3R4dC0+Y3VyID0gTlVMTDsKCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCAKCQkqIHNpbmNlIHRoZXkgYXJlIG5vdCBhdmFpbGFibGU6CgkJKiBmYWNldC0+bm9kZSBpcyBqdXN0IHRoZSBub2RlIGhvbGRpbmcgdGhlIGZhY2V0IAoJCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqIAoJCSogb2YgdGhlIGZhY2V0LgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUodmN0eHQsIGJhc2UsIAoJCSAgICBmYWNldC0+dmFsdWUsIDAsIDEsIDEsIDApOwoJCWZhY2V0LT52YWwgPSB2Y3R4dC0+dmFsdWU7CgkJdmN0eHQtPnZhbHVlID0gTlVMTDsJCQogICAgICAgICAgICAgICAgaWYgKHJldCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVCwgCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkgICAgImZhY2V0ICclcycgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSwgCgkJCSAgICBCQURfQ0FTVCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksIAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgZmFjZXQtPm5vZGUsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCBOVUxMLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgJyVzJyBuYW1lIG9mIHRoZSAiCgkJCSJmYWNldCAnJXMnIGFnYWluc3QgdGhlIGJhc2UgdHlwZSAnJXMnLlxuIiwKCQkJZmFjZXQtPnZhbHVlLCAKCQkJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQliYXNlLT5uYW1lLCBOVUxMLCBOVUxMKTsgCgkJICAgIHJldCA9IC0xOwoJCX0gICAKCQlpZiAocmV1c2VWYWxDdHh0ID09IDApCgkJICAgIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQodmN0eHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgZmFjZXQtPnJlZ2V4cCA9IHhtbFJlZ2V4cENvbXBpbGUoZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgaWYgKGZhY2V0LT5yZWdleHAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX1JFR0VYUF9JTlZBTElELAoJCSAgICAiVHlwZSBkZWZpbml0aW9uICclcyc6IFRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJICAgICJmYWNldCAncGF0dGVybicgaXMgbm90IHZhbGlkLlxuIiwKCQkgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6ewogICAgICAgICAgICAgICAgaW50IHRtcDsKCiAgICAgICAgICAgICAgICB0bXAgPQogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoZmFjZXQtPnZhbCkpOwogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkgICAgImZhY2V0ICclcycgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSwgCgkJCSAgICBCQURfQ0FTVCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgkJCSAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOnsKICAgICAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJwcmVzZXJ2ZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicmVwbGFjZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJjb2xsYXBzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9XSElURV9TUEFDRSwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnd2hpdGVTcGFjZScgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0RlZmF1bHRzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGVEZWNsLT5uYW1lOyAKICAgIC8qCiAgICAqIE5PVEU6IEl0IGlzIGludGVuZGVkIHRvIHVzZSB0aGUgZmFjZXRzIGxpc3QsIGluc3RlYWQKICAgICogb2YgZmFjZXRTZXQuCiAgICAqLwogICAgaWYgKHR5cGVEZWNsLT5mYWNldHMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQgPSB0eXBlRGVjbC0+ZmFjZXRzOwoJCgl3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUNoZWNrRmFjZXQoZmFjZXQsIHR5cGVEZWNsLCBjdHh0LCBuYW1lKTsKCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJfQogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmOgogKiBAY3R4dEdyOiB0aGUgc2VhcmNoZWQgbW9kZWwgZ3JvdXAKICogQGxpc3Q6IHRoZSBsaXN0IG9mIG1vZGVsIGdyb3VwcyB0byBiZSBwcm9jZXNzZWQKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UsIG90aGVyd2lzZSBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoeG1sU2NoZW1hVHlwZVB0ciBjdHh0R3JEZWYsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBncikKeyAgICAKICAgIHhtbFNjaGVtYVR5cGVQdHIgY2lyYyA9IE5VTEw7CiAgICBpbnQgbWFya2VkOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIG1vZGVsIGdyb3VwIHJlZmVyZW5jZSB3aGljaAogICAgKiByZWZlcmVuY2VzIHRoZSBjb250ZXh0IG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAgICAqLyAgICAgICAgCiAgICB3aGlsZSAoZ3IgIT0gTlVMTCkgewoJaWYgKCgoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB8fAoJICAgICAoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpKSAmJgoJICAgIChnci0+c3VidHlwZXMgIT0gTlVMTCkpIHsJCSAKCSAgICBtYXJrZWQgPSAwOwoJICAgIGlmICgoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSAmJgoJCShnci0+cmVmICE9IE5VTEwpKSB7CgkJaWYgKGdyLT5zdWJ0eXBlcyA9PSBjdHh0R3JEZWYpCgkJICAgIHJldHVybiAoZ3IpOwoJCWVsc2UgaWYgKGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQpIHsKCQkgICAgZ3IgPSBnci0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBNYXJrIHRvIGF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbiBvbgoJCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkgICAgKi8KCQkgICAgZ3ItPnN1YnR5cGVzLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKCQkgICAgbWFya2VkID0gMTsKCQl9IAoJCWlmIChnci0+c3VidHlwZXMtPnN1YnR5cGVzICE9IE5VTEwpCgkJICAgIGNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihjdHh0R3JEZWYsIAoJCQlnci0+c3VidHlwZXMtPnN1YnR5cGVzKTsKCQkgICAgLyoKCQkgICAgKiBVbm1hcmsgdGhlIHZpc2l0ZWQgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KCQkqLwoJCWlmIChtYXJrZWQpCgkJICAgIGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCSAgICB9IGVsc2UgewoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihjdHh0R3JEZWYsIAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgZ3ItPnN1YnR5cGVzKTsKCQlpZiAoY2lyYyAhPSBOVUxMKQoJCSAgICByZXR1cm4gKGNpcmMpOwoJICAgIH0KCgl9CglnciA9IGdyLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgdG8gbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoeG1sU2NoZW1hVHlwZVB0ciBtb2RlbEdyRGVmLAoJCQkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsgICAgCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IE1vZGVsIEdyb3VwIENvcnJlY3QKICAgICogMiBDaXJjdWxhciBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIHdpdGhpbiB0aGUge3BhcnRpY2xlc30gCiAgICAqIG9mIGEgZ3JvdXAgdGhlcmUgbXVzdCBub3QgYmUgYXQgYW55IGRlcHRoIGEgcGFydGljbGUgd2hvc2Uge3Rlcm19IAogICAgKiBpcyB0aGUgZ3JvdXAgaXRzZWxmLgogICAgKi8KICAgIC8qCiAgICAqIE5PVEU6ICJnci0+c3VidHlwZXMiIGhvbGRzIHRoZSByZWZlcmVuY2VkIGdyb3VwLgogICAgKi8KICAgIGlmICgobW9kZWxHckRlZi0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHx8IAoJKChtb2RlbEdyRGVmLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSA9PSAwKSB8fAoJKG1vZGVsR3JEZWYtPnN1YnR5cGVzID09IE5VTEwpKQoJcmV0dXJuOwogICAgZWxzZSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKG1vZGVsR3JEZWYsIG1vZGVsR3JEZWYtPnN1YnR5cGVzKTsKCWlmIChjaXJjICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogUmVwb3J0IHRoZSByZWZlcmVuY2VkIGF0dHIgZ3JvdXAgYXMgUU5hbWUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfTUdfUFJPUFNfQ09SUkVDVF8yLAoJCU5VTEwsIE5VTEwsIGNpcmMtPm5vZGUsCgkJIkNpcmN1bGFyIHJlZmVyZW5jZSB0byB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAnJXMnICIKCQkiZGVmaW5lZCIsIG1vZGVsR3JEZWYtPm5hbWUpOwoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLgoJICAgICogVE9ETzogU1BFQzogRG9lcyB0aGUgc3BlYyBkZWZpbmUgaG93IHRvIHByb2Nlc3MgaGVyZT8KCSAgICAqLwoJICAgIGNpcmMtPnN1YnR5cGVzID0gTlVMTDsKCX0KICAgIH0KfQoKCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmOgogKiBAY3R4dEdyOiB0aGUgc2VhcmNoZWQgYXR0cmlidXRlIGdyb3VwCiAqIEBhdHRyOiB0aGUgY3VycmVudCBhdHRyaWJ1dGUgbGlzdCB0byBiZSBwcm9jZXNzZWQKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja1NSQ0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgYXR0cmlidXRlIGdyb3UgcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGN0eHRHciwKCQkJICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKeyAgICAKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGNpcmMgPSBOVUxMLCBncjsKICAgIGludCBtYXJrZWQ7CiAgICAvKgogICAgKiBXZSB3aWxsIHNlYXJjaCBmb3IgYW4gYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZSB3aGljaAogICAgKiByZWZlcmVuY2VzIHRoZSBjb250ZXh0IGF0dHJpYnV0ZSBncm91cC4KICAgICovICAgIAkKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCW1hcmtlZCA9IDA7CglpZiAoYXR0ci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICBnciA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgYXR0cjsKCSAgICBpZiAoZ3ItPnJlZkl0ZW0gIT0gTlVMTCkgIHsKCQlpZiAoZ3ItPnJlZkl0ZW0gPT0gY3R4dEdyKQoJCSAgICByZXR1cm4gKGdyKTsKCQllbHNlIGlmIChnci0+cmVmSXRlbS0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRCkgewoJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBNYXJrIGFzIHZpc2l0ZWQgdG8gYXZvaWQgaW5maW5pdGUgcmVjdXJzaW9uIG9uCgkJICAgICogY2lyY3VsYXIgcmVmZXJlbmNlcyBub3QgeWV0IGV4YW1pbmVkLgoJCSAgICAqLwoJCSAgICBnci0+cmVmSXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRDsKCQkgICAgbWFya2VkID0gMTsKCQl9CgkgICAgfQoJICAgIGlmIChnci0+YXR0cmlidXRlcyAhPSBOVUxMKQoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKGN0eHRHciwgZ3ItPmF0dHJpYnV0ZXMpOwoJICAgIC8qCgkgICAgKiBVbm1hcmsgdGhlIHZpc2l0ZWQgZ3JvdXAncyBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKG1hcmtlZCkKCQlnci0+cmVmSXRlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRDsKCSAgICBpZiAoY2lyYyAhPSBOVUxMKQoJCXJldHVybiAoY2lyYyk7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCQkJCQovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNBdHRyaWJ1dGVHcm91cENpcmN1bGFyOgogKiBhdHRyR3I6ICB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgb2YgYXR0cmlidXRlIGdyb3Vwcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyR3IsCgkJCQkJeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCQljb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAogICAgKiBBdHRyaWJ1dGUgR3JvdXAgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSwogICAgKiAzIENpcmN1bGFyIGdyb3VwIHJlZmVyZW5jZSBpcyBkaXNhbGxvd2VkIG91dHNpZGUgPHJlZGVmaW5lPi4gCiAgICAqIFRoYXQgaXMsIHVubGVzcyB0aGlzIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHBhcmVudCBpcyAKICAgICogPHJlZGVmaW5lPiwgdGhlbiBhbW9uZyB0aGUgW2NoaWxkcmVuXSwgaWYgYW55LCB0aGVyZSBtdXN0IAogICAgKiBub3QgYmUgYW4gPGF0dHJpYnV0ZUdyb3VwPiB3aXRoIHJlZiBbYXR0cmlidXRlXSB3aGljaCByZXNvbHZlcyAKICAgICogdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4gSW5kaXJlY3QgCiAgICAqIGNpcmN1bGFyaXR5IGlzIGFsc28gcnVsZWQgb3V0LiBUaGF0IGlzLCB3aGVuIFFOYW1lIHJlc29sdXRpb24gCiAgICAqIChTY2hlbWEgRG9jdW1lbnQpICinMy4xNS4zKSBpcyBhcHBsaWVkIHRvIGEgt1FOYW1ltyBhcmlzaW5nIGZyb20gCiAgICAqIGFueSA8YXR0cmlidXRlR3JvdXA+cyB3aXRoIGEgcmVmIFthdHRyaWJ1dGVdIGFtb25nIHRoZSBbY2hpbGRyZW5dLCAKICAgICogaXQgbXVzdCBub3QgYmUgdGhlIGNhc2UgdGhhdCBhILdRTmFtZbcgaXMgZW5jb3VudGVyZWQgYXQgYW55IGRlcHRoIAogICAgKiB3aGljaCByZXNvbHZlcyB0byB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyA8YXR0cmlidXRlR3JvdXA+LgogICAgKi8KICAgIC8qCiAgICAqIE9ubHkgZ2xvYmFsIGNvbXBvbmVudHMgY2FuIGJlIHJlZmVyZW5jZWQuCiAgICAqLwogICAgaWYgKCgoYXR0ckdyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpID09IDApIHx8IAoJKGF0dHJHci0+YXR0cmlidXRlcyA9PSBOVUxMKSkKCXJldHVybjsKICAgIGVsc2UgewoJeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY2lyYzsKCgljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihhdHRyR3IsIGF0dHJHci0+YXR0cmlidXRlcyk7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfR1JPVVBfMywKCQlOVUxMLCBOVUxMLCBjaXJjLT5ub2RlLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIGF0dHJpYnV0ZSBncm91cCAnJXMnICIKCQkiZGVmaW5lZCIsIGF0dHJHci0+bmFtZSk7CgkgICAgLyoKCSAgICAqIE5PVEU6IFdlIHdpbGwgY3V0IHRoZSByZWZlcmVuY2UgdG8gYXZvaWQgZnVydGhlcgoJICAgICogY29uZnVzaW9uIG9mIHRoZSBwcm9jZXNzb3IuCgkgICAgKiBCQURTUEVDOiBUaGUgc3BlYyBzaG91bGQgZGVmaW5lIGhvdyB0byBwcm9jZXNzIGluIHRoaXMgY2FzZS4KCSAgICAqLwoJICAgIGNpcmMtPmF0dHJpYnV0ZXMgPSBOVUxMOwoJICAgIGNpcmMtPnJlZkl0ZW0gPSBOVUxMOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXR0ckdycEZpeHVwOgogKiBAYXR0cmdycERlY2w6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckdycEZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJncnAsCiAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBhdHRyZ3JwLT5uYW1lOwogICAgaWYgKGF0dHJncnAtPmF0dHJpYnV0ZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0cmdycC0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZWY7CgogICAgICAgIHJlZiA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGN0eHQtPnNjaGVtYSwgYXR0cmdycC0+cmVmLCAKCSAgICBhdHRyZ3JwLT5yZWZOcyk7CiAgICAgICAgaWYgKHJlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBhdHRyZ3JwLCBhdHRyZ3JwLT5ub2RlLAoJCSJyZWYiLCBhdHRyZ3JwLT5yZWYsIGF0dHJncnAtPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVAsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJYXR0cmdycC0+cmVmSXRlbSA9IHJlZjsKCS8qCgkqIENoZWNrIGZvciBzZWxmIHJlZmVyZW5jZSEKCSovCiAgICAgICAgeG1sU2NoZW1hQXR0ckdycEZpeHVwKHJlZiwgY3R4dCwgTlVMTCk7CiAgICAgICAgYXR0cmdycC0+YXR0cmlidXRlcyA9IHJlZi0+YXR0cmlidXRlczsKCWF0dHJncnAtPmF0dHJpYnV0ZVdpbGRjYXJkID0gcmVmLT5hdHRyaWJ1dGVXaWxkY2FyZDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJDaGVja1ZhbENvbnN0cjoKICogQGl0ZW06ICBhbiBzY2hlbWEgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiAKICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBjb25zdHJhaW50cyBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAoJCQkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKCiAgICAvKgogICAgKiBhLXByb3BzLWNvcnJlY3QKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAqCiAgICAqIDIgaWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKICAgICogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCiAgICAqIHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIAogICAgKi8KCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJaW50IHJldDsKCXhtbE5vZGVQdHIgbm9kZTsKCXhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCglpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInZhbHVlIGNvbnN0cmFpbnQiLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm47Cgl9CgoJLyoKCSogVE9ETzogVHJ5IHRvIGF2b2lkIGNyZWF0aW5nIGEgbmV3IGNvbnRleHQuCgkqIFRPRE86IFRoaXMgYWxsIGlzIG5vdCB2ZXJ5IHBlcmZvcm1hbnQuCgkqLwoJdHlwZSA9IGl0ZW0tPnN1YnR5cGVzOwoJLyoKCSogRW5zdXJlIHRoZXJlJ3MgdmFsaWRhdGlvbiBjb250ZXh0LgoJKi8KCWlmIChjdHh0LT52Y3R4dCA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyLCAiCgkJICAgICJjcmVhdGluZyBhIG5ldyB2YWxpZGF0aW9uIGNvbnRleHQuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCQlyZXR1cm47CgkgICAgfQoJfQoKCWlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpCgkgICAgbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGl0ZW0tPm5vZGUsIEJBRF9DQVNUICJmaXhlZCIpOwoJZWxzZQoJICAgIG5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChpdGVtLT5ub2RlLCBCQURfQ0FTVCAiZGVmYXVsdCIpOwoJY3R4dC0+dmN0eHQtPm5vZGUgPSBub2RlOwoJY3R4dC0+dmN0eHQtPmN1ciA9IE5VTEw7CgkvKgoJKiBOT1RFOiBUaGlzIGNhbGwgZG9lcyBub3QgY2hlY2sgdGhlIGNvbnRlbnQgbm9kZXMsIAoJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJKiBmYWNldC0+bm9kZSBpcyBqdXN0IHRoZSBub2RlIGhvbGRpbmcgdGhlIGZhY2V0IAoJKiBkZWZpbml0aW9uLCAqbm90KiB0aGUgYXR0cmlidXRlIGhvbGRpbmcgdGhlICp2YWx1ZSogCgkqIG9mIHRoZSBmYWNldC4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LT52Y3R4dCwgdHlwZSwgCgkgICAgaXRlbS0+ZGVmVmFsdWUsIDAsIDEsIDEsIDApOwoJaWYgKHJldCA9PSAwKSB7CgkgICAgLyoKCSAgICAqIFN0b3JlIHRoZSBjb21wdXRlZCB2YWx1ZS4KCSAgICAqLwogICAgCSAgICBpdGVtLT5kZWZWYWwgPSBjdHh0LT52Y3R4dC0+dmFsdWU7CgkgICAgY3R4dC0+dmN0eHQtPnZhbHVlID0gTlVMTDsJCgl9IGVsc2UgaWYgKHJldCA+IDApIHsKCSAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX0FfUFJPUFNfQ09SUkVDVF8yLCAKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwgCgkJICAgIHR5cGUsIE5VTEwsIGl0ZW0tPmRlZlZhbHVlLAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBdHRyQ2hlY2tWYWxDb25zdHIsICIKCQkiZmFpbGVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJImF0dHJpYnV0ZSBkZWNsL3VzZSBhZ2FpbnN0IHRoZSB0eXBlICclcyciLAoJCXR5cGUtPm5hbWUpOyAJICAgIAoJfQkgICAJCiAgICB9ICAgIAp9CgojaWYgMCAvKiBOb3QgdXNlZCB5ZXQuICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWRlY2wpCnsKICAgIC8qCiAgICAqIFRPRE86IDEgVGhlIHZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIG11c3QgYmUgYXMgCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgRWxlbWVudCBEZWNsYXJhdGlvbiBTY2hlbWEgCiAgICAqIENvbXBvbmVudCAopzMuMy4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuCiAgICAqLwogICAgLyoKICAgICogMiBJZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsIAogICAgKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUge3R5cGUgCiAgICAqIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLgogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyLgogICAgKi8KICAgIC8qCiAgICAqIDMgSWYgdGhlcmUgaXMgYSBub24tt2Fic2VudLcge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIAogICAgKiB0aGVuIHtzY29wZX0gbXVzdCBiZSBnbG9iYWwuCiAgICAqCiAgICAqIE5PVEU6IFRoaXMgaXMgZG9uZSBpbiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQuCiAgICAqIFRPRE86IE1vdmUgaXQgdG8gdGhpcyBsYXllciBoZXJlLgogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IDQgSWYgdGhlcmUgaXMgYSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgdGhlIHt0eXBlIGRlZmluaXRpb259IAogICAgKiBvZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB7dHlwZSAKICAgICogZGVmaW5pdGlvbn0gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCBnaXZlbiB0aGUgdmFsdWUgCiAgICAqIG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnN9IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIAogICAgKiBhZmZpbGlhdGlvbn0sIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAopzMuNC42KSAKICAgICogKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4KSBvciBhcyBkZWZpbmVkIGluIAogICAgKiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgCiAgICAqIHNpbXBsZSkuIAogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IDUgSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IG9yIHt0eXBlIGRlZmluaXRpb259J3Mge2NvbnRlbnQgdHlwZX0gCiAgICAqIGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LgogICAgKiBOb3RlOiBUaGUgdXNlIG9mIElEIGFzIGEgdHlwZSBkZWZpbml0aW9uIGZvciBlbGVtZW50cyBnb2VzIGJleW9uZCAKICAgICogWE1MIDEuMCwgYW5kIHNob3VsZCBiZSBhdm9pZGVkIGlmIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGlzIGRlc2lyZWQKICAgICovCiAgICAvKgogICAgKiBUT0RPOiA2IENpcmN1bGFyIHN1YnN0aXR1dGlvbiBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIGl0IG11c3Qgbm90IAogICAgKiBiZSBwb3NzaWJsZSB0byByZXR1cm4gdG8gYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBieSByZXBlYXRlZGx5IGZvbGxvd2luZyAKICAgICogdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259IHByb3BlcnR5LgogICAgKi8KfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHI6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGVsZW1lbnQgZGVjbGFyYXRpb24vcGFydGljbGUKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyKHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgCiAgICBpZiAoZGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJaW50IHJldDsKCXhtbE5vZGVQdHIgbm9kZSA9IE5VTEw7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJLyoKCSogMiBJZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsIAoJKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUge3R5cGUgCgkqIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLgoJKi8gICAgCglpZiAoZGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZGVjbC0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ciwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInRoZSB2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoJLyoKCSogRW5zdXJlIHRoZXJlJ3MgYSB2YWxpZGF0aW9uIGNvbnRleHQuCgkqLwoJaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkKCSAgICByZXR1cm47CgoJdHlwZSA9IGRlY2wtPnN1YnR5cGVzOwoKCWlmIChkZWNsLT5ub2RlICE9IE5VTEwpIHsKCSAgICBpZiAoZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChkZWNsLT5ub2RlLCBCQURfQ0FTVCAiZml4ZWQiKTsKCSAgICBlbHNlCgkJbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGRlY2wtPm5vZGUsIEJBRF9DQVNUICJkZWZhdWx0Iik7Cgl9CgljdHh0LT52Y3R4dC0+bm9kZSA9IG5vZGU7CgljdHh0LT52Y3R4dC0+Y3VyID0gTlVMTDsKCXJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KGN0eHQsIGN0eHQtPnZjdHh0LCB0eXBlLCBkZWNsLT52YWx1ZSwgCgkgICAgbm9kZSk7CglpZiAocmV0ID09IDApIHsKCSAgICAvKgoJICAgICogQ29uc3VtZSB0aGUgY29tcHV0ZWQgdmFsdWUuCgkgICAgKi8KICAgIAkgICAgZGVjbC0+ZGVmVmFsID0gY3R4dC0+dmN0eHQtPnZhbHVlOwoJICAgIGN0eHQtPnZjdHh0LT52YWx1ZSA9IE5VTEw7CQoJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hRWxlbUNoZWNrVmFsQ29uc3RyLCAiCgkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgIgoJCSJlbGVtZW50IGRlY2xhcmF0aW9uICclcyciLAoJCWRlY2wtPm5hbWUpOyAJICAgIAoJfQkgICAJCiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hQXR0ckZpeHVwOgogKiBAaXRlbTogIGFuIHNjaGVtYSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSAKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gYXR0cmlidXRlIGRlY2xhcmF0aW9ucy91c2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICAvKiAKICAgICogVE9ETzogSWYgaW5jbHVkaW5nIHRoaXMgaXMgZG9uZSB0d2ljZSAoISkgZm9yIGV2ZXJ5IGF0dHJpYnV0ZS4KICAgICogICAgICAgLT4gSG1tLCBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIGRvbmUuCiAgICAqLwogICAgLyoKICAgICogVGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+IGVsZW1lbnQgCiAgICAqIGluZm9ybWF0aW9uIGl0ZW0gaW4gdGhlIFtjaGlsZHJlbl0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgc2ltcGxlIAogICAgKiB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIHR5cGUgCiAgICAqIFthdHRyaWJ1dGVdLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEKQoJcmV0dXJuOwogICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9JTlRFUk5BTF9SRVNPTFZFRDsKICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChpdGVtLT50eXBlTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+dHlwZU5hbWUsCgkgICAgaXRlbS0+dHlwZU5zKTsKCWlmICgodHlwZSA9PSBOVUxMKSB8fCAoISBJU19TSU1QTEVfVFlQRSh0eXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgaXRlbS0+bm9kZSwKCQkidHlwZSIsIGl0ZW0tPnR5cGVOYW1lLCBpdGVtLT50eXBlTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJfSBlbHNlCgkgICAgaXRlbS0+c3VidHlwZXMgPSB0eXBlOwoJCiAgICB9IGVsc2UgaWYgKGl0ZW0tPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7CgoJLyoKCSogV2UgaGF2ZSBhbiBhdHRyaWJ1dGUgdXNlIGhlcmU7IGFzc2lnbiB0aGUgcmVmZXJlbmNlZCAKCSogYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8KCS8qCgkqIFRPRE86IEV2YWx1YXRlLCB3aGF0IGVycm9ycyBjb3VsZCBvY2N1ciBpZiB0aGUgZGVjbGFyYXRpb24gaXMgbm90CgkqIGZvdW5kLiBJdCBtaWdodCBiZSBwb3NzaWJsZSB0aGF0IHRoZSAidHlwZWZpeHVwIiBtaWdodCBjcmFzaCBpZgoJKiBubyByZWYgZGVjbGFyYXRpb24gd2FzIGZvdW5kLgoJKi8KCWRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zKTsKICAgICAgICBpZiAoZGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkgICAgCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJCSJyZWYiLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCWl0ZW0tPnJlZkRlY2wgPSBkZWNsOwogICAgICAgIHhtbFNjaGVtYUF0dHJGaXh1cChkZWNsLCBjdHh0LCBOVUxMKTsKCQogICAgICAgIGl0ZW0tPnN1YnR5cGVzID0gZGVjbC0+c3VidHlwZXM7CgkvKgoJKiBBdHRyaWJ1dGUgVXNlIENvcnJlY3QKCSogYXUtcHJvcHMtY29ycmVjdC4yOiBJZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIGEgZml4ZWQgCgkqIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlbiBpZiB0aGUgYXR0cmlidXRlIHVzZSBpdHNlbGYgaGFzIGEgCgkqIHt2YWx1ZSBjb25zdHJhaW50fSwgaXQgbXVzdCBhbHNvIGJlIGZpeGVkIGFuZCBpdHMgdmFsdWUgbXVzdCBtYXRjaCAKCSogdGhhdCBvZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0uCgkqLwoJaWYgKChkZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpICYmIAoJICAgIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJICAgIGlmICgoKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgPT0gMCkgfHwKCQkoIXhtbFN0ckVxdWFsKGl0ZW0tPmRlZlZhbHVlLCBkZWNsLT5kZWZWYWx1ZSkpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9BVV9QUk9QU19DT1JSRUNUXzIsIAoJCSAgICBOVUxMLCBOVUxMLCBpdGVtLT5ub2RlLCAKCQkgICAgIlRoZSB2YWx1ZSBjb25zdHJhaW50IG11c3QgYmUgZml4ZWQgIgoJCSAgICAiYW5kIG1hdGNoIHRoZSByZWZlcmVuY2VkIGF0dHJpYnV0ZSAiCgkJICAgICJkZWNsYXJhdGlvbnMncyB2YWx1ZSBjb25zdHJhaW50ICclcyciLAoJCSAgICBkZWNsLT5kZWZWYWx1ZSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBGVVRVUkU6IE9uZSBzaG91bGQgY2hhbmdlIHRoZSB2YWx1ZXMgb2YgdGhlIGF0dHIuIHVzZQoJICAgICogaWYgZXZlciB2YWxpZGF0aW9uIHNob3VsZCBiZSBhdHRlbXB0ZWQgZXZlbiBpZiB0aGUKCSAgICAqIHNjaGVtYSBpdHNlbGYgd2FzIG5vdCBmdWxseSB2YWxpZC4KCSAgICAqLwoJfQogICAgfSBlbHNlIHsKCWl0ZW0tPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7ICAgICAgICAKICAgIH0JCn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogcGFyc2UgYSBzY2hlbWEgZGVmaW5pdGlvbiByZXNvdXJjZSBhbmQgYnVpbGQgYW4gaW50ZXJuYWwKICogWE1MIFNoZW1hIHN0cnV0dXJlIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIGluc3RhbmNlcy4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUHRyCnhtbFNjaGVtYVBhcnNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldCA9IE5VTEw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sTm9kZVB0ciByb290OwogICAgaW50IHByZXNlcnZlID0gMDsKCiAgICAvKgogICAgKiBUaGlzIG9uZSBpcyB1c2VkIGlmIHRoZSBzY2hlbWEgdG8gYmUgcGFyc2VkIHdhcyBzcGVjaWZpZWQgdmlhIAogICAgKiB0aGUgQVBJOyBpLmUuIG5vdCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgZG9jdW1lbnQuCiAgICAqLwoKICAgIHhtbFNjaGVtYUluaXRUeXBlcygpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IE5VTEw7CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgaWYgKGN0eHQtPlVSTCAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZEZpbGUoKGNvbnN0IGNoYXIgKikgY3R4dC0+VVJMLCBOVUxMLCAKCSAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IGxvYWQgJyVzJy5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+VVJMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKGN0eHQtPmJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZE1lbW9yeShjdHh0LT5idWZmZXIsIGN0eHQtPnNpemUsIE5VTEwsIE5VTEwsCgkgICAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9QQVJTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZS5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIGRvYy0+VVJMID0geG1sU3RyZHVwKEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIik7CiAgICAgICAgY3R4dC0+VVJMID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIsIC0xKTsKICAgIH0gZWxzZSBpZiAoY3R4dC0+ZG9jICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSBjdHh0LT5kb2M7CglwcmVzZXJ2ZSA9IDE7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVEhJTkdfVE9fUEFSU0UsCgkJICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgcGFyc2UuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBhbmQgU2NoZW1hIHBhcnNlIGl0CiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAiVGhlIHNjaGVtYSBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudC5cbiIsIE5VTEwsIE5VTEwpOwoJaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIFRoZW4gZG8gdGhlIHBhcnNpbmcgZm9yIGdvb2QKICAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VTY2hlbWEoY3R4dCwgcm9vdCk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+cHJlc2VydmUgPSBwcmVzZXJ2ZTsKICAgIGN0eHQtPnNjaGVtYSA9IHJldDsKICAgIGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0ckRlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBncm91cCBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyZ3JwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyR3JwRml4dXAsCiAgICAgICAgICAgICAgICBjdHh0KTsKCiAgICAvKgogICAgKiBDaGVjayBhdHRyaWJ1dGUgZ3JvdXBzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgCgl4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIsIGN0eHQpOwoKICAgIC8qCiAgICAqIFRoZW4gZml4dXAgYWxsIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFHcm91cERlZkZpeHVwLCBjdHh0KTsKICAgIAogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIHR5cGVzIHByb3BlcnRpZXMKICAgICAqLyAgICAKICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXggcmVmZXJlbmNlcyBvZiBlbGVtZW50IGRlY2xhcmF0aW9uOyBhcHBseSBjb25zdHJhaW50cy4KICAgICAqLyAgICAKICAgIHhtbEhhc2hTY2FuRnVsbChyZXQtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2ssIGN0eHQpOwoKICAgICAvKgogICAgKiBDaGVjayBtb2RlbCBncm91cHMgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSAKCXhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhciwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gYnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGFsbCBjb21wbGV4IHR5cGVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBjaGVjayB0aGUgZGVmYXVsdHMgcGFydCBvZiB0aGUgdHlwZSBsaWtlIGZhY2V0cyB2YWx1ZXMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0RlZmF1bHRzLAogICAgICAgICAgICAgICAgY3R4dCk7CgogICAgLyoKICAgICogVmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgYXR0cmlidXRlIGRlY2xhcmF0aW9ucy91c2VzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0ckRlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyLCBjdHh0KTsKCiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmVsZW1EZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ciwgY3R4dCk7CgoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZShyZXQpOwogICAgICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgY2FsbGJhY2sKICogQHdhcm46ICB0aGUgd2FybmluZyBjYWxsYmFjawogKiBAY3R4OiAgY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzCiAqCiAqIFNldCB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIFhNbC1TY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGNhbGxiYWNrIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgY2FsbGJhY2sgcmVzdWx0CiAqIEBjdHg6IGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcyByZXN1bHQKICoKICogR2V0IHRoZSBjYWxsYmFjayBpbmZvcm1hdGlvbiB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGZhaWx1cmUsIDAgb3RoZXJ3aXNlCiAqLwppbnQgCnhtbFNjaGVtYUdldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuICgicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKCJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKCJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuICgidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKCJJbnRlcm5hbCBFcnJvciIpOwp9CgpzdGF0aWMgeG1sQ2hhciAqCnhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKGNvbnN0IHhtbENoYXIgKnZhbHVlKSB7CiAgICBjb25zdCB4bWxDaGFyICpjdXIgPSB2YWx1ZTsgICAgCiAgICB4bWxDaGFyICpyZXQgPSBOVUxMLCAqbWN1cjsgCgogICAgaWYgKHZhbHVlID09IE5VTEwpIAoJcmV0dXJuKE5VTEwpOwogICAgCiAgICB3aGlsZSAoKCpjdXIgIT0gMCkgJiYgCgkoKCgqY3VyKSAhPSAweGQpICYmICgoKmN1cikgIT0gMHg5KSAmJiAoKCpjdXIpICE9IDB4YSkpKSB7CgljdXIrKzsKICAgIH0KICAgIGlmICgqY3VyID09IDApCglyZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU3RyZHVwKHZhbHVlKTsKICAgIC8qIFRPRE8gRklYTUU6IEkgZ3Vlc3MgZ2NjIHdpbGwgYmFyayBhdCB0aGlzLiAqLwogICAgbWN1ciA9ICh4bWxDaGFyICopICAocmV0ICsgKGN1ciAtIHZhbHVlKSk7CiAgICBkbyB7CglpZiAoICgoKm1jdXIpID09IDB4ZCkgfHwgKCgqbWN1cikgPT0gMHg5KSB8fCAoKCptY3VyKSA9PSAweGEpICkKCSAgICAqbWN1ciA9ICcgJzsKCW1jdXIrKzsKICAgIH0gd2hpbGUgKCptY3VyICE9IDApOwkgICAgCiAgICByZXR1cm4ocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW5jOwoKICAgIC8qIAogICAgKiBUaGUgbm9ybWFsaXphdGlvbiB0eXBlIGNhbiBiZSBjaGFuZ2VkIG9ubHkgZm9yIHR5cGVzIHdoaWNoIGFyZSBkZXJpdmVkIAogICAgKiBmcm9tIHhzZDpzdHJpbmcuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgJiYKICAgICAgICAgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PUk1TVFJJTkcpKQoKCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfUFJFU0VSVkUpOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3IAoJICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0byAKCSAgICAqIGNvbGxhcHNlCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpOwoJfQkJICAgCSAgICAKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJLyoKCSogRm9yIGxpc3QgdHlwZXMgdGhlIGZhY2V0ICJ3aGl0ZVNwYWNlIiBpcyBmaXhlZCB0byAiY29sbGFwc2UiLiAKCSovCglyZXR1cm4gKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXJldHVybiAoLTEpOwogICAgfSBlbHNlIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGFueVNUOwoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbjsKCgkvKgoJKiBBdG9taWMgdHlwZXMuCgkqLwoJYW55U1QgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCWFuYyA9IHR5cGUtPmJhc2VUeXBlOwoJZG8gewoJICAgIC8qCgkgICAgKiBGb3IgYWxsILdhdG9taWO3IGRhdGF0eXBlcyBvdGhlciB0aGFuIHN0cmluZyAoYW5kIHR5cGVzILdkZXJpdmVktyAKCSAgICAqIGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBpdCkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2UgaXMgZml4ZWQgdG8gCgkgICAgKiBjb2xsYXBzZQoJICAgICovCgkgICAgaWYgKChhbmMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJCShhbmMtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykpIHsKCQkKCQlsaW4gPSB0eXBlLT5mYWNldFNldDsKCQlkbyB7CgkJICAgIGlmIChsaW4tPmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQlpZiAobGluLT5mYWNldC0+d2hpdGVzcGFjZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKSB7CgkJCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpOyAgCgkJCX0gZWxzZSBpZiAobGluLT5mYWNldC0+d2hpdGVzcGFjZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0UpIHsgCgkJCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfUkVQTEFDRSk7CgkJCX0gZWxzZQoJCQkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1BSRVNFUlZFKTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgbGluID0gbGluLT5uZXh0OwoJCX0gd2hpbGUgKGxpbiAhPSBOVUxMKTsJCgkJYnJlYWs7CgkgICAgfQoJICAgIGFuYyA9IGFuYy0+YmFzZVR5cGU7Cgl9IHdoaWxlIChhbmMgIT0gYW55U1QpOwoJcmV0dXJuIChYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSk7CQogICAgfSAgCiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHR5cGUgaG9sZGluZyB0aGUgZmFjZXRzCiAqIEBmYWNldHM6ICB0aGUgbGlzdCBvZiBmYWNldHMgdG8gY2hlY2sKICogQHZhbHVlOiAgdGhlIGxleGljYWwgcmVwciBvZiB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICogQHZhbDogIHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKiBAZmlyZUVycm9yczogIGlmIDAsIG9ubHkgaW50ZXJuYWwgZXJyb3JzIHdpbGwgYmUgZmlyZWQ7CiAqCQkgb3RoZXJ3aXNlIGFsbCBlcnJvcnMgd2lsbCBiZSBmaXJlZC4KICoKICogQ2hlY2sgYSB2YWx1ZSBhZ2FpbnN0IGFsbCBmYWNldCBjb25kaXRpb25zCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJY29uc3QgeG1sQ2hhciAqIHZhbHVlLAoJCQkJdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJCQlpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxTY2hlbWFUeXBlUHRyICBiaVR5cGU7IC8qIFRoZSBidWlsZC1pbiB0eXBlLiAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciB0bXBUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluazsKICAgIGludCByZXRGYWNldDsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgdW5zaWduZWQgbG9uZyBsZW4gPSAwOwoKI2lmZGVmIERFQlVHX1VOSU9OX1ZBTElEQVRJT04KICAgIHByaW50ZigiRmFjZXRzIG9mIHR5cGU6ICclcydcbiIsIChjb25zdCBjaGFyICopIHR5cGUtPm5hbWUpOwogICAgcHJpbnRmKCIgIGZpcmVFcnJvcnM6ICVkXG4iLCBmaXJlRXJyb3JzKTsKI2VuZGlmCiAgICAgICAgCiAgICBub2RlID0gY3R4dC0+bm9kZTsKICAgIC8qCiAgICAqIE5PVEU6IERvIG5vdCBqdW1wIGF3YXksIGlmIHRoZSBmYWNldFNldCBvZiB0aGUgZ2l2ZW4gdHlwZSBpcwogICAgKiBlbXB0eTogdW50aWwgbm93LCAicGF0dGVybiIgZmFjZXRzIG9mIHRoZSAqYmFzZSB0eXBlcyogbmVlZCB0bwogICAgKiBiZSBjaGVja2VkIGFzIHdlbGwuCiAgICAqLwogICAgYmlUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB3aGlsZSAoKGJpVHlwZSAhPSBOVUxMKSAmJiAoYmlUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpCgliaVR5cGUgPSBiaVR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJpVHlwZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAkJICAgIAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJICAgICJ0aGUgYmFzZSB0eXBlIGF4aXMgb2YgdGhlIGdpdmVuIHR5cGUgJyVzJyBkb2VzIG5vdCByZXNvbHZlIHRvICIKCSAgICAiYSBidWlsdC1pbiB0eXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsJCglyZXR1cm4gKC0xKTsKICAgIH0gICAgCiAgICAKICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CglmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsKCXdoaWxlIChmYWNldExpbmsgIT0gTlVMTCkgewoJICAgIGZhY2V0ID0gZmFjZXRMaW5rLT5mYWNldDsKCSAgICAvKgoJICAgICogU2tpcCB0aGUgcGF0dGVybiAid2hpdGVTcGFjZSI6IGl0IGlzIHVzZWQgdG8gCgkgICAgKiBmb3JtYXQgdGhlIGNoYXJhY3RlciBjb250ZW50IGJlZm9yZWhhbmQuCgkgICAgKi8JICAgIAoJICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgkJICAgIGJyZWFrOwoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOiAKCQkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKCQkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMaXN0U2ltcGxlVHlwZUZhY2V0KGZhY2V0LAoJCQkgICAgdmFsdWUsIGxlbmd0aCwgMCk7CgkJCWxlbiA9IGxlbmd0aDsKCQkgICAgfSBlbHNlCgkJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTGVuZ3RoRmFjZXQoYmlUeXBlLCBmYWNldCwKCQkJICAgIHZhbHVlLCBjdHh0LT52YWx1ZSwgJmxlbik7CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmlUeXBlLCBmYWNldCwgdmFsdWUsIAoJCQljdHh0LT52YWx1ZSk7CgkgICAgfQoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0IG9mIHR5cGUgJyVzJy5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJCWJyZWFrOwoJICAgIH0gZWxzZSBpZiAoKHJldCA+IDApICYmIChmaXJlRXJyb3JzKSkgewoJCXhtbFNjaGVtYVZGYWNldEVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCBsZW4sCgkJICAgIHR5cGUsIGZhY2V0LCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9CgoJICAgIGZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsKCX0KCWlmIChyZXQgPj0gMCkgewoJICAgIC8qCgkgICAgKiBQcm9jZXNzIGVudW1lcmF0aW9ucy4KCSAgICAqLwoJICAgIHJldEZhY2V0ID0gMDsKCSAgICBmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsKCSAgICB3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKCQlpZiAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkJICAgIHJldEZhY2V0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldChiaVR5cGUsIGZhY2V0TGluay0+ZmFjZXQsIAoJCQl2YWx1ZSwgY3R4dC0+dmFsdWUpOwkJCgkJICAgIGlmIChyZXRGYWNldCA8PSAwKQoJCQlicmVhazsKCQl9CgkJZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0OwoJICAgIH0KCSAgICBpZiAocmV0RmFjZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VOVU1FUkFUSU9OX1ZBTElEOwoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWRmFjZXRFcnIoY3R4dCwgcmV0LCBub2RlLAoJCQl2YWx1ZSwgMCwgdHlwZSwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXRGYWNldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXQgb2YgdHlwZSAnJXMnLlxuIiwKCQkgICAgQkFEX0NBU1QgImVudW1lcmF0aW9uIiwgTlVMTCk7CgkJICAgIHJldCA9IC0xOwkJCgkgICAgfQkJCgl9CiAgICB9CiAgICBpZiAocmV0ID49IDApIHsKCS8qCgkqIFByb2Nlc3MgcGF0dGVycy4gUGF0dGVybiBmYWNldHMgYXJlIE9SZWQgYXQgdHlwZSBsZXZlbCAKCSogYW5kIEFORGVkIGlmIGRlcml2ZWQuIFdhbGsgdGhlIGJhc2UgdHlwZSBheGlzLgoJKi8KCXRtcFR5cGUgPSB0eXBlOwoJZmFjZXQgPSBOVUxMOwoJZG8gewoJICAgIHJldEZhY2V0ID0gMDsKCSAgICBmb3IgKGZhY2V0TGluayA9IHRtcFR5cGUtPmZhY2V0U2V0OyBmYWNldExpbmsgIT0gTlVMTDsgCgkJZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0KSB7CgkJaWYgKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKQoJCSAgICBjb250aW51ZTsKCQlyZXRGYWNldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmlUeXBlLCBmYWNldExpbmstPmZhY2V0LCAKCQkgICAgdmFsdWUsIGN0eHQtPnZhbHVlKTsKCQlpZiAocmV0RmFjZXQgPT0gMCkgCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKHJldEZhY2V0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCQkJInZhbGlkYXRpbmcgJ3BhdHRlcm4nIGZhY2V0ICclcycgb2YgdHlwZSAnJXMnLlxuIiwKCQkJZmFjZXRMaW5rLT5mYWNldC0+dmFsdWUsIHRtcFR5cGUtPm5hbWUpOwoJCSAgICByZXQgPSAtMTsKCQkgICAgYnJlYWs7CgkJfSBlbHNlCgkJICAgIC8qIFNhdmUgdGhlIGxhc3Qgbm9uLXZhbGlkYXRpbmcgZmFjZXQuICovCgkJICAgIGZhY2V0ID0gZmFjZXRMaW5rLT5mYWNldDsKCSAgICB9CgkgICAgaWYgKHJldEZhY2V0ICE9IDApCgkJYnJlYWs7CQkgICAgCgkgICAgdG1wVHlwZSA9IHRtcFR5cGUtPmJhc2VUeXBlOwoJfSB3aGlsZSAoKHRtcFR5cGUgIT0gTlVMTCkgJiYgKHRtcFR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSk7CglpZiAocmV0RmFjZXQgPiAwKSB7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1BBVFRFUk5fVkFMSUQ7CgkgICAgaWYgKGZpcmVFcnJvcnMpIHsKCQl4bWxTY2hlbWFWRmFjZXRFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgMCwgdHlwZSwgZmFjZXQsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9CSAgICAKICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTaW1wbGUgdHlwZSB2YWxpZGF0aW9uCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlET00gVmFsaWRhdGlvbiBjb2RlCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCQkgIGludCB2YWxTaW1wbGVDb250ZW50KTsKCgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJTdGF0ZXM6CiAqIEBzdGF0ZTogIGEgbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqIEZyZWUgdGhlIGdpdmVuIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyh4bWxTY2hlbWFBdHRyU3RhdGVQdHIgc3RhdGUpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CiAgICB3aGlsZSAoc3RhdGUgIT0gTlVMTCkgewoJdG1wID0gc3RhdGU7CglzdGF0ZSA9IHN0YXRlLT5uZXh0OwkKCXhtbEZyZWUodG1wKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGF0dHJzOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZXMKICoKICogUmVnaXN0ZXIgdGhlIGxpc3Qgb2YgYXR0cmlidXRlcyBhcyB0aGUgc2V0IHRvIGJlIHZhbGlkYXRlZCBvbiB0aGF0IGVsZW1lbnQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbEF0dHJQdHIgYXR0cnMpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgogICAgY3R4dC0+YXR0ciA9IE5VTEw7CiAgICBjdHh0LT5hdHRyVG9wID0gTlVMTDsKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRycy0+bnMgIT0gTlVMTCkgJiYKICAgICAgICAgICAgKHhtbFN0ckVxdWFsKGF0dHJzLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpKSB7CiAgICAgICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCXRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCWlmICh0bXAgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXRtcC0+YXR0ciA9IGF0dHJzOwoJdG1wLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTjsKCXRtcC0+bmV4dCA9IE5VTEw7Cgl0bXAtPmRlY2wgPSBOVUxMOwoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgCiAgICAgICAgICAgIGN0eHQtPmF0dHIgPSB0bXA7CgllbHNlCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHRtcDsKCWN0eHQtPmF0dHJUb3AgPSB0bXA7CiAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIEN1cnJlbnRseSBub3QgdXNlZCAqLwovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0CiAqIEBub2RlbGlzdDogdGhlIGxpc3Qgb2Ygbm9kZXMKICoKICogQ2hlY2sgdGhlIG5vZGUgbGlzdCBpcyBvbmx5IG1hZGUgb2YgdGV4dCBub2RlcyBhbmQgZW50aXRpZXMgcG9pbnRpbmcKICogdG8gdGV4dCBub2RlcwogKgogKiBSZXR1cm5zIDEgaWYgdHJ1ZSwgMCBpZiBmYWxzZSBhbmQgLTEgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoeG1sTm9kZVB0ciBub2RlbGlzdCkKewogICAgd2hpbGUgKG5vZGVsaXN0ICE9IE5VTEwpIHsKICAgICAgICBpZiAobm9kZWxpc3QtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgewogICAgICAgICAgICBUT0RPICAgICAgICAgICAgICAgIC8qIGltcGxlbWVudCByZWN1cnNpb24gaW4gdGhlIGVudGl0eSBjb250ZW50ICovCiAgICAgICAgfQogICAgICAgIGlmICgobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DT01NRU5UX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfUElfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIHJldHVybiAoMCk7CiAgICAgICAgfQogICAgICAgIG5vZGVsaXN0ID0gbm9kZWxpc3QtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDEpOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUG9zdFNjaGVtYUFzc2VtYmxlRml4dXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpbnQgaSwgbmJJdGVtczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwgKml0ZW1zOwoKCiAgICAvKgogICAgKiBEdXJpbmcgdGhlIEFzc2VtYmxlIG9mIHRoZSBzY2hlbWEgY3R4dC0+Y3VySXRlbXMgaGFzCiAgICAqIGJlZW4gZmlsbGVkIHdpdGggdGhlIHJlbGV2YW50IG5ldyBpdGVtcy4gRml4IHRob3NlIHVwLgogICAgKi8KICAgIG5iSXRlbXMgPSBjdHh0LT5hc3NlbWJsZS0+bmJJdGVtczsKICAgIGl0ZW1zID0gKHhtbFNjaGVtYVR5cGVQdHIgKikgY3R4dC0+YXNzZW1ibGUtPml0ZW1zOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hQXR0ckZpeHVwKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjaygoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSwgY3R4dCwgCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUF0dHJHcnBGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIAoJCSAgICBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQl4bWxTY2hlbWFHcm91cERlZkZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOyAgICAgICAgICAgIAoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBDaXJjdWxhcml0eSBjaGVja3MuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQl4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVHcm91cENpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBGaXh1cCBmb3IgYWxsIG90aGVyIGl0ZW0uIAogICAgKiBUT0RPOiBIbW0sIG5vdCBzdXJlIGlmIHN0YXJ0aW5nIGZyb20gY29tcGxleC9zaW1wbGUgdHlwZXMsCiAgICAqIGFsbCBzdWJzZXF1ZW50IGl0ZW1zIHdpbGwgYmUgcmVhY2hlZC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJICAgIAogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFUeXBlRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGZhY2V0IHZhbHVlcy4gTm90ZSB0aGF0IGZhY2V0cyBhcmUKICAgICogaG9sZCBieSBjb21wbGV4IGFuZCBzaW1wbGUgdHlwZSBjb21wb25lbnRzIG9ubHkuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFDaGVja0RlZmF1bHRzKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBCdWlsZCB0aGUgY29udGVudCBtb2RlbCBmb3IgY29tcGxleCB0eXBlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJICAgIAoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0gCiAgICAvKgogICAgKiBWYWxpZGF0ZSB2YWx1ZSBjb250cmFpbnQgdmFsdWVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQl4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHIoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb246CiAqIEBwY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiB0aGUgZXhpc3Rpbmcgc2NoZW1hCiAqIEBub2RlOiB0aGUgbm9kZSB0aGF0IGZpcmVkIHRoZSBhc3NlbWJsaW5nCiAqIEBuc05hbWU6IHRoZSBuYW1lc3BhY2UgbmFtZSBvZiB0aGUgbmV3IHNjaGVtYQogKiBAbG9jYXRpb246IHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbikKewogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TnMsICpvbGR0bnM7IAogICAgeG1sRG9jUHRyIGRvYywgb2xkZG9jOwogICAgaW50IG9sZGZsYWdzLCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBkb2NFbGVtOwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKCiAgICAvKgogICAgKiBUaGlzIHNob3VsZCBiZSB1c2VkOgogICAgKiAxLiBvbiA8aW1wb3J0PihzKQogICAgKiAyLiBpZiByZXF1ZXN0ZWQgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSAKICAgICogMy4gaWYgcmVxdWVzdGVkIHZpYSB0aGUgQVBJCiAgICAqLwogICAgaWYgKCh2Y3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBDcmVhdGUgYSB0ZW1wb3JhcnkgcGFyc2VyIGNvbnRleHQuCiAgICAqLwogICAgaWYgKCh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgJiYKCSh4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQodmN0eHQpID09IC0xKSkgewoJeG1sU2NoZW1hVkVycih2Y3R4dCwgbm9kZSwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiwgIgoJICAgICJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQuXG4iLCAKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwkJCiAgICB9ICAgICAgICAgICAgCiAgICBwY3R4dCA9IHZjdHh0LT5wY3R4dDsKICAgIC8qCiAgICAqIFNldCB0aGUgY291bnRlciB0byBwcm9kdWNlIHVuaXF1ZSBuYW1lcyBmb3IgYW5vbnltb3VzIGl0ZW1zLgogICAgKi8KICAgIHBjdHh0LT5jb3VudGVyID0gc2NoZW1hLT5jb3VudGVyOyAgICAKICAgIC8qCiAgICAqIEFjcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHBjdHh0LCBzY2hlbWEsIG5vZGUsCgluc05hbWUsIGxvY2F0aW9uLCAmZG9jLCAmdGFyZ2V0TnMsIDApOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAoZG9jICE9IE5VTEwpCgkgICAgeG1sRnJlZURvYyhkb2MpOwogICAgfSBlbHNlIGlmIChkb2MgIT0gTlVMTCkgewoJZG9jRWxlbSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CgkvKgoJKiBDcmVhdGUgbmV3IGFzc2VtYmxlIGluZm8uCgkqLwoJaWYgKHBjdHh0LT5hc3NlbWJsZSA9PSBOVUxMKSB7CgkgICAgcGN0eHQtPmFzc2VtYmxlID0geG1sU2NoZW1hTmV3QXNzZW1ibGUoKTsKCSAgICBpZiAocGN0eHQtPmFzc2VtYmxlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkgICAgIk1lbW9yeSBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uLCAiCgkJICAgICJhbGxvY2F0aW5nIGFzc2VtYmxlIGluZm8iLCBOVUxMKTsKCQl4bWxGcmVlRG9jKGRvYyk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJLyoKCSogU2F2ZSBhbmQgcmVzZXQgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJb2xkZmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwoJb2xkdG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CglvbGRkb2MgPSBzY2hlbWEtPmRvYzsKCQoJeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyhzY2hlbWEpOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROczsKCS8qIHNjaGVtYS0+bmJDdXJJdGVtcyA9IDA7ICovCglwY3R4dC0+c2NoZW1hID0gc2NoZW1hOwoJcGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKCXBjdHh0LT5wYXJlbnRJdGVtID0gTlVMTDsKCQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyhwY3R4dCwgc2NoZW1hLCBkb2NFbGVtKTsJCQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgc2NoZW1hLCBkb2NFbGVtLT5jaGlsZHJlbik7Cgl4bWxTY2hlbWFQb3N0U2NoZW1hQXNzZW1ibGVGaXh1cChwY3R4dCk7CgkvKgoJKiBTZXQgdGhlIGNvdW50ZXIgb2YgaXRlbXMuCgkqLwoJc2NoZW1hLT5jb3VudGVyID0gcGN0eHQtPmNvdW50ZXI7CgkvKgoJKiBGcmVlIHRoZSBsaXN0IG9mIGFzc2VtYmxlZCBjb21wb25lbnRzLgoJKi8KCXBjdHh0LT5hc3NlbWJsZS0+bmJJdGVtcyA9IDA7CgkvKgoJKiBSZXN0b3JlIHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCXNjaGVtYS0+ZmxhZ3MgPSBvbGRmbGFnczsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gb2xkdG5zOwoJc2NoZW1hLT5kb2MgPSBvbGRkb2M7CglyZXQgPSBwY3R4dC0+ZXJyOwogICAgfSAgICAgICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0cjoKICogQHZjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB4c2lBdHRyOiBhbiB4c2kgYXR0cmlidXRlCiAqIEBub05hbWVzcGFjZTogd2hldGhlciBhIHNjaGVtYSB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UgaXMgZXhwdGVjdGVkCiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hIHVzaW5nCiAqIHRoZSB4c2k6c2NoZW1hTG9jYXRpb24gb3IgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gYXR0cmlidXRlCiAqIG9mIGFuIGluc3RhbmNlLiBJZiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBpcyB1c2VkLCBAbm9OYW1lc3BhY2UKICogbXVzdCBiZSBzZXQgdG8gMS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgeG1sQXR0clB0ciB4c2lBdHRyLAoJCQkgaW50IG5vTmFtZXNwYWNlKQp7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGNvbnN0IHhtbENoYXIgKm5zbmFtZSA9IE5VTEwsICpsb2NhdGlvbjsKICAgIGludCBjb3VudCA9IDA7CiAgICBpbnQgcmV0ID0gMDsKICAgIAogICAgaWYgKHhzaUF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJICAgIE5VTEwsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0ciwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIFBhcnNlIHRoZSB2YWx1ZTsgd2Ugd2lsbCBhc3N1bWUgYW4gZXZlbiBudW1iZXIgb2YgdmFsdWVzCiAgICAqIHRvIGJlIGdpdmVuICh0aGlzIGlzIGhvdyBYZXJjZXMgYW5kIFhTViB3b3JrKS4KICAgICovCiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KCh4bWxOb2RlUHRyKSB4c2lBdHRyKTsgICAgCiAgICBjdXIgPSB2YWx1ZTsKICAgIGRvIHsJCglpZiAobm9OYW1lc3BhY2UgIT0gMSkgewoJICAgIC8qCgkgICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBuYW1lLgoJICAgICovCgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBjb3VudCsrOwoJICAgIG5zbmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwkJCgkgICAgY3VyID0gZW5kOwoJfQoJLyoKCSogR2V0IHRoZSBVUkkuCgkqLwoJd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJICAgIGN1cisrOwoJZW5kID0gY3VyOwoJd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkgICAgZW5kKys7CglpZiAoZW5kID09IGN1cikKCSAgICBicmVhazsKCWNvdW50Kys7Cglsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwoJY3VyID0gZW5kOwkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbih2Y3R4dCwgdmN0eHQtPnNjaGVtYSwgCgkgICAgeHNpQXR0ci0+cGFyZW50LCBuc25hbWUsIGxvY2F0aW9uKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKHZjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkoeG1sTm9kZVB0cikgeHNpQXR0ciwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyLCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hdGEiLCBOVUxMKTsKCSAgICBpZiAodmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKHZhbHVlKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW06CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogYW4gZWxlbWVudCBub2RlIHBvc3NpYmx5IGhvbGRpbmcgeHNpIGF0dHJpYnV0ZXMKICogQG5vTmFtZXNwYWNlOiB3aGV0aGVyIGEgc2NoZW1hIHdpdGggbm8gdGFyZ2V0IG5hbWVzcGFjZSBpcyBleHB0ZWN0ZWQKICoKICogQXNzZW1ibGVzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZXMKICogb2YgdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsICAKCQkJIHhtbE5vZGVQdHIgZWxlbSkKeyAgICAKICAgIGludCByZXQgPSAwLCByZXROcyA9IDA7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJldE5zID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDApOwoJaWYgKHJldE5zID09IC0xKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDEpOwoJaWYgKHJldCA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChyZXROcyAhPSAwKQoJcmV0dXJuIChyZXROcyk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGRldGVjdGVkIChtaWdodCBiZSBOVUxMKQogKiBAdHlwZTogIHRoZSB0eXBlCiAqCiAqIEEgdHJhbnNpdGlvbiBoYXMgYmVlbiBtYWRlIGluIHRoZSBhdXRvbWF0YSBhc3NvY2lhdGVkIHRvIGFuIGVsZW1lbnQKICogY29udGVudCBtb2RlbAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgeG1sTm9kZVB0ciBvbGRub2RlID0gY3R4dC0+bm9kZTsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazogJXMsICVzLCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLT5uYW1lLCBub2RlLT5uYW1lKTsKI2VuZGlmCiAgICAvKgogICAgKiBAdHlwZS0+dHlwZSB3aWxsIGJlIFhNTF9TQ0hFTUFfVFlQRV9BTlkgb3IgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQuCiAgICAqLwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICBjdHh0LT5ub2RlID0gbm9kZTsgICAgCiAgICBjdHh0LT5jdXIgPSBub2RlLT5jaGlsZHJlbjsKICAgIC8qCiAgICAqIEFzc2VtYmxlIG5ldyBzY2hlbWF0YSB1c2luZyB4c2kuCiAgICAqLwogICAgaWYgKGN0eHQtPnhzaUFzc2VtYmxlKSB7CglpbnQgcmV0OwoKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9ICAgIAogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOiB7CgkgICAgLyoKCSAgICAqIE5PVEU6IFRoZSBidWlsZCBvZiB0aGUgY29udGVudCBtb2RlbCAKCSAgICAqICh4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwpIGVuc3VyZXMgdGhhdCB0aGUgZWxlbWVudCAKCSAgICAqIGRlY2xhcmF0aW9uIChhbmQgbm90IGEgcmVmZXJlbmNlIHRvIGl0KSB3aWxsIGJlIGdpdmVuLgoJICAgICovCgkgICAgaWYgKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgY3R4dC0+dHlwZSktPnJlZiAhPSBOVUxMKSB7CgkJLyoKCQkqIFRoaXMgaXMgcGFyYW5vaWQgY29kaW5nIDstKS4uLiBpdCBzaG91bGQgbm90CgkJKiBoYXBwZW4gaGVyZSBhbnkgbW9yZS4KCQkqLwoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkgICAgbm9kZSwgTlVMTCwJCQkJCQkKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCAiCgkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9uICdyZWZlcmVuY2UnIGVuY291bnRlcmVkLCAiCgkJICAgICJidXQgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiB3YXMgZXhwZWN0ZWQiLCAKCQkgICAgTlVMTCk7CgkJcmV0dXJuOwoJICAgIH0KCSAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIAoJCSh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlKTsKCSAgICBicmVhazsKCX0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZChjdHh0LCB0eXBlKTsKICAgICAgICAgICAgYnJlYWs7CglkZWZhdWx0OiAKCSAgICBicmVhazsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7Cn0gIAoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdmFsdWU6IHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQKICogQGZpcmVFcnJvcnM6IHNoYWxsIGVycm9ycyBiZSByZXBvcnRlZD8KICogQGFwcGx5RmFjZXRzOiBzaGFsbCBmYWNldHMgYmUgYXBwbGllZD8KICogQG5vcm1hbGl6ZTogc2hhbGwgdGhlIHZhbHVlIGJlIG5vcm1hbGl6ZWQ/CiAqIEBjaGVja05vZGVzOiBzaGFsbCB0aGUgY29udGVudCBub2RlcyBiZSBjaGVja2VkPwogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBieSB0aGUgZ2l2ZW4gdHlwZSAodXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluKS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJIGNvbnN0IHhtbENoYXIgKnZhbHVlLAkJCQkgCgkJCQkgaW50IGZpcmVFcnJvcnMsCQkJCSAKCQkJCSBpbnQgYXBwbHlGYWNldHMsCgkJCQkgaW50IG5vcm1hbGl6ZSwKCQkJCSBpbnQgY2hlY2tOb2RlcykKewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IHJldCA9IDA7ICAKICAgIHhtbENoYXIgKm5vcm1WYWx1ZSA9IE5VTEw7CiAgICBpbnQgd3RzcDsgICAgICAgCiAKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogU2F2ZSB0aGUgY3VycmVudCB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gdHlwZS4gKi8KICAgIHd0c3AgPSBjdHh0LT52YWx1ZVdTOwogICAgLyoKICAgICogTm9ybWFsaXplIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAobm9ybWFsaXplICYmIAoJKGN0eHQtPnZhbHVlV1MgIT0gWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpKSB7CglpbnQgbm9ybSA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwoJCglpZiAoKG5vcm0gIT0gLTEpICYmIChub3JtID4gY3R4dC0+dmFsdWVXUykpIHsKCSAgICBpZiAobm9ybSA9PSBYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSkKCQlub3JtVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkgICAgZWxzZQoJCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKHZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZVdTID0gbm9ybTsKCSAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBub3JtVmFsdWU7Cgl9CQkKICAgIH0gICAgCiAgICAvKgogICAgKiBUaGUgbm9kZXMgb2YgYSBjb250ZW50IG11c3QgYmUgY2hlY2tlZCBvbmx5IG9uY2UsCiAgICAqIHRoaXMgaXMgbm90IHdvcmtpbmcgc2luY2UgbGlzdCB0eXBlcyB3aWxsIGZpcmUgdGhpcwogICAgKiBtdWx0aXBsZSB0aW1lcy4KICAgICovCiAgICBpZiAoKGNoZWNrTm9kZXMgPT0gMSkgJiYgKGN0eHQtPmN1ciAhPSBOVUxMKSkgewoJeG1sTm9kZVB0ciBjdXIgPSBjdHh0LT5jdXI7CgoJZG8gewoJICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgoJICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKCSAgICBjYXNlIFhNTF9QSV9OT0RFOgoJICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9FTkQ6CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfRU5USVRZX1JFRl9OT0RFOgoJICAgIGNhc2UgWE1MX0VOVElUWV9OT0RFOgoJCS8qIFRPRE86IFNjb3VyIHRoZSBlbnRpdGllcyBmb3IgaWxsZWdhbCBub2Rlcy4gKi8KCQlUT0RPIGJyZWFrOwoJICAgIGNhc2UgWE1MX0VMRU1FTlRfTk9ERTogewoJICAgIC8qIE5PVEU6IENoYW5nZWQgdG8gYW4gaW50ZXJuYWwgZXJyb3IsIHNpbmNlIHRoZSAKCSAgICAqIGV4aXN0ZW5jZSBvZiBhbiBlbGVtZW50IG5vZGUgd2lsbCBiZSBhbHJlYWR5IGNoZWNrZWQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSBhbmQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUuCgkJKi8KCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgLyogWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLCAqLwoJCSAgICBub2RlLCB0eXBlLAoJCSAgICAiRWxlbWVudCAnJXMnIGZvdW5kIGluIHNpbXBsZSB0eXBlIGNvbnRlbnQiLCAKCQkgICAgY3VyLT5uYW1lKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFWX0lOVEVSTkFMKTsKCQkJCSAgIH0KCSAgICBjYXNlIFhNTF9BVFRSSUJVVEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX1RZUEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9GUkFHX05PREU6CgkgICAgY2FzZSBYTUxfTk9UQVRJT05fTk9ERToKCSAgICBjYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CgkgICAgY2FzZSBYTUxfRFREX05PREU6CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9ERUNMOgoJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9ERUNMOgoJICAgIGNhc2UgWE1MX0VOVElUWV9ERUNMOgoJICAgIGNhc2UgWE1MX05BTUVTUEFDRV9ERUNMOgojaWZkZWYgTElCWE1MX0RPQ0JfRU5BQkxFRAoJICAgIGNhc2UgWE1MX0RPQ0JfRE9DVU1FTlRfTk9ERTogCiNlbmRpZgkJICAgIAkJICAgIAkJICAgIAoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sICovCgkJICAgIG5vZGUsIE5VTEwsCgkJICAgICJOb2RlIG9mIHVuZXhwZWN0ZWQgdHlwZSBmb3VuZCBpbiBzaW1wbGUgdHlwZSBjb250ZW50IiwKCQkgICAgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BVl9JTlRFUk5BTCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlLCBhbnlUeXBlOwoKCWFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCgliYXNlID0gdHlwZS0+YmFzZVR5cGU7Cgl3aGlsZSAoKGJhc2UgIT0gTlVMTCkgJiYgCgkgICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgJiYKCSAgICAoYmFzZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkgICAgKGJhc2UgIT0gYW55VHlwZSkpIHsKCSAgICBiYXNlID0gYmFzZS0+YmFzZVR5cGU7Cgl9CglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBiYXNlLCB2YWx1ZSwgMSwgMCwgMSwgMCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGNvbXBsZXggdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgLyogCgkgICAgKiBDaGVjayBmYWNldHMuCgkgICAgKi8JICAgIAoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHNvbWVob3cgbm90IG5pY2UsIHNpbmNlIGlmIGFuIGVycm9yIG9jY3VycwoJICAgICogdGhlIHJlcG9ydGVkIHR5cGUgd2lsbCBiZSB0aGUgY29tcGxleCB0eXBlOyB0aGUgc3BlYwoJICAgICogd2FudHMgYSBzaW1wbGUgdHlwZSB0byBiZSBjcmVhdGVkIG9uIHRoZSBjb21wbGV4IHR5cGUKCSAgICAqIGlmIGl0IGhhcyBhIHNpbXBsZSBjb250ZW50LiBGb3Igbm93IHdlIGhhdmUgdG8gbGl2ZSB3aXRoCgkgICAgKiBpdC4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgY29tcGxleCB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJICAgIH0JCgl9CQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoKCWlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CgkvKgoJKiBTVFJFQU0tUkVBRC1DSElMRFJFTi4KCSovCSAgICAJCQoJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGVOb05vcm0odHlwZSwgdmFsdWUsICYoY3R4dC0+dmFsdWUpLCBub2RlKTsKCWlmIChyZXQgPiAwKSB7CSAgICAKCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJICAgIGVsc2UKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CSAgICAKCSAgICBpZiAoZmlyZUVycm9ycykKCQl4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGJ1aWx0LWluIHR5cGUgJyVzJ1xuIiwgdHlwZS0+bmFtZSwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgeyAgICAgICAgCgkvKiAxLjIuMSBpZiB7dmFyaWV0eX0gaXMgt2F0b21pY7cgdGhlbiB0aGUgc3RyaW5nIG11c3Qgt21hdGNotyAKCSogYSBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSAKCSovCQoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZS0+YmFzZVR5cGUsIHZhbHVlLCAwLCAwLCAwLCAwKTsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgYXRvbWljIHNpbXBsZSB0eXBlICclcydcbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7Cgl9IGVsc2UgaWYgKHJldCA+IDApIHsJICAgIAoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCSAgICBpZiAoZmlyZUVycm9ycykKCQl4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsJCgl9IGVsc2UgaWYgKChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgLyogCgkgICAgKiBDaGVjayBmYWNldHMuCgkgICAgKi8JICAgIAkgICAgCSAgICAKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCAwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIGF0b21pYyBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkJLyoKCQkgRGlzYWJsZWQsIHNpbmNlIHRoZSBmYWNldCB2YWxpZGF0aW9uIGFscmVhZHkgcmVwb3J0cyBlcnJvcnMuCgkJaWYgKGZpcmVFcnJvcnMpIAoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIGN0eHQtPmN1ciwgdmFsdWUsIHR5cGUpOwoJCSovCgkgICAgfQkKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewogICAgICAgIAoJeG1sU2NoZW1hVHlwZVB0ciB0bXBUeXBlOwoJY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kOwoJeG1sQ2hhciAqdG1wOwoJdW5zaWduZWQgbG9uZyBsZW4gPSAwOwoKCS8qIDEuMi4yIGlmIHt2YXJpZXR5fSBpcyC3bGlzdLcgdGhlbiB0aGUgc3RyaW5nIG11c3QgYmUgYSBzZXF1ZW5jZSAKCSogb2Ygd2hpdGUgc3BhY2Ugc2VwYXJhdGVkIHRva2VucywgZWFjaCBvZiB3aGljaCC3bWF0Y2i3ZXMgYSBsaXRlcmFsIAoJKiBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gCgkqLwoJCgl0bXBUeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKTsJCgljdXIgPSB2YWx1ZTsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIGxlbisrOwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHRtcFR5cGUsIHRtcCwgMCwgMSwgMCwgMCk7CgkgICAgeG1sRnJlZSh0bXApOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBhbiBpdGVtIG9mIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CQoJCWJyZWFrOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CgkJYnJlYWs7CgkgICAgfQkKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwoJLyogCgkqIENoZWNrIGZhY2V0cy4KCSovCglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAoKHJldCA9PSAwKSAmJiAoYXBwbHlGYWNldHMpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgbGVuLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCS8qCgkJIERpc2FibGVkLCBzaW5jZSB0aGUgZmFjZXQgdmFsaWRhdGlvbiBhbHJlYWR5IHJlcG9ydHMgZXJyb3JzLgoJCWlmIChmaXJlRXJyb3JzKSAKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBjdHh0LT5jdXIsIHZhbHVlLCB0eXBlKTsKCQkqLwoJICAgIH0JIAkgICAKCSAgIAoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyTGluazsKCgkvKgoJKiBUT0RPOiBGb3IgYWxsIGRhdGF0eXBlcyC3ZGVyaXZlZLcgYnkgt3VuaW9utyAgd2hpdGVTcGFjZSBkb2VzIAoJKiBub3QgYXBwbHkgZGlyZWN0bHk7IGhvd2V2ZXIsIHRoZSBub3JtYWxpemF0aW9uIGJlaGF2aW9yIG9mILd1bmlvbrcgCgkqIHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlIAoJKiC3bWVtYmVyVHlwZXO3IGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4gCgkqCgkqIFRoaXMgbWVhbnMgdGhhdCB0aGUgdmFsdWUgaXMgbm9ybWFsaXplZCBieSB0aGUgZmlyc3QgdmFsaWRhdGluZwoJKiBtZW1iZXIgdHlwZSwgdGhlbiB0aGUgZmFjZXRzIG9mIHRoZSB1bmlvbiB0eXBlIGFyZSBhcHBsaWVkLiBUaGlzCgkqIG5lZWRzIGNoYW5naW5nIG9mIHRoZSB2YWx1ZSEKCSovCQoJCgkvKgoJKiAxLjIuMyBpZiB7dmFyaWV0eX0gaXMgt3VuaW9utyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IGEgCgkqIGxpdGVyYWwgaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiBhdCBsZWFzdCBvbmUgbWVtYmVyIG9mIAoJKiB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IAoJKi8KI2lmZGVmIERFQlVHX1VOSU9OX1ZBTElEQVRJT04KCXByaW50ZigiVW5pb24gU1QgICAgIDogJyVzJ1xuIiwgKGNvbnN0IGNoYXIgKikgdHlwZS0+bmFtZSk7CglwcmludGYoIiAgZmlyZUVycm9ycyA6ICVkXG4iLCBmaXJlRXJyb3JzKTsKCXByaW50ZigiICBhcHBseUZhY2V0czogJWRcbiIsIGFwcGx5RmFjZXRzKTsKI2VuZGlmCgltZW1iZXJMaW5rID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZSk7CglpZiAobWVtYmVyTGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInVuaW9uIHNpbXBsZSB0eXBlICclcycgaGFzIG5vIG1lbWJlciB0eXBlc1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXQgPSAtMTsKCX0gCglpZiAocmV0ID09IDApIHsKCSAgICB3aGlsZSAobWVtYmVyTGluayAhPSBOVUxMKSB7CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgbWVtYmVyTGluay0+dHlwZSwgCgkJICAgIHZhbHVlLCAwLCAxLCAxLCAwKTsKCQlpZiAoKHJldCA8PSAwKSB8fCAocmV0ID09IDApKQoJCSAgICBicmVhazsJICAgIAoJCW1lbWJlckxpbmsgPSBtZW1iZXJMaW5rLT5uZXh0OwoJICAgIH0gICAgIAoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBtZW1iZXJzIG9mIHVuaW9uIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CgkgICAgfQoJfQoJLyoKCSogQXBwbHkgZmFjZXRzIChwYXR0ZXJuLCBlbnVtZXJhdGlvbikuCQoJKi8KCWlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgaW50IG13czsKCSAgICAvKgoJICAgICogVGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utyB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IAoJICAgICogdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlILdtZW1iZXJUeXBlc7cgCgkgICAgKiBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuIAoJICAgICovCQkgICAgCgkgICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidGhlIHZhbHVlIHdhcyBhbHJlYWR5IG5vcm1hbGl6ZWQgZm9yIHRoZSB1bmlvbiBzaW1wbGUgIgoJCSAgICAidHlwZSAnJXMnLlxuIiwgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfQoJICAgIG13cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKG1lbWJlckxpbmstPnR5cGUpOwoJICAgIGlmIChtd3MgPiBjdHh0LT52YWx1ZVdTKSB7CgkJaWYgKG13cyA9PSBYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSkKCQkgICAgbm9ybVZhbHVlID0geG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcodmFsdWUpOwoJCWVsc2UKCQkgICAgbm9ybVZhbHVlID0geG1sU2NoZW1hV2hpdGVTcGFjZVJlcGxhY2UodmFsdWUpOwoJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkgICAgdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBub3JtVmFsdWU7CgkgICAgfQoKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCAwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIHVuaW9uIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCQkvKgoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIGN0eHQtPmN1ciwgdmFsdWUsIHR5cGUpOwoJCSovCgkgICAgfQkKCX0KICAgIH0gICAgICAgICAgIAogICAgY3R4dC0+dmFsdWVXUyA9IHd0c3A7CiAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKG5vcm1WYWx1ZSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSBlbGVtZW50IG5vZGUgdG8gYmUgdmFsaWRhdGVkLgogKgogKiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgIGludCB2YWxTaW1wbGVDb250ZW50KQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGU7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIGludCByZXQgPSAwLCByZXR2YWwgPSAwOwogICAgICAgIAogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgTlVMTCwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7ICAgIAogICAgfQoKICAgIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgbm9kZSA9IGN0eHQtPm5vZGU7CiAgICAvKiAKICAgICogY3ZjLXR5cGU6IDMuMS4yIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBoYXZlIG5vIGVsZW1lbnQgCiAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KICAgICovICAgCiAgICAvKgogICAgKiBTVFJFQU06IENoaWxkIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgY3VyID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCS8qCgkqIFRPRE86IEVudGl0aWVzLCB3aWxsIHRoZXkgcHJvZHVjZSBlbGVtZW50cyBhcyB3ZWxsPwoJKi8KCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMiwKCQlub2RlLCB0eXBlLAkJCgkJIk5vIGVsZW1lbnQgY29udGVudCBhbGxvd2VkIiwgTlVMTCk7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzI7Cgl9CgljdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICAKICAgIC8qCiAgICAqIGN2Yy10eXBlIDMuMS4xOgogICAgKgogICAgKiBUaGUgYXR0cmlidXRlcyBvZiBtdXN0IGJlIGVtcHR5LCBleGNlcHRpbmcgdGhvc2Ugd2hvc2UgbmFtZXNwYWNlIG5hbWUgCiAgICAqIGlzIGlkZW50aWNhbCB0byBodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBhbmQgd2hvc2UgbG9jYWwgCiAgICAqIG5hbWUgaXMgb25lIG9mIHR5cGUsIG5pbCwgc2NoZW1hTG9jYXRpb24gb3Igbm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbi4KICAgICovICAgCiAgICAvKgogICAgKiBTVFJFQU06IEF0dHJpYnV0ZSBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewogICAgICAgIGlmICgoYXR0ci0+bnMgPT0gTlVMTCkgfHwKICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHx8CiAgICAgICAgICAgICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ0eXBlIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWwiKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsCiAgICAgICAgICAgICAgKGF0dHItPm5hbWUsIEJBRF9DQVNUICJub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIikpKSkgewoJICAgIHhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMSwgYXR0cik7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzE7CiAgICAgICAgfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBUaGlzIHdpbGwgc2tpcCB2YWxpZGF0aW9uIGlmIHRoZSB0eXBlIGlzICdhbnlTaW1wbGVUeXBlJyBhbmQKICAgICogaWYgdGhlIHZhbHVlIHdhcyBhbHJlYWR5IHZhbGlkYXRlZCAoZS5nLiBkZWZhdWx0IHZhbHVlcykuCiAgICAqLwogICAgaWYgKCh2YWxTaW1wbGVDb250ZW50ID09IDEpICYmCgkoKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB8fAoJICh0eXBlLT5idWlsdEluVHlwZSAhPSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkpIHsKCXhtbENoYXIgKnZhbHVlOwkKCgl2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwoJLyoKCSogTk9URTogVGhpcyBjYWxsIHdpbGwgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCBzaW5jZQoJKiB0aGlzIHNob3VsZCBiZSBjaGVja2VkIGhlcmUgYWxyZWFkeS4KCSovCglyZXR2YWwgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgCgkgICAgMSwgMSwgMSwgMCk7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICB4bWxGcmVlKHZhbHVlKTsKCWlmIChyZXR2YWwgIT0gMCkKCSAgICByZXQgPSByZXR2YWw7CiAgICB9CiAgICBjdHh0LT50eXBlID0gb2xkdHlwZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbFFOYW1lQWNxdWlyZToKICogQHZhbHVlOiB0aGUgbGV4aWNhbCByZXByZXNhbnRhdGlvbiBvZiB0aGUgUU5hbWUgdmFsdWUKICogQG5vZGU6IHRoZSBub2RlIHRvIHNlYXJjaCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCiAqIEBuc05hbWU6IHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIG5hbWUgaWYgZm91bmQKICoKICogQ2hlY2tzIHRoYXQgYSB2YWx1ZSBjb25mb3JtcyB0byB0aGUgbGV4aWNhbCBzcGFjZSBvZiB0aGUgdHlwZSBRTmFtZTsKICogaWYgdmFsaWQsIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBuYW1lIGlzIHNlYXJjaGVkIGFuZCByZXR1cmVkIAogKiBhcyBhIGNvcHkgaW4gQG5zTmFtZS4gVGhlIGxvY2FsIG5hbWUgaXMgcmV0dXJuZWQgaW4gQGxvY2FsTmFtZSBhcwogKiBhIGNvcHkuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZCwgMSBpZiBub3QgdmFsaWQgYnkgdHlwZSwgMiBpZiBubyBjb3JyZXNwb25kaW5nIAogKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gd2FzIGZvdW5kIGluIHNjb3BlOyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIAogKiBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbFFOYW1lQWNxdWlyZShjb25zdCB4bWxDaGFyICp2YWx1ZSwgeG1sTm9kZVB0ciBub2RlLAoJCQl4bWxDaGFyICoqbnNOYW1lLCB4bWxDaGFyICoqbG9jYWxOYW1lKQp7CiAgICBpbnQgcmV0OwogICAgeG1sQ2hhciAqbG9jYWwgPSBOVUxMOwoKICAgIGlmICgobnNOYW1lID09IE5VTEwpIHx8IChsb2NhbE5hbWUgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsgIAogICAgKm5zTmFtZSA9IE5VTEw7ICAgCiAgICAqbG9jYWxOYW1lID0gTlVMTDsKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA9PSAwKSB7Cgl4bWxDaGFyICpwcmVmaXg7Cgl4bWxOc1B0ciBuczsKCQoJLyoKCSogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCByZXR1cm4gYSBkdXBsaWNhdGVkCgkqIHN0cmluZy4KCSovCglsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChsb2NhbCA9PSBOVUxMKQoJICAgIGxvY2FsID0geG1sU3RyZHVwKHZhbHVlKTsKCW5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBwcmVmaXgpOwoJLyoKICAgICAgICAqIEEgbmFtZXNwYWNlIG5lZWQgbm90IHRvIGJlIGZvdW5kIGlmIHRoZSBwcmVmaXggaXMgTlVMTC4KCSovCglpZiAobnMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBJcyBpdCBuZWNlc3NhcnkgdG8gZHVwbGljYXRlIHRoZSBVUkkgaGVyZT8KCSAgICAqLwoJICAgICpuc05hbWUgPSB4bWxTdHJkdXAobnMtPmhyZWYpOwoJfSBlbHNlIGlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIHhtbEZyZWUocHJlZml4KTsgCgkgICAgaWYgKGxvY2FsICE9IE5VTEwpCgkJeG1sRnJlZShsb2NhbCk7CgkgICAgcmV0dXJuICgyKTsKCX0JCQoJKmxvY2FsTmFtZSA9IGxvY2FsOwoJaWYgKHByZWZpeCAhPSBOVUxMKQoJICAgIHhtbEZyZWUocHJlZml4KTsgICAgCiAgICB9IGVsc2UKCXJldHVybiAoMSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFIYXNFbGVtQ29udGVudDogCiAqIEBub2RlOiAgdGhlIG5vZGUKICoKICogU2NvdXJzIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBub2RlIGZvciBlbGVtZW50CiAqIG5vZGVzLgogKgogKiBSZXR1cm5zIDEgaWYgYW4gZWxlbWVudCBub2RlIGlzIGZvdW5kLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbUNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIG5vZGUgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChub2RlICE9IE5VTEwpIHsKCWlmIChub2RlLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgcmV0dXJuICgxKTsKCW5vZGUgPSBub2RlLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQovKioKICogeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQ6IAogKiBAbm9kZTogIHRoZSBub2RlCiAqCiAqIFNjb3VycyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gbm9kZSBmb3IgZWxlbWVudAogKiBhbmQgY2hhcmFjdGVyIG5vZGVzLgogKgogKiBSZXR1cm5zIDEgaWYgYW4gZWxlbWVudCBvciBjaGFyYWN0ZXIgbm9kZSBpcyBmb3VuZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKG5vZGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7Cglzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9FTEVNRU5UX05PREU6CQoJICAgIC8qIAoJICAgICogVE9ETzogQXNrIERhbmllbCBpZiB0aGVzZSBhcmUgYWxsIGNoYXJhY3RlciBub2Rlcy4KCSAgICAqLwoJICAgIGNhc2UgWE1MX1RFWFRfTk9ERToKCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CgkgICAgLyoKCSAgICAqIFRPRE86IEhvdyBYTUxfRU5USVRZX05PREVzIGV2YWx1YXRlZD8KCSAgICAqLwoJICAgIGNhc2UgWE1MX0VOVElUWV9SRUZfTk9ERToKCSAgICBjYXNlIFhNTF9FTlRJVFlfTk9ERToKCQlyZXR1cm4gKDEpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9Cglub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgdHlwZS4KICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgeG1sTm9kZVB0ciBlbGVtOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFjdHVhbFR5cGUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sQ2hhciAqYXR0clZhbHVlOyAKICAgIGludCBuaWxsZWQgPSAwLCBlbGVtSGFzQ29udGVudCA9IC0xOwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsLCAKICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlIGFuZCB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQuCiAgICAqIE5vdGUgdGhhdCBAZWxlbURlY2wgd2lsbCBiZSB0aGUgZGVjbGFyYXRpb24gYW5kIG5ldmVyIHRoZQogICAgKiByZWZlcmVuY2UgdG8gYSBkZWNsYXJhdGlvbi4KICAgICovCgogICAgaWYgKGN0eHQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgTlVMTCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkgICAgImJhZCBhcmd1bWVudHMuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGVsZW0gPSBjdHh0LT5ub2RlOyAgIAoKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDEKICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwgCgkgICAgZWxlbSwgTlVMTCwKCSAgICAiTm8gbWF0Y2hpbmcgZGVjbGFyYXRpb24gYXZhaWxhYmxlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMgogICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7Cgl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF8yLAoJICAgIGVsZW0sIE5VTEwsIAoJICAgICJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgICAKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDMKICAgICogSGFuZGxlICd4c2k6bmlsJy4KICAgICovCiAgICAKICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgIm5pbCIsIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJYXR0clZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoKHhtbE5vZGVQdHIpIGF0dHIpOwkKCWN0eHQtPm5vZGUgPSAoeG1sTm9kZVB0cikgYXR0cjsKCWN0eHQtPmN1ciA9IGF0dHItPmNoaWxkcmVuOwkKCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLAoJICAgIEJBRF9DQVNUIGF0dHJWYWx1ZSwgMSwgMSwgMSwgMSk7CgljdHh0LT5ub2RlID0gZWxlbTsKCWN0eHQtPnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2w7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJKHhtbE5vZGVQdHIpIGF0dHIsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIsIE5VTEwpOwoJICAgIGlmIChhdHRyVmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKGF0dHJWYWx1ZSk7CgkgICAgcmV0dXJuICgtMSk7Cgl9IAoJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSB7CgkvKiAKCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4xIAoJICAgICovCgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMSwgCgkJZWxlbSwgTlVMTCwKCQkiVGhlIGVsZW1lbnQgaXMgbm90ICduaWxsYWJsZSciLCBOVUxMKTsJCgl9IGVsc2UgewkJICAgIAoJICAgIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCBhdHRyVmFsdWUsIEJBRF9DQVNUICJ0cnVlIikgfHwKCQl4bWxTdHJFcXVhbChCQURfQ0FTVCBhdHRyVmFsdWUsIEJBRF9DQVNUICIxIikpIHsJCQoJCXJldCA9IDA7CgkJLyogCgkJKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjIuMSAKCQkqLwoJCWVsZW1IYXNDb250ZW50ID0geG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSk7CgkJaWYgKGVsZW1IYXNDb250ZW50ID09IDEpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMSwgCgkJCS8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwgKi8KCQkJZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCQkiVGhlICduaWxsZWQnIGVsZW1lbnQgbXVzdCBoYXZlIG5vIGNoYXJhY3RlciBvciAiCgkJCSJlbGVtZW50IGNvbnRlbnQiLCBOVUxMKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMTsKCQl9CgkJLyogCgkJKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjIuMiAKCQkqLwoJCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCQkgICAgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzIsIAoJCQkvKiBYTUxfU0NIRU1BU19FUlJfSEFWRURFRkFVTFQsICovCgkJCWVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJIlRoZXJlIGlzIGEgZml4ZWQgdmFsdWUgY29uc3RyYWludCBkZWZpbmVkIGZvciAiCgkJCSJ0aGUgJ25pbGxlZCcgZWxlbWVudCIsIE5VTEwpOwkJICAgIAoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yOwoJCX0KCQlpZiAocmV0ID09IDApCgkJICAgIG5pbGxlZCA9IDE7CQkKCSAgICB9Cgl9CglpZiAoYXR0clZhbHVlICE9IE5VTEwpCgkgICAgeG1sRnJlZShhdHRyVmFsdWUpOwogICAgfQogICAgCgogICAgYWN0dWFsVHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKICAgIC8qIAogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA0IAogICAgKiBIYW5kbGUgJ3hzaTp0eXBlJy4KICAgICovCiAgICAKICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgInR5cGUiLCAgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CQoJeG1sQ2hhciAqbnNOYW1lID0gTlVMTCwgKmxvY2FsID0gTlVMTDsKCQoJLyoKCSogVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhICp3YXJuaW5nKiB0aGF0IHRoZSB0eXBlIHdhcyBvdmVycmlkZW4KCSogYnkgdGhlIGluc3RhbmNlLgoJKi8KCQoJLyogCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDQuMSAKCSovCglhdHRyVmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgYXR0cik7CglyZXQgPSB4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmUoYXR0clZhbHVlLCBhdHRyLT5wYXJlbnQsCQoJICAgICZuc05hbWUsICZsb2NhbCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJKHhtbE5vZGVQdHIpIGF0dHIsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyB0aGUgYXR0cmlidXRlICd4c2k6dHlwZSciLCBOVUxMKTs7CgkgICAgRlJFRV9BTkRfTlVMTChhdHRyVmFsdWUpCgkJRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJRlJFRV9BTkRfTlVMTChsb2NhbCkKCQlyZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID09IDEpIHsKCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwKCQkoeG1sTm9kZVB0cikgYXR0ciwgYXR0clZhbHVlLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSkpOwoJfSBlbHNlIGlmIChyZXQgPT0gMikgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJKHhtbE5vZGVQdHIpIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vICIKCQkiY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUiLCAKCQlhdHRyVmFsdWUpOwkgICAgCSAgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDQuMiAKCSAgICAqLwoJICAgIGFjdHVhbFR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbG9jYWwsIG5zTmFtZSk7CgkgICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewkgIAoJCXhtbENoYXIgKnN0ckEgPSBOVUxMOwoJCQoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF80XzIsCgkJICAgICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSAgICAiVGhlIHZhbHVlICVzIGRvZXMgbm90IHJlc29sdmUgdG8gYSB0eXBlICIKCQkgICAgImRlZmluaXRpb24iLCAKCQkgICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyQSwgbnNOYW1lLCBsb2NhbCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyQSk7ICAgIAoJICAgIH0gZWxzZSB7CQkKCQkvKgoJCSogVVJHRU5UIFRPRE86IGN2Yy1lbHQgKDMuMy40KSA6IDQuMyAoVHlwZSBEZXJpdmF0aW9uIE9LKQoJCSovCQkKCSAgICB9Cgl9CglGUkVFX0FORF9OVUxMKGF0dHJWYWx1ZSkKCUZSRUVfQU5EX05VTEwobnNOYW1lKQoJRlJFRV9BTkRfTlVMTChsb2NhbCkKICAgIH0JCQogICAgLyogVE9ETzogQ2hhbmdlIHRoZSBoYW5kbGluZyBvZiBtaXNzaW5nIHR5cGVzIGFjY29yZGluZyB0bwogICAgKiB0aGUgc3BlYy4KICAgICovCiAgICBpZiAoYWN0dWFsVHlwZSA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAogICAgCSAgICBYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLAogICAgCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsIAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgCiAgICAvKgogICAgKiBUT0RPOiBTaW5jZSB0aGlzIHNob3VsZCBiZSBhbHJlYWR5IGNoZWNrZWQgYnkgdGhlIGNvbnRlbnQgbW9kZWwgYXV0b21hdG9uLAogICAgKiBhbmQgd2Ugd2FudCB0byBnZXQgcmlkIG9mIHRoZSBYTUxfU0NIRU1BU19FUlIuLi4gdHlwZXMsIHRoZSBlcnJvciBjb2RlCiAgICAqIGhhcyBiZWVuIGNoYW5nZWQgdG8gWE1MX1NDSEVNQVZfSU5URVJOQUwuCiAgICAqLwogICAgLyoKICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKGRlY2wtPm1pbk9jY3VycyA+IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgWE1MX1NDSEVNQVNfRVJSX01JU1NJTkcsIAoJCSJFbGVtZW50ICVzOiBtaXNzaW5nIGNoaWxkICVzXG4iLAoJCW5vZGUtPm5hbWUsIGRlY2wtPm5hbWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9IAogICAgKi8KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhlIGVsZW1lbnQgbWF0Y2hlcwogICAgICogVE9ETywgRklYTUU6IENhbiB0aGlzIHN0aWxsIGhhcHBlbiBoZXJlPyBJc24ndCB0aGlzIGFscmVhZHkgY2hlY2tlZAogICAgICogYnkgdGhlIGNvbnRlbnQgbW9kZWwgYXV0b21hdG9uPyAgICAgICAgIAogICAgaWYgKCF4bWxTdHJFcXVhbChjaGlsZC0+bmFtZSwgZGVjbC0+bmFtZSkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyMyhjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAgWE1MX1NDSEVNQVNfRVJSX1dST05HRUxFTSwgCgkgICAgIkVsZW1lbnQgJXM6IG1pc3NpbmcgY2hpbGQgJXMgZm91bmQgJXNcbiIsCgkgICAgbm9kZS0+bmFtZSwgZGVjbC0+bmFtZSwgY2hpbGQtPm5hbWUpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgICovICAgIAogICAgaWYgKGVsZW1IYXNDb250ZW50ID09IC0xKQoJZWxlbUhhc0NvbnRlbnQgPSB4bWxTY2hlbWFIYXNFbGVtT3JDaGFyQ29udGVudChlbGVtKTsKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDUgCiAgICAqIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDUuMSAKICAgICogSWYgdGhlIGRlY2xhcmF0aW9uIGhhcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgCiAgICAqIHRoZSBpdGVtIGhhcyBuZWl0aGVyIGVsZW1lbnQgbm9yIGNoYXJhY3RlciBbY2hpbGRyZW5dIGFuZCAKICAgICogY2xhdXNlIDMuMiBoYXMgbm90IGFwcGxpZWQsIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIGlmICgoZWxlbUhhc0NvbnRlbnQgPT0gMCkgJiYgKG5pbGxlZCA9PSAwKSAmJiAoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpKSB7CgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMSAKCSogSWYgdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBpcyBhILdsb2NhbCB0eXBlIGRlZmluaXRpb263CgkqIHRoZW4gdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0KCSogdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGRlZmF1bHQgZm9yIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgCgkqIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLiAKCSovCgkvKiAKCSogTk9URTogJ2xvY2FsJyBhYm92ZSBtZWFucyB0eXBlcyBhcXVpcmVkIGJ5IHhzaTp0eXBlLgoJKi8KCXJldCA9IDA7CglpZiAoYWN0dWFsVHlwZSAhPSBlbGVtRGVjbC0+c3VidHlwZXMpIHsKCSAgICB4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQoY3R4dCk7CgkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQoY3R4dC0+cGN0eHQsIGN0eHQsIGFjdHVhbFR5cGUsIAoJCWVsZW1EZWNsLT52YWx1ZSwgTlVMTCk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJICAgIGVsZW0sIGFjdHVhbFR5cGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSAgICAidmFsaWRhdGluZyBhIGRlZmF1bHQgdmFsdWUiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9Cgl9CgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMiAKCSogVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSB1c2VkIGFzIGl0cyAKCSogt25vcm1hbGl6ZWQgdmFsdWW3IG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIAoJKiC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpCgkqICinMy4zLjQpLgoJKi8KCS8qCiAgICAgICAgKiBEaXNhYmxlIHZhbGlkYXRpb24gb2YgdGhlIHNpbXBsZSBjb250ZW50LCBzaW5jZSBpdCB3YXMgYWxyZWFkeQoJKiBkb25lIGFib3ZlLgoJKi8KCWlmIChyZXQgPT0gMCkgewoJICAgIGlmIChhY3R1YWxUeXBlICE9IGVsZW1EZWNsLT5zdWJ0eXBlcykKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgMCk7CgkgICAgZWxzZQoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZShjdHh0LCBhY3R1YWxUeXBlLCAwKTsKCSAgICBjdHh0LT5ub2RlID0gZWxlbTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkgICAgZWxlbSwgYWN0dWFsVHlwZSwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJICAgICJ2YWxpZGF0aW5nIGFnYWluc3QgdGhlIHR5cGUiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFBTVkk6IENyZWF0ZSBhIHRleHQgbm9kZSBvbiB0aGUgaW5zdGFuY2UgZWxlbWVudC4KCSAgICAqLwoJICAgIGlmIChjdHh0LT5vcHRpb25zICYgWE1MX1NDSEVNQV9WQUxfVkNfSV9DUkVBVEUpIHsKCQl4bWxOb2RlUHRyIHRleHRDaGlsZDsKCQkKCQl0ZXh0Q2hpbGQgPSB4bWxOZXdUZXh0KGVsZW1EZWNsLT52YWx1ZSk7CgkJaWYgKHRleHRDaGlsZCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkJZWxlbSwgYWN0dWFsVHlwZSwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJCSJjb3VsZCBub3QgY3JlYXRlIGEgZGVmYXVsdCB0ZXh0IG5vZGUgZm9yIHRoZSBpbnN0YW5jZSIsIAoJCQlOVUxMKTsKCQl9IGVsc2UKCQkgICAgeG1sQWRkQ2hpbGQoZWxlbSwgdGV4dENoaWxkKTsJICAgIAoJICAgIH0KCX0KCiAgICB9IGVsc2UgewkKCS8qCgkqIDUuMi4xIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCAKCSogdG8gdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBhcyBkZWZpbmVkIGJ5IEVsZW1lbnQgTG9jYWxseSAKCSogVmFsaWQgKFR5cGUpICinMy4zLjQpLgoJKi8KCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZShjdHh0LCBhY3R1YWxUeXBlLCAxKTsKCWN0eHQtPm5vZGUgPSBlbGVtOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQllbGVtLCBhY3R1YWxUeXBlLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSJ2YWxpZGF0aW5nIGEgZGVmYXVsdCB2YWx1ZSIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogNS4yLjIgSWYgdGhlcmUgaXMgYSBmaXhlZCB7dmFsdWUgY29uc3RyYWludH0gYW5kIGNsYXVzZSAzLjIgaGFzIAoJKiBub3QgYXBwbGllZCwgYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKi8KCglpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmIChuaWxsZWQgPT0gMCkpIHsKCSAgICAvKgoJICAgICogNS4yLjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAoJICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgoJICAgICoKCSAgICAqIFRPRE8gUkVEVU5EQU5UOiBJZiB0aGUgYWN0dWFsIHR5cGUgZXhpc3RzLCB0aGUgYWJvdmUgY2FsbCAgdG8gCgkgICAgKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUgd2lsbCBhbHJlYWR5IGNoZWNrIGZvciBlbGVtZW50IAoJICAgICogbm9kZXMuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hSGFzRWxlbUNvbnRlbnQoZWxlbSkpIHsKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzEsIAoJCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJICAgICJFbGVtZW50cyBpbiB0aGUgY29udGVudCBhcmUgbm90IGFsbG93ZWQgaWYgaXQgaXMgIgoJCSAgICAiY29uc3RyYWluZWQgYnkgYSBmaXhlZCB2YWx1ZSIsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJLyoKCQkqIDUuMi4yLjIgVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IAoJCSogYmUgdHJ1ZToKCQkqLwoJCQoJCWlmIChhY3R1YWxUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHsKCQkgICAgeG1sQ2hhciAqdmFsdWU7CgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIG1peGVkLCB0aGVuIHRoZSAqaW5pdGlhbCB2YWx1ZSogb2YgdGhlIAoJCSAgICAqIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gCgkJICAgICogb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKgoJCSAgICAqIC4uLiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIGFuIGVsZW1lbnQgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBpcyB0aGUgc3RyaW5nIGNvbXBvc2VkIG9mLCBpbiBvcmRlciwgdGhlIAoJCSAgICAqIFtjaGFyYWN0ZXIgY29kZV0gb2YgZWFjaCBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gaXRlbSBpbiAKCQkgICAgKiB0aGUgW2NoaWxkcmVuXSBvZiB0aGF0IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbS4KCQkgICAgKi8KCQkgICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhlbGVtLT5kb2MsIGVsZW0tPmNoaWxkcmVuLCAxKTsKCQkgICAgaWYgKCEgeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIGVsZW1EZWNsLT52YWx1ZSkpIHsKCQkJLyogCgkJCSogVE9ETzogUmVwb3J0IGludmFsaWQgJiBleHBlY3RlZCB2YWx1ZXMgYXMgd2VsbC4KCQkJKiBUT0RPOiBJbXBsZW1lbnQgdGhlIGNvbm9uaWNhbCBzdHVmZi4KCQkJKi8KCQkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8xLCAKCQkJICAgIGVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJICAgICJUaGUgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIGNvbm9uaWNhbCAiCgkJCSAgICAibGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZml4ZWQgY29uc3RyYWludCIsIAoJCQkgICAgTlVMTCk7CgkJICAgIH0KCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOwoJCX0gZWxzZSBpZiAoKGFjdHVhbFR5cGUtPmNvbnRlbnRUeXBlID09IAoJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fCAKCQkgICAgKGFjdHVhbFR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpIHsKCQkgICAgeG1sQ2hhciAqdmFsdWU7CgoJCSAgICAvKgoJCSAgICAqIDUuMi4yLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlILdhY3R1YWwgdHlwZSAKCQkgICAgKiBkZWZpbml0aW9utyBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIAoJCSAgICAqICphY3R1YWwgdmFsdWUqIG9mIHRoZSBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCAKCQkgICAgKiBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCgkJICAgICovCgkJICAgIC8qCgkJICAgICogVE9ETzogKmFjdHVhbCB2YWx1ZSogaXMgdGhlIG5vcm1hbGl6ZWQgdmFsdWUsIGltcGwuIHRoaXMuCgkJICAgICogVE9ETzogUmVwb3J0IGludmFsaWQgJiBleHBlY3RlZCB2YWx1ZXMgYXMgd2VsbC4KCQkgICAgKiBUT0RPOiBJbXBsZW1lbnQgdGhlIGNvbm9uaWNhbCBzdHVmZi4KCQkgICAgKiAKCQkgICAgKi8KCQkgICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhlbGVtLT5kb2MsIGVsZW0tPmNoaWxkcmVuLCAxKTsKCQkgICAgaWYgKCEgeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIGVsZW1EZWNsLT52YWx1ZSkpIHsKCQkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMl8yLCAKCQkJICAgIGVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJICAgICJUaGUgbm9ybWFsaXplZCB2YWx1ZSBkb2VzIG5vdCBtYXRjaCB0aGUgY29ub25pY2FsICIKCQkJICAgICJsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaXhlZCBjb25zdHJhaW50IiwgCgkJCSAgICBOVUxMKTsKCQkgICAgfQoJCSAgICBpZiAodmFsdWUgIT0gTlVMTCkKCQkJeG1sRnJlZSh2YWx1ZSk7CgkJICAgIAoJCX0KCQkvKgoJCSogVE9ETzogV2hhdCBpZiB0aGUgY29udGVudCB0eXBlIGlzIG5vdCAnbWl4ZWQnIG9yIHNpbXBsZT8KCQkqLwoKCSAgICB9CgkgICAgCgl9CiAgICB9CgogICAgLyoKICAgICogVE9ETzogNiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gZWFjaCBvZiAKICAgICogdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb25zfSBhcyBwZXIgSWRlbnRpdHktY29uc3RyYWludCAKICAgICogU2F0aXNmaWVkICinMy4xMS40KS4KICAgICovCgogICAgLyoKICAgICogVE9ETzogNyBJZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzIHRoZSC3dmFsaWRhdGlvbiByb290tywgaXQgbXVzdCBiZSAKICAgICogt3ZhbGlktyBwZXIgVmFsaWRhdGlvbiBSb290IFZhbGlkIChJRC9JRFJFRikgKKczLjMuNCkuCiAgICAqLwogICAgICAgICAgICAgICAKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFJlcHJlc2VudHMgdGhlIHJlY3Vyc2l2ZSBwb3J0aW9uIG9mIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQuIAogKiBOb3QgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBvdGhlciBmdW5jdGlvbnMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCQkgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCAKCQkJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsgICAgICAgIAogICAgY29uc3QgeG1sQ2hhciAqdXJpOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwoKICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogTk9URTogV2Ugd29uJ3QgcmVhY3Qgb24gc2NoZW1hIHBhcnNlciBlcnJvcnMgaGVyZS4KCSogVE9ETzogQnV0IGEgd2FybmluZyB3b3VsZCBiZSBuaWNlLgoJKi8KICAgIH0gICAgCiAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzICE9IFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wgPSBOVUxMOwoKCWlmIChub2RlLT5ucyAhPSBOVUxMKQoJICAgIGRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAoJICAgIG5vZGUtPm5hbWUsIG5vZGUtPm5zLT5ocmVmLCBOVUxMKTsKCWVsc2UgCgkgICAgZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsIG5vZGUtPm5hbWUsIE5VTEwsIE5VTEwpOwoJaWYgKGRlY2wgIT0gTlVMTCkgewkJICAgIAoJICAgIGN0eHQtPm5vZGUgPSBub2RlOwkKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIGRlY2wpOwoJICAgIGlmIChyZXQgPCAwKSB7CQkKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQW55SW50ZXJuYWwsICIKCQkgICAgInZhbGlkYXRpbmcgYW4gZWxlbWVudCBpbiB0aGUgY29udGV4dCBvZiBhIHdpbGRjYXJkLiIsCgkJICAgIE5VTEwsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkKCQlyZXR1cm4gKHJldCk7Cgl9IGVsc2UgaWYgKHdpbGQtPnByb2Nlc3NDb250ZW50cyA9PSBYTUxfU0NIRU1BU19BTllfU1RSSUNUKSB7CgkgICAgLyogVE9ETzogQ2hhbmdlIHRvIHByb3BlciBlcnJvciBjb2RlLiAqLwoJICAgIHhtbFNjaGVtYVZXaWxkY2FyZEVycihjdHh0LCBYTUxfU0NIRU1BVl9DVkNfRUxUXzEsCgkJbm9kZSwgd2lsZCwgIk5vIG1hdGNoaW5nIGdsb2JhbCBkZWNsYXJhdGlvbiBhdmFpbGFibGUiKTsKCSAgICByZXR1cm4gKGN0eHQtPmVycik7Cgl9CiAgICB9CiAgICBpZiAobm9kZS0+Y2hpbGRyZW4gIT0gTlVMTCkgewkgICAKCWNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CglkbyB7CgkgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQlpZiAoY2hpbGQtPm5zICE9IE5VTEwpCgkJICAgIHVyaSA9IGNoaWxkLT5ucy0+aHJlZjsKCQllbHNlCgkJICAgIHVyaSA9IE5VTEw7CgkJaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHdpbGQsIHVyaSkgPT0gMCkgewoJCSAgICAvKiBUT0RPOiBlcnJvciBjb2RlLiAqLwoJCSAgICB4bWxTY2hlbWFWV2lsZGNhcmRFcnIoY3R4dCwgWE1MX1NDSEVNQVZfRUxFTUVOVF9DT05URU5ULAoJCQljaGlsZCwgd2lsZCwgCgkJCSJUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IGlzIG5vdCBhbGxvd2VkIik7CgkJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsgIAoJCX0KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoY3R4dCwgCgkJICAgIHdpbGQsIGNoaWxkKTsKCQlpZiAocmV0ICE9IDApCgkJICAgIHJldHVybiAocmV0KTsJCQoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSB3aGlsZSAgKGNoaWxkICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudENvbnRCeVdpbGRjYXJkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgICAgCiAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkgfHwKCShjdHh0LT5ub2RlID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIGN0eHQtPm5vZGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkLCAiCgkgICAgImJhZCBhcmd1bWVudHMiLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgcmV0dXJuKHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbChjdHh0LCAKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgY3R4dC0+bm9kZSkpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVBbnlUeXBlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjdXJyZW50IGVsZW1lbnQKICoKICogVGhpcyBvbmUgdmFsaWRhdGVzIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgb2YgdGhlIHR5cGUKICogJ2FueVR5cGUnLiBUaGUgcHJvY2VzcyBjb250ZW50cyBvZiB0aGUgd2lsZGNhcmQgb2YgJ2FueVR5cGUnIGlzICJsYXgiLCAKICogdGh1cyBlbGVtZW50cyBpbiB0aGUgc3VidHJlZSB3aWxsIGJlIHZhbGlkYXRlZCwgaWYgYSBjb3JyZXNwb25kaW5nCiAqIGRlY2xhcmF0aW9uIGluIHRoZSBzY2hlbWEgZXhpc3RzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgYW5kIGl0cyBzdWJ0cmVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGU7CiAgICB4bWxOb2RlUHRyIHRvcCwgY3VyOwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOwogICAgaW50IHNraXBDb250ZW50LCByZXQ7CgogICAgaWYgKCh0eXBlID09IE5VTEwpIHx8IChjdHh0LT5ub2RlID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKGN0eHQtPm5vZGUtPmNoaWxkcmVuID09IE5VTEwpIAoJcmV0dXJuICgwKTsKCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIHRvcCA9IGN0eHQtPm5vZGU7ICAgICAgICAKICAgIC8qCiAgICAqIFNUUkVBTTogQ2hpbGQgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBjdXIgPSBjdHh0LT5ub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJc2tpcENvbnRlbnQgPSAwOwoJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkgICAgLyoKCSAgICAqIFRoZSBwcm9jZXNzIGNvbnRlbnRzIG9mIHRoZSB3aWxkY2FyZCBpcyAibGF4IiwgdGh1cwoJICAgICogd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgZWxlbWVudCBpZiBhIGRlY2xhcmF0aW9uCgkgICAgKiBleGlzdHMuCgkgICAgKi8JCQoJICAgIGlmIChjdXItPm5zICE9IE5VTEwpCgkJZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCgkJICAgIGN1ci0+bmFtZSwgY3VyLT5ucy0+aHJlZiwgTlVMTCk7CgkgICAgZWxzZSAKCQlkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwgY3VyLT5uYW1lLCBOVUxMLCBOVUxMKTsJICAgIAoJICAgIGlmIChkZWNsICE9IE5VTEwpIHsJCSAgICAKCQljdHh0LT5ub2RlID0gY3VyOwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZGVjbCk7CgkJY3R4dC0+bm9kZSA9IHRvcDsKCQlpZiAocmV0IDwgMCkgewkJCgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3VyLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUFueVR5cGVDb250ZW50LCAiCgkJCSJ2YWxpZGF0aW5nIGFuIGVsZW1lbnQgaW4gdGhlIGNvbnRleHQgb2YgYSB3aWxkY2FyZC4iLAoJCQlOVUxMLCBOVUxMKTsKCQkgICAgcmV0dXJuIChyZXQpOwoJCX0gZWxzZSBpZiAocmV0ID4gMCkKCQkgICAgcmV0dXJuIChyZXQpOwoJCXNraXBDb250ZW50ID0gMTsKCSAgICB9Cgl9ICAgCgkvKgoJKiBCcm93c2UgdGhlIGZ1bGwgc3VidHJlZSwgZGVlcCBmaXJzdC4KCSovCiAgICAgICAgaWYgKChza2lwQ29udGVudCA9PSAwKSAmJiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSkgewoJICAgIC8qIGRlZXAgZmlyc3QgKi8KCSAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwoJfSBlbHNlIGlmICgoY3VyICE9IHRvcCkgJiYgKGN1ci0+bmV4dCAhPSBOVUxMKSkgewoJICAgIC8qIHRoZW4gc2libGluZ3MgKi8KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9IGVsc2UgaWYgKGN1ciAhPSB0b3ApIHsKCSAgICAvKiBnbyB1cCB0byBwYXJlbnRzLT5uZXh0IGlmIG5lZWRlZCAqLwoJICAgIHdoaWxlIChjdXIgIT0gdG9wKSB7CgkgICAgICAgIGlmIChjdXItPnBhcmVudCAhPSBOVUxMKQoJCSAgICBjdXIgPSBjdXItPnBhcmVudDsKCQlpZiAoKGN1ciAhPSB0b3ApICYmIChjdXItPm5leHQgIT0gTlVMTCkpIHsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCSAgICBicmVhazsKCQl9CgkJaWYgKGN1ci0+cGFyZW50ID09IE5VTEwpIHsKCQkgICAgY3VyID0gTlVMTDsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCSAgICAvKiBleGl0IGNvbmRpdGlvbiAqLwoJICAgIGlmIChjdXIgPT0gdG9wKSAKCSAgICAgICAgY3VyID0gTlVMTDsKCX0gZWxzZQoJICAgIGJyZWFrOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBjb21wbGV4IHR5cGUgdHlwZQogKiB4bWxzY2hlbWEtMS5odG1sI2N2Yy1jb21wbGV4LXR5cGUKICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICogTm90ZSBvbiByZXBvcnRlZCBlcnJvcnM6IEFsdGhvdWdoIGl0IG1pZ2h0IGJlIG5pY2UgdG8gcmVwb3J0CiAqIHRoZSBuYW1lIG9mIHRoZSBzaW1wbGUvY29tcGxleCB0eXBlLCB1c2VkIHRvIHZhbGlkYXRlIHRoZSBjb250ZW50CiAqIG9mIGEgbm9kZSwgaXQgaXMgcXVpdGUgdW5uZWNlc3Nhcnk6IGZvciBnbG9iYWwgZGVmaW5lZCB0eXBlcwogKiB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBlcXVhbCB0byB0aGUgTkNOYW1lIG9mIHRoZSB0eXBlLAogKiBmb3IgbG9jYWwgZGVmaW5lZCB0eXBlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBvdXRwdXQgdGhlIGludGVybmFsCiAqIGNvbXB1dGVkIG5hbWUgb2YgdGhlIHR5cGUuIFRPRE86IEluc3RlYWQsIG9uZSBzaG91bGQgYXR0YWNoIHRoZSAKICogc3RydWN0IG9mIHRoZSB0eXBlIGludm9sdmVkIHRvIHRoZSBlcnJvciBoYW5kbGVyIC0gdGhpcyBhbGxvd3MKICogdGhlIHJlcG9ydCBvZiBhbnkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBieSB0aGUgdXNlci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOyAgICAKICAgIHhtbE5vZGVQdHIgZWxlbSwgY2hpbGQ7CiAgICBpbnQgcmV0ID0gMDsKICAgIGNvbnN0IHhtbENoYXIgKm5zVXJpOyAgICAKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRycyA9IE5VTEwsIGF0dHJUb3AgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpCglyZXR1cm4gKC0xKTsKCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgZWxlbSA9IGN0eHQtPm5vZGU7CgogICAgLyoKICAgICogVmVyaWZ5IHRoZSBhdHRyaWJ1dGVzCiAgICAqLwogICAgLyoKICAgICogVE9ETzogVGhpcyAiYXR0clRvcCIgdGhpbmcgaXMgbm90IG5lZWRlZCBhbnkgbW9yZS4KICAgICovICAKICAgIC8qIE5PVEU6IHJlbW92ZWQsIHNpbmNlIGEgY2hlY2sgZm9yIGFic3RyYWN0IGlzCiAgICAqIGRvbmUgaW4gdGhlIGN2Yy10eXBlIGNvbnN0cmFpbnQuCiAgICAqCiAgICAqCiAgICAqIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1QpIHsKICAgICoJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAogICAgKgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8xLAogICAgKgkgICAgZWxlbSwgdHlwZSwgCiAgICAqCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnN0cmFjdCIpOwogICAgKglyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMSk7CiAgICAqfQogICAgKi8KICAgIAogICAgYXR0cnMgPSBjdHh0LT5hdHRyOyAgICAKICAgIGF0dHJUb3AgPSBjdHh0LT5hdHRyVG9wOyAgIAogICAgLyoKICAgICogU1RSRUFNOiBBdHRyaWJ1dGUgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoY3R4dCwgZWxlbS0+cHJvcGVydGllcyk7ICAgICAKICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBlbGVtLCB0eXBlKTsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgY3R4dC0+YXR0ciA9IGF0dHJzOyAgICAKICAgIGN0eHQtPmF0dHJUb3AgPSBhdHRyVG9wOyAgICAKCiAgICAvKgogICAgKiBUT0RPOiBUaGlzIG9uZSBjcmVhdGVzIGEgcmVnZXhwIGV2ZW4gaWYgbm8gY29udGVudAogICAgKiBtb2RlbCB3YXMgZGVmaW5lZC4gU29tZWhvdyAtPmNvbnRNb2RlbCBpcyBhbHdheXMgbm90IE5VTEwKICAgICogZm9yIGNvbXBsZXggdHlwZXMsIGV2ZW4gaWYgdGhleSBhcmUgZW1wdHkuCiAgICAqIFRPRE86IENoZWNrIGlmIHRoZSBvYm92ZSBzdGlsbCBvY2N1cnMuCiAgICAqLyAgICAgICAgICAgICAgCiAgICBzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTogewoJICAgIC8qCgkgICAgKiAxIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbXB0eSwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiAKCSAgICAqIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBvciBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBUT0RPOiBJcyB0aGUgZW50aXR5IHN0dWZmIGNvcnJlY3Q/CgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSkgPT0gMSkgewkgICAgCSAgICAKCQl4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8xLAoJCSAgICBlbGVtLCB0eXBlLCAKCQkgICAgIkNoYXJhY3RlciBvciBlbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkgICAgImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbXB0eSIpOwogICAgICAgICAgICB9CSAKICAgICAgICAgICAgYnJlYWs7Cgl9CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKCSAgICBpZiAoKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpICYmIAoJCSh0eXBlLT5iYXNlVHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpIHsKCQkvKgoJCSogVGhlIHR5cGUgaGFzICdhbnlUeXBlJyBhcyBpdHMgYmFzZSBhbmQgbm8gY29udGVudCBtb2RlbAoJCSogaXMgZGVmaW5lZCAtPiB1c2UgJ2FueVR5cGUnIGFzIHRoZSB0eXBlIHRvIHZhbGlkYXRlCgkJKiBhZ2FpbnN0LgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKGN0eHQsIHR5cGUtPmJhc2VUeXBlKTsKCQkvKiBUT0RPOiBIYW5kbGUgLTEuICovCgkJYnJlYWs7CgkgICAgfQoJICAgIC8qIE5vIGJyZWFrIG9uIHB1cnBvc2UuICovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgewoJICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIG9sZHJlZ2V4cCA9IE5VTEw7CgkgICAgCgkgICAgLyoKCSAgICAqIENvbnRlbnQgbW9kZWwgY2hlY2sgaW5pdGlhbGl6YXRpb24uCgkgICAgKi8KCSAgICBpZiAodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpIHsJCQkJCQoJCW9sZHJlZ2V4cCA9IGN0eHQtPnJlZ2V4cDsKCQljdHh0LT5yZWdleHAgPSB4bWxSZWdOZXdFeGVjQ3R4dCh0eXBlLT5jb250TW9kZWwsCgkJICAgICh4bWxSZWdFeGVjQ2FsbGJhY2tzKQoJCSAgICB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCBjdHh0KTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICI9PT09PiAlc1xuIiwgZWxlbS0+bmFtZSk7CiNlbmRpZgoJICAgIH0KCSAgICAvKgoJICAgICogU1RSRUFNOiBDaGlsZHJlbiBhcmUgcHJvY2Vzc2VkLgoJICAgICovCgkgICAgY2hpbGQgPSBlbGVtLT5jaGlsZHJlbjsKCSAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewkJCgkJaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQkgICAgaWYgKGNoaWxkLT5ucyAhPSBOVUxMKQoJCQluc1VyaSA9IGNoaWxkLT5ucy0+aHJlZjsKCQkgICAgZWxzZQoJCQluc1VyaSA9IE5VTEw7CgkJICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nMihjdHh0LT5yZWdleHAsCgkJCWNoaWxkLT5uYW1lLCBuc1VyaSwgY2hpbGQpOwoJCSAgICAvKgoJCSAgICAqIFVSR0VOVCBUT0RPOiBDb3VsZCB3ZSBhbmNob3IgYW4gZXJyb3IgcmVwb3J0CgkJICAgICogaGVyZSB0byBub3RpZnkgb2YgaW52YWxpZCBlbGVtZW50cz8KCQkgICAgKi8KI2lmZGVmIERFQlVHX0FVVE9NQVRBCQkgICAgCgkJICAgIGlmIChyZXQgPCAwKQoJCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkJIiAgLS0+ICVzIEVycm9yXG4iLCBjaGlsZC0+bmFtZSk7CgkJICAgIGVsc2UKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlc1xuIiwgY2hpbGQtPm5hbWUpOwojZW5kaWYKCQl9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpICYmIAoJCSAgICAvKiAKCQkgICAgKiBUT0RPOiBBc2sgRGFuaWVsIGlmIHRoaXMgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkJICAgICovCgkJICAgICgoKGNoaWxkLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICghSVNfQkxBTktfTk9ERShjaGlsZCkpKSB8fAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwJCSAgICAJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSB8fAkJICAgIAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSkgewkJICAgIAoJCSAgICAvKiAKCQkgICAgKiAyLjMgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVsZW1lbnQtb25seSwgdGhlbiB0aGUgCgkJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBbY2hpbGRyZW5dIG90aGVyIHRoYW4gdGhvc2Ugd2hvc2UgW2NoYXJhY3RlciAKCQkgICAgKiBjb2RlXSBpcyBkZWZpbmVkIGFzIGEgd2hpdGUgc3BhY2UgaW4gW1hNTCAxLjAgKFNlY29uZCAKCQkgICAgKiBFZGl0aW9uKV0uCgkJICAgICovCQkJCgkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzMsCgkJCWVsZW0sIHR5cGUsIAoJCQkiQ2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkJImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbGVtZW50LW9ubHkiKTsJCSAgICAKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CQkgICAgCgkgICAgfSAgICAKCSAgICAvKgoJICAgICogQ29udGVudCBtb2RlbCBjaGVjayBmaW5hbGl6YXRpb24uCgkgICAgKi8KICAgICAgIAkgICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CgkJcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICI9PT09PiAlcyA6ICVkXG4iLCBlbGVtLT5uYW1lLCByZXQpOwojZW5kaWYKCQlpZiAocmV0ID09IDApIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCWVsZW0sIHR5cGUsICJUaGUgZWxlbWVudCBjb250ZW50IGlzIG5vdCB2YWxpZCIsIE5VTEwpOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwKCQkJZWxlbSwgdHlwZSwgIlRoZSBlbGVtZW50IGNvbnRlbnQgaXMgbm90IHZhbGlkIiwgTlVMTCk7CiNpZmRlZiBERUJVR19DT05URU5UCgkJfSBlbHNlIHsKCQkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgc3VjY2VlZGVkXG4iLAoJCQllbGVtLT5uYW1lKTsKCQkgICAgCiNlbmRpZgoJCX0KCQl4bWxSZWdGcmVlRXhlY0N0eHQoY3R4dC0+cmVnZXhwKTsKCQljdHh0LT5yZWdleHAgPSBvbGRyZWdleHA7CgkgICAgfQoJfQogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKCSAgICAvKgoJICAgICogSWYgdGhlIHNpbXBsZSBjb250ZW50IHdhcyBhbHJlYWR5IHZhbGlkYXRlZCAKCSAgICAqIChlLmcuIGEgZGVmYXVsdCB2YWx1ZSksIHRoZSBjb250ZW50IG5lZWQgbm90CgkgICAgKiB0byBiZSB2YWxpZGF0ZWQgYWdhaW4uCgkgICAgKi8KCWlmICh2YWxTaW1wbGVDb250ZW50ID09IDEpIHsKCSAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFdlIGhpdCBhIGNvbXBsZXhUeXBlIHdpdGggYSBzaW1wbGVDb250ZW50IHJlc29sdmluZwoJICAgICogdG8gYSB1c2VyIGRlcml2ZWQgb3IgYnVpbHQtaW4gc2ltcGxlIHR5cGUuCgkgICAgKi8KCSAgICAvKiAKCSAgICAqIDIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAKCSAgICAqIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgYW5kIHRoZSC3bm9ybWFsaXplZCB2YWx1ZbcgCgkgICAgKiBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzILd2YWxpZLcgd2l0aCByZXNwZWN0IAoJICAgICogdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIAoJICAgICogVmFsaWQgKKczLjE0LjQpLgoJICAgICovCSAgCgkgICAgLyoKCSAgICAqIFNUUkVBTTogQ2hpbGRyZW4gYXJlIHByb2Nlc3NlZC4KCSAgICAqLwoJICAgIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCQkvKgoJCSogVE9ETzogQ291bGQgdGhlIGVudGl0eSBzdHVmZiBwcm9kdWNlIGVsZW1lbnRzCgkJKiBhcyB3ZWxsPwoJCSovCiAgICAgICAgICAgICAgICBpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCWVsZW0sIHR5cGUsIAoJCQkiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCBiZWNhdXNlICIKCQkJInRoZSBjb250ZW50IHR5cGUgaXMgYSBzaW1wbGUgdHlwZSIpOwoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMjsKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CQkgICAgCgkgICAgfQkKCSAgICBjdHh0LT5ub2RlID0gZWxlbTsKCSAgICBjdHh0LT5jdXIgPSBlbGVtLT5jaGlsZHJlbjsKCSAgICBpZiAocmV0ID09IDApIHsKCQkvKgoJCSogVmFsaWRhdGUgdGhlIGNoYXJhY3RlciBjb250ZW50IGFnYWluc3QgYSBzaW1wbGUgdHlwZS4KCQkqLwoJCS8qCgkJKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkJKi8KCQlpZiAoZWxlbS0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkgICAgdmFsdWUgPSBOVUxMOwoJCWVsc2UKCQkgICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChlbGVtKTsgCgkJLyoKCQkqIFVSR0VOVCBUT0RPOiBTaG91bGQgZmFjZXRzIGZvciB0aGUgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBiZSAKCQkqIGRpc2FibGVkLCBpZiB0aGUgZGVyaXZhdGlvbiBvZiBmYWNldHMgZm9yIGNvbXBsZXggdHlwZXMgCgkJKiBpcyBpbXBsZW1lbnRlZD8KCQkqLwoJCS8qCgkJKiBOT1RFOiBUaGlzIGNhbGwgd29uJ3QgY2hlY2sgdGhlIGNvcnJlY3QgdHlwZXMgb2YgdGhlCgkJKiBjb250ZW50IG5vZGVzLCBzaW5jZSB0aGlzIHNob3VsZCBiZSBkb25lIGhlcmUuCgkJKi8KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgMSwgMSwgMSwgMCk7CgkJaWYgKHJldCA+IDApIHsJCgkJICAgIC8qCgkJICAgICogTk9URTogQWx0aG91Z2ggYW4gZXJyb3Igd2lsbCBiZSByZXBvcnRlZCBieSAKCQkgICAgKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgdGhlIHNwZWMgd2FudHMKCQkgICAgKiBhIHNwZWNpZmljIGNvbXBsZXggdHlwZSBlcnJvciB0byBiZSByZXBvcnRlZCAKCQkgICAgKiBhZGRpdGlvbmFsbHkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCWVsZW0sIHR5cGUsICAKCQkJIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSwgIgoJCQkiRWxlbWVudCAnJXMnOiBFcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlICclcycuXG4iLAoJCQllbGVtLT5uYW1lLCB0eXBlLT5uYW1lKTsKCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOyAKCQkgICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CSAgICAKCSAgICBpZiAocmV0ID09IDApIHsKCQkvKiAKCQkqIEFwcGx5IGZhY2V0cyBvZiB0aGUgY29tcGxleFR5cGUuIEJlIHN1cmUgdG8gcGFzcyB0aGUgCgkJKiBidWlsdC1pbiB0eXBlIHRvIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwuCgkJKi8JICAgIAoJCS8qIFVSR0VOVCBUT0RPOiBJIGRvbid0IGtub3cgeWV0IGlmIHRoZSBmYWNldHMgb2YgdGhlIHNpbXBsZSB0eXBlCgkJKiBhcmUgdXNlZCwgb3IgaWYgdGhlIGZhY2V0cywgZGVmaW5lZCBieSB0aGlzIGNvbXBsZXggdHlwZSwKCQkqIGFyZSB0byBiZSB1c2VkIG9ubHkuIFRoaXMgaGVyZSBhcHBsaWVzIGJvdGggZmFjZXQgc2V0cy4KCQkqLwkgICAgCgoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgCgkJICAgIHR5cGUsIHZhbHVlLCAwLCAxKTsKCQlpZiAocmV0ID4gMCkgewoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAKCQkJIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSwgIgoJCQkiRWxlbWVudCAnJXMnOiBFcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlICclcyc7IGZhaWxlZCB0byAiCgkJCSJhcHBseSBmYWNldHMuXG4iLAoJCQl0eXBlLT5uYW1lLCBOVUxMKTsKCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOyAKCQkgICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSh2YWx1ZSk7ICAgIAoJICAgIAoJfQoJICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRPRE8geG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmltcGxlbWVudGVkIGNvbnRlbnQgdHlwZSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29udGVudFR5cGUpOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBsaXN0IG9mIHR5cGUgZGVjbGFyYXRpb25zCiAqCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICAgIGludCB2YWxTaW1wbGVDb250ZW50KQp7CiAgICBpbnQgcmV0OwoKICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlLCAiCgkgICAgImJhZCBhcmd1bWVudHMiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsgICAgCiAgICB9ICAgIAkKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24iLgogICAgKiBJdCB3aWxsIGZvcndhcmQgdG8gdGhlIHByb3BlciB2YWxpZGF0aW9uIAogICAgKiBwcm9jZWR1cmVzIGZvciB0aGUgZ2l2ZW4gdHlwZS4KICAgICovICAgICAgICAKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgIAl4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCiAgICAJICAgIFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEsCiAgICAJICAgIGN0eHQtPm5vZGUsIE5VTEwsIAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUKSB7CiAgICAJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAogICAgCSAgICBYTUxfU0NIRU1BVl9DVkNfVFlQRV8yLAogICAgCSAgICBjdHh0LT5ub2RlLCB0eXBlLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzdHJhY3QiKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzIpOwogICAgfQoKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZShjdHh0LCB0eXBlLAoJCXZhbFNpbXBsZUNvbnRlbnQpOwogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlKGN0eHQsIHR5cGUsCgkJdmFsU2ltcGxlQ29udGVudCk7CiAgICAgICAgICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgkgICAgaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKGN0eHQsIHR5cGUpOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoY3R4dCwgdHlwZSwKCQkgICAgdmFsU2ltcGxlQ29udGVudCk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldCA9IC0xOwoJICAgIGJyZWFrOwogICAgfQkKICAgIGlmIChyZXQgPT0gLTEpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UKCXJldHVybiAocmV0KTsKfQoKCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2wsCgkJCSAgICAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgc3RhdGUsCgkJCSAgICAgICB4bWxBdHRyUHRyIGF0dHIpCnsKICAgIHhtbENoYXIgKnZhbHVlOwogICAgY29uc3QgeG1sQ2hhciAqZGVmVmFsdWU7CiAgICB4bWxTY2hlbWFWYWxQdHIgZGVmVmFsOwogICAgaW50IGZpeGVkOwogICAgaW50IHJldDsKCiAgICBpZiAoZGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9UWVBFX05PVF9SRVNPTFZFRDsKCXJldHVybiAoWE1MX1NDSEVNQVNfQVRUUl9UWVBFX05PVF9SRVNPTFZFRCk7CiAgICB9CiAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGF0dHItPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwogICAgY3R4dC0+bm9kZSA9ICh4bWxOb2RlUHRyKSBhdHRyOwogICAgY3R4dC0+Y3VyID0gYXR0ci0+Y2hpbGRyZW47CiAgICAvKgogICAgKiBOT1RFOiBUaGlzIGNhbGwgYWxzbyBjaGVja3MgdGhlIGNvbnRlbnQgbm9kZXMgZm9yIGNvcnJlY3QgdHlwZS4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBkZWNsLT5zdWJ0eXBlcywKCXZhbHVlLCAxLCAxLCAxLCAxKTsKICAgIAkgICAgCiAgICAvKgogICAgKiBIYW5kbGUgJ2ZpeGVkJyBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChyZXQgPiAwKSB7CglzdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUU7CgkvKgoJKiBOT1RFOiBGaXhlZCB2YWx1ZSBjb25zdHJhaW50cyB3aWxsIGJlIG5vdAoJKiBhcHBsaWVkIGlmIHRoZSB2YWx1ZSB3YXMgaW52YWxpZCwgYmVjYXVzZTogCgkqIDEuIFRoZSB2YWxpZGF0aW9uIHByb2Nlc3MgZG9lcyBub3QgcmV0dXJuIGEgcHJlY29tcHV0ZWQgCgkqICAgIHZhbHVlLgoJKiAyLiBBbiBpbnZhbGlkIHZhbHVlIGltcGxpZXMgYSB2aW9sYXRpb24gb2YgYSBmaXhlZCAKCSogICAgdmFsdWUgY29uc3RyYWludC4KCSovCiAgICB9IGVsc2UgaWYgKHJldCA9PSAwKSB7CglzdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CglpZiAoeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGRlY2wsIAoJICAgICZmaXhlZCwgJmRlZlZhbHVlLCAmZGVmVmFsKSAmJiAoZml4ZWQgPT0gMSkpIHsKCSAgICAvKgoJICAgICogY3ZjLWF1IDogQXR0cmlidXRlIExvY2FsbHkgVmFsaWQgKFVzZSkKCSAgICAqIEZvciBhbiBhdHRyaWJ1dGUgaW5mb3JtYXRpb24gaXRlbSB0byBiZbd2YWxpZLcgCgkgICAgKiB3aXRoIHJlc3BlY3QgdG8gYW4gYXR0cmlidXRlIHVzZSBpdHMgt25vcm1hbGl6ZWQgCgkgICAgKiB2YWx1ZbcgbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24KCSAgICAqIG9mIHRoZSBhdHRyaWJ1dGUgdXNlJ3Mge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLCBpZiBpdCAKCSAgICAqIGlzIHByZXNlbnQgYW5kIGZpeGVkLgoJICAgICovCgkgICAgLyogCgkgICAgKiBOT1RFOiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IGhvbGRzIGluIGN0eHQtPnZhbHVlIHRoZQoJICAgICogcHJlY29tcHV0ZWQgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZTsgd2VsbCBmb3Igc29tZSB0eXBlcywKCSAgICAqIGZhbGxiYWNrIHRvIHN0cmluZyBjb21wYXJpc29uIGlmIG5vIGNvbXB1dGVkIHZhbHVlIAoJICAgICogZXhpc3RzLgoJICAgICovCgkgICAgaWYgKCgoY3R4dC0+dmFsdWUgIT0gTlVMTCkgJiYgCgkJKHhtbFNjaGVtYUNvbXBhcmVWYWx1ZXMoY3R4dC0+dmFsdWUsIGRlZlZhbCkgIT0gMCkpIHx8CgkJKChjdHh0LT52YWx1ZSA9PSBOVUxMKSAmJgoJCSghIHhtbFN0ckVxdWFsKGRlZlZhbHVlLCBCQURfQ0FTVCB2YWx1ZSkpKSkgewoJCXN0YXRlLT5zdGF0ZSA9IAoJCSAgICBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfRklYRURfVkFMVUU7CQkJCgkgICAgfQoJfQogICAgfSAgCiAgICBpZiAodmFsdWUgIT0gTlVMTCkgewoJeG1sRnJlZSh2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBjb21wbGV4VHlwZSBob2xkaW5nIHRoZSBhdHRyaWJ1dGUgdXNlcwogKgogKiBWYWxpZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiBhbiBlbGVtZW50LgogKgogKiAxLiBFeGlzdGVudCwgaW52YWxpZCBhdHRyaWJ1dGVzIGFyZSByZXBvcnRlZCBpbiB0aGUgZm9ybSAKICogICAgInByZWZpeDpsb2NhbE5hbWUiLiAKICogICAgUmVhc29uOiByZWFkYWJpbGl0eSAtIGl0IGlzIGVhc2llciB0byBmaW5kIHRoZSBhY3R1YWwgWE1MIAogKiAgICByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXR0cmlidXRlcyBRTmFtZS4KICogMi4gTWlzc2luZyBhdHRyaWJ1dGVzIGFyZSByZXBvcnRlZCBpbiB0aGUgZm9ybSAKICogICAgeyJVUkkiLCAibG9jYWxOYW1lIn0uCiAqICAgIFRoaXMgaXMgbmVjZXNzYXJ5LCBzaW5jZSB0aGUgdGhlIHByZWZpeCBuZWVkIG5vdCB0byBiZSBkZWNsYXJlZAogKiAgICBhdCBhbGwsIGFuZCB0aHVzIGlzIG5vdCBjb21wdXRhYmxlLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0sIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgY29uc3QgeG1sQ2hhciAqbnNVUkk7CiAgICBpbnQgcmV0OwogICAgeG1sQXR0clB0ciBhdHRyOyAvKiBBbiBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQuICovCiAgICBjb25zdCB4bWxDaGFyICpkZWZWYWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciBkZWZWYWw7CiAgICBpbnQgZml4ZWQ7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIGF0dHJVc2UgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJEZWNsOwogICAgaW50IGZvdW5kOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGN1clN0YXRlLCByZXFBdHRyU3RhdGVzID0gTlVMTCwgcmVxQXR0clN0YXRlc1RvcCA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgZGVmQXR0clN0YXRlcyA9IE5VTEwsIGRlZkF0dHJTdGF0ZXNUb3AgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBvbGRub2RlOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCiAgICBpbnQgcmVkdW5kYW50ID0gMDsKI2VuZGlmCgogICAgICAKICAgIC8qCiAgICAqIEFsbG93IGFsbCBhdHRyaWJ1dGVzIGlmIHRoZSB0eXBlIGlzIGFueVR5cGUuCiAgICAqLwogICAgaWYgKHR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCglyZXR1cm4gKDApOwoKICAgIG9sZG5vZGUgPSBjdHh0LT5ub2RlOwogICAgaWYgKHR5cGUgIT0gTlVMTCkKCWF0dHJVc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwogICAgd2hpbGUgKGF0dHJVc2UgIT0gTlVMTCkgewogICAgICAgIGZvdW5kID0gMDsgICAgCglhdHRyRGVjbCA9IGF0dHJVc2UtPmF0dHI7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCXByaW50ZigiYXR0ciB1c2UgLSBuYW1lOiAlc1xuIiwgeG1sU2NoZW1hR2V0QXR0ck5hbWUoYXR0ckRlY2wpKTsKCXByaW50ZigiYXR0ciB1c2UgLSB1c2U6ICVkXG4iLCBhdHRyRGVjbC0+b2NjdXJzKTsKI2VuZGlmCiAgICAgICAgZm9yIChjdXJTdGF0ZSA9IGN0eHQtPmF0dHI7IGN1clN0YXRlICE9IE5VTEw7IGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQpIHsJCSAgICAKCgkgICAgaWYgKGN1clN0YXRlLT5kZWNsID09IGF0dHJVc2UtPmF0dHIpIHsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJCXJlZHVuZGFudCA9IDE7CiNlbmRpZgoJICAgIH0KCSAgICBhdHRyID0gY3VyU3RhdGUtPmF0dHI7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImF0dHIgLSBuYW1lOiAlc1xuIiwgYXR0ci0+bmFtZSk7CgkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpCgkJcHJpbnRmKCJhdHRyIC0gbnM6ICVzXG4iLCBhdHRyLT5ucy0+aHJlZik7CgkgICAgZWxzZQoJCXByaW50ZigiYXR0ciAtIG5zOiBub25lXG4iKTsKI2VuZGlmCgkgICAgLyogVE9ETzogQ2FuIHRoaXMgZXZlciBoYXBwZW4/ICovCiAgICAgICAgICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+cmVmKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKChhdHRyRGVjbC0+cmVmTnMgPT0gTlVMTCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgYXR0ckRlY2wtPnJlZk5zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyRGVjbC0+cmVmTnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+bmFtZSkpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaGFuZGxlIHRoZSBuYW1lc3BhY2VzIGNoZWNrcyBoZXJlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICAqIGFjY2VwdCBhbiB1bnF1YWxpZmllZCBhdHRyaWJ1dGUgb25seSBpZiB0aGUgdGFyZ2V0CgkJICAgICAqIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyYXRpb24gaXMgYWJzZW50LgoJCSAgICAgKi8KCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKCQkJLyogCgkJCSAqIFRoaXMgY2hlY2sgd2FzIHJlbW92ZWQsIHNpbmNlIHRoZSB0YXJnZXQgbmFtZXNwYWNlCgkJCSAqIHdhcyBldmFsdWF0ZWQgZHVyaW5nIHBhcnNpbmcgYW5kIGFscmVhZHkgdG9vawoJCQkgKiAiYXR0cmlidXRlRm9ybURlZmF1bHQiIGludG8gYWNjb3VudC4KCQkJICovCgkJICAgICAgICAvKiAoKGF0dHJpYnV0ZXMtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9OU0RFRkFVTFQpID09IDApKSAqLwoJCSAgICAgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkKCQkgICAgICAgIGNvbnRpbnVlOwoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJICAgICAgICAgICAgICAgICAgICAgYXR0ci0+bnMtPmhyZWYpKQoJCQljb250aW51ZTsKCQl9CiAgICAgICAgICAgIH0KI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigiZm91bmRcbiIpOwojZW5kaWYKICAgICAgICAgICAgZm91bmQgPSAxOwkgICAgCgkgICAgY3VyU3RhdGUtPmRlY2wgPSBhdHRyRGVjbDsKCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0F0dHJMb2NhbGx5VmFsaWQoY3R4dCwgYXR0ckRlY2wsIGN1clN0YXRlLCBhdHRyKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFmb3VuZCkgewoJICAgIGlmIChhdHRyRGVjbC0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSB7CgkJeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCQkKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJCXByaW50ZigicmVxdWlyZWQgYXR0ciBub3QgZm91bmRcbiIpOwojZW5kaWYKCQkvKgoJCSogQWRkIGEgbmV3IGR1bW15IGF0dHJpYnV0ZSBzdGF0ZS4KCQkqLwkKCQl0bXAgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsICJyZWdpc3RlcmluZyByZXF1aXJlZCBhdHRyaWJ1dGVzIiwgTlVMTCk7CgkJICAgIGN0eHQtPm5vZGUgPSBvbGRub2RlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9ICAgICAgICAgICAgCgkJdG1wLT5hdHRyID0gTlVMTDsKCQl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HOwoJCXRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJCgkJaWYgKHJlcUF0dHJTdGF0ZXMgPT0gTlVMTCkgewoJCSAgICByZXFBdHRyU3RhdGVzID0gdG1wOwoJCSAgICByZXFBdHRyU3RhdGVzVG9wID0gdG1wOwoJCX0gZWxzZSB7CgkJICAgIHJlcUF0dHJTdGF0ZXNUb3AtPm5leHQgPSB0bXA7CgkJICAgIHJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CgkJfQoJICAgIH0gZWxzZSBpZiAoKGF0dHJEZWNsLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJICAgICh4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYXR0ckRlY2wsIAoJCQkmZml4ZWQsICZkZWZWYWx1ZSwgJmRlZlZhbCkpKSB7CgkJeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCQkvKgoJCSogSGFuZGxlIG5vbiBleGlzdGVudCBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkJKi8JCgkJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgCgkJCSJyZWdpc3RlcmluZyBzY2hlbWEgc3BlY2lmaWVkIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCQkgICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7CgkJICAgIHJldHVybiAoLTEpOwoJCX0gICAgICAgICAgICAKCQl0bXAtPmF0dHIgPSBOVUxMOwoJCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQ7CgkJdG1wLT5kZWNsID0gYXR0ckRlY2w7CgkJdG1wLT52YWx1ZSA9IGRlZlZhbHVlOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJCgkJaWYgKGRlZkF0dHJTdGF0ZXMgPT0gTlVMTCkgewoJCSAgICBkZWZBdHRyU3RhdGVzID0gdG1wOwoJCSAgICBkZWZBdHRyU3RhdGVzID0gdG1wOwoJCX0gZWxzZSB7CgkJICAgIGRlZkF0dHJTdGF0ZXMtPm5leHQgPSB0bXA7CgkJICAgIGRlZkF0dHJTdGF0ZXNUb3AgPSB0bXA7CgkJfQkJCQkKCSAgICB9CQkJCgl9CiAgICAgICAgYXR0clVzZSA9IGF0dHJVc2UtPm5leHQ7CiAgICB9CiAgICAvKgogICAgICogQWRkIHJlcXVpcmVkIGF0dHJpYnV0ZXMgdG8gdGhlIGF0dHJpYnV0ZSBzdGF0ZXMgb2YgdGhlIGNvbnRleHQuCiAgICAgKi8KICAgIGlmIChyZXFBdHRyU3RhdGVzICE9IE5VTEwpIHsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIHsKCSAgICBjdHh0LT5hdHRyID0gcmVxQXR0clN0YXRlczsKCX0gZWxzZSB7CQkKCSAgICBjdHh0LT5hdHRyVG9wLT5uZXh0ID0gcmVxQXR0clN0YXRlczsKCX0KCWN0eHQtPmF0dHJUb3AgPSByZXFBdHRyU3RhdGVzVG9wOwogICAgfQogICAgLyoKICAgICogUHJvY2VzcyB3aWxkY2FyZHMuCiAgICAqLwogICAgCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSB7CQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5zOwkKCXByaW50ZigibWF0Y2hpbmcgd2lsZGNhcmQ6IFslZF0gb2YgY29tcGxleFR5cGU6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+bmFtZSk7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBsYXhcbiIpOwoJZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfU1RSSUNUKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBzdHJpY3RcbiIpOwoJZWxzZQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBza2lwXG4iKTsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+YW55KQoJICAgIHByaW50ZigidHlwZTogYW55XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgcHJpbnRmKCJ0eXBlOiBuZWdhdGVkXG4iKTsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKQoJCXByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCSAgICBlbHNlCgkJcHJpbnRmKCJuczogJXNcbiIsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUpOwoJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogc2V0XG4iKTsKCSAgICBucyA9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uc1NldDsKCSAgICB3aGlsZSAobnMgIT0gTlVMTCkgewoJCWlmIChucy0+dmFsdWUgPT0gTlVMTCkKCQkgICAgcHJpbnRmKCJuczogKGFic2VudClcbiIpOwoJCWVsc2UKCQkgICAgcHJpbnRmKCJuczogJXNcbiIsIG5zLT52YWx1ZSk7CgkJbnMgPSBucy0+bmV4dDsKCSAgICB9CSAgICAKCX0gZWxzZQoJICAgIHByaW50ZigiZW1wdHlcbiIpOwoKCiNlbmRpZgkKCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlIChjdXJTdGF0ZSAhPSBOVUxMKSB7CgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pIHsJCQoJCWlmIChjdXJTdGF0ZS0+YXR0ci0+bnMgIT0gTlVMTCkgCgkJICAgIG5zVVJJID0gY3VyU3RhdGUtPmF0dHItPm5zLT5ocmVmOwoJCWVsc2UKCQkgICAgbnNVUkkgPSBOVUxMOwkJCgkJaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQkgICAgbnNVUkkpKSB7CgkJICAgIC8qCgkJICAgICogSGFuZGxlIHByb2Nlc3NDb250ZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQlYTUxfU0NIRU1BU19BTllfTEFYKSB8fAoJCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkpIHsKCQkJCgkJCWF0dHIgPSBjdXJTdGF0ZS0+YXR0cjsJCQkJCQkKCQkJYXR0ckRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCAKCQkJICAgIGF0dHItPm5hbWUsIG5zVVJJKTsKCQkJY3VyU3RhdGUtPmRlY2wgPSBhdHRyRGVjbDsKCQkJaWYgKGF0dHJEZWNsICE9IE5VTEwpIHsKCQkJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0F0dHJMb2NhbGx5VmFsaWQoY3R4dCwgYXR0ckRlY2wsIGN1clN0YXRlLCBhdHRyKTsJCQkgICAgCgkJCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJICAgIFhNTF9TQ0hFTUFTX0FOWV9MQVgpIHsKCQkJICAgIGN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCQkJfQkJCQkJCQkJCQkJCgkJICAgIH0gZWxzZQoJCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJfQkJCgkgICAgfQoJICAgIGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAqIFJlcG9ydCBtaXNzaW5nIGFuZCBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkgewoJY3VyU3RhdGUgPSBjdHh0LT5hdHRyOwoJd2hpbGUgKChjdXJTdGF0ZSAhPSBOVUxMKSAmJiAoY3VyU3RhdGUgIT0gY3R4dC0+YXR0clRvcC0+bmV4dCkpIHsgICAgCgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQpIHsKCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CgkJaWYgKGN1clN0YXRlLT5kZWNsICE9IE5VTEwpIHsKCQkgICAgaWYgKGN1clN0YXRlLT5kZWNsLT5yZWYgIT0gTlVMTCkKCQkJYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbC0+cmVmRGVjbDsKCQkgICAgZWxzZSAKCQkJYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbDsKCQl9IGVsc2UKCQkgICAgYXR0ckRlY2wgPSBOVUxMOwoJCWlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HKSB7CgkJICAgIHhtbFNjaGVtYVZNaXNzaW5nQXR0ckVycihjdHh0LCBlbGVtLCBhdHRyRGVjbCk7CgkJfSBlbHNlIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQVRUUklCVVRFXzIsCgkJCSh4bWxOb2RlUHRyKSBhdHRyLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2wsCgkJCSJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIsCgkJCU5VTEwpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IAoJCSAgICBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfRklYRURfVkFMVUUpIHsJCQkKCQkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0FVLCAKCQkJICAgICh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2wsCgkJCSAgICAiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCB2YWx1ZSAiCgkJCSAgICAiY29uc3RyYWludCIsIE5VTEwpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikgewoJCSAgICAvKiBUT0RPOiAicHJvaGliaXRlZCIgd29uJ3QgZXZlciBiZSB0b3VjaGVkIGhlcmUhLiAKCQkgICAgICAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfUFJPSElCSVRFRCkpCgkJICAgICovCgkJICAgIC8qCgkJICAgICogVE9ETzogT25lIG1pZ2h0IHJlcG9ydCBkaWZmZXJlbnQgZXJyb3IgbWVzc2FnZXMgCgkJICAgICogZm9yIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgoJCSAgICAqLwoJCSAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpKSB7CgkJCXhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfM18yXzEsIGF0dHIpOwoJCSAgICB9IGVsc2UgewoJCQl4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8yLCBhdHRyKTsKCQkgICAgfQoJCX0KCSAgICB9CQoJICAgIGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQ7Cgl9ICAKICAgIH0gICAgCiAgICAKICAgIC8qCiAgICAqIEFkZCBtaXNzaW5nIGRlZmF1bHQvZml4ZWQgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAoY3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSB7CgljdXJTdGF0ZSA9IGRlZkF0dHJTdGF0ZXM7Cgl3aGlsZSAoY3VyU3RhdGUgIT0gTlVMTCkgeyAKCSAgICBhdHRyRGVjbCA9IGN1clN0YXRlLT5kZWNsOwoJICAgIGlmIChhdHRyRGVjbC0+cmVmICE9IE5VTEwpCgkJYXR0ckRlY2wgPSBhdHRyRGVjbC0+cmVmRGVjbDsKCSAgICAvKgoJICAgICogUFNWSTogQWRkIGEgbmV3IGF0dHJpYnV0ZSBub2RlIHRvIHRoZSBjdXJyZW50IGVsZW1lbnQuCgkgICAgKi8KCSAgICBpZiAoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSB7CgkJeG1sTmV3UHJvcChlbGVtLCBhdHRyRGVjbC0+bmFtZSwgY3VyU3RhdGUtPnZhbHVlKTsKCSAgICB9IGVsc2UgewoJCXhtbE5zUHRyIG5zOwoJCQoJCW5zID0geG1sU2VhcmNoTnNCeUhyZWYoZWxlbS0+ZG9jLCBlbGVtLCAKCQkgICAgYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSk7CgkJaWYgKG5zID09IE5VTEwpIHsKCQkgICAgeG1sQ2hhciBwcmVmaXhbMTJdOwoJCSAgICBpbnQgY291bnRlciA9IDE7CgoJCSAgICBhdHRyID0gY3VyU3RhdGUtPmF0dHI7CgkJICAgIC8qCgkJICAgICogQ3JlYXRlIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG9uIHRoZSB2YWxpZGF0aW9uIAoJCSAgICAqIHJvb3Qgbm9kZSBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgaW4gc2NvcGUuCgkJICAgICovCQkgICAgCgkJICAgIHNucHJpbnRmKChjaGFyICopIHByZWZpeCwgc2l6ZW9mKHByZWZpeCksICJwIik7CgkJICAgIC8qCgkJICAgICogVGhpcyBpcyBzb21laG93IG5vdCBwZXJmb3JtYW50LCBzaW5jZSB0aGUgYW5jZXN0b3IgCgkJICAgICogYXhpcyBiZXlvbmQgQGVsZW0gd2lsbCBiZSBzZWFyY2hlZCBhcyB3ZWxsLgoJCSAgICAqLwoJCSAgICBucyA9IHhtbFNlYXJjaE5zKGVsZW0tPmRvYywgZWxlbSwgQkFEX0NBU1QgcHJlZml4KTsKCQkgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKCQkJaWYgKGNvdW50ZXIgPiAxMDAwKSB7CgkJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMsICIKCQkJCSJjb3VsZCBub3QgY29tcHV0ZSBhIG5zIHByZWZpeCBmb3IgIgoJCQkJImRlZmF1bHQvZml4ZWQgYXR0cmlidXRlICclcycuXG4iLAoJCQkJYXR0ckRlY2wtPm5hbWUsIE5VTEwpOwoJCQkgICAgCgkJCSAgICBicmVhazsKCQkJfQoJCQlzbnByaW50ZigoY2hhciAqKSBwcmVmaXgsIAoJCQkgICAgc2l6ZW9mKHByZWZpeCksICJwJWQiLCBjb3VudGVyKyspOwoJCQlucyA9IHhtbFNlYXJjaE5zKGVsZW0tPmRvYywgZWxlbSwgCgkJCSAgICBCQURfQ0FTVCBwcmVmaXgpOwoJCSAgICB9CgkJICAgIGlmIChucyA9PSBOVUxMKSB7CgkJCW5zID0geG1sTmV3TnMoY3R4dC0+dmFsaWRhdGlvblJvb3QsIAoJCQkgICAgYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSwgQkFEX0NBU1QgcHJlZml4KTsKCQkJeG1sTmV3TnNQcm9wKGVsZW0sIG5zLCBhdHRyRGVjbC0+bmFtZSwgCgkJCSAgICBjdXJTdGF0ZS0+dmFsdWUpOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgeG1sTmV3TnNQcm9wKGVsZW0sIG5zLCBhdHRyRGVjbC0+bmFtZSwgCgkJCWN1clN0YXRlLT52YWx1ZSk7CgkJfQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGRlZkF0dHJTdGF0ZXMgIT0gTlVMTCkgCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGRlZkF0dHJTdGF0ZXMpOwoJCQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCiAgICBpZiAocmVkdW5kYW50KQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkgICAgICAgICAgICAgICAgInhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlczogcmVkdW5kYW50IGNhbGwgYnkgdHlwZTogJXNcbiIsCgkgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSk7CiNlbmRpZgogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKgogKiBWYWxpZGF0ZSBhbiBlbGVtZW50IGluIGEgdHJlZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOyAgICAKICAgIGludCByZXQgPSAwOwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCBhbmQKICAgICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50LgogICAgKi8gIAogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7CgkvKgoJKiBObyBzY2hlbWEgd2FzIHNwZWNpZmllZCBhdCB0aW1lIG9mIGNyZWF0aW9uIG9mIHRoZSB2YWxpZGF0aW9uCgkqIGNvbnRleHQuIFVzZSB4c2k6c2NoZW1hTG9jYXRpb24gYW5kIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uCgkqIG9mIHRoZSBpbnN0YW5jZSB0byBidWlsZCBhIHNjaGVtYS4KCSovCglpZiAoY3R4dC0+cGN0eHQgPT0gTlVMTCkgCgkgICAgY3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7CglpZiAoY3R4dC0+cGN0eHQgPT0gTlVMTCkKCSAgICByZXR1cm4gKC0xKTsKCWN0eHQtPnNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0LT5wY3R4dCk7CglpZiAoY3R4dC0+c2NoZW1hID09IE5VTEwpCgkgICAgcmV0dXJuICgtMSk7CgkvKiBUT0RPOiBhc3NpZ24gdXNlciBkYXRhLiAqLwoJY3R4dC0+cGN0eHQtPmVycm9yID0gY3R4dC0+ZXJyb3I7CgljdHh0LT5wY3R4dC0+d2FybmluZyA9IGN0eHQtPndhcm5pbmc7CQoJY3R4dC0+eHNpQXNzZW1ibGUgPSAxOwogICAgfSBlbHNlCgljdHh0LT54c2lBc3NlbWJsZSA9IDA7CiAgICAvKiBjdHh0LT5vcHRpb25zIHw9IFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFOwogICAgKiBjdHh0LT54c2lBc3NlbWJsZSA9IDE7CiAgICAqLwogICAgLyoKICAgICogQXNzZW1ibGUgbmV3IHNjaGVtYXRhIHVzaW5nIHhzaS4KICAgICovCiAgICBpZiAoY3R4dC0+eHNpQXNzZW1ibGUpIHsJCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbShjdHh0LCBjdHh0LT5ub2RlKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYSBieSB4c2kiLCBOVUxMKTsJICAgIAoJfQoJLyoKCSogTk9URTogV2Ugd29uJ3QgcmVhY3Qgb24gc2NoZW1hIHBhcnNlciBlcnJvcnMgaGVyZS4KCSogVE9ETzogQnV0IGEgd2FybmluZyB3b3VsZCBiZSBuaWNlLgoJKi8KICAgIH0KICAgIGlmIChyZXQgIT0gLTEpIHsJICAgIAoJaWYgKGN0eHQtPm5vZGUtPm5zICE9IE5VTEwpCgkgICAgZWxlbURlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKGN0eHQtPnNjaGVtYSwgY3R4dC0+bm9kZS0+bmFtZSwgCgkJY3R4dC0+bm9kZS0+bnMtPmhyZWYpOwoJZWxzZQoJICAgIGVsZW1EZWNsID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGN0eHQtPm5vZGUtPm5hbWUsIE5VTEwpOwoJCglpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkgIAoJCSJObyBtYXRjaGluZyBnbG9iYWwgZGVjbGFyYXRpb24gYXZhaWxhYmxlIiwgTlVMTCk7CgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xOwoJfSBlbHNlIHsgCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbihjdHh0LCBlbGVtRGVjbCk7ICAgIAoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgY3R4dC0+bm9kZSwgTlVMTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQsICIKCQkgICAgImNhbGxpbmcgdmFsaWRhdGlvbiBieSBkZWNsYXJhdGlvbiIsIE5VTEwpOwoJICAgIH0KCX0KICAgIH0KICAgIC8qIGN0eHQtPnhzaUFzc2VtYmxlID0gMDsgKi8KICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewoJaWYgKGN0eHQtPnNjaGVtYSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZShjdHh0LT5zY2hlbWEpOwoJICAgIGN0eHQtPnNjaGVtYSA9IE5VTEw7Cgl9CiAgICB9CiAgICByZXR1cm4gKHJldCk7ICAgCn0KCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQgbm9kZQogKgogKiBWYWxpZGF0ZSBhIGJyYW5jaCBvZiBhIHRyZWUsIHN0YXJ0aW5nIHdpdGggdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgYW5kIGl0cyBzdWJ0cmVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIAogKiBjb2RlIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlT25lRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkgfHwgKGVsZW0tPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCglyZXR1cm4gKC0xKTsKCiAgICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkFQSSBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50LCAiCgkgICAgIm5vIHNjaGVtYSBzcGVjaWZpZWQuXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGN0eHQtPmRvYyA9IGVsZW0tPmRvYzsKICAgIGN0eHQtPmVyciA9IDA7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5ub2RlID0gZWxlbTsKICAgIGN0eHQtPnZhbGlkYXRpb25Sb290ID0gZWxlbTsKICAgIHJldHVybiAoeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KGN0eHQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBkb2M6ICBhIHBhcnNlZCBkb2N1bWVudCB0cmVlCiAqIEB4c2lBc3NlbWJsZTogc2hvdWxkIHNjaGVtYXRhIGJlIGFkZGVkIGlmIHJlcXVlc3RlZCBieSB0aGUgaW5zdGFuY2U/CiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykKewogICAgeG1sTm9kZVB0ciByb290OwogICAgIAogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BVl9ET0NVTUVOVF9FTEVNRU5UX01JU1NJTkcsCgkgICAgKHhtbE5vZGVQdHIpIGRvYywgTlVMTCwKCSAgICAiVGhlIGRvY3VtZW50IGhhcyBubyBkb2N1bWVudCBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAgICAKICAgIC8qIGN0eHQtPm9wdGlvbnMgfD0gWE1MX1NDSEVNQV9WQUxfWFNJX0FTU0VNQkxFOyAqLwogICAgLyoKICAgICAqIE9rYXksIHN0YXJ0IHRoZSByZWN1cnNpdmUgdmFsaWRhdGlvbgogICAgICovCiAgICBjdHh0LT5ub2RlID0gcm9vdDsKICAgIGN0eHQtPnZhbGlkYXRpb25Sb290ID0gcm9vdDsKICAgIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudChjdHh0KTsKCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlTQVggVmFsaWRhdGlvbiBjb2RlCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpb24gaW50ZXJmYWNlcwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFOZXdWYWxpZEN0eHQ6CiAqIEBzY2hlbWE6ICBhIHByZWNvbXBpbGVkIFhNTCBTY2hlbWFzCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQgYmFzZWQgb24gdGhlIGdpdmVuIHNjaGVtYQogKgogKiBSZXR1cm5zIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFWYWxpZEN0eHRQdHIKeG1sU2NoZW1hTmV3VmFsaWRDdHh0KHhtbFNjaGVtYVB0ciBzY2hlbWEpCnsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVZhbGlkQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFWYWxpZEN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgdmFsaWRhdGlvbiBjb250ZXh0IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFWYWxpZEN0eHQpKTsKICAgIHJldC0+c2NoZW1hID0gc2NoZW1hOyAgICAKICAgIHJldC0+YXR0clRvcCA9IE5VTEw7CiAgICByZXQtPmF0dHIgPSBOVUxMOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CiAgICBpZiAoY3R4dC0+cGN0eHQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQoY3R4dC0+cGN0eHQpOwogICAgfQogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoY3R4dC0+cGN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFZhbGlkRXJyb3JzOgogKiBAY3R4dDoJYSBYTUwtU2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgZnVuY3Rpb24gcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbiByZXN1bHQKICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0IHJlc3VsdAogKgogKiBHZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkJCQl4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG9wdGlvbnM6IGEgY29tYmluYXRpb24gb2YgeG1sU2NoZW1hVmFsaWRPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgdmFsaWRhdGlvbi4KICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBhbgogKiBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hU2V0VmFsaWRPcHRpb25zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkgaW50IG9wdGlvbnMpCgkJCQkJCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFWYWxpZE9wdGlvbi4KICAgICogVE9ETzogSXMgdGhlcmUgYW4gb3RoZXIsIG1vcmUgZWFzeSB0byBtYWludGFpbiwKICAgICogd2F5PwogICAgKi8KICAgIGZvciAoaSA9IDE7IGkgPCAoaW50KSBzaXplb2YoaW50KSAqIDg7IGkrKykgewogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgTlVMTCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVNldFZhbGlkT3B0aW9ucywgIgoJCSJpbnZhbGlkIG9wdGlvbiBhcmd1bWVudC5cbiIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOyAgIAogICAgICAgIH0JCiAgICB9CiAgICBjdHh0LT5vcHRpb25zID0gb3B0aW9uczsKICAgIHJldHVybiAoMCk7ICAgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRWYWxpZE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQgCiAqCiAqIFJldHVybnMgdGhlIG9wdGlvbiBjb21iaW5hdGlvbiBvZiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0LgogKi8KaW50CnhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpCgkJCQkJCnsgICAgCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlIAoJcmV0dXJuIChjdHh0LT5vcHRpb25zKTsgICAgCn0KCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVEb2M6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBkb2M6ICBhIHBhcnNlZCBkb2N1bWVudCB0cmVlCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZURvYyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykKewogICAgaW50IHJldDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGRvYyA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICBjdHh0LT5kb2MgPSBkb2M7CiAgICBjdHh0LT5lcnIgPSAwOyAKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIAogICAgLyoKICAgIGlmIChjdHh0LT5zY2hlbWEgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJBUEkgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRG9jLCAiCgkgICAgIm5vIHNjaGVtYSBzcGVjaWZpZWQgYW5kIGFzc2VtYmxpbmcgb2Ygc2NoZW1hdGEgIgoJICAgICJ1c2luZyB4c2k6c2NoZW1hTG9jYXRpb24gYW5kIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uICIKCSAgICAiaXMgbm90IGVuYWJsZWQuXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoY3R4dCwgZG9jKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAaW5wdXQ6ICB0aGUgaW5wdXQgdG8gdXNlIGZvciByZWFkaW5nIHRoZSBkYXRhCiAqIEBlbmM6ICBhbiBvcHRpb25hbCBlbmNvZGluZyBpbmZvcm1hdGlvbgogKiBAc2F4OiAgYSBTQVggaGFuZGxlciBmb3IgdGhlIHJlc3VsdGluZyBldmVudHMKICogQHVzZXJfZGF0YTogIHRoZSBjb250ZXh0IHRvIHByb3ZpZGUgdG8gdGhlIFNBWCBoYW5kbGVyLgogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0LCB4bWxDaGFyRW5jb2RpbmcgZW5jLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTQVhIYW5kbGVyUHRyIHNheCwgdm9pZCAqdXNlcl9kYXRhKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGlucHV0ID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgY3R4dC0+aW5wdXQgPSBpbnB1dDsKICAgIGN0eHQtPmVuYyA9IGVuYzsKICAgIGN0eHQtPnNheCA9IHNheDsKICAgIGN0eHQtPnVzZXJfZGF0YSA9IHVzZXJfZGF0YTsKICAgIFRPRE8gcmV0dXJuICgwKTsKfQoKI2VuZGlmIC8qIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQgKi8K