LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlIAogKiAgICAgbmVlZCB0byB2YWxpZGF0ZSBhbGwgc2NoZW1hIGF0dHJpYnV0ZXMgKHJlZiwgdHlwZSwgbmFtZSkKICogICAgIGFnYWluc3QgdGhlaXIgdHlwZXMuCiAqLwojZGVmaW5lIElOX0xJQlhNTAojaW5jbHVkZSAibGlieG1sLmgiCgojaWZkZWYgTElCWE1MX1NDSEVNQVNfRU5BQkxFRAoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgojaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KCiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hcy5oPgojaW5jbHVkZSA8bGlieG1sL3NjaGVtYXNJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxzY2hlbWFzdHlwZXMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxhdXRvbWF0YS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHJlZ2V4cC5oPgojaW5jbHVkZSA8bGlieG1sL2RpY3QuaD4KCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKLyogI2RlZmluZSBERUJVR19VTklPTl9WQUxJREFUSU9OIDEgKi8KCgojZGVmaW5lIFVOQk9VTkRFRCAoMSA8PCAzMCkKI2RlZmluZSBUT0RPIAkJCQkJCQkJXAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCQkJCVwKCSAgICAiVW5pbXBsZW1lbnRlZCBibG9jayBhdCAlczolZFxuIiwJCQkJXAogICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOwoKI2RlZmluZSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikgIiMjIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgcmVmLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkF0dHJpYnV0ZSBkZWNsLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiQXR0cmlidXRlIHJlZi4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc1NUID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJTVCI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQ1QgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkNUIjsKCiNkZWZpbmUgSVNfU0NIRU1BKG5vZGUsIHR5cGUpCQkJCQkJXAogICAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPm5zICE9IE5VTEwpICYmCQkJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0eXBlKSkgJiYJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkKCiNkZWZpbmUgRlJFRV9BTkRfTlVMTChzdHIpCQkJCQkJXAogICAgaWYgKHN0ciAhPSBOVUxMKSB7CQkJCQkJCVwKCXhtbEZyZWUoc3RyKTsJCQkJCQkJXAoJc3RyID0gTlVMTDsJCQkJCQkJXAogICAgfQoKI2RlZmluZSBYTUxfU0NIRU1BU19WQUxfV1RTUF9QUkVTRVJWRSAwCiNkZWZpbmUgWE1MX1NDSEVNQVNfVkFMX1dUU1BfUkVQTEFDRSAgMQojZGVmaW5lIFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFIDIKCiNkZWZpbmUgWE1MX1NDSEVNQVNfUEFSU0VfRVJST1IJCTEKCiNkZWZpbmUgU0NIRU1BU19QQVJTRV9PUFRJT05TIFhNTF9QQVJTRV9OT0VOVAoKLyoKICogeG1sU2NoZW1hVmFsaWRPcHRpb246CiAqCiAqIFRoaXMgaXMgdGhlIHNldCBvZiBYTUwgU2NoZW1hIHZhbGlkYXRpb24gb3B0aW9ucy4KICovCnR5cGVkZWYgZW51bSB7CiAgICBYTUxfU0NIRU1BX1ZBTF9YU0lfQVNTRU1CTEUJCQk9IDE8PDAKCS8qIGFzc2VtYmxlIHNjaGVtYXRhIHVzaW5nCgkqIHhzaTpzY2hlbWFMb2NhdGlvbiBhbmQKCSogeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gKi8KCn0geG1sU2NoZW1hVmFsaWRPcHRpb247CgovKgoqIFhNTF9TQ0hFTUFfVkFMX1hTSV9BU1NFTUJMRV9UTlNfQ09NUE9TRQkgCiogYWxsb3cgdG8gYXNzZW1ibGUgc2NoZW1hdGEgd2l0aCAKKiB0aGUgc2FtZSB0YXJnZXQgbmFtZXNwYWNlIGZyb20gCiogZGlmZmVyZW50IHNvdXJjZXM7IG90aGVyd2lzZSwgdGhlIGZpcnN0IAoqIGVuY291bnRlcmVkIHNjaGVtYSB3aXRoIGEgc3BlY2lmaWMgdGFyZ2V0IAoqIG5hbWVzcGFjZSB3aWxsIGJlIHVzZWQgb25seSAqCiAgIAoqIAoqIFhNTF9TQ0hFTUFfVkFMX0xPQ0FURV9CWV9OU05BTUUgPSAxPDwyCiogbG9jYXRlIHNjaGVtYXRhIHRvIGJlIGltcG9ydGVkCiogdXNpbmcgdGhlIG5hbWVzcGFjZSBuYW1lOyBvdGhlcndpc2UKKiB0aGUgbG9jYXRpb24gVVJJIHdpbGwgYmUgdXNlZCAqLwoKLyoKKiB4bWxTY2hlbWFQYXJzZXJPcHRpb246CioKKiBUaGlzIGlzIHRoZSBzZXQgb2YgWE1MIFNjaGVtYSBwYXJzZXIgb3B0aW9ucy4KKi8KdHlwZWRlZiBlbnVtIHsKICAgIFhNTF9TQ0hFTUFfUEFSX0xPQ0FURV9CWV9OU05BTUUJPSAxPDwwCgkvKiBsb2NhdGUgc2NoZW1hdGEgdG8gYmUgaW1wb3J0ZWQKCSogdXNpbmcgdGhlIG5hbWVzcGFjZSBuYW1lOyBvdGhlcndpc2UKCSogdGhlIGxvY2F0aW9uIFVSSSB3aWxsIGJlIHVzZWQgKi8KfSB4bWxTY2hlbWFQYXJzZXJPcHRpb247CgovKgpYTUxQVUJGVU4gaW50IFhNTENBTEwKCSAgICB4bWxTY2hlbWFWYWxpZEN0eHRTZXRPcHRpb25zKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJCSBpbnQgb3B0aW9ucyk7ClhNTFBVQkZVTiBpbnQgWE1MQ0FMTAoJICAgIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpOwpYTUxQVUJGVU4gaW50IFhNTENBTEwKCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJICBpbnQgb3B0aW9ucyk7ClhNTFBVQkZVTiBpbnQgWE1MQ0FMTAoJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRHZXRPcHRpb25zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCk7CgoqLwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUFzc2VtYmxlIHhtbFNjaGVtYUFzc2VtYmxlOwp0eXBlZGVmIHhtbFNjaGVtYUFzc2VtYmxlICp4bWxTY2hlbWFBc3NlbWJsZVB0cjsKc3RydWN0IF94bWxTY2hlbWFBc3NlbWJsZSB7CiAgICB2b2lkICppdGVtczsgIC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBuYkl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgc2l6ZUl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCn07CgpzdHJ1Y3QgX3htbFNjaGVtYVBhcnNlckN0eHQgewogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFNjaGVtYVZhbGlkRXJyb3IgZXJyOwogICAgaW50IG5iZXJyb3JzOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHRvcHNjaGVtYTsJLyogVGhlIG1haW4gc2NoZW1hICovCiAgICB4bWxIYXNoVGFibGVQdHIgbmFtZXNwYWNlczsJLyogSGFzaCB0YWJsZSBvZiBuYW1lc3BhY2VzIHRvIHNjaGVtYXMgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIGNvbnN0IHhtbENoYXIgKmNvbnRhaW5lcjsgICAvKiB0aGUgY3VycmVudCBlbGVtZW50LCBncm91cCwgLi4uICovCiAgICBpbnQgY291bnRlcjsKCiAgICBjb25zdCB4bWxDaGFyICpVUkw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHByZXNlcnZlOwkJLyogV2hldGhlciB0aGUgZG9jIHNob3VsZCBiZSBmcmVlZCAgKi8KCiAgICBjb25zdCBjaGFyICpidWZmZXI7CiAgICBpbnQgc2l6ZTsKCiAgICAvKgogICAgICogVXNlZCB0byBidWlsZCBjb21wbGV4IGVsZW1lbnQgY29udGVudCBtb2RlbHMKICAgICAqLwogICAgeG1sQXV0b21hdGFQdHIgYW07CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBlbmQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXRlOwoKICAgIHhtbERpY3RQdHIgZGljdDsJCS8qIGRpY3Rpb25uYXJ5IGZvciBpbnRlcm5lZCBzdHJpbmcgbmFtZXMgKi8KICAgIGludCAgICAgICAgaW5jbHVkZXM7CS8qIHRoZSBpbmNsdXNpb24gbGV2ZWwsIDAgZm9yIHJvb3Qgb3IgaW1wb3J0cyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHBhcmVudEl0ZW07IC8qIFRoZSBjdXJyZW50IHBhcmVudCBzY2hlbWEgaXRlbSAqLwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzZW1ibGU7CiAgICBpbnQgb3B0aW9uczsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORyA0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFIDUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEIDYKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dDoKICoKICogQSBTY2hlbWFzIHZhbGlkYXRpb24gY29udGV4dAogKi8KCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvcjsKCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dDsKICAgIHhtbENoYXJFbmNvZGluZyBlbmM7CiAgICB4bWxTQVhIYW5kbGVyUHRyIHNheDsKICAgIHZvaWQgKnVzZXJfZGF0YTsKCiAgICB4bWxEb2NQdHIgbXlEb2M7CiAgICBpbnQgZXJyOwogICAgaW50IG5iZXJyb3JzOwoKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbE5vZGVQdHIgY3VyOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIHJlZ2V4cDsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWx1ZTsKCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0clRvcDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRyOwogICAgLyogeG1sTm9kZVB0ciBzY29wZTsgbm90IHVzZWQgKi8KICAgIGludCB2YWx1ZVdTOwogICAgaW50IG9wdGlvbnM7Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgaW4gdGhlIHNjaGVtYXMgaW1wb3J0U2NoZW1hcyBoYXNoIHRhYmxlCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHhtbFNjaGVtYUltcG9ydDsKdHlwZWRlZiB4bWxTY2hlbWFJbXBvcnQgKnhtbFNjaGVtYUltcG9ydFB0cjsKc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgewogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAvKiBub3QgdXNlZCBhbnkgbW9yZSAqLwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCBpc01haW47Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgYXNzb2NpYXRlZCB0byBpbmNsdWRlcyBpbiBhIHNjaGVtYXMKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHhtbFNjaGVtYUluY2x1ZGU7CnR5cGVkZWYgeG1sU2NoZW1hSW5jbHVkZSAqeG1sU2NoZW1hSW5jbHVkZVB0cjsKc3RydWN0IF94bWxTY2hlbWFJbmNsdWRlIHsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgbmV4dDsKCiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbERvY1B0ciBkb2M7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU29tZSBwcmVkZWNsYXJhdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVBhcnNlSW5jbHVkZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSk7CnN0YXRpYyBjb25zdCBjaGFyICoKeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSBpbnQgZmlyZUVycm9ycywJCQkJIAoJCQkJIGludCBhcHBseUZhY2V0cywKCQkJCSBpbnQgbm9ybWFsaXplLAoJCQkJIGludCBjaGVja05vZGVzKTsKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCk7IApzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpOwpzdGF0aWMgaW50CnhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbXBvcnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJRGF0YXR5cGUgZXJyb3IgaGFuZGxlcnMJCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFQRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyck1lbW9yeSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwoJc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnIyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAbm9kZTogdGhlIGN1cnJlbnQgY2hpbGQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyMih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZCwgaW50IGVycm9yLAogICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgaWYgKGNoaWxkICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjaGlsZCwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7CiAgICBlbHNlCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgbXNnLCBzdHIxLCBzdHIyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFQRXJyRXh0OgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlIAogKiBAc3RyRGF0YTE6IGV4dHJhIGRhdGEKICogQHN0ckRhdGEyOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMzogZXh0cmEgZGF0YQogKiBAbXNnOiB0aGUgbWVzc2FnZQogKiBAc3RyMTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMjogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMzogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNDogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCgkJY29uc3QgeG1sQ2hhciAqIHN0ckRhdGExLCBjb25zdCB4bWxDaGFyICogc3RyRGF0YTIsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMywgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgCgkJY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCBjb25zdCB4bWxDaGFyICogc3RyNCwKCQljb25zdCB4bWxDaGFyICogc3RyNSkKewoKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CglzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTEsIChjb25zdCBjaGFyICopIHN0ckRhdGEyLCAKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgCgkJICAgIHN0cjMsIHN0cjQsIHN0cjUpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVZUeXBlRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVyck1lbW9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpleHRyYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjdHh0LT5lcnIgPSBYTUxfU0NIRU1BVl9JTlRFUk5BTDsKICAgIH0KICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1YsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWRXJyMzoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiBAc3RyMzogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVycjMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKnN0cjEsIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkgICAgICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CgljdHh0LT5lcnIgPSBlcnJvcjsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwogICAgfQogICAgLyogcmVhanVzdCB0byBnbG9iYWwgZXJyb3IgbnVtYmVycyAqLwogICAgLyogUmVtb3ZlZCwgc2luY2UgdGhlIG9sZCBzY2hlbWEgZXJyb3IgY29kZXMgaGF2ZSBiZWVuIAogICAgKiBzdWJzdGl0dXRlZCBmb3IgdGhlIGdsb2JhbCBlcnJvciBjb2Rlcy4KICAgICoKICAgICogZXJyb3IgKz0gWE1MX1NDSEVNQVZfTk9ST09UIC0gWE1MX1NDSEVNQVNfRVJSX05PUk9PVDsgCiAgICAqLwogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTViwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLAoJCSAgICAoY29uc3QgY2hhciAqKSBzdHIzLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMiwgc3RyMyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWRXJyRXh0OgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlIAogKiBAbXNnOiB0aGUgbWVzc2FnZQogKiBAc3RyMTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMjogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMzogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNDogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVyckV4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCgkJIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIAoJCSBjb25zdCB4bWxDaGFyICogc3RyMiwgY29uc3QgeG1sQ2hhciAqIHN0cjMsIAoJCSBjb25zdCB4bWxDaGFyICogc3RyNCwgY29uc3QgeG1sQ2hhciAqIHN0cjUpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgICAvKiBSZW1vdmVkLCBzaW5jZSB0aGUgb2xkIHNjaGVtYSBlcnJvciBjb2RlcyBoYXZlIGJlZW4gCiAgICAqIHN1YnN0aXR1dGVkIGZvciB0aGUgZ2xvYmFsIGVycm9yIGNvZGVzLgogICAgKgogICAgKiBlcnJvciArPSBYTUxfU0NIRU1BVl9OT1JPT1QgLSBYTUxfU0NIRU1BU19FUlJfTk9ST09UOwogICAgKi8KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsIE5VTEwsIE5VTEwsIE5VTEwsIDAsIDAsIAoJCSAgICBtc2csIHN0cjEsIHN0cjIsIHN0cjMsIHN0cjQsIHN0cjUpOwp9Ci8qKgogKiB4bWxTY2hlbWFWRXJyOgogKiBAY3R4dDogdGhlIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSB2YWxpZGF0aW9uIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CgljdHh0LT5lcnIgPSBlcnJvcjsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgLyogcmVhanVzdCB0byBnbG9iYWwgZXJyb3IgbnVtYmVycyAqLwogICAgLyogUmVtb3ZlZCwgc2luY2UgdGhlIG9sZCBzY2hlbWEgZXJyb3IgY29kZXMgaGF2ZSBiZWVuIAogICAgKiBzdWJzdGl0dXRlZCBmb3IgdGhlIGdsb2JhbCBlcnJvciBjb2Rlcy4KICAgICoKICAgICogZXJyb3IgKz0gWE1MX1NDSEVNQVZfTk9ST09UIC0gWE1MX1NDSEVNQVNfRVJSX05PUk9PVDsKICAgICovCiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE9ueW1vdXNUeXBlTmFtZToKICogQGF0dHI6ICB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKgogKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGU7IGlmIHRoZSBhdHRyaWJ1dGUKICogaXMgYSByZWZlcmVuY2UsIHRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGdsb2JhbCB0eXBlIHdpbGwgYmUgcmV0dXJuZWQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldEF0dHJOYW1lKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKSAKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKSAKCXJldHVybihhdHRyLT5yZWYpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPm5hbWUpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSToKICogQHR5cGU6ICB0aGUgdHlwZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCiAqCiAqIFJldHVybnMgdGhlIHRhcmdldCBuYW1lc3BhY2UgVVJJIG9mIHRoZSB0eXBlOyBpZiB0aGUgdHlwZSBpcyBhIHJlZmVyZW5jZSwKICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHJlZmVyZW5jZWQgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsgIAogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKQoJcmV0dXJuIChhdHRyLT5yZWZOcyk7CiAgICBlbHNlCglyZXR1cm4oYXR0ci0+dGFyZ2V0TmFtZXNwYWNlKTsgIAp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQHVyaTogIHRoZSBuYW1lc3BhY2UgVVJJCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBVUkkgdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4KICoKICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcsIGlmIEBucyBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8gIApzdGF0aWMgY29uc3QgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCh4bWxDaGFyICoqYnVmLAoJCQkgICBjb25zdCB4bWxDaGFyICp1cmksIGNvbnN0IHhtbENoYXIgKmxvY2FsKQp7CiAgICBpZiAoKmJ1ZiAhPSBOVUxMKQoJeG1sRnJlZSgqYnVmKTsKICAgIGlmICh1cmkgPT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyciKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbG9jYWwpOwogICAgfSBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIHVyaSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInLCAnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsJCiAgICB9CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInfSIpOwogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWw6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBuczogIHRoZSBuYW1lc3BhY2UKICogQGxvY2FsOiB0aGUgbG9jYWwgbmFtZQogKgogKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIFVSSSB1c2VkCiAqIGZvciBlcnJvciByZXBvcnRzLgogKgogKiBSZXR1cm5zIGFuIGVtcHR5IHN0cmluZywgaWYgQG5zIGlzIE5VTEwsIGEgZm9ybWF0dGVkCiAqIHN0cmluZyBvdGhlcndpc2UuCiAqLyAgCnN0YXRpYyBjb25zdCB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKHhtbENoYXIgKipidWYsCgkJCSAgICAgIHhtbE5zUHRyIG5zLCBjb25zdCB4bWxDaGFyICpsb2NhbCkKewogICAgaWYgKCpidWYgIT0gTlVMTCkgewoJeG1sRnJlZSgqYnVmKTsKCSpidWYgPSBOVUxMOwogICAgfQogICAgaWYgKChucyA9PSBOVUxMKSB8fCAobnMtPnByZWZpeCA9PSBOVUxMKSkKCXJldHVybihsb2NhbCk7CiAgICBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAobnMtPnByZWZpeCk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsKICAgIH0KICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0OgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBpdGVtCiAqIEBpdGVtTmFtZTogdGhlIG5hbWUgb2YgdGhlIGl0ZW0KICogQGl0ZW06IHRoZSBpdGVtIGFzIGFuIG9iamVjdCAKICogQGl0ZW1Ob2RlOiB0aGUgbm9kZSBvZiB0aGUgaXRlbQogKiBAbG9jYWw6IHRoZSBsb2NhbCBuYW1lCiAqIEBwYXJzaW5nOiBpZiB0aGUgZnVuY3Rpb24gaXMgdXNlZCBkdXJpbmcgdGhlIHBhcnNlCiAqCiAqIFJldHVybnMgYSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gaXRlbSB1c2VkCiAqIGZvciBlcnJvciByZXBvcnRzLiAKICoKICogVGhlIGZvbGxvd2luZyBvcmRlciBpcyB1c2VkIHRvIGJ1aWxkIHRoZSByZXN1bHRpbmcgCiAqIGRlc2lnbmF0aW9uIGlmIHRoZSBhcmd1bWVudHMgYXJlIG5vdCBOVUxMOgogKiAxYS4gSWYgaXRlbURlcyBub3QgTlVMTCAtPiBpdGVtRGVzCiAqIDFiLiBJZiAoaXRlbURlcyBub3QgTlVMTCkgYW5kIChpdGVtTmFtZSBub3QgTlVMTCkKICogICAgIC0+IGl0ZW1EZXMgKyBpdGVtTmFtZQogKiAyLiBJZiB0aGUgcHJlY2VkaW5nIHdhcyBOVUxMIGFuZCAoaXRlbSBub3QgTlVMTCkgLT4gaXRlbQogKiAzLiBJZiB0aGUgcHJlY2VkaW5nIHdhcyBOVUxMIGFuZCAoaXRlbU5vZGUgbm90IE5VTEwpIC0+IGl0ZW1Ob2RlCiAqIAogKiBJZiB0aGUgaXRlbU5vZGUgaXMgYW4gYXR0cmlidXRlIG5vZGUsIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgcmVzdWx0LgogKgogKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIGFuZCBzZXRzIEBidWYgdG8gdGhlIHJlc3VsdGluZyB2YWx1ZS4KICovICAKc3RhdGljIHhtbENoYXIqICAgCnhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoeG1sQ2hhciAqKmJ1ZiwJCSAgICAgCgkJICAgICBjb25zdCB4bWxDaGFyICppdGVtRGVzLAoJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICAgeG1sTm9kZVB0ciBpdGVtTm9kZSwKCQkgICAgIGludCBwYXJzaW5nKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgaW50IG5hbWVkID0gMTsKCiAgICBpZiAoKmJ1ZiAhPSBOVUxMKSB7Cgl4bWxGcmVlKCpidWYpOwoJKmJ1ZiA9IE5VTEw7CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKGl0ZW1EZXMgIT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChpdGVtRGVzKTsJCiAgICB9IGVsc2UgaWYgKGl0ZW0gIT0gTlVMTCkgewoJaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkgICAgaWYgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJ2FueVR5cGUnIik7CgkgICAgZWxzZSBpZiAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInYW55U2ltcGxlVHlwZSciKTsKCSAgICBlbHNlIHsKCQkvKiAqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJiaSAiKTsgKi8KCQkvKiAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUVsZW1EZXNTVCk7ICovCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCX0gZWxzZSBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNTVCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc1NUKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgbG9jYWwiKTsKCSAgICB9Cgl9IGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0NUKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzQ1QpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiBsb2NhbCIpOwoJICAgIH0KCX0gZWxzZSBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFKSB7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHI7CgoJICAgIGF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtOwkgICAgCgkgICAgaWYgKChhdHRyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB8fAoJCShhdHRyLT5yZWYgPT0gTlVMTCkpIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGF0dHItPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5yZWZQcmVmaXgpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIjoiKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGF0dHItPnJlZik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgfQkJCgl9IGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQpIHsKCSAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW07CgoJICAgIGVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbTsJICAgIAoJICAgIGlmICgoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgfHwgCgkJKGVsZW0tPnJlZiA9PSBOVUxMKSkgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzRWxlbVJlZik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPnJlZlByZWZpeCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiOiIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+cmVmKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfQkJCgl9IGVsc2UKCSAgICBuYW1lZCA9IDA7CiAgICB9IGVsc2UgCgluYW1lZCA9IDA7CgogICAgaWYgKChuYW1lZCA9PSAwKSAmJiAoaXRlbU5vZGUgIT0gTlVMTCkpIHsKCXhtbE5vZGVQdHIgZWxlbTsKCglpZiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIGVsZW0gPSBpdGVtTm9kZS0+cGFyZW50OwoJZWxzZSAKCSAgICBlbGVtID0gaXRlbU5vZGU7CgkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCWlmIChwYXJzaW5nKQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+bmFtZSk7CgllbHNlCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCAKCQl4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHIsIGVsZW0tPm5zLCBlbGVtLT5uYW1lKSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CiAgICB9CiAgICBpZiAoKGl0ZW1Ob2RlICE9IE5VTEwpICYmIChpdGVtTm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpKSB7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsIGF0dHJpYnV0ZSAnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ciwgCgkgICAgaXRlbU5vZGUtPm5zLCBpdGVtTm9kZS0+bmFtZSkpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChzdHIpOwogICAgCiAgICByZXR1cm4gKCpidWYpOwp9CgovKioKICogeG1sU2NoZW1hUEZvcm1hdEl0ZW1EZXM6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBpdGVtOiB0aGUgaXRlbSBhcyBhIHNjaGVtYSBvYmplY3QKICogQGl0ZW1Ob2RlOiB0aGUgaXRlbSBhcyBhIG5vZGUKICoKICogSWYgdGhlIHBvaW50ZXIgdG8gQGJ1ZiBpcyBub3QgTlVMTCBhbmQgQGJ1dCBob2xkcyBubyB2YWx1ZSwKICogdGhlIHZhbHVlIGlzIHNldCB0byBhIGl0ZW0gZGVzaWduYXRpb24gdXNpbmcgCiAqIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQuIFRoaXMgb25lIGF2b2lkcyBhZGRpbmcKICogYW4gYXR0cmlidXRlIGRlc2lnbmF0aW9uIHBvc3RmaXguCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFJlcXVlc3RJdGVtRGVzKHhtbENoYXIgKipidWYsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgICAgeG1sTm9kZVB0ciBpdGVtTm9kZSkKewogICAgaWYgKChidWYgPT0gMCkgfHwgKCpidWYgIT0gTlVMTCkpIAoJcmV0dXJuOwogICAgaWYgKGl0ZW1Ob2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCWl0ZW1Ob2RlID0gaXRlbU5vZGUtPnBhcmVudDsKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoYnVmLCBOVUxMLCBpdGVtLCBpdGVtTm9kZSwgMSk7CQp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0OgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAdHlwZTogdGhlIHR5cGUgaG9sZGluZyB0aGUgZW51bWVyYXRpb24gZmFjZXRzCiAqCiAqIEJ1aWxkcyBhIHN0cmluZyBjb25zaXN0aW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICoKICogUmV0dXJucyBhIHN0cmluZyBvZiBhbGwgZW51bWVyYXRpb24gZWxlbWVudHMuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldCh4bWxDaGFyICoqYnVmLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBsaW5rOwoKICAgIGlmICgqYnVmICE9IE5VTEwpCgl4bWxGcmVlKCpidWYpOyAgICAKICAgICpidWYgPSBOVUxMOwogICAgZm9yIChsaW5rID0gdHlwZS0+ZmFjZXRTZXQ7IGxpbmsgIT0gTlVMTDsgbGluayA9IGxpbmstPm5leHQpIHsKCWlmIChsaW5rLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgaWYgKCpidWYgPT0gTlVMTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxpbmstPmZhY2V0LT52YWx1ZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiLCAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsaW5rLT5mYWNldC0+dmFsdWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gKChjb25zdCB4bWxDaGFyICopICpidWYpOwp9CgovKioKICogeG1sU2NoZW1hVkZhY2V0RXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG5vZGU6IHRoZSBub2RlIHRvIGJlIHZhbGlkYXRlZCAgCiAqIEB2YWx1ZTogdGhlIHZhbHVlIG9mIHRoZSBub2RlCiAqIEB0eXBlOiB0aGUgdHlwZSBob2xkaW5nIHRoZSBmYWNldAogKiBAZmFjZXQ6IHRoZSBmYWNldAogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2Ugb2YgTlVMTAogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiBAc3RyMzogZXh0cmEgZGF0YQogKgogKiBSZXBvcnRzIGEgZmFjZXQgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRmFjZXRFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCQkgICAKCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkgICB1bnNpZ25lZCBsb25nIGxlbmd0aCwKCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCQkgICAKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMiwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIGZhY2V0VHlwZTsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIE5VTEwsIG5vZGUsIDApOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsIGZhY2V0ICciKTsKICAgIGlmIChlcnJvciA9PSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQpIHsKCWZhY2V0VHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CgkvKgoJKiBJZiBlbnVtZXJhdGlvbnMgYXJlIHZhbGlkYXRlZCwgb25lIG11c3Qgbm90IGV4cGVjdCB0aGUKCSogZmFjZXQgdG8gYmUgZ2l2ZW4uCgkqLwkKICAgIH0gZWxzZQkKCWZhY2V0VHlwZSA9IGZhY2V0LT50eXBlOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXRUeXBlKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJ106ICIpOwogICAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgewoJLyoKCSogVXNlIGEgZGVmYXVsdCBtZXNzYWdlLgoJKi8KCWlmICgoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEgpIHx8CgkgICAgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSCkpIHsKCgkgICAgY2hhciBsZW5bMjVdLCBhY3RMZW5bMjVdOwoKCSAgICAvKiBGSVhNRSwgVE9ETzogV2hhdCBpcyB0aGUgbWF4IGV4cGVjdGVkIHN0cmluZyBsZW5ndGggb2YgdGhlCgkgICAgKiB0aGlzIHZhbHVlPwoJICAgICovCgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgaGFzIGEgbGVuZ3RoIG9mICclcyc7ICIpOwoKCSAgICBzbnByaW50ZihsZW4sIDI0LCAiJWx1IiwgeG1sU2NoZW1hR2V0RmFjZXRWYWx1ZUFzVUxvbmcoZmFjZXQpKTsKCSAgICBzbnByaW50ZihhY3RMZW4sIDI0LCAiJWx1IiwgbGVuZ3RoKTsKCgkgICAgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBkaWZmZXJzIGZyb20gdGhlIGFsbG93ZWQgbGVuZ3RoIG9mICclcycuXG4iKTsgICAgIAoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBleGNlZWRzIHRoZSBhbGxvd2VkIG1heGltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEgpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgCgkJQkFEX0NBU1QgInRoaXMgdW5kZXJydW5zIHRoZSBhbGxvd2VkIG1pbmltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICAKCSAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJeG1sU2NoZW1hVkVyckV4dChjdHh0LCBub2RlLCBlcnJvciwKCQkgICAgKGNvbnN0IGNoYXIgKikgbXNnLAoJCSAgICB2YWx1ZSwgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4sCgkJICAgIE5VTEwsIE5VTEwpOwoJICAgIGVsc2UgCgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgIAoJCSAgICAoY29uc3QgY2hhciAqKSBtc2csCgkJICAgIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCQoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgYW4gZWxlbWVudCAiCgkJIm9mIHRoZSBzZXQgeyVzfS5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCXhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldCgmc3RyLCB0eXBlKSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFjY2VwdGVkICIKCQkiYnkgdGhlIHBhdHRlcm4gJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCWZhY2V0LT52YWx1ZSk7CSAgICAgICAKCX0gZWxzZSBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsJCQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgZmFjZXQtdmFsaWQuXG4iKTsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsKCX0gZWxzZSB7CSAgICAKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7Cgl4bWxTY2hlbWFWRXJyMyhjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKICAgIH0gICAgICAgIAogICAgRlJFRV9BTkRfTlVMTChzdHIpCiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgdHlwZSB1c2VkIGZvciB2YWxpZGF0aW9uCiAqIEBub2RlOiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgdmFsdWUKICogQHZhbHVlOiB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqCiAqIFJlcG9ydHMgYSBzaW1wbGUgdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKiBUT0RPOiBTaG91bGQgdGhpcyByZXBvcnQgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgYXMgd2VsbD8KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCQoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsICBOVUxMLCBub2RlLCAwKTsgICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwogICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXTogVGhlIHZhbHVlICclcycgaXMgbm90IHZhbGlkLlxuIik7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXTogVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIpOwoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIEZSRUVfQU5EX05VTEwoc3RyKQkKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBub2RlOiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgdmFsdWUKICogQHR5cGU6IHRoZSBjb21wbGV4IHR5cGUgdXNlZCBmb3IgdmFsaWRhdGlvbgogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhIGNvbXBsZXggdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwJCQkKCQkJY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgIE5VTEwsIG5vZGUsIDApOyAgICAKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLCBOVUxMLCAwKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXTogJXMuXG4iKTsgICAgCQogICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCAKCShjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UsIE5VTEwpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpCQogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgIHRoZSBvd25lcgogKiBAb3duZXJOYW1lOiB0aGUgbmFtZSBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiB0aGUgb3duZXIgYXMgYW4gZWxlbWVudCBub2RlCiAqIEBub2RlOiB0aGUgcGFyZW50IGVsZW1lbnQgbm9kZSBvZiB0aGUgbWlzc2luZyBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvZiB0aGUgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQkJIAoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgICAgIAogICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwgIiVzOiAlcy5cbiIsIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBlbHNlCQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLCAKCSAgICAiJXM6IFRoZSBhdHRyaWJ1dGUgJyVzJyBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsIAoJICAgIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZSk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmc6CiAqIEB0eXBlOiB0aGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgb2YgYSBzY2hlbWEgaXRlbS4KICovCnN0YXRpYyBjb25zdCBjaGFyICoKeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICByZXR1cm4oInNpbXBsZSB0eXBlIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgcmV0dXJuKCJjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCSAgICByZXR1cm4oImVsZW1lbnQgZGVjbGFyYXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICByZXR1cm4oImF0dHJpYnV0ZSBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkgICAgcmV0dXJuKCJtb2RlbCBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCSAgICByZXR1cm4oImF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9OT1RBVElPTjoKCSAgICByZXR1cm4oIm5vdGF0aW9uIGRlY2xhcmF0aW9uIik7CglkZWZhdWx0OgoJICAgIHJldHVybigiTm90IGEgc2NoZW1hIGNvbXBvbmVudCIpOwogICAgfQp9Ci8qKgogKiB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mICB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiB0aGUgb3duZXIgYXMgYW4gZWxlbWVudCBub2RlCiAqIEBuYW1lOiB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIGhvbGRpbmcgdGhlIFFOYW1lIAogKiBAcmVmTmFtZTogdGhlIHJlZmVyZW5jZWQgbG9jYWwgbmFtZQogKiBAcmVmVVJJOiB0aGUgcmVmZXJlbmNlZCBuYW1lc3BhY2UgVVJJCiAqIEBtZXNzYWdlOiBvcHRpb25hbCBtZXNzYWdlCiAqCiAqIFVzZWQgdG8gcmVwb3J0IFFOYW1lIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdCBmYWlsZWQgdG8gcmVzb2x2ZQogKiB0byBzY2hlbWEgY29tcG9uZW50cy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBSZXNDb21wQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQkJIAoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxOb2RlUHRyIG93bmVyRWxlbSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUsCgkJCSBjb25zdCB4bWxDaGFyICpyZWZOYW1lLAoJCQkgY29uc3QgeG1sQ2hhciAqcmVmVVJJLAoJCQkgeG1sU2NoZW1hVHlwZVR5cGUgcmVmVHlwZSwKCQkJIGNvbnN0IGNoYXIgKnJlZlR5cGVTdHIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJBID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZQoJZGVzID0gKm93bmVyRGVzOwogICAgaWYgKHJlZlR5cGVTdHIgPT0gTlVMTCkKCXJlZlR5cGVTdHIgPSB4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nKHJlZlR5cGUpOyAgICAKCXhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwgCgkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCSAgICAiJXMsIGF0dHJpYnV0ZSAnJXMnOiBUaGUgUU5hbWUgdmFsdWUgJXMgZG9lcyBub3QgcmVzb2x2ZSB0byBhKG4pICIKCSAgICAiJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUsIAoJICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIHJlZlVSSSwgcmVmTmFtZSksIAoJICAgIEJBRF9DQVNUIHJlZlR5cGVTdHIsIE5VTEwpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21BdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZSAKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZSBkdXJpbmcgdGhlIHBhcnNlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCQl4bWxDaGFyICoqb3duZXJEZXMsCgkJCXhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQl4bWxBdHRyUHRyIGF0dHIsCgkJCWNvbnN0IGNoYXIgKm1zZykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAgCiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlcywgYXR0cmlidXRlICclcyc6ICVzLlxuIiwgCglCQURfQ0FTVCBkZXMsIGF0dHItPm5hbWUsIChjb25zdCB4bWxDaGFyICopIG1zZywgTlVMTCwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgYXR0cmlidXRlJ3Mgb3duZXIKICogQG93bmVySXRlbTogdGhlIGF0dHJpYnV0ZSdzIG93bmVyIGl0ZW0KICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlIAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlIGR1cmluZyB0aGUgcGFyc2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sQXR0clB0ciBhdHRyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgIAogICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIAoJIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iLCBCQURfQ0FTVCBkZXMsIAoJeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyQSwgYXR0ci0+bnMsIGF0dHItPm5hbWUpKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJBKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBBcXVpcmVEZXM6CiAqIEBkZXM6IHRoZSBmaXJzdCBkZXNpZ25hdGlvbiAKICogQGl0ZW1EZXM6IHRoZSBzZWNvbmQgZGVzaWduYXRpb24KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbSAKICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICoKICogQ3JlYXRlcyBhIGRlc2lnbmF0aW9uIGZvciBhbiBpdGVtLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEFxdWlyZURlcyh4bWxDaGFyICoqZGVzLAoJCSAgICB4bWxDaGFyICoqaXRlbURlcywgCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSkKewogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoZGVzLCBOVUxMLCBpdGVtLCBpdGVtRWxlbSwgMSk7CiAgICBlbHNlIGlmICgqaXRlbURlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KGl0ZW1EZXMsIE5VTEwsIGl0ZW0sIGl0ZW1FbGVtLCAxKTsKCSpkZXMgPSAqaXRlbURlczsKICAgIH0gZWxzZSAKCSpkZXMgPSAqaXRlbURlczsgIAp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIyOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjM6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJICAgIHhtbENoYXIgKippdGVtRGVzLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjIsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICptc2cgPSBOVUxMOwoKICAgIHhtbFNjaGVtYVBBcXVpcmVEZXMoJmRlcywgaXRlbURlcywgaXRlbSwgaXRlbUVsZW0pOyAgIAogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlczogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIGlmICgoaXRlbUVsZW0gPT0gTlVMTCkgJiYgKGl0ZW0gIT0gTlVMTCkpCglpdGVtRWxlbSA9IGl0ZW0tPm5vZGU7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGl0ZW1FbGVtLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwgCgkoY29uc3QgY2hhciAqKSBtc2csIEJBRF9DQVNUIGRlcywgc3RyMSwgc3RyMiwgc3RyMywgTlVMTCk7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEN1c3RvbUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJICAgIHhtbENoYXIgKippdGVtRGVzLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEpCnsKICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwgZXJyb3IsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtLCBtZXNzYWdlLAoJc3RyMSwgTlVMTCwgTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQXR0clVzZUVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbTogdGhlIHNjaGVtYSB0eXBlCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSB0eXBlCiAqIEBhdHRyOiB0aGUgaW52YWxpZCBzY2hlbWEgYXR0cmlidXRlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIGF0dHJpYnV0ZSB1c2UgZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQXR0clVzZUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJICAgIHhtbENoYXIgKippdGVtRGVzLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0sCgkJICAgIGNvbnN0IHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEwsICptc2cgPSBOVUxMOwoKICAgIHhtbFNjaGVtYVBBcXVpcmVEZXMoJmRlcywgaXRlbURlcywgaXRlbSwgaXRlbUVsZW0pOwogICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyQSwgeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGF0dHIpLCAKCXhtbFNjaGVtYUdldEF0dHJOYW1lKGF0dHIpKTsKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXMsIGF0dHIuIHVzZSAlczogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIGlmICgoaXRlbUVsZW0gPT0gTlVMTCkgJiYgKGl0ZW0gIT0gTlVMTCkpCglpdGVtRWxlbSA9IGl0ZW0tPm5vZGU7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGl0ZW1FbGVtLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwgCgkoY29uc3QgY2hhciAqKSBtc2csIEJBRF9DQVNUIGRlcywgQkFEX0NBU1Qgc3RyQSwgc3RyMSwgTlVMTCwgTlVMTCk7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJBKTsKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgdHlwZQogKiBAaXRlbTogdGhlIHNjaGVtYSB0eXBlCiAqIEBiYXNlSXRlbTogdGhlIGJhc2UgdHlwZSBvZiB0eXBlCiAqIEBmYWNldDogdGhlIGlsbGVnYWwgZmFjZXQKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGZhY2V0IGZvciBhdG9taWMgc2ltcGxlIHR5cGVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0Vycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkJICB4bWxDaGFyICoqaXRlbURlcywKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlSXRlbSwKCQkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0clQgPSBOVUxMOwoKICAgIHhtbFNjaGVtYVBBcXVpcmVEZXMoJmRlcywgaXRlbURlcywgaXRlbSwgaXRlbS0+bm9kZSk7CiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGl0ZW0tPm5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJIiVzOiBUaGUgZmFjZXQgJyVzJyBpcyBub3QgYWxsb3dlZCBvbiB0eXBlcyBkZXJpdmVkIGZyb20gdGhlICIKCSJ0eXBlICVzLlxuIiwKCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyVCwgTlVMTCwgYmFzZUl0ZW0sIE5VTEwsIDEpLAoJTlVMTCwgTlVMTCk7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJUKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbSBpbnZvbHZlZAogKiBAZmFjZXQ6IHRoZSBpbGxlZ2FsIGZhY2V0CiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBmYWNldCBmb3IgPGxpc3Q+IGFuZCA8dW5pb24+LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkJICB4bWxDaGFyICoqaXRlbURlcywKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW0tPm5vZGUpOwogICAgeG1sU2NoZW1hUEVycihjdHh0LCBpdGVtLT5ub2RlLCBlcnJvciwgCgkiJXM6IFRoZSBmYWNldCAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwgCglCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwogICAgRlJFRV9BTkRfTlVMTChzdHJUKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGVsZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQgbm9kZQogKiBAYXR0cjogdGhlIGJhZCBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvZiB0aGUgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbEF0dHJQdHIgYXR0ciwJCQkgCgkJCSBjb25zdCBjaGFyICpuYW1lMSwKCQkJIGNvbnN0IGNoYXIgKm5hbWUyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CQogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgIAogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXM6IFRoZSBhdHRyaWJ1dGVzICclcycgYW5kICclcycgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS5cbiIsIAoJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lMSwgQkFEX0NBU1QgbmFtZTIsIE5VTEwsIE5VTEwpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKfQoKLyoqCiAqIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQHR5cGU6IHRoZSB0eXBlIHNwZWNpZmllcgogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3QgaWYgZXhpc3RlbnQgCiAqIEBub2RlOiB0aGUgdmFsaWRhdGVkIG5vZGUKICogQHZhbHVlOiB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqCiAqIFJlcG9ydHMgYSBzaW1wbGUgdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKiBUT0RPOiBTaG91bGQgdGhpcyByZXBvcnQgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgYXMgd2VsbD8KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJeG1sQ2hhciAqKm93bmVyRGVzLAoJCQl4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJeG1sTm9kZVB0ciBub2RlLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCWNvbnN0IGNoYXIgKnR5cGVEZXMsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQljb25zdCBjaGFyICptZXNzYWdlLAoJCQljb25zdCB4bWxDaGFyICpzdHIxLAoJCQljb25zdCB4bWxDaGFyICpzdHIyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEwsICpzdHJUID0gTlVMTDsgICAgCiAgICAKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hUFJlcXVlc3RJdGVtRGVzKCZkZXMsIG93bmVySXRlbSwgbm9kZSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUFJlcXVlc3RJdGVtRGVzKG93bmVyRGVzLCBvd25lckl0ZW0sIG5vZGUpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgIAogICAgaWYgKHR5cGUgIT0gTlVMTCkKCXR5cGVEZXMgPSAoY29uc3QgY2hhciAqKSB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJULCBOVUxMLCB0eXBlLCBOVUxMLCAxKTsKICAgIGlmIChtZXNzYWdlID09IE5VTEwpIHsKCS8qCgkqIFVzZSBkZWZhdWx0IG1lc3NhZ2VzLgoJKi8KCWlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewoJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkJIiVzLCBhdHRyaWJ1dGUgJyVzJyBbJXNdOiBUaGUgdmFsdWUgJyVzJyBpcyBub3QgIgoJCSJ2YWxpZC5cbiIsIAoJCUJBRF9DQVNUIGRlcywgeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyQSwgbm9kZS0+bnMsIAoJCW5vZGUtPm5hbWUpLCBCQURfQ0FTVCB0eXBlRGVzLCB2YWx1ZSwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIAoJCSIlcyBbJXNdOiBUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkLlxuIiwKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHR5cGVEZXMpOwoJfQogICAgfSBlbHNlIHsKCXhtbENoYXIgKm1zZzsKCgltc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzIik7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiwgYXR0cmlidXRlICclcyciKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyVzXTogIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKCWlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewoJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkJKGNvbnN0IGNoYXIgKikgbXNnLCAKCQlCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIAoJCW5vZGUtPm5zLCBub2RlLT5uYW1lKSwgQkFEX0NBU1QgdHlwZURlcywgc3RyMSwgc3RyMik7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgbm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkJKGNvbnN0IGNoYXIgKikgbXNnLCAKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHR5cGVEZXMsIHN0cjEsIHN0cjIsIE5VTEwpOwoJfQoJeG1sRnJlZShtc2cpOwogICAgfQogICAgLyogQ2xlYW51cC4gKi8KICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKICAgIEZSRUVfQU5EX05VTEwoc3RyVCkKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ29udGVudEVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb253ZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBpdGVtIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVyRWxlbTogdGhlIG5vZGUgb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAY2hpbGQ6IHRoZSBpbnZhbGlkIGNoaWxkIG5vZGUKICogQG1lc3NhZ2U6IHRoZSBvcHRpb25hbCBlcnJvciBtZXNzYWdlCiAqIEBjb250ZW50OiB0aGUgb3B0aW9uYWwgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGNvcnJlY3QgY29udGVudAogKgogKiBSZXBvcnRzIGFuIGVycm9yIGNvbmNlcm5pbmcgdGhlIGNvbnRlbnQgb2YgYSBzY2hlbWEgZWxlbWVudC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDb250ZW50RXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJICAgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkgICAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAkJICAgICAKCQkgICAgIHhtbE5vZGVQdHIgY2hpbGQsCgkJICAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICAgY29uc3QgY2hhciAqY29udGVudCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKICAgIAogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgCiAgICBpZiAobWVzc2FnZSAhPSBOVUxMKQoJeG1sU2NoZW1hUEVycjIoY3R4dCwgb3duZXJFbGVtLCBjaGlsZCwgZXJyb3IsIAoJICAgICIlczogJXMuXG4iLCAKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZSB7CglpZiAoY29udGVudCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgb3duZXJFbGVtLCBjaGlsZCwgZXJyb3IsIAoJCSIlczogVGhlIGNvbnRlbnQgaXMgbm90IHZhbGlkLiBFeHBlY3RlZCBpcyAlcy5cbiIsIAoJCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgY29udGVudCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLCAKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIsIAoJCUJBRF9DQVNUIGRlcywgTlVMTCk7Cgl9CiAgICB9CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQp9ICAgCgovKioKICogeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbEF0dHJQdHIgYXR0cikKewogICAgeG1sQ2hhciAqc3RyRSA9IE5VTEwsICpzdHJBID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCQoJZXJyb3IsCgkvKiBYTUxfU0NIRU1BU19FUlJfQVRUUlVOS05PV04sICovCgkiJXM6IFRoZSBhdHRyaWJ1dGUgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJFLCBOVUxMLCBOVUxMLCBhdHRyLT5wYXJlbnQsIDApLAoJeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyQSwgYXR0ci0+bnMsIGF0dHItPm5hbWUpKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyRSkKICAgIEZSRUVfQU5EX05VTEwoc3RyQSkKfQoKLyoqCiAqIHhtbFNjaGVtYVZDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBub2RlOiB0aGUgdmFsaWRhdGVkIG5vZGUKICogQHR5cGU6IHRoZSBzY2hlbWEgdHlwZSBvZiB0aGUgdmFsaWRhdGVkIG5vZGUKICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiB0aGUgb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYSB2YWxpZGF0aW9uIGVycm9yLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkN1c3RvbUVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAgICAKCQkgICAgeG1sTm9kZVB0ciBub2RlLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEwsICpzdHIgPSBOVUxMOwogICAgCiAgICBpZiAobm9kZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWQ3VzdG9tRXJyLCBubyBub2RlICIKCSAgICAiZ2l2ZW4uXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybjsKICAgIH0KICAgIC8qIFRPRE86IEFyZSB0aGUgSFRNTCBhbmQgRE9DQiBkb2Mgbm9kZXMgZXhwZWN0ZWQgaGVyZT8gKi8KICAgIGlmIChub2RlLT50eXBlICE9IFhNTF9ET0NVTUVOVF9OT0RFKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIE5VTEwsIG5vZGUsIDApOwoJaWYgKHR5cGUgIT0gTlVMTCkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdIik7Cgl9Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiOiAiKTsKICAgIH0gZWxzZQoJbXNnID0geG1sU3RyZHVwKChjb25zdCB4bWxDaGFyICopICIiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOyAgIAogICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQogICAgRlJFRV9BTkRfTlVMTChzdHIpCn0KCi8qKgogKiB4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmc6CiAqIEBwYzogdGhlIHR5cGUgb2YgcHJvY2Vzc0NvbnRlbnRzCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUgb2YgCiAqIHByb2Nlc3NDb250ZW50cy4KICovCnN0YXRpYyBjb25zdCBjaGFyICoKeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKGludCBwYykKewogICAgc3dpdGNoIChwYykgewoJY2FzZSBYTUxfU0NIRU1BU19BTllfU0tJUDoKCSAgICByZXR1cm4gKCJza2lwIik7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9MQVg6CgkgICAgcmV0dXJuICgibGF4Iik7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1Q6CgkgICAgcmV0dXJuICgic3RyaWN0Iik7CglkZWZhdWx0OgoJICAgIHJldHVybiAoImludmFsaWQgcHJvY2VzcyBjb250ZW50cyIpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hVldpbGRjYXJkRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB3aWxkOiB0aGUgd2lsZGNhcmQgdXNlZAogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiB2YWxpZGF0aW9uLWJ5LXdpbGRjYXJkIGVycm9yLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVldpbGRjYXJkRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQkJICAgIAoJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGQsCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICptc2cgPSBOVUxMOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgTlVMTCwgbm9kZSwgMCk7CiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzLCBbIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCB4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmcod2lsZC0+cHJvY2Vzc0NvbnRlbnRzKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFdDXTogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgQkFEX0NBU1QgZGVzLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZNaXNzaW5nQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgcGFyZW50IGVsZW1lbnQgbm9kZSBvZiB0aGUgbWlzc2luZyBhdHRyaWJ1dGUgbm9kZQogKiBAdHlwZTogdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvZiB0aGUgYXR0cmlidXRlIG5vZGUKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZNaXNzaW5nQXR0ckVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJIHhtbE5vZGVQdHIgZWxlbSwKCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciB0eXBlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqdXJpOwogICAgeG1sQ2hhciAqc3RyRSA9IE5VTEwsICpzdHJBID0gTlVMTDsKCiAgICBpZiAodHlwZS0+cmVmICE9IE5VTEwpIHsJCQkJCgluYW1lID0gdHlwZS0+cmVmOwoJdXJpID0gdHlwZS0+cmVmTnM7CiAgICB9IGVsc2UgewoJbmFtZSA9IHR5cGUtPm5hbWU7Cgl1cmkgPSB0eXBlLT50YXJnZXROYW1lc3BhY2U7CiAgICB9CQkJICAgIAogICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCAKCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfNCwKCS8qIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLCAqLwoJIiVzOiBUaGUgYXR0cmlidXRlICVzIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nLlxuIiwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckUsIE5VTEwsIE5VTEwsIGVsZW0sIDApLAoJeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyQSwgdXJpLCBuYW1lKSk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckUpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlBbGxvY2F0aW9uIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFOZXdTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEFsbG9jYXRlIGEgbmV3IFNjaGVtYSBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hUHRyCnhtbFNjaGVtYU5ld1NjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWEpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgc2NoZW1hIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWEpKTsKICAgIHJldC0+ZGljdCA9IGN0eHQtPmRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKHJldC0+ZGljdCk7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3U2NoZW1hOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBBbGxvY2F0ZSBhIG5ldyBTY2hlbWEgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUFzc2VtYmxlUHRyCnhtbFNjaGVtYU5ld0Fzc2VtYmxlKHZvaWQpCnsKICAgIHhtbFNjaGVtYUFzc2VtYmxlUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXNzZW1ibGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXNzZW1ibGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIC8qIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYXNzZW1ibGUgaW5mbyIsIE5VTEwpOyAqLwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXNzZW1ibGUpKTsKICAgIHJldC0+aXRlbXMgPSBOVUxMOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RmFjZXQ6CiAqCiAqIEFsbG9jYXRlIGEgbmV3IEZhY2V0IHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnhtbFNjaGVtYUZhY2V0UHRyCnhtbFNjaGVtYU5ld0ZhY2V0KHZvaWQpCnsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hRmFjZXRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hRmFjZXQpKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdBbm5vdDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIG5vZGUKICoKICogQWxsb2NhdGUgYSBuZXcgYW5ub3RhdGlvbiBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQW5ub3RQdHIKeG1sU2NoZW1hTmV3QW5ub3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUFubm90UHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hQW5ub3RQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQW5ub3QpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYW5ub3RhdGlvbiIsIG5vZGUpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQW5ub3QpKTsKICAgIHJldC0+Y29udGVudCA9IG5vZGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlQW5ub3Q6CiAqIEBhbm5vdDogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBhbm5vdGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUFubm90KHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICBpZiAoYW5ub3QgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKGFubm90KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbXBvcnQ6CiAqIEBpbXBvcnQ6ICBhIHNjaGVtYSBpbXBvcnQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYW4gaW1wb3J0IHN0cnVjdHVyZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUltcG9ydCh4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0KQp7CiAgICBpZiAoaW1wb3J0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbFNjaGVtYUZyZWUoaW1wb3J0LT5zY2hlbWEpOwogICAgeG1sRnJlZURvYyhpbXBvcnQtPmRvYyk7CiAgICB4bWxGcmVlKGltcG9ydCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZToKICogQGluY2x1ZGU6ICBhIHNjaGVtYSBpbmNsdWRlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZSh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGUpCnsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbEZyZWVEb2MoaW5jbHVkZS0+ZG9jKTsKICAgIHhtbEZyZWUoaW5jbHVkZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3Q6CiAqIEBpbmNsdWRlczogIGEgc2NoZW1hIGluY2x1ZGUgbGlzdAogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoeG1sU2NoZW1hSW5jbHVkZVB0ciBpbmNsdWRlcykKewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwoKICAgIHdoaWxlIChpbmNsdWRlcyAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IGluY2x1ZGVzLT5uZXh0OwoJeG1sU2NoZW1hRnJlZUluY2x1ZGUoaW5jbHVkZXMpOwoJaW5jbHVkZXMgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZU5vdGF0aW9uOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgbm90YXRpb24gc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgTm90YXRpb24gc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU5vdGF0aW9uKHhtbFNjaGVtYU5vdGF0aW9uUHRyIG5vdGEpCnsKICAgIGlmIChub3RhID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShub3RhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpIAoJeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIHhtbEZyZWUoYXR0cik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldDoKICogc2V0OiAgYSBzY2hlbWEgd2lsZGNhcmQgbmFtZXNwYWNlCiAqCiAqIERlYWxsb2NhdGVzIGEgbGlzdCBvZiB3aWxkY2FyZCBjb25zdHJhaW50IHN0cnVjdHVyZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldCh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHNldCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuZXh0OwogICAgCiAgICB3aGlsZSAoc2V0ICE9IE5VTEwpIHsKCW5leHQgPSBzZXQtPm5leHQ7Cgl4bWxGcmVlKHNldCk7CglzZXQgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkOgogKiBAd2lsZGNhcmQ6ICBhIHdpbGRjYXJkIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlcyBhIHdpbGRjYXJkIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjYXJkKQp7CiAgICBpZiAod2lsZGNhcmQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAod2lsZGNhcmQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHdpbGRjYXJkLT5hbm5vdCk7CiAgICBpZiAod2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpIAoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQod2lsZGNhcmQtPm5zU2V0KTsgICAgCiAgICBpZiAod2lsZGNhcmQtPm5lZ05zU2V0ICE9IE5VTEwpIAoJeG1sRnJlZSh3aWxkY2FyZC0+bmVnTnNTZXQpOyAgICAKICAgIHhtbEZyZWUod2lsZGNhcmQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgYXR0cmlidXRlIGdyb3VwIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0cikKewogICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ci0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgaWYgKChhdHRyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpICYmIAoJKGF0dHItPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkKGF0dHItPmF0dHJpYnV0ZVdpbGRjYXJkKTsKCiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3Q6CiAqIEBhdHRyVXNlOiAgYW4gYXR0cmlidXRlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2Ygc2NoZW1hIGF0dHJpYnV0ZSB1c2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGF0dHJVc2UgIT0gTlVMTCkgewoJbmV4dCA9IGF0dHJVc2UtPm5leHQ7Cgl4bWxGcmVlKGF0dHJVc2UpOwoJYXR0clVzZSA9IG5leHQ7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdDoKICogQGFsaW5rOiBhIHR5cGUgbGluawogKgogKiBEZWFsbG9jYXRlIGEgbGlzdCBvZiB0eXBlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3QoeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaykKewogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbmV4dDsKCiAgICB3aGlsZSAobGluayAhPSBOVUxMKSB7CgluZXh0ID0gbGluay0+bmV4dDsKCXhtbEZyZWUobGluayk7CglsaW5rID0gbmV4dDsKICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlRWxlbWVudDoKICogQHNjaGVtYTogIGEgc2NoZW1hIGVsZW1lbnQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRWxlbWVudCBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlRWxlbWVudCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0pCnsKICAgIGlmIChlbGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGVsZW0tPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGVsZW0tPmFubm90KTsKICAgIGlmIChlbGVtLT5jb250TW9kZWwgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGVsZW0tPmNvbnRNb2RlbCk7CiAgICB4bWxGcmVlKGVsZW0pOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUZhY2V0OgogKiBAZmFjZXQ6ICBhIHNjaGVtYSBmYWNldCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBGYWNldCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVGYWNldCh4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgaWYgKGZhY2V0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGZhY2V0LT52YWwgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoZmFjZXQtPnZhbCk7CiAgICBpZiAoZmFjZXQtPnJlZ2V4cCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZmFjZXQtPnJlZ2V4cCk7CiAgICBpZiAoZmFjZXQtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGZhY2V0LT5hbm5vdCk7CiAgICB4bWxGcmVlKGZhY2V0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlOgogKiBAdHlwZTogIGEgc2NoZW1hIHR5cGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgVHlwZSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAodHlwZS0+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+bnMtPmhyZWYsIEJBRF9DQVNUIHVyaSkpCgkgICAgcmV0dXJuKHByb3ApOwoJcHJvcCA9IHByb3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldE5vZGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxDaGFyICp2YWw7CiAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgogICAgdmFsID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOyAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByb3A6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBub2RlCiAqIEBuYW1lOiB0aGUgcHJvcGVydHkgbmFtZQogKiAKICogUmVhZCBhIGF0dHJpYnV0ZSB2YWx1ZSBhbmQgaW50ZXJuYWxpemUgdGhlIHN0cmluZwogKgogKiBSZXR1cm5zIHRoZSBzdHJpbmcgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0UHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lKQp7CiAgICB4bWxDaGFyICp2YWw7CiAgICBjb25zdCB4bWxDaGFyICpyZXQ7CgogICAgdmFsID0geG1sR2V0UHJvcChub2RlLCBCQURfQ0FTVCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwogICAgeG1sRnJlZSh2YWwpOwogICAgcmV0dXJuKHJldCk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFHZXROYW1lc3BhY2U6CiAqIEBjdHh0OiB0aGUgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYXMgY29udGFpbmluZyB0aGUgZGVjbGFyYXRpb24KICogQG5vZGU6IHRoZSBub2RlCiAqIEBxbmFtZTogdGhlIFFOYW1lIHRvIGFuYWx5emUKICogCiAqIEZpbmQgdGhlIG5hbWVzcGFjZSBuYW1lIGZvciB0aGUgZ2l2ZW4gZGVjbGFyYXRpb24uCiAqCiAqIFJldHVybnMgdGhlIGxvY2FsIG5hbWUgZm9yIHRoYXQgZGVjbGFyYXRpb24sIGFzIHdlbGwgYXMgdGhlIG5hbWVzcGFjZSBuYW1lCiAqIE5PVEU6IFRoaXMgZnVuY3Rpb24gaXMgbm8gbG9uZ2VyIHVzZWQgKEJ1Y2hjaWssIE1heSAnMDQpIAogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROYW1lc3BhY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IHhtbENoYXIgKnFuYW1lLAoJICAgICBjb25zdCB4bWxDaGFyICoqbmFtZXNwYWNlKSB7CiAgICBpbnQgbGVuOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnByZWZpeCwgKmRlZiA9IE5VTEw7CiAgICB4bWxOc1B0ciBuczsKCiAgICAqbmFtZXNwYWNlID0gTlVMTDsKICAgIAogICAgLyogVE9ETzogVGhlIGZvbGxvd2luZyBzZWVtcyB0byBiZSBub3QgY29ycmVjdCBoZXJlOgogICAgICogMS4gVGhlIG5hbWUgb2YgYSBkZWNsYXJhdGlvbiBpcyBhIE5DTmFtZSwgbm90IGEgUU5hbWUuCiAgICAgKiAyLiBUaGUgYXR0cmlidXRlICJ0YXJnZXROYW1lc3BhY2UiIGlzIGFsbG93ZWQgZm9yIHRoZQogICAgICogICAgPHNjaGVtYT4gRWxlbWVudCBJbmZvcm1hdGlvbiBJdGVtIG9ubHkuCiAgICAgKiAzLiBPbmUgY2Fubm90IGV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlLCBieSB0aGUgdHlwZQogICAgICogICAgb2YgZGVjbGFyYXRpb24sIHNpbmNlIGl0IGlzIGRlcGVuZGFudCBvbiB0aGUgeHh4Rm9ybURlZmF1bHQKICAgICAqICAgIG9mIDxzY2hlbWE+IGFuZCB0aGUgZm9ybSBhdHRyaWJ1dGUgb2YgYW4gPGVsZW1lbnQ+IG9yIDxhdHRyaWJ1dGU+LgogICAgICovCiAgIAogICAgaWYgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJlbGVtZW50IikgfHwKICAgICAgICB4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiYXR0cmlidXRlIikgfHwKCXhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJzaW1wbGVUeXBlIikgfHwKCXhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJjb21wbGV4VHlwZSIpKSB7CglkZWYgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIH0KCgogICAgcW5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHFuYW1lLCAtMSk7IC8qIGludGVybiB0aGUgc3RyaW5nICovCiAgICBuYW1lID0geG1sU3BsaXRRTmFtZTMocW5hbWUsICZsZW4pOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIGlmIChkZWYgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiZWxlbWVudCIpKSB7CgkJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkKCQkgICAgKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImF0dHJpYnV0ZSIpKSB7CgkJaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikKCQkgICAgKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0gZWxzZSBpZiAoKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJzaW1wbGVUeXBlIikpIHx8CgkgICAgICAgICAgICAgICAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImNvbXBsZXhUeXBlIikpKSB7CgkJKm5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgKm5hbWVzcGFjZSA9IGRlZjsKCX0KCXJldHVybihxbmFtZSk7CiAgICB9CgogICAgbmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBxbmFtZSwgbGVuKTsKICAgIGlmIChkZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfREVGX0FORF9QUkVGSVgsCiAgICAgICAgICAgICAgICAgICAgICAiJXM6IHByZXNlbmNlIG9mIGJvdGggcHJlZml4ICVzIGFuZCB0YXJnZXROYW1lc3BhY2VcbiIsCiAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBwcmVmaXgpOwogICAgfQogICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CiAgICBpZiAobnMgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKICAgICAgICAgICAgICAgICAgICAgICIlczogVGhlIFFOYW1lIHByZWZpeCAlcyBpcyB1bmRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBwcmVmaXgpOwoJcmV0dXJuKG5hbWUpOwogICAgfQogICAgKm5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIHJldHVybihuYW1lKTsKfQojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFHZXRFbGVtOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKiBAbnM6ICB0aGUgZWxlbWVudCBuYW1lc3BhY2UKICoKICogTG9va3VwIGEgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUdldEVsZW0oeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICAKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfSBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICAqIFRoaXMgb25lIHdhcyByZW1vdmVkLCBzaW5jZSB0b3AgbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbnMgaGF2ZQogICAgICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugc3BlY2lmaWVkIGluIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgPHNjaGVtYT4KICAgICAqIGluZm9ybWF0aW9uIGVsZW1lbnQsIGV2ZW4gaWYgZWxlbWVudEZvcm1EZWZhdWx0IGlzICJ1bnF1YWxpZmllZCIuCiAgICAgKi8KICAgIAogICAgLyogZWxzZSBpZiAoKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkgewogICAgICAgIGlmICh4bWxTdHJFcXVhbChuYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBOVUxMKTsKCWVsc2UKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKChsZXZlbCA9PSAwKSB8fCAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUwpKSkgewogICAgICAgICAgICByZXR1cm4gKHJldCk7Cgl9CiAgICAqLwogICAgCiAgICAvKgogICAgKiBSZW1vdmVkIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQogICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRFbGVtKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UsIGxldmVsICsgMSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFR5cGU6CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcyBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIHR5cGUgbmFtZQogKiBAbnM6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogTG9va3VwIGEgdHlwZSBpbiB0aGUgc2NoZW1hcyBvciB0aGUgcHJlZGVmaW5lZCB0eXBlcwogKgogKiBSZXR1cm5zIHRoZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0VHlwZSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldDsKCiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQogICAgICAgICAgICByZXR1cm4gKHJldCk7CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFHZXRQcmVkZWZpbmVkVHlwZShuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKHJldCAhPSBOVUxMKQoJcmV0dXJuIChyZXQpOwogICAgLyoKICAgICogUmVtb3ZlZCwgc2luY2UgdGhlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBncmFmdGVkIG9uIHRoZQogICAgKiBtYWluIHNjaGVtYSBvbmx5LiAgICAKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0VHlwZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBhdHRyaWJ1dGUgCiAqCiAqIExvb2t1cCBhIGFuIGF0dHJpYnV0ZSBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0ckRlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSkKCXJldHVybiAocmV0KTsgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCwgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEgCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwIAogKgogKiBMb29rdXAgYSBhbiBhdHRyaWJ1dGUgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+YXR0cmdycERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpKQoJcmV0dXJuIChyZXQpOyAgCiAgICBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsJCiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgYXR0cmlidXRlIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEdyb3VwOgogKiBAc2NoZW1hOiAgdGhlIGNvbnRleHQgb2YgdGhlIHNjaGVtYSAKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGdyb3VwIAogKgogKiBMb29rdXAgYSBncm91cCBpbiB0aGUgc2NoZW1hIG9yIGltcG9ydGVkIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldEdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIAogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5ncm91cERlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCXJldHVybiAocmV0KTsgIAogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKQoJICAgIHJldHVybiAocmV0KTsKCWVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGdyb3VwICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBJU19CTEFOS19OT0RFKG4pCQkJCQkJXAogICAgKCgobiktPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgJiYgKHhtbFNjaGVtYUlzQmxhbmsoKG4pLT5jb250ZW50KSkpCgovKioKICogeG1sU2NoZW1hSXNCbGFuazoKICogQHN0cjogIGEgc3RyaW5nCiAqCiAqIENoZWNrIGlmIGEgc3RyaW5nIGlzIGlnbm9yYWJsZQogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHN0cmluZyBpcyBOVUxMIG9yIG1hZGUgb2YgYmxhbmtzIGNoYXJzLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc0JsYW5rKHhtbENoYXIgKiBzdHIpCnsKICAgIGlmIChzdHIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKDEpOwogICAgd2hpbGUgKCpzdHIgIT0gMCkgewogICAgICAgIGlmICghKElTX0JMQU5LX0NIKCpzdHIpKSkKICAgICAgICAgICAgcmV0dXJuICgwKTsKICAgICAgICBzdHIrKzsKICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBpdGVtOiAgdGhlIGl0ZW0KICoKICogQWRkIGEgaXRlbSB0byB0aGUgc2NoZW1hJ3MgbGlzdCBvZiBjdXJyZW50IGl0ZW1zLgogKiBUaGlzIGlzIHVzZWQgaWYgdGhlIHNjaGVtYSB3YXMgYWxyZWFkeSBjb25zdHJ1Y3RlZCBhbmQKICogbmV3IHNjaGVtYXRhIG5lZWQgdG8gYmUgYWRkZWQgdG8gaXQuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNlZWRzIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0pCnsKICAgIHN0YXRpYyBpbnQgZ3Jvd1NpemUgPSAxMDA7CiAgICB4bWxTY2hlbWFBc3NlbWJsZVB0ciBhc3M7CgogICAgYXNzID0gY3R4dC0+YXNzZW1ibGU7CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPCAwKSB7CgkvKiBJZiBkaXNhYmxlZC4gKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAoYXNzLT5zaXplSXRlbXMgPD0gMCkgewoJYXNzLT5pdGVtcyA9IHhtbE1hbGxvYyhncm93U2l6ZSAqIHNpemVvZih4bWxTY2hlbWFUeXBlUHRyKSk7CglpZiAoYXNzLT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LAoJCSJhbGxvY2F0aW5nIG5ldyBpdGVtIGJ1ZmZlciIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQkKCWFzcy0+c2l6ZUl0ZW1zID0gZ3Jvd1NpemU7CiAgICB9IGVsc2UgaWYgKGFzcy0+c2l6ZUl0ZW1zIDw9IGFzcy0+bmJJdGVtcykgewoJYXNzLT5zaXplSXRlbXMgKj0gMjsKCWFzcy0+aXRlbXMgPSAoeG1sTnNQdHIgKikgeG1sUmVhbGxvYyhhc3MtPml0ZW1zLCAKCSAgICBhc3MtPnNpemVJdGVtcyAqIHNpemVvZih4bWxTY2hlbWFUeXBlUHRyKSk7CglpZiAoYXNzLT5pdGVtcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LAoJCSJncm93aW5nIGl0ZW0gYnVmZmVyIiwgTlVMTCk7CgkgICAgYXNzLT5zaXplSXRlbXMgPSAwOwoJICAgIHJldHVybiAoLTEpOwoJfQkKICAgIH0KICAgICgoeG1sU2NoZW1hVHlwZVB0ciAqKSBhc3MtPml0ZW1zKVthc3MtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBpdGVtOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZE5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBhbm5vdGF0aW9uIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYUFkZE5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPm5vdGFEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGQgYW5ub3RhdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPm5vdGFEZWNsLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJLyoKCSogVE9ETzogVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBzaW5jZSBhIHVuaXF1ZSBuYW1lIHdpbGwgYmUgY29tcHV0ZWQuCgkqIElmIGl0IGZhaWxzLCB0aGVuIGFuIG90aGVyIGludGVybmFsIGVycm9yIG11c3QgaGF2ZSBvY2N1cmVkLgoJKi8KCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9SRURFRklORURfTk9UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAiQW5ub3RhdGlvbiBkZWNsYXJhdGlvbiAnJXMnIGlzIGFscmVhZHkgZGVjbGFyZWQuXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hQWRkQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UsCgkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgYXR0cmlidXRlICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT5hdHRyRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+YXR0ckRlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnRhcmdldE5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZXNwYWNlLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkzKHNjaGVtYS0+YXR0ckRlY2wsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRURFRklORURfQVRUUiwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJBIGdsb2JhbCBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIG5hbWUpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOyAKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIEdyb3VwIGRlY2xhcmF0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAoJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmF0dHJncnBEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0KICAgICAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpCiAgICAgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhdHRyaWJ1dGUgZ3JvdXAiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyZ3JwRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9BVFRSR1JPVVAsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiQSBnbG9iYWwgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIG5hbWUpOwogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgdHlwZSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgdHlwZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgRWxlbWVudCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYUFkZEVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBlbGVtZW50ICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+ZWxlbURlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGVsZW1lbnQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnQpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWVzcGFjZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJaWYgKHRvcExldmVsKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1JFREVGSU5FRF9FTEVNRU5ULAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkEgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgIgoJCSJhbHJlYWR5IGV4aXN0IiwgbmFtZSk7CiAgICAgICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgY2hhciBidWZbMzBdOyAKCgkgICAgc25wcmludGYoYnVmLCAyOSwgIiNlQ29udCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgKHhtbENoYXIgKikgYnVmLAoJCW5hbWVzcGFjZSwgcmV0KTsKCSAgICBpZiAodmFsICE9IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEVsZW1lbnQsICIKCQkgICAgImEgZHVibGljYXRlIGVsZW1lbnQgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCQkgICAgImNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgaGFzaC4iLCBuYW1lKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9Cgl9CiAgICAgICAgCiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkJCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgaXRlbQogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUFkZFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgdHlwZSAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPnR5cGVEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVR5cGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyB0eXBlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+cmVkZWYgPSBOVUxMOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsJCiAgICAgICAgaWYgKGN0eHQtPmluY2x1ZGVzID09IDApIHsJICAgIAoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfVFlQRSwKCQlOVUxMLCBOVUxMLCBub2RlLCAKCQkiQSBnbG9iYWwgdHlwZSBkZWZpbml0aW9uIHdpdGggdGhlIG5hbWUgJyVzJyBkb2VzIGFscmVhZHkgZXhpc3QiLCBuYW1lKTsgICAgICAgICAgICAJICAgIAoJICAgIHhtbEZyZWUocmV0KTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIHByZXY7CgoJICAgIHByZXYgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPnR5cGVEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwoJICAgIGlmIChwcmV2ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgIFhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkVHlwZSwgb24gdHlwZSAiCgkJICAgICInJXMnLlxuIiwKCQkgICAgbmFtZSwgTlVMTCk7CgkJeG1sRnJlZShyZXQpOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIHJldC0+cmVkZWYgPSBwcmV2LT5yZWRlZjsKCSAgICBwcmV2LT5yZWRlZiA9IHJldDsKCX0KICAgIH0KICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKICAgIHJldC0+YXR0cmlidXRlVXNlcyA9IE5VTEw7CiAgICByZXQtPmF0dHJpYnV0ZVdpbGRjYXJkID0gTlVMTDsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCxyZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGdyb3VwIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgR3JvdXAgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFBZGRHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmdyb3VwRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+Z3JvdXBEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hVHlwZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGRpbmcgZ3JvdXAiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0KICAgICAgICB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+Z3JvdXBEZWNsLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9SRURFRklORURfR1JPVVAsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiQSBnbG9iYWwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5IGV4aXN0IiwgbmFtZSk7ICAgIAogICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpCQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1dpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgd2lsZGNhcmQgbmFtZXNwYWNlIGNvbnN0cmFpbnQuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyCnhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciByZXQ7CgogICAgcmV0ID0gKHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIpIAoJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZE5zKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImNyZWF0aW5nIHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50IiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOyAgICAKICAgIH0KICAgIHJldC0+dmFsdWUgPSBOVUxMOwogICAgcmV0LT5uZXh0ID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZFdpbGRjYXJkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBBZGRzIGEgd2lsZGNhcmQuIEl0IGNvcnJlc3BvbmRzIHRvIGEgCiAqIHhzZDphbnlBdHRyaWJ1dGUgYW5kIGlzIHVzZWQgYXMgc3RvcmFnZSBmb3IgbmFtZXNwYWNlIAogKiBjb25zdHJhaW50cyBvbiBhIHhzZDphbnkuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFBZGRXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIHdpbGRjYXJkIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZCkpOwogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqCQlVdGlsaXRpZXMgZm9yIHBhcnNpbmcJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbEdldFFOYW1lUHJvcDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHJlc3VsdCBuYW1lc3BhY2UgaWYgYW55CiAqCiAqIEV4dHJhY3QgYSBRTmFtZSBBdHRyaWJ1dGUgdmFsdWUKICoKICogUmV0dXJucyB0aGUgTkNOYW1lIG9yIE5VTEwgaWYgbm90IGZvdW5kLCBhbmQgYWxzbyB1cGRhdGUgQG5hbWVzcGFjZQogKiAgICB3aXRoIHRoZSBuYW1lc3BhY2UgVVJJCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbEdldFFOYW1lUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICB4bWxOc1B0ciBuczsKICAgIGNvbnN0IHhtbENoYXIgKnJldCwgKnByZWZpeDsKICAgIGludCBsZW47CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChOVUxMKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIC8qCiAgICAqIFRPRE86IElzIHRoZSBlbXB0eSB2YWx1ZSB2YWxpZCBmb3IgUU5hbWVzPwogICAgKi8KICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmICghc3RyY2hyKChjaGFyICopIHZhbCwgJzonKSkgewoJbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIDApOwoJaWYgKG5zKSB7CgkgICAgKm5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKCSAgICByZXR1cm4gKHZhbCk7Cgl9CiAgICB9CiAgICByZXQgPSB4bWxTcGxpdFFOYW1lMyh2YWwsICZsZW4pOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuICh2YWwpOwogICAgfQogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCByZXQsIC0xKTsKICAgIHByZWZpeCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCBsZW4pOwoKICAgIG5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBwcmVmaXgpOwogICAgaWYgKG5zID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCBYTUxfU0NIRU1BUF9QUkVGSVhfVU5ERUZJTkVELCAKCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCBOVUxMLCB2YWwsCgkgICAgIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSAiCgkgICAgImRlY2xhcmF0aW9uIGluIHNjb3BlIiwgdmFsLCBOVUxMKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKm5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lVmFsdWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgcGFyZW50IGFzIGEgc2NoZW1hIG9iamVjdAogKiBAdmFsdWU6ICB0aGUgUU5hbWUgdmFsdWUgCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIHRoZSBsb2NhbCBuYW1lIGFuZCB0aGUgVVJJIG9mIGEgUU5hbWUgdmFsdWUgYW5kIHZhbGlkYXRlcyBpdC4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQKICogc2hvdWxkIHJlc29sdmUgdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqCiAqIFJldHVybnMgMCwgaW4gY2FzZSB0aGUgUU5hbWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBpZiBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKipwcmVmaXgsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsKQp7CiAgICBjb25zdCB4bWxDaGFyICpwcmVmOwogICAgeG1sTnNQdHIgbnM7CiAgICBpbnQgbGVuLCByZXQ7CiAgICAKICAgICp1cmkgPSBOVUxMOwogICAgKmxvY2FsID0gTlVMTDsKICAgIGlmIChwcmVmaXggIT0gMCkKCSpwcmVmaXggPSBOVUxMOwogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ID4gMCkgewkJCgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLCAKCSAgICBvd25lckRlcywgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLCAKCSAgICAiUU5hbWUiLCB2YWx1ZSwgCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CQoJKmxvY2FsID0gdmFsdWU7CglyZXR1cm4gKGN0eHQtPmVycik7IAogICAgfSBlbHNlIGlmIChyZXQgPCAwKQoJcmV0dXJuICgtMSk7CiAgIAogICAgaWYgKCFzdHJjaHIoKGNoYXIgKikgdmFsdWUsICc6JykpIHsJCglucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCAwKTsKCWlmIChucykKCSAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSB7CgkgICAgLyoKCSAgICAqIFRoaXMgb25lIHRha2VzIGNhcmUgb2YgaW5jbHVkZWQgc2NoZW1hcyB3aXRoIG5vCgkgICAgKiB0YXJnZXQgbmFtZXNwYWNlLgoJICAgICovCgkgICAgKnVyaSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfQkKCSpsb2NhbCA9IHZhbHVlOwoJcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAqIEF0IHRoaXMgcG9pbnQgeG1sU3BsaXRRTmFtZTMgaGFzIHRvIHJldHVybiBhIGxvY2FsIG5hbWUuCiAgICAqLwogICAgKmxvY2FsID0geG1sU3BsaXRRTmFtZTModmFsdWUsICZsZW4pOwogICAgKmxvY2FsID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCAqbG9jYWwsIC0xKTsKICAgIHByZWYgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbHVlLCBsZW4pOwogICAgaWYgKHByZWZpeCAhPSAwKQoJKnByZWZpeCA9IHByZWY7CiAgICBucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgYXR0ci0+cGFyZW50LCBwcmVmKTsKICAgIGlmIChucyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIG93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksICJRTmFtZSIsIHZhbHVlLAoJICAgICJUaGUgUU5hbWUgdmFsdWUgJyVzJyBoYXMgbm8gY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgIgoJICAgICJkZWNsYXJhdGlvbiBpbiBzY29wZSIsIHZhbHVlLCBOVUxMKTsKCXJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKnVyaSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbnMtPmhyZWYsIC0xKTsKICAgIH0gICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogdGhlIHNjaGVtYSBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lciBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQGF0dHI6ICB0aGUgYXR0cmlidXRlIG5vZGUKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyB0aGUgUU5hbWUgb2YgYW4gYXR0cmlidXRlIHZhbHVlLgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9uIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdAogKiBzaG91bGQgcmVzb2x2ZSB0byBzY2hlbWEgY29tcG9uZW50cy4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgICAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqdXJpLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKipwcmVmaXgsCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKCiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZShjdHh0LCBzY2hlbWEsIAoJb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwgdmFsdWUsIHVyaSwgcHJlZml4LCBsb2NhbCkpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJRTmFtZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIHRoZSBRTmFtZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUuCiAqCiAqIFJldHVybnMgMCwgaW4gY2FzZSB0aGUgUU5hbWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBpZiBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJRTmFtZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgCgkJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJCSAgIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkJICAgY29uc3QgY2hhciAqbmFtZSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICBjb25zdCB4bWxDaGFyICoqcHJlZml4LAoJCQkJICAgY29uc3QgeG1sQ2hhciAqKmxvY2FsKQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG93bmVyRWxlbSwgbmFtZSk7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CgkqbG9jYWwgPSBOVUxMOwoJKnVyaSA9IE5VTEw7CglyZXR1cm4gKDApOyAgICAKICAgIH0KICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLCAKCW93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsIHVyaSwgcHJlZml4LCBsb2NhbCkpOwp9CgovKioKICogeG1sR2V0TWF4T2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWF4T2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWF4T2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAoJCWludCBtaW4sIGludCBtYXgsIGludCBkZWYsIGNvbnN0IGNoYXIgKmV4cGVjdGVkKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1heE9jY3VycyIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoZGVmKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCiAgICBpZiAoeG1sU3RyRXF1YWwodmFsLCAoY29uc3QgeG1sQ2hhciAqKSAidW5ib3VuZGVkIikpIHsKCWlmIChtYXggIT0gVU5CT1VOREVEKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkvKiBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywgKi8KCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgZXhwZWN0ZWQsCgkJdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKGRlZik7Cgl9IGVsc2UgCgkgICAgcmV0dXJuIChVTkJPVU5ERUQpOyAgLyogZW5jb2RpbmcgaXQgd2l0aCAtMSBtaWdodCBiZSBhbm90aGVyIG9wdGlvbiAqLwogICAgfQoKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICAvKiBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywgKi8KCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgZXhwZWN0ZWQsCgkgICAgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGRlZik7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxHZXRNaW5PY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtaW5PY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNaW5PY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIAoJCWludCBtaW4sIGludCBtYXgsIGludCBkZWYsIGNvbnN0IGNoYXIgKmV4cGVjdGVkKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1pbk9jY3VycyIpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoZGVmKTsKICAgIHZhbCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKICAgIGN1ciA9IHZhbDsKICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIGlmICgqY3VyID09IDApIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHdoaWxlICgoKmN1ciA+PSAnMCcpICYmICgqY3VyIDw9ICc5JykpIHsKICAgICAgICByZXQgPSByZXQgKiAxMCArICgqY3VyIC0gJzAnKTsKICAgICAgICBjdXIrKzsKICAgIH0KICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKICAgICAgICBjdXIrKzsKICAgIC8qCiAgICAqIFRPRE86IFJlc3RyaWN0IHRoZSBtYXhpbWFsIHZhbHVlIHRvIEludGVnZXIuCiAgICAqLwogICAgaWYgKCgqY3VyICE9IDApIHx8IChyZXQgPCBtaW4pIHx8ICgobWF4ICE9IC0xKSAmJiAocmV0ID4gbWF4KSkpIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEV2YWx1YXRlIGlmIGEgYm9vbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqIDEgaWYgZm91bmQgdG8gYmUgdHJ1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRCb29sZWFuUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGludCBkZWYpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoZGVmKTsKICAgIC8qIAogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63IAogICAgKiBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGxlZ2FsIGxpdGVyYWxzIHt0cnVlLCBmYWxzZSwgMSwgMH0uCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMSIpKQoJZGVmID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgIjAiKSkKICAgICAgICBkZWYgPSAwOyAgICAKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckRlcywgb3duZXJJdGVtLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwgCgkgICAgIigxIHwgMCB8IHRydWUgfCBmYWxzZSkiLCB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChkZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVNoZW1hIGV4dHJhY3Rpb24gZnJvbSBhbiBJbmZvc2V0CQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgCgkJCQkJCSAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VBbGwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgICAgIGludCB0b3BMZXZlbCk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDaG9pY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSk7CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWU6CiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAYXR0cjogIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUgYmVpbmcgdmFsaWRhdGVkCiAqIEB2YWx1ZTogdGhlIHZhbHVlCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdCAKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAkJCSAgIAoJCQkgICB4bWxBdHRyUHRyIGF0dHIsCgkJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIAogICAgaW50IHJldCA9IDA7IAoKICAgIC8qCiAgICAqIE5PVEU6IFNob3VsZCB3ZSBtb3ZlIHRoaXMgdG8geG1sc2NoZW1hdHlwZXMuYz8gSG1tLCBidXQgdGhpcwogICAgKiBvbmUgaXMgcmVhbGx5IG1lYW50IHRvIGJlIHVzZWQgaW50ZXJuYWxseSwgc28gYmV0dGVyIG5vdC4KICAgICovICAgIAogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpIHx8IChhdHRyID09IE5VTEwpKQoJcmV0dXJuICgtMSk7ICAgCiAgICBpZiAodHlwZS0+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+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIAoJICAgIE5VTEwsICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqYXR0clZhbHVlOwogICAgeG1sQ2hhciAqcmVwTmFtZSA9IE5VTEw7IC8qIFRoZSByZXBvcnRlZCBkZXNpZ25hdGlvbi4gKi8KICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHIsIG5hbWVBdHRyOwogICAgaW50IGlzUmVmID0gMDsKCiAgICAvKgogICAgICogTm90ZSB0aGF0IHRoZSB3M2Mgc3BlYyBhc3N1bWVzIHRoZSBzY2hlbWEgdG8gYmUgdmFsaWRhdGVkIHdpdGggc2NoZW1hCiAgICAgKiBmb3Igc2NoZW1hcyBiZWZvcmVoYW5kLgogICAgICoKICAgICAqIDMuMi4zIENvbnN0cmFpbnRzIG9uIFhNTCBSZXByZXNlbnRhdGlvbnMgb2YgQXR0cmlidXRlIERlY2xhcmF0aW9ucwogICAgICovCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7CiAgICBuYW1lQXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CgogICAgaWYgKChhdHRyID09IE5VTEwpICYmIChuYW1lQXR0ciA9PSBOVUxMKSkgewoJLyogCgkqIDMuMi4zIDogMy4xCgkqIE9uZSBvZiByZWYgb3IgbmFtZSBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aCAKCSovCgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8zXzEsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBOVUxMLCBub2RlLCBOVUxMLCAKCSAgICAiT25lIG9mIHRoZSBhdHRyaWJ1dGVzICdyZWYnIG9yICduYW1lJyBtdXN0IGJlIHByZXNlbnQiKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIE5VTEwsIG5vZGUsIAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCiAgICB9IGVsc2UKCWlzUmVmID0gMTsJCiAgICAKICAgIGlmIChpc1JlZikgewoJY2hhciBidWZbMTAwXTsgCgljb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMLCAqcmVmUHJlZml4ID0gTlVMTDsgCgoJLyoKCSogUGFyc2UgYXMgYXR0cmlidXRlIHJlZmVyZW5jZS4KCSovCQkKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYsIE5VTEwsIGF0dHIsICZyZWZOcywgCgkgICAgJnJlZlByZWZpeCwgJnJlZikgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CQogICAgICAgIHNucHJpbnRmKGJ1ZiwgOTksICIjYVJlZiAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgICAgIG5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CglyZXQtPm5vZGUgPSBub2RlOwoJcmV0LT5yZWZOcyA9IHJlZk5zOwoJcmV0LT5yZWZQcmVmaXggPSByZWZQcmVmaXg7CglyZXQtPnJlZiA9IHJlZjsJCQoJLyoKCXhtbFNjaGVtYUZvcm1hdFR5cGVSZXAoJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIE5VTEwsIE5VTEwpOwoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMSwgCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5hbWVBdHRyLCAKCQkicmVmIiwgIm5hbWUiKTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSB7CgkJICAgIC8qIAoJCSAgICAqIDMuMi4zIDogMy4yCgkJICAgICogSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxzaW1wbGVUeXBlPiwKCQkgICAgKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LiAKCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMiwgJnJlcE5hbWUsIAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCQl9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ1c2UiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJiAKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYgCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCSAgICAKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0JCiAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHhtbENoYXIgKm5zID0gTlVMTDsKCQoJLyoKCSogUGFyc2UgYXMgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8JCQkKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIE5VTEwsIG5hbWVBdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgkvKgoJeG1sU2NoZW1hRm9ybWF0VHlwZVJlcCgmcmVwTmFtZSwgTlVMTCwgeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBuYW1lKTsKCSovCgkvKiAKCSogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4bWxucyBOb3QgQWxsb3dlZCAKCSovCglpZiAoeG1sU3RyRXF1YWwobmFtZSwgQkFEX0NBU1QgInhtbG5zIikpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9OT19YTUxOUywgCgkJJnJlcE5hbWUsIE5VTEwsICh4bWxOb2RlUHRyKSBuYW1lQXR0ciwgCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgIk5DTmFtZSIsIE5VTEwsCgkJIlRoZSB2YWx1ZSBtdXN0IG5vdCBtYXRjaCAneG1sbnMnIiwgCgkJTlVMTCwgTlVMTCk7CSAgICAKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JICAgIAoJLyogCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlIAoJKi8JCglpZiAodG9wTGV2ZWwpIHsKCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfSBlbHNlIHsKCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZvcm0iKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJCQkmcmVwTmFtZSwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwkJCQoJCX0KCSAgICB9IGVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwkJCgl9CQkJCQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgbmFtZSwgbnMsIG5vZGUpOwoJaWYgKHJldCA9PSBOVUxMKSB7CgkgICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCQl4bWxGcmVlKHJlcE5hbWUpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOwoJcmV0LT5ub2RlID0gbm9kZTsJCQkJCglpZiAodG9wTGV2ZWwpCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTDsKCS8qIAoJKiAzLjIuNiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IHhzaTogTm90IEFsbG93ZWQgCgkqLwkKCWlmICh4bWxTdHJFcXVhbChyZXQtPnRhcmdldE5hbWVzcGFjZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX05PX1hTSSwKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgbXVzdCBub3QgbWF0Y2ggJyVzJyIsIAoJCXhtbFNjaGVtYUluc3RhbmNlTnMpOwkgICAgICAgIAoJfQoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4gCgkqLwkKCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CQkKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYgCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgJiYgCQkJCQoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJgkJICAgIAoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkpIHsKCQkgICAgaWYgKCh0b3BMZXZlbCkgfHwJCQkJCQkgICAgCQkKCQkgICAgICAgICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmb3JtIikpICYmCgkJCSAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ1c2UiKSkpKSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCgkJICAgIH0KCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwkKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9Cgl4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsCgkgICAgbm9kZSwgInR5cGUiLCAmcmV0LT50eXBlTnMsIE5VTEwsICZyZXQtPnR5cGVOYW1lKTsKICAgIH0gICAgCiAgICAvKiBUT0RPOiBDaGVjayBJRC4gKi8KICAgIHJldC0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOyAgCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImZpeGVkIi4KICAgICovCiAgICByZXQtPmRlZlZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKICAgIGlmIChyZXQtPmRlZlZhbHVlICE9IE5VTEwpCglyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQ7CiAgICAvKiAKICAgICogQXR0cmlidXRlICJkZWZhdWx0Ii4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImRlZmF1bHQiKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCS8qIAoJKiAzLjIuMyA6IDEKCSogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LiAKCSovCglpZiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpIHsKCSAgICB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8xLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyLCAiZGVmYXVsdCIsICJmaXhlZCIpOwoJfSBlbHNlCgkgICAgcmV0LT5kZWZWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsJCQogICAgfSAgICAKICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CgkvKiAKCSogQXR0cmlidXRlICJ1c2UiLiAKCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInVzZSIpOwoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAib3B0aW9uYWwiKSkKCQlyZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMOwoJICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInByb2hpYml0ZWQiKSkKCQlyZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQ7CgkgICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicmVxdWlyZWQiKSkKCQlyZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEOwoJICAgIGVsc2UKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX1VTRSwgCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJICAgIE5VTEwsICIob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIiwgCgkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CQkJCQoJfSBlbHNlCgkgICAgcmV0LT5vY2N1cnMgPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTDsKCS8qIAoJKiAzLjIuMyA6IDIKCSogSWYgZGVmYXVsdCBhbmQgdXNlIGFyZSBib3RoIHByZXNlbnQsIHVzZSBtdXN0IGhhdmUKCSogdGhlIGFjdHVhbCB2YWx1ZSBvcHRpb25hbC4KCSovCglpZiAoKHJldC0+b2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJiAKCSAgICAocmV0LT5kZWZWYWx1ZSAhPSBOVUxMKSAmJiAKCSAgICAoKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSA9PSAwKSkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfMiwgCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQlOVUxMLCAiKG9wdGlvbmFsIHwgcHJvaGliaXRlZCB8IHJlcXVpcmVkKSIsIE5VTEwsIAoJCSJUaGUgdmFsdWUgbXVzdCBiZSAnb3B0aW9uYWwnIGlmIHRoZSBhdHRyaWJ1dGUgIgoJCSInZGVmYXVsdCcgaXMgcHJlc2VudCBhcyB3ZWxsIiwgTlVMTCwgTlVMTCk7CSAgICAKCX0KICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9ICAgIAogICAgaWYgKGlzUmVmKSB7CglpZiAoY2hpbGQgIT0gTlVMTCkgewkgICAgCgkgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkKCQkvKiAKCQkqIDMuMi4zIDogMy4yCgkJKiBJZiByZWYgaXMgcHJlc2VudCwgdGhlbiBhbGwgb2YgPHNpbXBsZVR5cGU+LAoJCSogZm9ybSBhbmQgdHlwZSBtdXN0IGJlIGFic2VudC4gCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMiwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSAgICAiKGFubm90YXRpb24/KSIpOwoJICAgIGVsc2UgCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgTlVMTCwKCQkgICAgIihhbm5vdGF0aW9uPykiKTsgIAoJfQogICAgfSBlbHNlIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICBpZiAocmV0LT50eXBlTmFtZSAhPSBOVUxMKSB7CgkJLyogCgkJKiAzLjIuMyA6IDQKCQkqIHR5cGUgYW5kIDxzaW1wbGVUeXBlPiBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJCSovCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV80LAoJCSAgICAmcmVwTmFtZSwgICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSAgICAiYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZQoJCXJldC0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlPykiKTsKICAgIH0KICAgIC8qCiAgICAqIENsZWFudXAuCiAgICAqLwogICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCXhtbEZyZWUocmVwTmFtZSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsgICAgCiAgICB4bWxBdHRyUHRyIGF0dHIsIG5hbWVBdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgbmFtZUF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibmFtZSIpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsgICAKICAgIGlmICgodG9wTGV2ZWwpIHx8IChhdHRyID09IE5VTEwpKSB7CgkvKgoJKiBQYXJzZSBhcyBhbiBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbi4KCSogTm90ZSB0aGF0IHRob3NlIGFyZSBhbGxvd2VkIGF0IHRvcCBsZXZlbCBvbmx5LgoJKi8KCWlmIChuYW1lQXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywKCQlOVUxMLCBOVUxMLCBub2RlLCAibmFtZSIsIE5VTEwpOwkgICAgCgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCW5hbWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgbmFtZUF0dHIpOwoJLyoKCSogVGhlIG5hbWUgaXMgY3J1Y2lhbCwgZXhpdCBpZiBpbnZhbGlkLiAKCSovCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsCgkgICAgTlVMTCwgTlVMTCwgbmFtZUF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldCA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwKGN0eHQsIHNjaGVtYSwgbmFtZSwgbm9kZSk7CglpZiAocmV0ID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDsKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTDsKCXJldC0+bm9kZSA9IG5vZGU7CiAgICB9IGVsc2UgeyAgICAKCWNoYXIgYnVmWzUwXTsKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEwsICpyZWZQcmVmaXg7CgoJLyoKCSogUGFyc2UgYXMgYW4gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLgoJKi8KCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJTlVMTCwgTlVMTCwgbm9kZSwgInJlZiIsIE5VTEwpOwoJfQkKCXhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwKCSAgICBOVUxMLCBOVUxMLCBhdHRyLCAmcmVmTnMsICZyZWZQcmVmaXgsICZyZWYpOwoJIAogICAgICAgIHNucHJpbnRmKGJ1ZiwgNDksICIjYUdyUmVmICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgluYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwoJaWYgKG5hbWUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImNyZWF0aW5nIGludGVybmFsIG5hbWUgZm9yIGFuICIKCQkiYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlIiwgbm9kZSk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBuYW1lLCBub2RlKTsKCWlmIChyZXQgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOwoJcmV0LT5yZWYgPSByZWY7CglyZXQtPnJlZk5zID0gcmVmTnM7CgkvKiBUT0RPOiBJcyBAcmVmUHJlZml4IGN1cnJlbnRseSB1c2VkPyAqLwoJcmV0LT5yZWZQcmVmaXggPSByZWZQcmVmaXg7CglyZXQtPm5vZGUgPSBub2RlOwogICAgfQogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgoKHRvcExldmVsID09IDApICYmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpKSkgfHwKCQkgKHRvcExldmVsICYmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpKSAKCSAgICB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQlOVUxMLCBOVUxMLCBhdHRyKTsKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQkKICAgIC8qIFRPRE86IFZhbGlkYXRlICJpZCIgPyAqLyAgCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsgICAgCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKHRvcExldmVsKSB7CgljaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOyAKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewoJICAgIHJldC0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLCAKCSAgICAiKGFubm90YXRpb24/KSIpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdDoKICogQHZhbHVlOiAgdGhlIHZhbHVlCiAqIEBmbGFnczogdGhlIGZsYWdzIHRvIGJlIG1vZGlmaWVkCiAqIEBmbGFnUXVhbGlmaWVkOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInF1YWxpZmllZCIKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyRm9ybURlZmF1bHQoY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgaW50ICpmbGFncywKCQkJICAgICBpbnQgZmxhZ1F1YWxpZmllZCkKewogICAgaWYgKHhtbFN0ckVxdWFsKHZhbHVlLCBCQURfQ0FTVCAicXVhbGlmaWVkIikpIHsKCWlmICAoKCpmbGFncyAmIGZsYWdRdWFsaWZpZWQpID09IDApCgkgICAgKmZsYWdzIHw9IGZsYWdRdWFsaWZpZWQ7CiAgICB9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpCglyZXR1cm4gKDEpOyAgICAKCQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbDoKICogQHZhbHVlOiAgdGhlIHZhbHVlCiAqIEBmbGFnczogdGhlIGZsYWdzIHRvIGJlIG1vZGlmaWVkCiAqIEBmbGFnQWxsOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgIiNhbGwiCiAqIEBmbGFnRXh0ZW5zaW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgImV4dGVuc2lvbiIKICogQGZsYWdSZXN0cmljdGlvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJyZXN0cmljdGlvbiIKICogQGZsYWdTdWJzdGl0dXRpb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAic3Vic3RpdHV0aW9uIgogKiBAZmxhZ0xpc3Q6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAibGlzdCIKICogQGZsYWdVbmlvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJ1bmlvbiIKICoKICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBvZiB0aGUgYXR0cmlidXRlICJmaW5hbCIgYW5kICJibG9jayIuIFRoZSB2YWx1ZQogKiBpcyBjb252ZXJ0ZWQgaW50byB0aGUgc3BlY2lmaWVkIGZsYWcgdmFsdWVzIGFuZCByZXR1cm5lZCBpbiBAZmxhZ3MuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIDEgb3RoZXJ3aXNlLgogKi8KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkgICAgaW50ICpmbGFncywJCQkKCQkJICAgIGludCBmbGFnQWxsLAoJCQkgICAgaW50IGZsYWdFeHRlbnNpb24sCgkJCSAgICBpbnQgZmxhZ1Jlc3RyaWN0aW9uLAoJCQkgICAgaW50IGZsYWdTdWJzdGl0dXRpb24sCgkJCSAgICBpbnQgZmxhZ0xpc3QsCgkJCSAgICBpbnQgZmxhZ1VuaW9uKQkJCQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBUT0RPOiBUaGlzIGRvZXMgbm90IGNoZWNrIGZvciBkdWJsaWNhdGUgZW50cmllcy4KICAgICovCiAgICBpZiAodmFsdWUgPT0gTlVMTCkKCXJldHVybiAoMSk7CiAgICBpZiAoeG1sU3RyRXF1YWwodmFsdWUsIEJBRF9DQVNUICIjYWxsIikpIHsKCWlmIChmbGFnQWxsICE9IC0xKQoJICAgICpmbGFncyB8PSBmbGFnQWxsOwoJZWxzZSB7CgkgICAgaWYgKGZsYWdFeHRlbnNpb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnRXh0ZW5zaW9uOyAKCSAgICBpZiAoZmxhZ1Jlc3RyaWN0aW9uICE9IC0xKSAKCQkqZmxhZ3MgfD0gZmxhZ1Jlc3RyaWN0aW9uOwoJICAgIGlmIChmbGFnU3Vic3RpdHV0aW9uICE9IC0xKSAKCQkqZmxhZ3MgfD0gZmxhZ1N1YnN0aXR1dGlvbjsKCSAgICBpZiAoZmxhZ0xpc3QgIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnTGlzdDsKCSAgICBpZiAoZmxhZ1VuaW9uICE9IC0xKSAKCQkqZmxhZ3MgfD0gZmxhZ1VuaW9uOwoJfQogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKmVuZCwgKmN1ciA9IHZhbHVlOwoJeG1sQ2hhciAqaXRlbTsKCQoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgaXRlbSA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOyAgICAJICAgIAoJICAgIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAiZXh0ZW5zaW9uIikpIHsKCQlpZiAoZmxhZ0V4dGVuc2lvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdFeHRlbnNpb24pID09IDApCgkJCSpmbGFncyB8PSBmbGFnRXh0ZW5zaW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJyZXN0cmljdGlvbiIpKSB7CgkJaWYgKGZsYWdSZXN0cmljdGlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdSZXN0cmljdGlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdSZXN0cmljdGlvbjsKCQl9IGVsc2UgCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uIikpIHsKCQlpZiAoZmxhZ1N1YnN0aXR1dGlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdTdWJzdGl0dXRpb24pID09IDApCgkJCSpmbGFncyB8PSBmbGFnU3Vic3RpdHV0aW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJsaXN0IikpIHsKCQlpZiAoZmxhZ0xpc3QgIT0gLTEpIHsKCQkgICAgaWYgKCgqZmxhZ3MgJiBmbGFnTGlzdCkgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdMaXN0OwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJ1bmlvbiIpKSB7CgkJaWYgKGZsYWdVbmlvbiAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdVbmlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdVbmlvbjsKCQl9IGVsc2UgCgkJICAgIHJldCA9IDE7CgkgICAgfSBlbHNlIAoJCXJldCA9IDE7CgkgICAgaWYgKGl0ZW0gIT0gTlVMTCkKCQl4bWxGcmVlKGl0ZW0pOwoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKChyZXQgPT0gMCkgJiYgKCpjdXIgIT0gMCkpOyAKICAgIH0gICAgCiAgICAKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgRWxlbWVudCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlZCBlbGVtZW50IGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hUGFyc2VFbGVtZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lID0gTlVMTDsgICAgCiAgICBjb25zdCB4bWxDaGFyICphdHRyVmFsdWU7CiAgICB4bWxDaGFyICpyZXBOYW1lID0gTlVMTDsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7ICAgIAogICAgeG1sQXR0clB0ciBhdHRyLCBuYW1lQXR0cjsKICAgIGludCBtaW5PY2N1cnMsIG1heE9jY3VyczsKICAgIGludCBpc1JlZiA9IDA7CgogICAgLyogMy4zLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBFbGVtZW50IERlY2xhcmF0aW9ucyAqLwogICAgLyogVE9ETzogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgMy4zLjYgKi8KICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgICAKICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7ICAgCiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCSh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsLCBOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbmFtZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBuYW1lQXR0cik7CQkKICAgIH0gZWxzZSB7Cglpc1JlZiA9IDE7CgkKICAgIH0KICAgIC8qIAogICAgKiAuLi4gdW5sZXNzIG1pbk9jY3Vycz1tYXhPY2N1cnM9MCwgaW4gd2hpY2ggY2FzZSB0aGUgaXRlbSBjb3JyZXNwb25kcyAKICAgICogdG8gbm8gY29tcG9uZW50IGF0IGFsbAogICAgKiBUT0RPOiBJdCBtaWdodCBiZSBiZXR0ZXIgdG8gdmFsaWRhdGUgdGhlIGVsZW1lbnQsIGV2ZW4gaWYgaXQgd29uJ3QgYmUgCiAgICAqIHVzZWQuCiAgICAqLyAgICAKICAgIG1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgIm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgbWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgIihub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICBpZiAoKG1pbk9jY3VycyA9PSAwKSAmJiAobWF4T2NjdXJzID09IDApKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIElmIHdlIGdldCBhICJyZWYiIGF0dHJpYnV0ZSBvbiBhIGxvY2FsIDxlbGVtZW50PiB3ZSB3aWxsIGFzc3VtZSBpdCdzCiAgICAqIGEgcmVmZXJlbmNlIC0gZXZlbiBpZiB0aGVyZSdzIGEgIm5hbWUiIGF0dHJpYnV0ZTsgdGhpcyBzZWVtcyB0byBiZSBtb3JlIAogICAgKiByb2J1c3QuCiAgICAqLwogICAgaWYgKGlzUmVmKSB7CgljaGFyIGJ1Zls1MF07Cgljb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMLCAqcmVmUHJlZml4OwoKCS8qCgkqIFBhcnNlIGFzIGEgcGFydGljbGUuCgkqLwoJeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYsIAoJICAgIE5VTEwsIGF0dHIsICZyZWZOcywgJnJlZlByZWZpeCwgJnJlZik7CQkJCgkgCiAgICAgICAgc25wcmludGYoYnVmLCA0OSwgIiNlUmVmICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgluYW1lID0gKGNvbnN0IHhtbENoYXIgKikgYnVmOwoJcmV0ID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUsIDApOwoJaWYgKHJldCA9PSBOVUxMKSB7CgkgICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCQl4bWxGcmVlKHJlcE5hbWUpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDsKCXJldC0+bm9kZSA9IG5vZGU7ICAgICAJCQoJcmV0LT5yZWYgPSByZWY7CglyZXQtPnJlZk5zID0gcmVmTnM7CglyZXQtPnJlZlByZWZpeCA9IHJlZlByZWZpeDsKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9SRUY7CgkvKiAKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCgkvKiAKCSogMy4zLjMgOiAyLjEKCSogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzJfMSwKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbmFtZUF0dHIsCgkJInJlZiIsICJuYW1lIik7Cgl9CgkvKiAzLjMuMyA6IDIuMiAqLyAgIAoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpICYmIAkJCQkKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmIAoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkgJiYJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzJfMiwKCQkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIsIAoJCQkiT25seSB0aGUgYXR0cmlidXRlcyAnbWluT2NjdXJzJywgJ21heE9jY3VycycgYW5kICIKCQkJIidpZCcgYXJlIGFsbG93ZWQgaW4gYWRkaXRpb24gdG8gJ3JlZiciKTsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0JICAgICAgCiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqbnMgPSBOVUxMLCAqZml4ZWQ7CgoJLyoKCSogUGFyc2UgYXMgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KCSovCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsLCBOVUxMLCBuYW1lQXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApCgkgICAgcmV0dXJuIChOVUxMKTsKCS8qIAoJKiBFdmFsdWF0ZSB0aGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCglpZiAodG9wTGV2ZWwpIHsKCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfSBlbHNlIHsKCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZvcm0iKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJCQkmcmVwTmFtZSwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwkJCQoJCX0KCSAgICB9IGVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwkJCgl9CQoJcmV0ID0geG1sU2NoZW1hQWRkRWxlbWVudChjdHh0LCBzY2hlbWEsIG5hbWUsIG5zLCBub2RlLCB0b3BMZXZlbCk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOwoJcmV0LT5ub2RlID0gbm9kZTsJCQkJCQoJLyogCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ0eXBlIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCQkKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaXhlZCIpKSAmJgkJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImJsb2NrIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5pbGxhYmxlIikpKSB7CgkJICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7IAoJCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInN1YnN0aXR1dGlvbkdyb3VwIikpIHsKCQkJICAgIC8qCgkJCSAgICAqIDMuMy42IDogMyBJZiB0aGVyZSBpcyBhIG5vbi23YWJzZW50tyB7c3Vic3RpdHV0aW9uIAoJCQkgICAgKiBncm91cCBhZmZpbGlhdGlvbn0sIHRoZW4ge3Njb3BlfSBtdXN0IGJlIGdsb2JhbC4KCQkJICAgICogVE9ETzogVGhpcyBvbmUgaXMgcmVkdW5kYW50LCBzaW5jZSB0aGUgUzRTIGRvZXMgCgkJCSAgICAqIHByb2hpYml0IHRoaXMgYXR0cmlidXRlIG9uIGxvY2FsIGRlY2xhcmF0aW9ucyBhbHJlYWR5OyAKCQkJICAgICogc28gd2h5IGFuIGV4cGxpY2l0IGVycm9yIGNvZGU/IFdlaXJkIHNwZWMuCgkJCSAgICAqIFRPRE86IE1vdmUgdGhpcyB0byB0aGUgcHJvcGVyIGNvbnN0cmFpbnQgbGF5ZXIuCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9FX1BST1BTX0NPUlJFQ1RfMywKCQkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsgCQkJCQkJCgkJCX0gZWxzZSBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkgJiYKCQkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZvcm0iKSkpIHsKCgkJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJCQl9CgkJICAgIH0gZWxzZSBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkgJiYgCgkJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpICYmIAoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzdWJzdGl0dXRpb25Hcm91cCIpKSkgewoKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCSAgICAKCQkgICAgfQoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQkKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CQkKCS8qCgkqIEV4dHJhY3QvdmFsaWRhdGUgYXR0cmlidXRlcy4KCSovCglpZiAodG9wTGV2ZWwpIHsKCSAgICAvKiAKCSAgICAqIFByb2Nlc3MgdG9wIGF0dHJpYnV0ZXMgb2YgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGhlcmUuCgkgICAgKi8KCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMOwoJICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9UT1BMRVZFTDsKCSAgICB4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgJnJlcE5hbWUsIAoJCSh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsICJzdWJzdGl0dXRpb25Hcm91cCIsIAoJCSYocmV0LT5zdWJzdEdyb3VwTnMpLCBOVUxMLCAmKHJldC0+c3Vic3RHcm91cCkpOwoJICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgIAoJCW5vZGUsICJhYnN0cmFjdCIsIDApKQoJCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVDsgCgkgICAgLyoKCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJICAgICovCgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaW5hbCIpOwkgICAgCgkgICAgaWYgKGF0dHIgPT0gTlVMTCkgewoJCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9BQlNFTlQ7CgkgICAgfSBlbHNlIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CSAgICAKCQlpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihyZXQtPmZsYWdzKSwgCgkJICAgIC0xLAoJCSAgICBYTUxfU0NIRU1BU19FTEVNX0ZJTkFMX0VYVEVOU0lPTiwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9SRVNUUklDVElPTiwgLTEsIC0xLCAtMSkgIT0gMCkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkJTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgcmVzdHJpY3Rpb24pKSIsIAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJCX0KCSAgICB9Cgl9ICAgIAoJLyoKCSogQXR0cmlidXRlICJibG9jayIuCgkqLwoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJibG9jayIpOwkKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfQUJTRU5UOwoJfSBlbHNlIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CSAgICAKCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgJihyZXQtPmZsYWdzKSwgCgkJLTEsCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19FWFRFTlNJT04sCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19SRVNUUklDVElPTiwgCgkJWE1MX1NDSEVNQVNfRUxFTV9CTE9DS19TVUJTVElUVVRJT04sIC0xLCAtMSkgIT0gMCkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgTlVMTCwgIigjYWxsIHwgTGlzdCBvZiAoZXh0ZW5zaW9uIHwgIgoJCSAgICAicmVzdHJpY3Rpb24gfCBzdWJzdGl0dXRpb24pKSIsIGF0dHJWYWx1ZSwgCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwkJCgkgICAgfQoJfQoJaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAKCSAgICBub2RlLCAibmlsbGFibGUiLCAwKSkKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEU7CQoKCXhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCAKCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgCgkgICAgInR5cGUiLCAmKHJldC0+bmFtZWRUeXBlTnMpLCBOVUxMLCAmKHJldC0+bmFtZWRUeXBlKSk7CgoJcmV0LT52YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImRlZmF1bHQiKTsgICAgCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZpeGVkIik7CQoJaWYgKGF0dHIgIT0gTlVMTCkgewoJICAgIGZpeGVkID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmIChyZXQtPnZhbHVlICE9IE5VTEwpIHsKCQkvKiAKCQkqIDMuMy4zIDogMSAKCQkqIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4gCgkJKi8KCQl4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMSwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIsCgkJICAgICJkZWZhdWx0IiwgImZpeGVkIik7CgkgICAgfSBlbHNlIHsKCQlyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQ7CgkJcmV0LT52YWx1ZSA9IGZpeGVkOwoJICAgIH0KCX0JCiAgICB9ICAgICAKICAgIC8qCiAgICAqIEV4dHJhY3QvdmFsaWRhdGUgY29tbW9uIGF0dHJpYnV0ZXMuCiAgICAqLyAgICAKICAgIC8qIFRPRE86IENoZWNrIElEOiAqLwogICAgcmV0LT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICByZXQtPm1pbk9jY3VycyA9IG1pbk9jY3VyczsKICAgIHJldC0+bWF4T2NjdXJzID0gbWF4T2NjdXJzOyAKICAgIGlmICh0b3BMZXZlbCAhPSAxKQoJeG1sU2NoZW1hUENoZWNrUGFydGljbGVDb3JyZWN0XzIoY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgCgkgICAgbm9kZSwgbWluT2NjdXJzLCBtYXhPY2N1cnMpOyAgICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoaXNSZWYpIHsKCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzIsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQlOVUxMLCAiKGFubm90YXRpb24/KSIpOwoJfQogICAgfSBlbHNlIHsJCQkKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgLyogCgkgICAgKiAzLjMuMyA6IDMgCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkKCSAgICAqIGV4Y2x1c2l2ZSAKCSAgICAqLwoJICAgIGlmIChyZXQtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ3R5cGUnIGFuZCB0aGUgPGNvbXBsZXhUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CQkKCSAgICB9IGVsc2UKCQlyZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICAvKiAKCSAgICAqIDMuMy4zIDogMyAKCSAgICAqICJ0eXBlIiBhbmQgZWl0aGVyIDxzaW1wbGVUeXBlPiBvciA8Y29tcGxleFR5cGU+IGFyZQoJICAgICogbXV0dWFsbHkgZXhjbHVzaXZlIAoJICAgICovCgkgICAgaWYgKHJldC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8zLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwkJCQkKCSAgICB9IGVsc2UKCQlyZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CQoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJ1bmlxdWUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHx8IChJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkpIHsKCSAgICBUT0RPIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CglpZiAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQlOVUxMLCAiKGFubm90YXRpb24/LCAoKHNpbXBsZVR5cGUgfCBjb21wbGV4VHlwZSk/LCAiCgkJIih1bmlxdWUgfCBrZXkgfCBrZXlyZWYpKikpIik7Cgl9CQkKCiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICAvKgogICAgKiBDbGVhbnVwLgogICAgKi8KICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgl4bWxGcmVlKHJlcE5hbWUpOyAgICAKICAgIC8qCiAgICAqIE5PVEU6IEVsZW1lbnQgRGVjbGFyYXRpb24gUmVwcmVzZW50YXRpb24gT0sgNC4gd2lsbCBiZSBjaGVja2VkIGF0IGEgCiAgICAqIGRpZmZlcmVudCBsYXllci4KICAgICovCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVVuaW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBVbmlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlVW5pb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBsYXN0ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiI3VuaW9uICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9VTklPTjsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWVtYmVyVHlwZXMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlICJtZW1iZXJUeXBlcyIuIFRoaXMgaXMgYSBsaXN0IG9mIFFOYW1lcy4KICAgICogVE9ETzogVmFsaWRhdGUgdGhlIFFOYW1lcy4KICAgICovCiAgICB0eXBlLT5iYXNlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibWVtYmVyVHlwZXMiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsJCiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyogVE9ETzogVGhpbmsgYWJvdXQgdGhlIGVycm9yIGNvZGUuICovCgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fVU5JT05fQ0hJTEQsIAoJICAgIE5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlKikiKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxpc3Q6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIExpc3QgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiNsaXN0ICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0xJU1Q7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpdGVtVHlwZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIHR5cGUsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0JCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgIml0ZW1UeXBlIi4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgTlVMTCwgTlVMTCwKCW5vZGUsICJpdGVtVHlwZSIsICYodHlwZS0+YmFzZU5zKSwgTlVMTCwgJih0eXBlLT5iYXNlKSk7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9ICAgIAkKICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkJTlVMTCwgdHlwZSwgbm9kZSwgCgkJIlRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJImFyZSBtdXR1YWxseSBleGNsdXNpdmUiLCBOVUxMKTsJICAgIAoJfSBlbHNlIHsJCgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsgICAgICAgIAogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCS8qIFRPRE86IFRoaW5rIGFib3V0IHRoZSBlcnJvciBjb2RlLiAqLwoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0xJU1RfQ0hJTEQsIAoJICAgIE5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLCAiKGFubm90YXRpb24/LCBzaW1wbGVUeXBlPykiKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZSBUeXBlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBjdHh0VHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlID0gTlVMTDsKICAgIHhtbENoYXIgKnJlcE5hbWUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CgogICAgaWYgKHRvcExldmVsKSB7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIAoJCSh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBOVUxMLCBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmYXR0clZhbHVlKSAhPSAwKSB7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KICAgICAgICAgICAgCiAgICBpZiAodG9wTGV2ZWwgPT0gMCkgewogICAgICAgIGNoYXIgYnVmWzEwMF07CgoJLyoKCSogUGFyc2UgYXMgbG9jYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSovCiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgIiNzdCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZyZXBOYW1lLCB0eXBlLCBhdHRyKTsJCSAgICAKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCQkmcmVwTmFtZSwgdHlwZSwgYXR0cik7CQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CQkKCS8qCgkqIFBhcnNlIGFzIGdsb2JhbCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJKi8JCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIGF0dHJWYWx1ZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRTsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikpICYmCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpKXsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZyZXBOYW1lLCB0eXBlLCBhdHRyKTsJCgkJfQoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICAmcmVwTmFtZSwgdHlwZSwgYXR0cik7CQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIEF0dHJpYnV0ZSAiZmluYWwiLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsJCglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9ERUZBVUxUOwoJfSBlbHNlIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaW5hbCIpOwoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwgCgkJLTEsIC0xLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OLCAtMSwJICAgIAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVCwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSAhPSAwKSB7CgoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICAmcmVwTmFtZSwgdHlwZSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCSAgICBOVUxMLCAiKCNhbGwgfCBMaXN0IG9mIChsaXN0IHwgdW5pb24gfCByZXN0cmljdGlvbikiLCAKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9ICAgIAogICAgLyogVE9ETzogQ2hlY2sgaWQuICovICAgIAogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7ICAgICAgICAgCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJsaXN0IikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlTGlzdChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJ1bmlvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVVuaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7ICAgIAogICAgaWYgKChjaGlsZCAhPSBOVUxMKSB8fCAoc3VidHlwZSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJICAgICZyZXBOYW1lLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwgCgkgICAgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgbGlzdCB8IHVuaW9uKSkiKTsKICAgIH0KICAgIGN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CiAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJeG1sRnJlZShyZXBOYW1lKTsKCiAgICByZXR1cm4gKHR5cGUpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnJlZiA9IE5VTEwsICpyZWZOcyA9IE5VTEw7CiAgICBjaGFyIGJ1ZlsxMDBdOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBUT0RPOiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBldmVuIGlmIG5vIGl0ZW0gaXMgY3JlYXRlZCAKICAgICogKGkuZS4gbWluL21heE9jY3VycyA9PSAwKS4KICAgICovCiAgICBtaW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsICIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgaWYgKChtaW5PY2N1cnMgPT0gMCkgJiYgKG1heE9jY3VycyA9PSAwKSkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQlYTUxfU0NIRU1BUF9HUk9VUF9OT05BTUVfTk9SRUYsCgkJIkdyb3VwIGRlZmluaXRpb24gb3IgcGFydGljbGU6IE9uZSBvZiB0aGUgYXR0cmlidXRlcyBcIm5hbWVcIiAiCgkJIm9yIFwicmVmXCIgbXVzdCBiZSBwcmVzZW50LlxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQoJaWYgKHJlZk5zID09IE5VTEwpCgkgICAgcmVmTnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAiYW5vbmdyb3VwICVkIiwgY3R4dC0+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+cGFyZW50SXRlbSA9IE5VTEw7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJbXBvcnRQdHIKeG1sU2NoZW1hQWRkSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgeG1sSGFzaFRhYmxlUHRyICppbXBvcnRzLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hSW1wb3J0UHRyIHJldDsKCiAgICBpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJKmltcG9ydHMgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKCWlmICgqaW1wb3J0cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9GQUlMRURfQlVJTERfSU1QT1JULAoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJIkludGVybmFsIGVycm9yOiBmYWlsZWQgdG8gYnVpbGQgdGhlIGltcG9ydCB0YWJsZSIsCgkJTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KICAgIH0KICAgIHJldCA9ICh4bWxTY2hlbWFJbXBvcnQqKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGltcG9ydCBzdHJ1Y3QiLCBOVUxMKTsKCXJldHVybiAoTlVMTCk7CiAgICB9ICAgCiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAobnNOYW1lID09IE5VTEwpCgluc05hbWUgPSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0U7CiAgICB4bWxIYXNoQWRkRW50cnkoKmltcG9ydHMsIG5zTmFtZSwgcmV0KTsgIAoKICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgICAgICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbiwKCQkJICAgICAgIHhtbERvY1B0ciAqZG9jLAoJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnRhcmdldE5hbWVzcGFjZSwKCQkJICAgICAgIGludCBhYnNvbHV0ZSkKewogICAgeG1sUGFyc2VyQ3R4dFB0ciBwYXJzZXJDdHh0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydDsKICAgIGNvbnN0IHhtbENoYXIgKm5zOwogICAgeG1sTm9kZVB0ciByb290OwoKICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgd2lsbCBiZSB1c2VkIGZvciA8aW1wb3J0PiwgPHhzaTpzY2hlbWFMb2NhdGlvbj4gYW5kCiAgICAqIDx4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj4uCiAgICAqLwogICAgKmRvYyA9IE5VTEw7CiAgICAvKgogICAgKiBHaXZlbiB0aGF0IHRoZSBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSBpcyBvbmx5IGEgaGludCwgaXQgaXMgb3BlbiAKICAgICogdG8gYXBwbGljYXRpb25zIHRvIGlnbm9yZSBhbGwgYnV0IHRoZSBmaXJzdCA8aW1wb3J0PiBmb3IgYSBnaXZlbiAKICAgICogbmFtZXNwYWNlLCByZWdhcmRsZXNzIG9mIHRoZSC3YWN0dWFsIHZhbHVltyBvZiBzY2hlbWFMb2NhdGlvbiwgYnV0CiAgICAqIHN1Y2ggYSBzdHJhdGVneSByaXNrcyBtaXNzaW5nIHVzZWZ1bCBpbmZvcm1hdGlvbiB3aGVuIG5ldwogICAgKiBzY2hlbWFMb2NhdGlvbnMgYXJlIG9mZmVyZWQuCiAgICAqCiAgICAqIFhTViAodmVyIDIuNS0yKSBkb2VzIHVzZSB0aGUgZmlyc3QgPGltcG9ydD4gd2hpY2ggcmVzb2x2ZXMgdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIFhlcmNlcy1KICh2ZXIgMi41LjEpIGlnbm9yZXMgYWxsIGJ1dCB0aGUgZmlyc3QgZ2l2ZW4gPGltcG9ydD4gLSByZWdhcmRsZXNzIGlmCiAgICAqIHZhbGlkIG9yIG5vdC4KICAgICogV2Ugd2lsbCBmb2xsb3cgWFNWIGhlcmUuIAogICAgKi8KICAgIGlmIChsb2NhdGlvbiA9PSBOVUxMKSB7CgkvKgoJKiBTY2hlbWEgRG9jdW1lbnQgTG9jYXRpb24gU3RyYXRlZ3k6CgkqCgkqIDMgQmFzZWQgb24gdGhlIG5hbWVzcGFjZSBuYW1lLCBpZGVudGlmeSBhbiBleGlzdGluZyBzY2hlbWEgZG9jdW1lbnQsCgkqIGVpdGhlciBhcyBhIHJlc291cmNlIHdoaWNoIGlzIGFuIFhNTCBkb2N1bWVudCBvciBhIDxzY2hlbWE+IGVsZW1lbnQgCgkqIGluZm9ybWF0aW9uIGl0ZW0sIGluIHNvbWUgbG9jYWwgc2NoZW1hIHJlcG9zaXRvcnk7IAoJKgoJKiA1IEF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgbmFtZXNwYWNlIG5hbWUgdG8gbG9jYXRlIHN1Y2ggYSByZXNvdXJjZS4gCgkqCgkqIE5PVEU6IFRob3NlIHN0YXRlZ2llcyBhcmUgbm90IHN1cHBvcnRlZCwgc28gd2Ugd2lsbCBza2lwLgoJKi8KCXJldHVybiAoMCk7CiAgICB9CiAgICBpZiAobnNOYW1lID09IE5VTEwpIAoJbnMgPSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0U7CiAgICBlbHNlCglucyA9IG5zTmFtZTsKICAgIAogICAgaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBucyk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsJCgkvKgoJKiBUaGVyZSB3YXMgYSB2YWxpZCByZXNvdXJjZSBmb3IgdGhlIHNwZWNpZmllZCBuYW1lc3BhY2UgYWxyZWFkeQoJKiBkZWZpbmVkLCBzbyBza2lwLgoJKiBUT0RPOiBUaGlzIG1pZ2h0IGJlIGNoYW5nZWQgc29tZWRheSB0byBhbGxvdyBpbXBvcnQgb2YKCSogY29tcG9uZW50cyBmcm9tIG11bHRpcGxlIGRvY3VtZW50cyBmb3IgYSBzaW5nbGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCglyZXR1cm4gKDApOwogICAgfSAKICAgIC8qCiAgICAqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneTogCiAgICAqCiAgICAqIDIgQmFzZWQgb24gdGhlIGxvY2F0aW9uIFVSSSwgaWRlbnRpZnkgYW4gZXhpc3Rpbmcgc2NoZW1hIGRvY3VtZW50LCAKICAgICogZWl0aGVyIGFzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gWE1MIGRvY3VtZW50IG9yIGEgPHNjaGVtYT4gZWxlbWVudCAKICAgICogaW5mb3JtYXRpb24gaXRlbSwgaW4gc29tZSBsb2NhbCBzY2hlbWEgcmVwb3NpdG9yeTsgICAKICAgICoKICAgICogNCBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIGxvY2F0aW9uIFVSSSwgdG8gbG9jYXRlIGEgcmVzb3VyY2Ugb24gdGhlIAogICAgKiB3ZWIgd2hpY2ggaXMgb3IgY29udGFpbnMgb3IgcmVmZXJlbmNlcyBhIDxzY2hlbWE+IGVsZW1lbnQ7CiAgICAqIFRPRE86IEhtbSwgSSBkb24ndCBrbm93IGlmIHRoZSByZWZlcmVuY2Ugc3R1ZmYgaW4gNC4gd2lsbCB3b3JrLgogICAgKgogICAgKi8KICAgIGlmICgoYWJzb2x1dGUgPT0gMCkgJiYgKG5vZGUgIT0gTlVMTCkpIHsKCXhtbENoYXIgKmJhc2UsICpVUkk7CgoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIG5vZGUtPmRvYy0+VVJMKTsKCX0gZWxzZSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIGJhc2UpOwoJICAgIHhtbEZyZWUoYmFzZSk7Cgl9CglpZiAoVVJJICE9IE5VTEwpIHsKCSAgICBsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgVVJJLCAtMSk7CgkgICAgeG1sRnJlZShVUkkpOwoJfQogICAgfQogICAgcGFyc2VyQ3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKICAgIGlmIChwYXJzZXJDdHh0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgInhtbFNjaGVtYVBhcnNlSW1wb3J0OiAiCgkgICAgImFsbG9jYXRpbmcgYSBwYXJzZXIgY29udGV4dCIsIE5VTEwpOwoJcmV0dXJuKC0xKTsKICAgIH0JCQogICAgCiAgICAqZG9jID0geG1sQ3R4dFJlYWRGaWxlKHBhcnNlckN0eHQsIChjb25zdCBjaGFyICopIGxvY2F0aW9uLCAKCSAgICBOVUxMLCBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwoKICAgIC8qCiAgICAqIDIuMSBUaGUgcmVmZXJlbnQgaXMgKGEgZnJhZ21lbnQgb2YpIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gCiAgICAqIFhNTCBkb2N1bWVudCAoc2VlIGNsYXVzZSAxLjEpLCB3aGljaCBpbiB0dXJuIGNvcnJlc3BvbmRzIHRvIAogICAgKiBhIDxzY2hlbWE+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpbiBhIHdlbGwtZm9ybWVkIGluZm9ybWF0aW9uIAogICAgKiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIFRPRE86IFdoYXQgdG8gZG8gd2l0aCB0aGUgImZyYWdtZW50IiBzdHVmZj8KICAgICoKICAgICogMi4yIFRoZSByZWZlcmVudCBpcyBhIDxzY2hlbWE+IGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpbiAKICAgICogYSB3ZWxsLWZvcm1lZCBpbmZvcm1hdGlvbiBzZXQsIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgCiAgICAqIHRvIGEgdmFsaWQgc2NoZW1hLgogICAgKiBOT1RFOiAyLjIgd29uJ3QgYXBwbHksIHNpbmNlIG9ubHkgWE1MIGRvY3VtZW50cyB3aWxsIGJlIHByb2Nlc3NlZCAKICAgICogaGVyZS4KICAgICovICAgICAgIAogICAgaWYgKCpkb2MgPT0gTlVMTCkgewkKCXhtbEVycm9yUHRyIGxlcnI7CgkvKgoJKiBJdCBpcyAqbm90KiBhbiBlcnJvciBmb3IgdGhlIGFwcGxpY2F0aW9uIHNjaGVtYSByZWZlcmVuY2UgCgkqIHN0cmF0ZWd5IHRvIGZhaWwuCgkqIAoJKiBJZiB0aGUgZG9jIGlzIE5VTEwgYW5kIHRoZSBwYXJzZXIgZXJyb3IgaXMgYW4gSU8gZXJyb3Igd2UKCSogd2lsbCBhc3N1bWUgdGhhdCB0aGUgcmVzb3VyY2UgY291bGQgbm90IGJlIGxvY2F0ZWQgb3IgYWNjZXNzZWQuCgkqCgkqIFRPRE86IFRyeSB0byBmaW5kIHNwZWNpZmljIGVycm9yIGNvZGVzIHRvIHJlYWN0IG9ubHkgb24KCSogbG9jYWxpc2F0aW9uIGZhaWx1cmVzLgoJKgoJKiBUT0RPLCBGSVhNRTogQ2hlY2sgdGhlIHNwZWM6IGlzIGEgbmFtZXNwYWNlIGFkZGVkIHRvIHRoZSBpbXBvcnRlZAoJKiBuYW1lc3BhY2VzLCBldmVuIGlmIHRoZSBzY2hlbWFMb2NhdGlvbiBkaWQgbm90IHByb3ZpZGUKCSogYSByZXNvdXJjZT8gSSBndWVzcyBzbywgc2luY2Ugb21pdHRpbmcgdGhlICJzY2hlbWFMb2NhdGlvbiIKCSogYXR0cmlidXRlLCBpbXBvcnRzIGEgbmFtZXNwYWNlIGFzIHdlbGwuCgkqLwoJbGVyciA9IHhtbEdldExhc3RFcnJvcigpOwoJaWYgKChsZXJyICE9IE5VTEwpICYmIChsZXJyLT5kb21haW4gPT0gWE1MX0ZST01fSU8pKSB7CQoJICAgIHhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwoJICAgIHJldHVybigwKTsKCX0KCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiRmFpbGVkIHRvIHBhcnNlIHRoZSByZXNvdXJjZSAnJXMnIGZvciBpbXBvcnQiLAoJICAgIGxvY2F0aW9uKTsKCXhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwoJcmV0dXJuKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0KICAgIHhtbEZyZWVQYXJzZXJDdHh0KHBhcnNlckN0eHQpOwogICAgCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoKmRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIFhNTCBkb2N1bWVudCAnJXMnIHRvIGJlIGltcG9ydGVkIGhhcyBubyBkb2N1bWVudCAiCgkgICAgImVsZW1lbnQiLCBsb2NhdGlvbik7CQoJeG1sRnJlZURvYygqZG9jKTsKCSpkb2MgPSBOVUxMOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSk7CiAgICB9CQogICAgCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwkKICAgIAogICAgaWYgKCFJU19TQ0hFTUEocm9vdCwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIFhNTCBkb2N1bWVudCAnJXMnIHRvIGJlIGltcG9ydGVkIGlzIG5vdCBhIFhNTCBzY2hlbWEgZG9jdW1lbnQiLAoJICAgIGxvY2F0aW9uKTsJCgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0JCiAgICAqdGFyZ2V0TmFtZXNwYWNlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCByb290LCAidGFyZ2V0TmFtZXNwYWNlIik7CiAgICAvKgogICAgKiBTY2hlbWEgUmVwcmVzZW50YXRpb24gQ29uc3RyYWludDogSW1wb3J0IENvbnN0cmFpbnRzIGFuZCBTZW1hbnRpY3MKICAgICovICAgIAogICAgaWYgKG5zTmFtZSA9PSBOVUxMKSB7CglpZiAoKnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18yLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBYTUwgc2NoZW1hIHRvIGJlIGltcG9ydGVkIGlzIG5vdCBleHBlY3RlZCAiCgkJInRvIGhhdmUgYSB0YXJnZXQgbmFtZXNwYWNlOyB0aGlzIGRpZmZlcnMgZnJvbSAiCgkJIml0cyB0YXJnZXQgbmFtZXNwYWNlIG9mICclcyciLCAqdGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIpOwoJfQogICAgfSBlbHNlIHsKCWlmICgqdGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIFhNTCBzY2hlbWEgdG8gYmUgaW1wb3J0ZWQgaXMgZXhwZWN0ZWQgdG8gaGF2ZSBhIHRhcmdldCAiCgkJIm5hbWVzcGFjZSBvZiAnJXMnIiwgbnNOYW1lKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEpOwoJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoKnRhcmdldE5hbWVzcGFjZSwgbnNOYW1lKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnJFeHQoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgWE1MIHNjaGVtYSB0byBiZSBpbXBvcnRlZCBpcyBleHBlY3RlZCB0byBoYXZlIGEgIgoJCSJ0YXJnZXQgbmFtZXNwYWNlIG9mICclcyc7IHRoaXMgZGlmZmVycyBmcm9tICIKCQkiaXRzIHRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJyIsIAoJCW5zTmFtZSwgKnRhcmdldE5hbWVzcGFjZSwgTlVMTCk7CgkgICAgeG1sRnJlZURvYygqZG9jKTsKCSAgICAqZG9jID0gTlVMTDsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18xKTsKCX0KICAgIH0KCiAgICBpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQoY3R4dCwgJihzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSwgbnNOYW1lKTsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9GQUlMRURfQlVJTERfSU1QT1JULAoJICAgIE5VTEwsIE5VTEwsIE5VTEwsCSAgICAKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFjcXVpcmVTY2hlbWFEb2MsICIKCSAgICAiZmFpbGVkIHRvIGJ1aWxkIGltcG9ydCB0YWJsZSIsIE5VTEwpOwoJeG1sRnJlZURvYygqZG9jKTsKCSpkb2MgPSBOVUxMOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpbXBvcnQtPnNjaGVtYUxvY2F0aW9uID0gbG9jYXRpb247CiAgICBpbXBvcnQtPmRvYyA9ICpkb2M7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbXBvcnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEltcG9ydCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGlmIAogKiBub3QgdmFsaWQgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuIAogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKeyAgICAKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2UgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24gPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlLCAqb2xkVE5TLCAqdXJsOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBmbGFncywgcmV0ID0gMDsKCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZXNwYWNlIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgCgkibmFtZXNwYWNlIiwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgCgkmbmFtZXNwYWNlKSAhPSAwKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAkgICAgCgkgICAgWE1MX1NDSEVNQVBfSU1QT1JUX05BTUVTUEFDRV9OT1RfVVJJLCAKCSAgICBOVUxMLCBOVUxMLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCAKCSAgICBOVUxMLCBuYW1lc3BhY2UsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9JTVBPUlRfTkFNRVNQQUNFX05PVF9VUkkpOwogICAgfQoKICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAKCSJzY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIAoJJnNjaGVtYUxvY2F0aW9uKSAhPSAwKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAkgICAgCgkgICAgWE1MX1NDSEVNQVBfSU1QT1JUX1NDSEVNQV9OT1RfVVJJLCAKCSAgICBOVUxMLCBOVUxMLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCAKCSAgICBOVUxMLCBuYW1lc3BhY2UsIE5VTEwsIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9JTVBPUlRfU0NIRU1BX05PVF9VUkkpOwogICAgfSAgICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbiBoZXJlIGlzIHNpbXBseSBkaXNjYXJkZWQgLi4uCiAgICAgICAgICovCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fSU1QT1JUX0NISUxELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICAvKgogICAgKiBBcHBseSBhZGRpdGlvbmFsIGNvbnN0cmFpbnRzLgogICAgKi8KICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkgewoJLyoKCSogMS4xIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgcHJlc2VudCwgdGhlbiBpdHMgt2FjdHVhbCB2YWx1ZbcgCgkqIG11c3Qgbm90IG1hdGNoIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgZW5jbG9zaW5nIDxzY2hlbWE+J3MgCgkqIHRhcmdldE5hbWVzcGFjZSBbYXR0cmlidXRlXS4KCSovCglpZiAoeG1sU3RyRXF1YWwoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5hbWVzcGFjZSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBub3QgbWF0Y2ggIgoJCSJ0aGUgdGFyZ2V0IG5hbWVzcGFjZSAnJXMnIG9mIHRoZSBpbXBvcnRpbmcgc2NoZW1hIiwKCQlzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzFfMSk7Cgl9CiAgICB9IGVsc2UgewoJLyoKCSogMS4yIElmIHRoZSBuYW1lc3BhY2UgW2F0dHJpYnV0ZV0gaXMgbm90IHByZXNlbnQsIHRoZW4gdGhlIGVuY2xvc2luZyAKCSogPHNjaGVtYT4gbXVzdCBoYXZlIGEgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMV8yLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBhdHRyaWJ1dGUgJ25hbWVzcGFjZScgbXVzdCBiZSBleGlzdGVudCBpZiAiCgkJInRoZSBpbXBvcnRpbmcgc2NoZW1hIGhhcyBubyB0YXJnZXQgbmFtZXNwYWNlIiwKCQlOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMV8yKTsKCX0KICAgIH0KICAgIC8qCiAgICAqIExvY2F0ZSBhbmQgYXF1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYyhjdHh0LCBzY2hlbWEsIG5vZGUsIG5hbWVzcGFjZSwgCglzY2hlbWFMb2NhdGlvbiwgJmRvYywgJnRhcmdldE5hbWVzcGFjZSwgMCk7CiAgICBpZiAocmV0ICE9IDApIHsKCWlmIChkb2MgIT0gTlVMTCkKCSAgICB4bWxGcmVlRG9jKGRvYyk7CglyZXR1cm4gKHJldCk7CiAgICB9IGVsc2UgaWYgKGRvYyAhPSBOVUxMKSB7ICAgICAgIAoJLyoKCSogU2F2ZSBhbmQgcmVzZXQgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJdXJsID0gY3R4dC0+VVJMOyAgCgkvKiBUT0RPOiBJcyB1c2luZyB0aGUgZG9jLT5VUkwgaGVyZSBjb3JyZWN0PyAqLwoJY3R4dC0+VVJMID0gZG9jLT5VUkw7CglmbGFncyA9IHNjaGVtYS0+ZmxhZ3M7CglvbGRUTlMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCS8qCgkqIFBhcnNlIHRoZSBzY2hlbWEuCgkqLwoJcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7Cgl4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHNjaGVtYSk7Cgl4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKGN0eHQsIHNjaGVtYSwgcm9vdCk7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5hbWVzcGFjZTsKCXhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCByb290LT5jaGlsZHJlbik7CgkvKgoJKiBSZXN0b3JlIHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCXNjaGVtYS0+ZmxhZ3MgPSBmbGFnczsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gb2xkVE5TOwoJY3R4dC0+VVJMID0gdXJsOwogICAgfQogICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbmNsdWRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBJbmNsdWRlIGRlZmluaXRpb24KICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiwgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGU7CiAgICBpbnQgd2FzQ29udmVydGluZ05zID0gMDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzYXZlRmxhZ3M7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgTlVMTCwgYXR0cik7CQkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICAvKgogICAgICogUHJlbGltaW5hcnkgc3RlcCwgZXh0cmFjdCB0aGUgVVJJLVJlZmVyZW5jZSBmb3IgdGhlIGluY2x1ZGUgYW5kCiAgICAgKiBtYWtlIGFuIFVSSSBmcm9tIHRoZSBiYXNlLgogICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInNjaGVtYUxvY2F0aW9uIik7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CiAgICAgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEw7CiAgICAgICAgeG1sQ2hhciAqdXJpID0gTlVMTDsKCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgJnNjaGVtYUxvY2F0aW9uKSAhPSAwKQoJICAgIHJldHVybiAoLTEpOwoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgdXJpID0geG1sQnVpbGRVUkkoc2NoZW1hTG9jYXRpb24sIG5vZGUtPmRvYy0+VVJMKTsKCX0gZWxzZSB7CgkgICAgdXJpID0geG1sQnVpbGRVUkkoc2NoZW1hTG9jYXRpb24sIGJhc2UpOwoJICAgIHhtbEZyZWUoYmFzZSk7Cgl9CglpZiAodXJpICE9IE5VTEwpIHsKCSAgICBzY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdXJpLCAtMSk7CgkgICAgeG1sRnJlZSh1cmkpOwoJfQogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9JTkNMVURFX1NDSEVNQV9OT19VUkksIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsICJzY2hlbWFMb2NhdGlvbiIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlIGFubm90YXRpb25zIGhlcmUgYXJlIHNpbXBseSBkaXNjYXJkZWQgLi4uCiAgICAgICAgICovCiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0lOQ0xVREVfQ0hJTEQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KCiAgICAvKgogICAgICogRmlyc3Qgc3RlcCBpcyB0byBwYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgaW50byBhbiBET00vSW5mb3NldAogICAgICovCiAgICBkb2MgPSB4bWxSZWFkRmlsZSgoY29uc3QgY2hhciAqKSBzY2hlbWFMb2NhdGlvbiwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICBpZiAoZG9jID09IE5VTEwpIHsKCS8qCgkqIFRPRE86IEl0IGlzIG5vdCBhbiBlcnJvciBmb3IgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSAKCSogc2NoZW1hTG9jYXRpb24gW2F0dHJpYnV0ZV0gdG8gZmFpbCB0byByZXNvbHZlIGl0IGFsbCwgaW4gd2hpY2ggCgkqIGNhc2Ugbm8gY29ycmVzcG9uZGluZyBpbmNsdXNpb24gaXMgcGVyZm9ybWVkLiAKCSogU28gZG8gd2UgbmVlZCBhIHdhcm5pbmcgcmVwb3J0IGhlcmU/CgkqLwoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgICJGYWlsZWQgdG8gbG9hZCB0aGUgZG9jdW1lbnQgJyVzJyBmb3IgaW5jbHVzaW9uIiwgc2NoZW1hTG9jYXRpb24pOwoJcmV0dXJuKC0xKTsKICAgIH0KCiAgICAvKgogICAgICogVGhlbiBleHRyYWN0IHRoZSByb290IG9mIHRoZSBzY2hlbWEKICAgICAqLwogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfTk9ST09ULAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBpbmNsdWRlZCBkb2N1bWVudCAnJXMnIGhhcyBubyBkb2N1bWVudCAiCgkgICAgImVsZW1lbnQiLCBzY2hlbWFMb2NhdGlvbik7CQkKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgc2NoZW1hcyB0b3AgbGV2ZWwgZWxlbWVudAogICAgICovCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIlRoZSBkb2N1bWVudCAnJXMnIHRvIGJlIGluY2x1ZGVkIGlzIG5vdCBhIHNjaGVtYSBkb2N1bWVudCIsIAoJICAgIHNjaGVtYUxvY2F0aW9uKTsKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIAogICAgdGFyZ2V0TmFtZXNwYWNlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCByb290LCAidGFyZ2V0TmFtZXNwYWNlIik7CiAgICAvKgogICAgKiAyLjEgU0lJIGhhcyBhIHRhcmdldE5hbWVzcGFjZSBbYXR0cmlidXRlXSwgYW5kIGl0cyC3YWN0dWFsIAogICAgKiB2YWx1ZbcgaXMgaWRlbnRpY2FsIHRvIHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdGFyZ2V0TmFtZXNwYWNlIAogICAgKiBbYXR0cmlidXRlXSBvZiBTSUmSICh3aGljaCBtdXN0IGhhdmUgc3VjaCBhbiBbYXR0cmlidXRlXSkuCiAgICAqLwogICAgaWYgKHRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CglpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU5DTFVERSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgaW5jbHVkZWQgc2NoZW1hICIKCQkiJyVzJyBoYXMgdG8gYmUgYWJzZW50LCBzaW5jZSB0aGUgaW5jbHVkaW5nIHNjaGVtYSAiCgkJImhhcyBubyB0YXJnZXQgbmFtZXNwYWNlIiwgCgkJc2NoZW1hTG9jYXRpb24pOwoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHRhcmdldE5hbWVzcGFjZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSB0YXJnZXQgbmFtZXNwYWNlICclcycgb2YgdGhlIGluY2x1ZGVkIHNjaGVtYSAnJXMnICIKCQkiZGlmZmVycyBmcm9tICclcycgb2YgdGhlIGluY2x1ZGluZyBzY2hlbWEiLCAKCQl0YXJnZXROYW1lc3BhY2UsIHNjaGVtYUxvY2F0aW9uLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfSBlbHNlIGlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7ICAgICAJCglpZiAoKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUykgPT0gMCkgewoJICAgIHNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlM7CSAgICAKCX0gZWxzZQoJICAgIHdhc0NvbnZlcnRpbmdOcyA9IDE7CiAgICB9CiAgICAvKgogICAgICogcmVnaXN0ZXIgdGhlIGluY2x1ZGUKICAgICAqLwogICAgaW5jbHVkZSA9ICh4bWxTY2hlbWFJbmNsdWRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpKTsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGluY2x1ZGVkIHNjaGVtYSIsIE5VTEwpOwoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIG1lbXNldChpbmNsdWRlLCAwLCBzaXplb2YoeG1sU2NoZW1hSW5jbHVkZSkpOwogICAgaW5jbHVkZS0+c2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHNjaGVtYUxvY2F0aW9uLCAtMSk7CiAgICBpbmNsdWRlLT5kb2MgPSBkb2M7CiAgICBpbmNsdWRlLT5uZXh0ID0gc2NoZW1hLT5pbmNsdWRlczsKICAgIHNjaGVtYS0+aW5jbHVkZXMgPSBpbmNsdWRlOwoKICAgIC8qCiAgICAgKiBwYXJzZSB0aGUgZGVjbGFyYXRpb25zIGluIHRoZSBpbmNsdWRlZCBmaWxlIGxpa2UgaWYgdGhleQogICAgICogd2VyZSBpbiB0aGUgb3JpZ2luYWwgZmlsZS4KICAgICAqLyAgICAKICAgIC8qCiAgICAqIFRPRE86IFRoZSBjb21wbGV0ZSB2YWxpZGF0aW9uIG9mIHRoZSA8c2NoZW1hPiBlbGVtZW50IGlzIG5vdCBkb25lLgogICAgKi8KICAgIC8qICAgIAogICAgKiBUaGUgZGVmYXVsdCB2YWx1ZXMgKCJibG9ja0RlZmF1bHQiLCAiZWxlbWVudEZvcm1EZWZhdWx0IiwgZXRjLikKICAgICogYXJlIHNldCB0byB0aGUgdmFsdWVzIG9mIHRoZSBpbmNsdWRlZCBzY2hlbWEgYW5kIHJlc3RvcmVkIGFmdGVyd2FyZHMuCiAgICAqLyAgICAKICAgIHNhdmVGbGFncyA9IHNjaGVtYS0+ZmxhZ3M7CiAgICB4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHNjaGVtYSk7CiAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKGN0eHQsIHNjaGVtYSwgcm9vdCk7CiAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgcm9vdC0+Y2hpbGRyZW4pOwogICAgc2NoZW1hLT5mbGFncyA9IHNhdmVGbGFnczsKICAgIC8qCiAgICAqIFJlbW92ZSB0aGUgY29udmVydGluZyBmbGFnLgogICAgKi8KICAgIGlmICgod2FzQ29udmVydGluZ05zID09IDApICYmIAoJKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUykpCglzY2hlbWEtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TOwogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ2hvaWNlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDaG9pY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUNob2ljZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBsYXN0ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgImNob2ljZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgIm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgCgkiKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpKSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CiAgICAgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQW55KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyogVE9ETzogZXJyb3IgY29kZS4gKi8KCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9DSE9JQ0VfQ0hJTEQsCgkgICAgTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIik7CiAgICB9CgogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNlcXVlbmNlIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjc2VxICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgdHlwZSwgYXR0cik7CQkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIHR5cGUtPm1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsIAoJIihub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjdHh0LT5jb250YWluZXIgPSAoY29uc3QgeG1sQ2hhciAqKSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKICAgICAgICBzdWJ0eXBlID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbnkoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0KICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0VRVUVOQ0VfQ0hJTEQsCgkgICAgTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIik7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CgogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFJlc3RyaWN0aW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsgICAgCiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjcmVzdHIgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJiYXNlIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgdHlwZSwgYXR0cik7CQkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQkKICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgLyoKICAgICogQXR0cmlidXRlICJiYXNlIi4KICAgICovCiAgICB0eXBlLT5iYXNlID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJiYXNlIiwgJih0eXBlLT5iYXNlTnMpKTsKICAgIGlmICgodHlwZS0+YmFzZSA9PSBOVUxMKSAmJiAKCShjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCS8qIFRPRE86IFRoaW5rIGFib3V0IHRoZSBlcnJvciBjb2RlLiAqLwoJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUkVTVFJJQ1RJT05fTk9OQU1FX05PUkVGLCAKCSAgICBOVUxMLCB0eXBlLCBub2RlLCAiYmFzZSIsIE5VTEwpOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewoJICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9CiAgICB9IGVsc2UgaWYgKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICBpZiAodHlwZS0+YmFzZSAhPSBOVUxMKSB7CgkJLyogCgkJKiBzcmMtcmVzdHJpY3Rpb24tYmFzZS1vci1zaW1wbGVUeXBlCgkJKiBFaXRoZXIgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gb3IgdGhlIHNpbXBsZVR5cGUgW2NoaWxkXSBvZiB0aGUgCgkJKiA8cmVzdHJpY3Rpb24+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguIAoJCSovCgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19SRVNUUklDVElPTl9CQVNFX09SX1NJTVBMRVRZUEUsCgkJICAgIE5VTEwsIE5VTEwsIHR5cGUtPm5vZGUsIGNoaWxkLAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAnYmFzZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwoJICAgIH0gZWxzZSB7CgkJc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkJdHlwZS0+YmFzZVR5cGUgPSBzdWJ0eXBlOwoJICAgIH0JICAgICAgICAKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfSBlbHNlIGlmIChjdHh0LT5wYXJlbnRJdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CSAgICAgICAgCQogICAgfQogICAgaWYgKChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB8fAoJKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSkgewoJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsIGxhc3RmYWNldCA9IE5VTEw7CQoJCQoJLyoKCSogQWRkIHRoZSBmYWNldHMgdG8gdGhlIHBhcmVudCBzaW1wbGVUeXBlL2NvbXBsZXhUeXBlLgoJKi8KCS8qCgkqIFRPRE86IERhdGF0eXBlczogNC4xLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9uIG9mIAoJKiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiAKCSogKlNpbmdsZSBGYWNldCBWYWx1ZSoKCSovCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgIm1pbkluY2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5FeGNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4SW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heEV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJ0b3RhbERpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJmcmFjdGlvbkRpZ2l0cyIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJwYXR0ZXJuIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImVudW1lcmF0aW9uIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIndoaXRlU3BhY2UiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1heExlbmd0aCIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtaW5MZW5ndGgiKSkpIHsKCSAgICBmYWNldCA9IHhtbFNjaGVtYVBhcnNlRmFjZXQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKGZhY2V0ICE9IE5VTEwpIHsKCQlpZiAobGFzdGZhY2V0ID09IE5VTEwpCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5mYWNldHMgPSBmYWNldDsJCQkKCQllbHNlCgkJICAgIGxhc3RmYWNldC0+bmV4dCA9IGZhY2V0OwoJCWxhc3RmYWNldCA9IGZhY2V0OwoJCWxhc3RmYWNldC0+bmV4dCA9IE5VTEw7CgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CgkvKgoJKiBDcmVhdGUgbGlua3MgZm9yIGRlcml2YXRpb24gYW5kIHZhbGlkYXRpb24uCgkqLwkgICAgCglpZiAobGFzdGZhY2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rLCBsYXN0RmFjZXRMaW5rID0gTlVMTDsKCgkgICAgZmFjZXQgPSBjdHh0LT5jdHh0VHlwZS0+ZmFjZXRzOwoJICAgIGRvIHsJCSAgICAKCQlmYWNldExpbmsgPSAoeG1sU2NoZW1hRmFjZXRMaW5rUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0TGluaykpOwoJCWlmIChmYWNldExpbmsgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgZmFjZXQgbGluayIsIE5VTEwpOwoJCSAgICB4bWxGcmVlKGZhY2V0TGluayk7CgkJICAgIHJldHVybiAoTlVMTCk7CgkJfQkKCQlmYWNldExpbmstPmZhY2V0ID0gZmFjZXQ7CgkJZmFjZXRMaW5rLT5uZXh0ID0gTlVMTDsKCQlpZiAobGFzdEZhY2V0TGluayA9PSBOVUxMKSAKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZhY2V0U2V0ID0gZmFjZXRMaW5rOwkJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJZWxzZQoJCSAgICBsYXN0RmFjZXRMaW5rLT5uZXh0ID0gZmFjZXRMaW5rOwoJCWxhc3RGYWNldExpbmsgPSBmYWNldExpbms7CgkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCX0KICAgIH0gICAgCiAgICBpZiAoY3R4dC0+Y3R4dFR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsKCSAgICBjdHh0LT5jdHh0VHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCS8qIFRPRE86IFRoaW5rIGFib3V0IHRoZSBlcnJvciBjb2RlLiAqLwoJaWYgKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgewkgICAgCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfVU5LTk9XTl9SRVNUUklDVElPTl9DSElMRCwgCgkJTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJImFubm90YXRpb24/LCAoZ3JvdXAgfCBhbGwgfCBjaG9pY2UgfCBzZXF1ZW5jZSk/LCAiCgkJIigoYXR0cmlidXRlIHwgYXR0cmlidXRlR3JvdXApKiwgYW55QXR0cmlidXRlPykpIik7Cgl9IGVsc2UgaWYgKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CgkgICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1VOS05PV05fUkVTVFJJQ1RJT05fQ0hJTEQsIAoJCU5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPywgKG1pbkV4Y2x1c2l2ZSB8IG1pbkluY2x1c2l2ZSB8ICIKCQkibWF4RXhjbHVzaXZlIHwgbWF4SW5jbHVzaXZlIHwgdG90YWxEaWdpdHMgfCBmcmFjdGlvbkRpZ2l0cyB8ICIKCQkibGVuZ3RoIHwgbWluTGVuZ3RoIHwgbWF4TGVuZ3RoIHwgZW51bWVyYXRpb24gfCB3aGl0ZVNwYWNlIHwgIgoJCSJwYXR0ZXJuKSopPywgKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKCX0gZWxzZSB7CgkgICAgLyogU2ltcGxlIHR5cGUgKi8KCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9VTktOT1dOX1JFU1RSSUNUSU9OX0NISUxELCAKCQlOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiKGFubm90YXRpb24/LCAoc2ltcGxlVHlwZT8sIChtaW5FeGNsdXNpdmUgfCBtaW5JbmNsdXNpdmUgfCAiCgkJIm1heEV4Y2x1c2l2ZSB8IG1heEluY2x1c2l2ZSB8IHRvdGFsRGlnaXRzIHwgZnJhY3Rpb25EaWdpdHMgfCAiCgkJImxlbmd0aCB8IG1pbkxlbmd0aCB8IG1heExlbmd0aCB8IGVudW1lcmF0aW9uIHwgd2hpdGVTcGFjZSB8ICIKCQkicGF0dGVybikqKSkiKTsKCX0KICAgIH0gICAgICAgCiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VFeHRlbnNpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEV4dGVuc2lvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgImV4dGVuc2lvbiAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKCiAgICB0eXBlLT5iYXNlID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJiYXNlIiwgJih0eXBlLT5iYXNlTnMpKTsKICAgIGlmICh0eXBlLT5iYXNlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfRVhURU5TSU9OX05PX0JBU0UsCgkgICAgIjxleHRlbnNpb24+OiBUaGUgYXR0cmlidXRlIFwiYmFzZVwiIGlzIG1pc3NpbmcuXG4iLCAKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUFsbChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoc3VidHlwZSAhPSBOVUxMKQogICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmICgoY3R4dC0+Y3R4dFR5cGUgIT0gTlVMTCkgJiYKCShjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55QXR0cmlidXRlIikpIHsJICAgIAoJICAgIGN0eHQtPmN0eHRUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IAoJCXhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fRVhURU5TSU9OX0NISUxELAoJICAgICI8ZXh0ZW5zaW9uPiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwgdHlwZS0+bmFtZSwKCSAgICBOVUxMKTsKICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZUNvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAic2ltcGxlQ29udGVudCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IHR5cGU7CiAgICBzdWJ0eXBlID0gTlVMTDsgICAgCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TSU1QTEVDT05URU5UX0NISUxELAoJICAgICI8c2ltcGxlQ29udGVudD4gaGFzIHVuZXhwZWN0ZWQgY29udGVudC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJjb21wbGV4Q29udGVudCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7ICAgIAogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9DT01QTEVYQ09OVEVOVF9DSElMRCwKCSAgICAiPGNvbXBsZXhDb250ZW50PiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4IFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIGNoYXIgYnVmWzEwMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgImNvbXBsZXhUeXBlICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgluYW1lID0gKGNvbnN0IHhtbENoYXIgKilidWY7Cgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgfSBlbHNlIHsKCiAgICAgICAgLyogbG9jYWwgPSB4bWxTY2hlbWFHZXROYW1lc3BhY2UoY3R4dCwgc2NoZW1hLCBub2RlLCBuYW1lLCAmbnMpOyAqLwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbm9kZSk7CiAgICB9CiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBOVUxMLCB0eXBlLCBub2RlLCAibWl4ZWQiLCAwKSkgCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOyAgICAKCiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKICAgIC8qIFNldCBhcyBkZWZhdWx0IGZvciBhdHRyaWJ1dGUgd2lsZGNhcmRzLiAKICAgICogVGhpcyB3aWxsIGJlIG9ubHkgY2hhbmdlZCBpZiBhIGNvbXBsZXggdHlwZQogICAgKiBpbmhlcml0cyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQgZnJvbSBhIGJhc2UgdHlwZS4KICAgICovCiAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgY3R4dC0+Y29udGFpbmVyID0gbmFtZTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBjdHh0LT5jdHh0VHlwZSA9IHR5cGU7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlQ29udGVudCIpKSB7CgkvKiAzLjQuMyA6IDIuMiAgCgkgKiBTcGVjaWZ5aW5nIG1peGVkPSd0cnVlJyB3aGVuIHRoZSA8c2ltcGxlQ29udGVudD4KCSAqIGFsdGVybmF0aXZlIGlzIGNob3NlbiBoYXMgbm8gZWZmZWN0CgkgKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4Q29udGVudCIpKSB7CiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICBjaGlsZCA9IHhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKGN0eHQsIHNjaGVtYSwgY2hpbGQsIHR5cGUpOwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CSAgICAKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQ09NUExFWFRZUEVfQ0hJTEQsCgkgICAgIkNvbXBsZXggdHlwZSBkZWZpbml0aW9uIFwiJXNcIiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKQoJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEOwogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIGEgbm9kZSBzZXQKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZVNjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUHRyIHNjaGVtYSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVBhcnNlIG9ubHkgYW5kIGlzIHVzZWQgaWYKICAgICogdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgdGhlIEFQSTsgaS5lLiBub3QKICAgICogYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGlmIChJU19TQ0hFTUEobm9kZSwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwoKICAgICAgICBzY2hlbWEgPSB4bWxTY2hlbWFOZXdTY2hlbWEoY3R4dCk7CiAgICAgICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwoJLyoKCSogRGlzYWJsZSBidWlsZCBvZiBsaXN0IG9mIGl0ZW1zLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidGFyZ2V0TmFtZXNwYWNlIik7IAkJCglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZ2YWwpOwoJICAgIC8qCgkgICAgKiBUT0RPOiBTaG91bGQgd2UgcHJvY2VlZCB3aXRoIGFuIGludmFsaWQgdGFyZ2V0IG5hbWVzcGFjZT8KCSAgICAqLwoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCX0gZWxzZSB7CgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBOVUxMOwoJfQoJLyoKCSogQWRkIHRoZSBjdXJyZW50IG5zIG5hbWUgYW5kIGxvY2F0aW9uIHRvIHRoZSBpbXBvcnQgdGFibGU7CgkqIHRoaXMgaXMgbmVlZGVkIHRvIGhhdmUgYSBjb25zaXN0ZW50IG1lY2hhbmlzbSwgcmVnYXJkbGVzcwoJKiBpZiBhbGwgc2NoZW1hdGEgYXJlIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5IGZpcmVkIGJ5IHRoZQoJKiBpbnN0YW5jZSBvciBpZiB0aGUgc2NoZW1hIHRvIGJlIHVzZWQgd2FzIHNwZWNpZmllZCB2aWEKCSogdGhlIEFQSS4KCSovCglpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQoY3R4dCwgJihzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSwKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CglpZiAoaW1wb3J0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkJTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBhcnNlU2NoZW1hLCAiCgkJImZhaWxlZCB0byBhZGQgYW4gaW1wb3J0IGVudHJ5IiwgTlVMTCk7CgkgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwoJICAgIHNjaGVtYSA9IE5VTEw7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCWltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBjdHh0LT5VUkw7CgkvKgoJKiBOT1RFOiBXZSB3b24ndCBzZXQgdGhlIGRvYyBoZXJlLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBmcmVlZAoJKiBpZiB0aGUgaW1wb3J0IHN0cnVjdCBpcyBmcmVlZC4KCSogaW1wb3J0LT5kb2MgPSBjdHh0LT5kb2M7CgkqLwoKCS8qIFRPRE86IENoZWNrIGlkLiAqLwogICAgICAgIHNjaGVtYS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoJeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgInZlcnNpb24iLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19UT0tFTiksICYoc2NoZW1hLT52ZXJzaW9uKSk7CgoJeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyhjdHh0LCBzY2hlbWEsIG5vZGUpOwkKICAgICAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgbm9kZS0+Y2hpbGRyZW4pOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxEb2NQdHIgZG9jOwoKCWRvYyA9IG5vZGUtPmRvYzsKCiAgICAgICAgaWYgKChkb2MgIT0gTlVMTCkgJiYgKGRvYy0+VVJMICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIlRoZSBmaWxlIFwiJXNcIiBpcyBub3QgYSBYTUwgc2NoZW1hLlxuIiwgZG9jLT5VUkwsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiVGhlIGZpbGUgaXMgbm90IGEgWE1MIHNjaGVtYS5cbiIsIE5VTEwsIE5VTEwpOwoJfQoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwogICAgICAgICAgICBzY2hlbWEgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIGN0eHQtPm5iZXJyb3JzID0gbmJlcnJvcnM7CiNpZmRlZiBERUJVRwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2UoKSBmYWlsZWRcbiIpOwojZW5kaWYKICAgIHJldHVybiAoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpbmcgdXNpbmcgU2NoZW1hcwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVJlYWRpbmcvV3JpdGluZyBTY2hlbWFzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAgLyogV2lsbCBiZSBlbmFibGVkIGlmIGl0IGlzIGNsZWFyIHdoYXQgb3B0aW9ucyBhcmUgbmVlZGVkLiAqLwovKioKICogeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFQYXJzZXJPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgcGFyc2UuCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgIGludCBvcHRpb25zKQoJCQkJCQp7CiAgICBpbnQgaTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBXQVJOSU5HOiBDaGFuZ2UgdGhlIHN0YXJ0IHZhbHVlIGlmIGFkZGluZyB0byB0aGUKICAgICogeG1sU2NoZW1hUGFyc2VPcHRpb24uCiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgcmV0dXJuICgtMSk7ICAgCiAgICAgICAgfQkKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OiBhIHNjaGVtYSBwYXJzZXIgY29udGV4dCAKICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9mIHRoZSBwYXJzZXIgY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQoJCQkJCQp7ICAgIAogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZSAKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7ICAgIAp9Cgogdm9pZCAqY3VySXRlbXM7ICAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgbmJDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IHNpemVDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwoKI2VuZGlmCgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dChjb25zdCBjaGFyICpVUkwpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoY29uc3QgY2hhciAqVVJMLCB4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5kaWN0ID0gZGljdDsKICAgIHJldC0+VVJMID0geG1sRGljdExvb2t1cChkaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldC0+aW5jbHVkZXMgPSAwOwogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0OgogKiBAZG9jOiAgYSBwcmVwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBkb2N1bWVudC4KICogTkIuIFRoZSBkb2N1bWVudCBtYXkgYmUgbW9kaWZpZWQgZHVyaW5nIHRoZSBwYXJzaW5nIHByb2Nlc3MuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0KHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChkb2MgPT0gTlVMTCkKICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAoJCQkgIE5VTEwpOwogICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgLyogVGhlIGFwcGxpY2F0aW9uIGhhcyByZXNwb25zaWJpbGl0eSBmb3IgdGhlIGRvY3VtZW50ICovCiAgICByZXQtPnByZXNlcnZlID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5kb2MgIT0gTlVMTCAmJiAhY3R4dC0+cHJlc2VydmUpCiAgICAgICAgeG1sRnJlZURvYyhjdHh0LT5kb2MpOwogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpIHsKCXhtbEZyZWUoY3R4dC0+YXNzZW1ibGUtPml0ZW1zKTsKCXhtbEZyZWUoY3R4dC0+YXNzZW1ibGUpOwogICAgfQogICAgeG1sRGljdEZyZWUoY3R4dC0+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+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDp7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCgkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtOwogICAgICAgICAgICAgICAgaW50IGxheDsKCiAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgaWYgKHN1YnR5cGVzID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoJCSAgICAvKgoJCSAgICAgKiB0aGUgZm9sbG93aW5nICdpZicgd2FzIG5lZWRlZCB0byBmaXggYnVnIDEzOTg5NwoJCSAgICAgKiBub3QgcXVpdGUgc3VyZSB3aHkgaXQgb25seSBuZWVkcyB0byBiZSBkb25lIGZvcgoJCSAgICAgKiBlbGVtZW50cyB3aXRoIGEgJ3JlZicsIGJ1dCBpdCBzZWVtcyB0byB3b3JrIG9rLgoJCSAgICAgKi8KCQkgICAgaWYgKHN1YnR5cGVzLT5yZWYgIT0gTlVMTCkKCQkgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBzdWJ0eXBlczsJCSAgICAKICAgICAgICAgICAgICAgICAgICAvKiBUT0RPIDogaGFuZGxlIHRoZSBuYW1lc3BhY2UgdG9vICovCiAgICAgICAgICAgICAgICAgICAgaWYgKChlbGVtLT5taW5PY2N1cnMgPT0gMSkgJiYgKGVsZW0tPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld09uY2VUcmFucyhjdHh0LT5hbSwgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLCBlbGVtLT5uYW1lLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCBzdWJ0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudFRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLCBlbGVtLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bWluT2NjdXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bWF4T2NjdXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGF4ID0gdHlwZS0+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+YXR0cmlidXRlV2lsZGNhcmQtPm5vZGU7ICAKCQkgICAgCgkJfSBlbHNlIGlmICh4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoY3R4dCwgKmNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQoKmNvbXBsZXRlV2lsZCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJICAgIH0KCX0KCWF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgIAkJICAgICAgICAgICAgICAgICAKICAgIHJldHVybiAoMCk7ICAgCn0KCi8qKgogKiB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROczoKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDEpOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigxKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYgCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsJCgkKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIAogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBjdXIsIGJhc2UsIHRtcCwgaWQgPSBOVUxMLCBwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIAoJbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW55VHlwZTsKICAgIGludCBiYXNlSXNBbnlUeXBlID0gMDsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgZXJyID0gMDsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKiAKICAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIHdpdGggY29tcGxleCBjb250ZW50IFNjaGVtYSBDb21wb25lbnQuCiAgICAgKgogICAgICogQXR0cmlidXRlIHVzZXMuCiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkJICAgICAgImF0dHJpYnV0ZSB1c2VzIGFscmVhZHkgYnVpbGRlZC5cbiIsCgkJICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCQkgICAgICAiY29tcGxleCB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2VUeXBlID09IGFueVR5cGUpCgliYXNlSXNBbnlUeXBlID0gMTsKICAgIC8qCiAgICAgKiBJbmhlcml0IHRoZSBhdHRyaWJ1dGUgdXNlcyBvZiB0aGUgYmFzZSB0eXBlLgogICAgICovCiAgICAvKgogICAgICogTk9URTogSXQgaXMgYWxsb3dlZCB0byAiZXh0ZW5kIiB0aGUgYW55VHlwZSBjb21wbGV4IHR5cGUuCiAgICAgKi8KICAgIGlmICghYmFzZUlzQW55VHlwZSkgewoJaWYgKGJhc2VUeXBlICE9IE5VTEwpIHsKCSAgICBmb3IgKGN1ciA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVVc2VzOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CgkJdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCQkJImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIG9mIGNvbXBsZXhUeXBlIiwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQl0bXAtPmF0dHIgPSBjdXItPmF0dHI7CgkJdG1wLT5uZXh0ID0gTlVMTDsKCQlpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJfSBlbHNlIAoJCSAgICBsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQlsYXN0QmFzZVVzZSA9IHRtcDsgCgkgICAgfQoJfQogICAgfQogICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCSgodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgfHwgCgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpKSB7CgkvKiAKCSogdHlwZSAtLT4gKDxzaW1wbGVDb250ZW50Pnw8Y29tcGxleENvbnRlbnQ+KSAKCSogICAgICAgIC0tPiAoPHJlc3RyaWN0aW9uPnw8ZXh0ZW5zaW9uPikgLS0+IGF0dHJpYnV0ZXMKCSovIAoJYXR0cnMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CiAgICB9IGVsc2UgewoJLyogU2hvcnQgaGFuZCBmb3JtIG9mIHRoZSBjb21wbGV4VHlwZS4gKi8KCWF0dHJzID0gdHlwZS0+YXR0cmlidXRlczsKICAgIH0KICAgIC8qCiAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgd2lsZGNhcmRzLgogICAgKi8JCiAgICBlcnIgPSB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCglhdHRycywgJnR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKTsgICAgCiAgICAvKgogICAgKiBOT1RFOiBEdXJpbmcgdGhlIHBhcnNlIHRpbWUsIHRoZSB3aWxkY2FyZCBpcyBjcmVhdGVkIG9uIHRoZSBjb21wbGV4VHlwZQogICAgKiBkaXJlY3RseSwgaWYgZW5jb3VudGVyZWQgaW4gYSA8cmVzdHJpY3Rpb24+IG9yIDxleHRlbnNpb24+IGVsZW1lbnQuCiAgICAqLwogICAgaWYgKGVyciA9PSAtMSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJICAgICJmYWlsZWQgdG8gYnVpbGQgYW4gaW50ZXJzZWN0ZWQgYXR0cmlidXRlIHdpbGRjYXJkLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgJiYgCgkoKGJhc2VJc0FueVR5cGUpIHx8CgkgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAJICAgIAoJICAoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCSAgICAgIAoJICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSkpIHsJICAgIAoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVW5pb24gdGhlIGNvbXBsZXRlIHdpbGRjYXJkIHdpdGggdGhlIGJhc2Ugd2lsZGNhcmQuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoY3R4dCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJcmV0dXJuICgtMSk7Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBKdXN0IGluaGVyaXQgdGhlIHdpbGRjYXJkLgoJICAgICovCgkgICAgLyoKCSAgICAqIE5PVEU6IFRoaXMgaXMgdGhlIG9ubHkgY2FzZSB3aGVyZSBhbiBhdHRyaWJ1dGUgCiAgICAgICAgICAgICogd2lsZGNhcmQgaXMgc2hhcmVkLgogICAgICAgICAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRCkKCQl0eXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSBiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQ7Cgl9CiAgICB9CiAgICAKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyogCgkgICAgKiBEZXJpdmF0aW9uIFZhbGlkIChSZXN0cmljdGlvbiwgQ29tcGxleCkgCSAgICAKCSAgICAqIDQuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGFsc28gaGF2ZSBvbmUuIAoJICAgICovCgkgICAgaWYgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSB7CSAgCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCgkJICAgICJUaGUgdHlwZSBoYXMgYW4gYXR0cmlidXRlIHdpbGRjYXJkLCAiCgkJICAgICJidXQgdGhlIGJhc2UgdHlwZSAlcyBkb2VzIG5vdCBoYXZlIG9uZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCgKCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJLyogNC4yICovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIiAKCQkgICAgInN1YnNldCBvZiB0aGUgd2lsZGNhcmQgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJICAgIAoJCXJldHVybiAoMSk7CgkgICAgfQoJICAgIC8qIDQuMyBVbmxlc3MgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILd1ci10eXBlIAoJICAgICogZGVmaW5pdGlvbrcsIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgCgkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30gbXVzdCBiZSBpZGVudGljYWwgdG8gb3IgCgkgICAgKiBzdHJvbmdlciB0aGFuIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2F0dHJpYnV0ZSAKCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSwgd2hlcmUgc3RyaWN0IGlzIHN0cm9uZ2VyIAoJICAgICogdGhhbiBsYXggaXMgc3Ryb25nZXIgdGhhbiBza2lwLgoJICAgICovCgkgICAgaWYgKCh0eXBlLT5iYXNlVHlwZSAhPSBhbnlUeXBlKSAmJiAKCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA8IAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzMsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgJ3Byb2Nlc3MgY29udGVudHMnIG9mIHRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgd2Vha2VyIHRoYW4gIgoJCSAgICAidGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkvKgoJKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCgkqIEF0IHRoaXMgcG9pbnQgdGhlIHR5cGUgYW5kIHRoZSBiYXNlIGhhdmUgYm90aCwgZWl0aGVyCgkqIG5vIHdpbGRjYXJkIG9yIGEgd2lsZGNhcmQuCgkqLwoJaWYgKChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCSAgICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSkgewoJICAgIC8qIDEuMyAqLwoJICAgIGlmICh4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkgICAgIlRoZSBhdHRyaWJ1dGUgd2lsZGNhcmQgaXMgbm90IGEgdmFsaWQgIiAKCQkgICAgInN1cGVyc2V0IG9mIHRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQoJCXJldHVybiAoMSk7CQkKCSAgICB9Cgl9CQkKICAgIH0JCgogICAgLyoKICAgICAqIEdhdGhlciBhdHRyaWJ1dGUgdXNlcyBkZWZpbmVkIGJ5IHRoaXMgdHlwZS4KICAgICAqLwogICAgaWYgKGF0dHJzICE9IE5VTEwpIHsKCWlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCBhdHRycywgCgkgICAgJnVzZXMsICZsYXN0VXNlKSA9PSAtMSkgewoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgLyogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0IDQuCiAgICAgKiAiVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKICAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLiIKICAgICAqCiAgICAgKiBGb3IgImV4dGVuc2lvbiIgdGhpcyBpcyBkb25lIGZ1cnRoZXIgZG93bi4KICAgICAqLwogICAgaWYgKCh1c2VzICE9IE5VTEwpICYmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgPT0gMCkpIHsKCWN1ciA9IHVzZXM7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICB0bXAgPSBjdXItPm5leHQ7CgkgICAgd2hpbGUgKHRtcCAhPSBOVUxMKSB7CSAgICAKCQlpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCSAgICB4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkgICAgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShjdXItPmF0dHIgKSwgCgkJICAgIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwgCgkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwJCQkKCQkJIkR1cGxpY2F0ZSBhdHRyaWJ1dGUgdXNlICVzIHNwZWNpZmllZCIsCgkJCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgCgkJCSAgICB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSwgCgkJCSAgICB4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKQoJCSAgICApOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikJCSAgICAJCSAgICAKCQkgICAgYnJlYWs7CgkJfQoJCXRtcCA9IHRtcC0+bmV4dDsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfQkKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsJCgkvKgoJICogRGVyaXZlIGJ5IHJlc3RyaWN0aW9uLgoJICovCglpZiAoYmFzZUlzQW55VHlwZSkgewoJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwoJfSBlbHNlIHsKCSAgICBpbnQgZm91bmQ7CgoJICAgIGN1ciA9IHVzZXM7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWJhc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoJCXdoaWxlIChiYXNlICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkgJiYKCQkJeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0cikpKSB7CgkJCQoJCQlmb3VuZCA9IDE7CgkJCWlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAyLjEuMQoJCQkgICAgKi8JCgkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMSwKCQkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwKCQkJCSJUaGUgJ29wdGlvbmFsJyB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggYSBtYXRjaGluZyAiCgkJCQkiJ3JlcXVpcmVkJyB1c2Ugb2YgdGhlIGJhc2UgdHlwZSIsIE5VTEwpOwkJCQkKCQkJfSBlbHNlIGlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDMgCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8zLCAKCQkJCU5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJCQkiQSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGZvciB0aGUgJ3JlcXVpcmVkJyAiCgkJCQkiYXR0cmlidXRlIHVzZSAlcyBvZiB0aGUgYmFzZSB0eXBlIGlzIG1pc3NpbmciLAoJCQkJeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyLCAKCQkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShiYXNlLT5hdHRyKSwgCgkJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkpOwkKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQl9IGVsc2UgewoJCQkgICAgLyoKCQkJICAgICogT3ZlcnJpZGUgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqLwoJCQkgICAgYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJfQoJCQkvKgoJCQkqIFRPRE86IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMS4yICh7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCkKCQkJKiBUT0RPOiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjEuMyAKCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0JCQkJCgkJICAgIGJhc2UgPSBiYXNlLT5uZXh0OwoJCX0KCQkKCQlpZiAoIWZvdW5kKSB7CgkJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJCS8qCgkJCSogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4yCgkJCSovCgkJCWlmICgodHlwZS0+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+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CgkJaWYgKGFuY2VzdG9yLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGFuY2VzdG9yLCBjdHh0LCAgTlVMTCk7CgkJaWYgKGFuY2VzdG9yID09IGFueVNpbXBsZVR5cGUpCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKGFuY2VzdG9yID09IHR5cGUpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzQsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCQl9IGVsc2UgaWYgKGFuY2VzdG9yLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJICAgIC8qCgkJICAgICogVE9ETywgRklYTUU6IEFsdGhvdWdoIGEgbGlzdCBzaW1wbGUgdHlwZSBtdXN0IG5vdCBoYXZlIGEgdW5pb24gU1QKCQkgICAgKiB0eXBlIGFzIGl0ZW0gdHlwZSwgd2hpY2ggaW4gdHVybiBoYXMgYSBsaXN0IFNUIGFzIG1lbWJlciAKCQkgICAgKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGlzIGhlcmUgYXMgd2VsbCwgc2luY2UgdGhpcyBjaGVjayAKCQkgICAgKiB3YXMgbm90IHlldCBwZXJmb3JtZWQuCgkJICAgICovCgoJCX0KCQlhbmNlc3RvciA9IGFuY2VzdG9yLT5iYXNlVHlwZTsKCSAgICB9ICAgCgkgICAgbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIE5vdCB5ZXQgdXNlZCBjb2RlIGZvciBDVCBzY2hlbWEgdmFsaWRhdGlvbiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDU2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgIGludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0OwogICAgLyoKICAgICogMy4xNC40IFNpbXBsZSBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwogICAgKiBWYWxpZGF0aW9uIFJ1bGU6IFN0cmluZyBWYWxpZAogICAgKi8KICAgIC8qCiAgICAqIDEgSXQgaXMgc2NoZW1hLXZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCAKICAgICogYnkgRGF0YXR5cGUgVmFsaWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUsIHZhbHVlLCAKCWZpcmVFcnJvcnMsIDEsIDEsIDEpOwogICAgcmV0dXJuIChyZXQpOwogICAgLyoKICAgICogMi4xIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUWSBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVFkgZ2l2ZW4gCiAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgdGhlbgogICAgKiB0aGUgc3RyaW5nIG11c3QgYmUgYSC3ZGVjbGFyZWQgZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMiBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVElFUyBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVElFUyAKICAgICogZ2l2ZW4gdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLCAKICAgICogdGhlbiBldmVyeSB3aGl0ZXNwYWNlLWRlbGltaXRlZCBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkIAogICAgKiBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4zIG90aGVyd2lzZSBubyBmdXJ0aGVyIGNvbmRpdGlvbiBhcHBsaWVzLgogICAgKi8KCiAgICByZXR1cm4gKDApOwp9CgkJCSAgICAgIAoKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsgICAKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlZjsKICAgIGlmIChlbGVtRGVjbC0+dmFsdWUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBpZiAoZWxlbURlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsIGVsZW1EZWNsLT5ub2RlLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQsICIKCSAgICAidGhlIGVsZW1lbnQgZGVjbC4gJyVzJyBoYXMgbm8gdHlwZSBhc3NpZ25lZCIsIGVsZW1EZWNsLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgdHlwZURlZiA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKICAgIGlmICgodHlwZURlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB8fCAKCSgodHlwZURlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCSAgKCh0eXBlRGVmLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSB8fAoJICAgKHR5cGVEZWYtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykpKSkgewoJeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwoJeG1sQXR0clB0ciBhdHRyOwoJaW50IHJldCA9IDA7CgkvKgoJKiAxIElmIHRoZSB0eXBlIGRlZmluaXRpb24gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSBzdHJpbmcgCgkqIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIAoJKiBWYWxpZCAopzMuMTQuNCkuCgkqLwoJLyoKCSogMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCgkqIHN0cmluZyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKCSogYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgoJKi8KCS8qCgkqIFRPRE86ID8KCSovCgoJdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CglpZiAodmN0eHQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZWxlbURlY2wtPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJCSJjcmVhdGlvbiBvZiBhIG5ldyB2YWxpZGF0aW9uIGNvbnRleHQgZmFpbGVkLlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsJCgl9CQoJaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpCgkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKGVsZW1EZWNsLT5ub2RlLCAiZml4ZWQiKTsKCWVsc2UKCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUoZWxlbURlY2wtPm5vZGUsICJkZWZhdWx0Iik7CgkvKgoJKiBUT0RPOiBUaGlzIHdvbid0IHdvcmsgeWV0LiAKCSovCglpZiAodHlwZURlZi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkgICAgdmN0eHQtPm5vZGUgPSBlbGVtRGVjbC0+bm9kZTsKCSAgICB2Y3R4dC0+Y3VyID0gYXR0ci0+Y2hpbGRyZW47CgkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tDVkNTaW1wbGVUeXBlKHZjdHh0LCBlbGVtRGVjbC0+dmFsdWUsIHR5cGVEZWYsIDApOwoJfQoJaWYgKHJldCA+IDApIHsJICAgIAoJICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xLCAKCQkgICAgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCAoeG1sTm9kZVB0cikgYXR0ciwKCQkgICAgZWxlbURlY2wtPnN1YnR5cGVzLCBOVUxMLCBlbGVtRGVjbC0+dmFsdWUsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCQlyZXR1cm4gKGN0eHQtPmVycik7CgkgICAgfQoJICAgIHJldCA9IGN0eHQtPmVycjsKCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZWxlbURlY2wtPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJCSJ3aGlsZSB2YWxpZGF0aW5nIHRoZSBkZWZhdWx0L2ZpeGVkIHZhbHVlLlxuIiwKCQlOVUxMLCBOVUxMKTsJCQoJfSAgICAgICAgICAgICAgICAJCQkJCgl4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKCXJldHVybiAocmV0KTsKICAgIH0gZWxzZSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIDIuMSBpdHMge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgbWl4ZWQuCgkqLwoJaWYgKChlbGVtRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpICYmCgkgICAgKGVsZW1EZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSAmJgoJICAgIChlbGVtRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsIE5VTEwsCgkJIlRoZSBjb250ZW50IHR5cGUgbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgbWl4ZWQuIiwKCQlOVUxMKTsKCSAgICByZXR1cm4oY3R4dC0+ZXJyKTsKCX0JCglpZiAoKGVsZW1EZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgJiYKCSAgICAoZWxlbURlY2wtPnN1YnR5cGVzLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwoJICAgIHhtbEF0dHJQdHIgYXR0cjsKCSAgICBpbnQgcmV0OwoJICAgIAoJICAgIC8qIFRPRE86IEF2b2lkIGNyZWF0aW9uIG9mIGEgbmV3IGNvbnRleHQuICovCgkgICAgdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CgkgICAgaWYgKHZjdHh0ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW1EZWNsLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJCSAgICAiY3JlYXRpb24gb2YgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0IGZhaWxlZC5cbiIsCgkJICAgIE5VTEwsIE5VTEwpOwoJCXJldHVybiAoLTEpOwkKCSAgICB9CgoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCBlbGVtRGVjbC0+c3VidHlwZXMsIAoJCWVsZW1EZWNsLT52YWx1ZSwgMCwgMSwgMSk7CSAgICAKCSAgICBpZiAocmV0ID4gMCkgewoJCWlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUoZWxlbURlY2wtPm5vZGUsICJmaXhlZCIpOwoJCWVsc2UKCQkgICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKGVsZW1EZWNsLT5ub2RlLCAiZGVmYXVsdCIpOwoJCWlmIChjdHh0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSwgCgkJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJCWVsZW1EZWNsLT5zdWJ0eXBlcywgTlVMTCwgZWxlbURlY2wtPnZhbHVlLCAKCQkJTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKCQl9CgkJcmV0ID0gY3R4dC0+ZXJyOwoJICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgZWxlbURlY2wtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0LCAiCgkJICAgICJ3aGlsZSB2YWxpZGF0aW5nIHRoZSBkZWZhdWx0L2ZpeGVkIHZhbHVlLlxuIiwKCQkgICAgTlVMTCwgTlVMTCk7CQkKCSAgICB9ICAgICAgICAgICAgICAgIAkJCQkKCSAgICB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAyLjIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgbWl4ZWQsIHRoZW4gdGhlIHtjb250ZW50IHR5cGV9J3MgCgkgICAgKiBwYXJ0aWNsZSBtdXN0IGJlILdlbXB0aWFibGW3IGFzIGRlZmluZWQgYnkgUGFydGljbGUgRW1wdGlhYmxlIAoJICAgICogKKczLjkuNikuCgkgICAgKi8KCSAgICAvKgoJICAgICogVE9ETzogSW1wbGVtZW50IHRoaXMuCgkgICAgKi8KCX0KICAgIH0KICAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFNUQ29udGVudE9mQ1Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKgogKiBSZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZSB0eXBlIGZvciB0aGUgY29udGVudCBvZgogKiB0aGUgY29tcGxleCB0eXBlLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0U1RDb250ZW50T2ZDVCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvcmlnID0gdHlwZSwgYW55VHlwZTsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICB3aGlsZSAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUgIT0gYW55VHlwZSkgJiYgCgkodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpIHsKCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpCgkgICAgcmV0dXJuKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJWE1MX1NDSEVNQVBfSU5URVJOQUwsCglOVUxMLCBvcmlnLCBOVUxMLAoJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRTVENvbnRlbnRUeXBlT2ZDVCwgIgoJIm5vIHNpbXBsZSB0eXBlIGZvciB0aGUgY29udGVudCBvZiBjb21wbGV4IHR5cGUgJyVzJyBjb3VsZCBiZSAiCgkiY29tcHV0ZWQiLCBvcmlnLT5uYW1lKTsKICAgIHJldHVybiAoTlVMTCk7Cn0KCgpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRDb250ZW50VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCSAgICAidGhlIGNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCXJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CglpZiAoKHR5cGUtPmJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgoJICAgICgodHlwZS0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8CgkgICAgICh0eXBlLT5iYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgJiYgCgkgICAgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikpIHsKCSAgICAvKgoJICAgICogMSBJZiB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mCgkgICAgKiB0aGUgYmFzZSBbYXR0cmlidXRlXSBpcyBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIHdob3NlIG93biAKCSAgICAqIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBhbmQgdGhlIDxyZXN0cmljdGlvbj4gCgkgICAgKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4KCSAgICAqLwoKCQoJfQogICAgfSBlbHNlIHsKCQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgLyogCiAgICAqIDEgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwgCiAgICAqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHMsICIKCSAgICAidGhlIGNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKGJhc2UtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCS8qCgkqIDEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSogY29udGFpbiBleHRlbnNpb24uCgkqLwoJaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04pIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImNvbnRhaW5zIGV4dGVuc2lvbiIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KCS8qCgkqIDEuMiBJdHMge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSB7YXR0cmlidXRlIHVzZXN9IAoJKiBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmLCB0aGF0IGlzLCBmb3IgZXZlcnkgYXR0cmlidXRlIAoJKiB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0sIHRoZXJlIAoJKiBtdXN0IGJlIGFuIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGNvbXBsZXggCgkqIHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIHRoZSBzYW1lIAoJKiB7bmFtZX0sIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge3R5cGUgZGVmaW5pdGlvbn0gYXMgaXRzIGF0dHJpYnV0ZSAKCSogZGVjbGFyYXRpb24KCSoKCSogTk9URTogVGhpcyB3aWxsIGJlIGFscmVhZHkgc2F0aXNmaWVkIGJ5IHRoZSB3YXkgdGhlIGF0dHJpYnV0ZSB1c2VzCgkqIGFyZSBleHRlbmRlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgdGhpcyBjaGVjawoJKiBpcyBub3QgbmVlZGVkLgoJKi8KCgkvKgoJKiAxLjMgSWYgaXQgaGFzIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gCgkqIG11c3QgYWxzbyBoYXZlIG9uZSwgYW5kIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgCgkqIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUgY29tcGxleCAKCSogdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9LCAKCSogYXMgZGVmaW5lZCBieSBXaWxkY2FyZCBTdWJzZXQgKKczLjEwLjYpLgoJKgoJKiBUaGlzIGlzIGFscmVhZHkgY2hlY2tlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgCgkqIHRoaXMgY2hlY2sgaXMgbm90IG5lZWRlZC4KCSovCgkKCS8qCgkqIDEuNCBPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqCgkqIDEuNC4xIFRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBhbmQgdGhlIAoJKiB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmIG11c3QgYmUgdGhlIHNhbWUgCgkqIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KCSovCgoKCQogICAgfSBlbHNlIHsKCS8qCgkqIDIgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAKCSogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJLyoKCSogMi4xIFRoZSB7Y29udGVudCB0eXBlfSBtdXN0IGJlIHRoZSBzYW1lIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwoJLyoKCSogMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gCgkqIGV4dGVuc2lvbgoJKi8KICAgIH0KCn0KCiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYUdyb3VwRGVmRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4ZXMgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFHcm91cERlZkZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgZ3JvdXAsCgkJICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsgICAgCiAgICBncm91cC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICBpZiAoKGdyb3VwLT5yZWYgIT0gTlVMTCkgJiYgKGdyb3VwLT5zdWJ0eXBlcyA9PSBOVUxMKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBncm91cERlZjsKCS8qCgkqIFJlc29sdmUgdGhlIHJlZmVyZW5jZS4KCSovCglncm91cERlZiA9IHhtbFNjaGVtYUdldEdyb3VwKGN0eHQtPnNjaGVtYSwgZ3JvdXAtPnJlZiwKCSAgICBncm91cC0+cmVmTnMpOwoJaWYgKGdyb3VwRGVmID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIAoJCU5VTEwsIGdyb3VwLCBOVUxMLAoJCSJyZWYiLCBncm91cC0+cmVmLCBncm91cC0+cmVmTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9HUk9VUCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoJZ3JvdXAtPnN1YnR5cGVzID0gZ3JvdXBEZWY7CiAgICB9CQkKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaXh1cDoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGU7CgogICAgaWYgKGl0ZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICAvKgogICAgKiBEbyBub3QgYWxsb3cgdGhlIGZvbGxvd2luZyB0eXBlcyB0byBiZSB0eXBlZml4ZWQsIHByaW9yIHRvCiAgICAqIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5jdHh0VHlwZSA9PSBOVUxMKSB7Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgkgICAgCgkJcmV0dXJuOwoJICAgIGRlZmF1bHQ6CgkgICAgICAgIGJyZWFrOwoJfQogICAgfQogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gaXRlbS0+bmFtZTsKICAgIGlmIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewogICAgICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDp7CQkgICAgCgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkJCWlmIChpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsCgkJCQlOVUxMKTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSBOVUxMOwoKCQkgICAgY3R4dC0+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+dHlwZSAhPSAKCQkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSAmJiAKCQkJKGl0ZW0tPnN1YnR5cGVzLT50eXBlICE9IAoJCQlYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSkpIHsKCQkJLyogCgkJCSogVGhpcyBjYXNlIGlzIHVuZGVyc3Rvb2QgYXMgc2hvcnRoYW5kIGZvciBjb21wbGV4IAoJCQkqIGNvbnRlbnQgcmVzdHJpY3RpbmcgdGhlIHVyLXR5cGUgZGVmaW5pdGlvbiwgYW5kIAoJCQkqIHRoZSBkZXRhaWxzIG9mIHRoZSBtYXBwaW5ncyBzaG91bGQgYmUgbW9kaWZpZWQgYXMgCgkJCSogbmVjZXNzYXJ5LgoJCQkqLwkJCQoJCQlpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoJCQlpdGVtLT5mbGFncyB8PSAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgkJCS8qCgkJCSogQXNzdW1lIHRoYXQgd2UgaW5oZXJpdCB0aGUgY29udGVudC10eXBlIHR5cGUgZnJvbSAnYW55VHlwZScuCgkJCSovCgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0gaXRlbS0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlOwoJCSAgICB9IAkJCQoJCSAgICAvKgoJCSAgICAqIEZpeHVwIHRoZSBzdWIgY29tcG9uZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCQkoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09CgkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewkJCSAgICAKCQkJeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQkgICAgfQoJCSAgICBpZiAoaXRlbS0+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+bm9kZSkpOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIlR5cGUgb2YgJXMgOiIsIG5hbWUpOwogICAgfQogICAgc3dpdGNoIChpdGVtLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJzaW1wbGVcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbGVtZW50c1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAidW5rbm93biAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbXB0eVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgkvKiBSZW1vdmVkLCBzaW5jZSBub3QgdXNlZC4gKi8KCS8qCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWQgb3IgZWxlbXNcbiIpOwogICAgICAgICAgICBicmVhazsKCSovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0OgogKiBAZmFjZXQ6ICB0aGUgZmFjZXQKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKgogKiBSZXR1cm5zIDAgaWYgb2theSBvciAtMSBpbiBjYWUgb2YgZXJyb3IKICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBub25OZWdhdGl2ZUludGVnZXJUeXBlID0gTlVMTDsKICAgIGludCByZXQgPSAwOwoKICAgIGlmIChub25OZWdhdGl2ZUludGVnZXJUeXBlID09IE5VTEwpIHsKICAgICAgICBub25OZWdhdGl2ZUludGVnZXJUeXBlID0KICAgICAgICAgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTk5JTlRFR0VSKTsKICAgIH0KICAgIHN3aXRjaCAoZmFjZXQtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOiB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogT2theSB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICogYXQgdGhhdCBwb2ludC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0OwoJCXhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCgkJLyogNC4zLjUuNSBDb25zdHJhaW50cyBvbiBlbnVtZXJhdGlvbiBTY2hlbWEgQ29tcG9uZW50cwoJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBlbnVtZXJhdGlvbiB2YWxpZCByZXN0cmljdGlvbgoJCSogSXQgaXMgYW4gt2Vycm9ytyBpZiBhbnkgbWVtYmVyIG9mIHt2YWx1ZX0gaXMgbm90IGluIHRoZSAKCQkqILd2YWx1ZSBzcGFjZbcgb2Yge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4gCgkJKgoJCSogbWluSW5jbHVzaXZlLCBtYXhJbmNsdXNpdmUsIG1pbkV4Y2x1c2l2ZSwgbWF4RXhjbHVzaXZlOgoJCSogVGhlIHZhbHVlILdtdXN0tyBiZSBpbiB0aGUgCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHRoZSC3YmFzZSB0eXBlty4gCgkJKi8KCQkvKgoJCSogVGhpcyBmdW5jdGlvbiBpcyBpbnRlbmRlZCB0byBkZWxpdmVyIGEgY29tcGlsZWQgdmFsdWUKCQkqIG9uIHRoZSBmYWNldC4gSW4gWE1MIFNjaGVtYXMgdGhlIHR5cGUgaG9sZGluZyBhIGZhY2V0LCAKCQkqIGNhbm5vdCBiZSBhIGJ1aWx0LWluIHR5cGUuIFRodXMgdG8gZW5zdXJlIHRoYXQgb3RoZXIgQVBJCgkJKiBjYWxscyAocmVsYXhuZykgZG8gd29yaywgaWYgdGhlIGdpdmVuIHR5cGUgaXMgYSBidWlsdC1pbiAKCQkqIHR5cGUsIHdlIHdpbGwgYXNzdW1lIHRoYXQgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUgKmlzCgkJKiBhbHJlYWR5KiB0aGUgYmFzZSB0eXBlLgkJCgkJKi8KCQlpZiAodHlwZURlY2wtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgkJICAgIGJhc2UgPSB0eXBlRGVjbC0+YmFzZVR5cGU7CgkJICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSAgICAidGhlIHR5cGUgJyVzJyBoYXMgbm8gYmFzZSB0eXBlLlxuIiwKCQkJICAgIHR5cGVEZWNsLT5uYW1lLCBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0JCQoJCX0gZWxzZQoJCSAgICBiYXNlID0gdHlwZURlY2w7CgkJLyoKCQkqIFRPRE86IFRyeSB0byBhdm9pZCBjcmVhdGluZyBhIG5ldyBjb250ZXh0LgoJCSovCiAgICAgICAgICAgICAgICB2Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKICAgICAgICAgICAgICAgIGlmICh2Y3R4dCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJImNyZWF0aW5nIGEgbmV3IHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJCU5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOwkKCQl9CgkJdmN0eHQtPm5vZGUgPSBmYWNldC0+bm9kZTsKCQl2Y3R4dC0+Y3VyID0gTlVMTDsKCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCAKCQkqIHNpbmNlIHRoZXkgYXJlIG5vdCBhdmFpbGFibGU6CgkJKiBmYWNldC0+bm9kZSBpcyBqdXN0IHRoZSBub2RlIGhvbGRpbmcgdGhlIGZhY2V0IAoJCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqIAoJCSogb2YgdGhlIGZhY2V0LgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUodmN0eHQsIGJhc2UsIAoJCSAgICBmYWNldC0+dmFsdWUsIDAsIDEsIDEsIDApOwoJCWZhY2V0LT52YWwgPSB2Y3R4dC0+dmFsdWU7CgkJdmN0eHQtPnZhbHVlID0gTlVMTDsJCQogICAgICAgICAgICAgICAgaWYgKHJldCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVCwgCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkgICAgImZhY2V0ICclcycgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSwgCgkJCSAgICBCQURfQ0FTVCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksIAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgZmFjZXQtPm5vZGUsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCBOVUxMLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgJyVzJyBuYW1lIG9mIHRoZSAiCgkJCSJmYWNldCAnJXMnIGFnYWluc3QgdGhlIGJhc2UgdHlwZSAnJXMnLlxuIiwKCQkJZmFjZXQtPnZhbHVlLCAKCQkJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQliYXNlLT5uYW1lLCBOVUxMLCBOVUxMKTsgCgkJICAgIHJldCA9IC0xOwoJCX0gICAgICAgICAgICAgICAgCQkJCQoJCXhtbFNjaGVtYUZyZWVWYWxpZEN0eHQodmN0eHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgZmFjZXQtPnJlZ2V4cCA9IHhtbFJlZ2V4cENvbXBpbGUoZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgaWYgKGZhY2V0LT5yZWdleHAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX1JFR0VYUF9JTlZBTElELAoJCSAgICAiVHlwZSBkZWZpbml0aW9uICclcyc6IFRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJICAgICJmYWNldCAncGF0dGVybicgaXMgbm90IHZhbGlkLlxuIiwKCQkgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6ewogICAgICAgICAgICAgICAgaW50IHRtcDsKCiAgICAgICAgICAgICAgICB0bXAgPQogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoZmFjZXQtPnZhbCkpOwogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+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+YXR0cmlidXRlczsKCWF0dHJncnAtPmF0dHJpYnV0ZVdpbGRjYXJkID0gcmVmLT5hdHRyaWJ1dGVXaWxkY2FyZDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJGaXh1cDoKICogQGF0dHJEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2wsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICAvKiAKICAgICogVE9ETzogSWYgaW5jbHVkaW5nIHRoaXMgaXMgZG9uZSB0d2ljZSAoISkgZm9yIGV2ZXJ5IGF0dHJpYnV0ZS4KICAgICovCiAgICAvKgogICAgKiBUaGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gZWxlbWVudCAKICAgICogaW5mb3JtYXRpb24gaXRlbSBpbiB0aGUgW2NoaWxkcmVuXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSBzaW1wbGUgCiAgICAqIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdHlwZSAKICAgICogW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmIChhdHRyRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEKQoJcmV0dXJuOwogICAgYXR0ckRlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfSU5URVJOQUxfUkVTT0xWRUQ7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBhdHRyRGVjbC0+bmFtZTsKICAgIGlmIChhdHRyRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ckRlY2wtPnR5cGVOYW1lICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJdHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBhdHRyRGVjbC0+dHlwZU5hbWUsCgkgICAgYXR0ckRlY2wtPnR5cGVOcyk7CglpZiAoKHR5cGUgPT0gTlVMTCkgfHwgCgkgICAgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpICYmCgkgICAgICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpIHx8CgkgICAgKCh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYKCSAgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBhdHRyRGVjbCwgYXR0ckRlY2wtPm5vZGUsCgkJInR5cGUiLCBhdHRyRGVjbC0+dHlwZU5hbWUsIGF0dHJEZWNsLT50eXBlTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJfSBlbHNlCgkgICAgYXR0ckRlY2wtPnN1YnR5cGVzID0gdHlwZTsKICAgIH0gZWxzZSBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJlZjsKCgkvKgoJKiBUT0RPOiBFdmFsdWF0ZSwgd2hhdCBlcnJvcnMgY291bGQgb2NjdXIgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIG5vdAoJKiBmb3VuZC4gSXQgbWlnaHQgYmUgcG9zc2libGUgdGhhdCB0aGUgInR5cGVmaXh1cCIgbWlnaHQgY3Jhc2ggaWYKCSogbm8gcmVmIGRlY2xhcmF0aW9uIHdhcyBmb3VuZC4KCSovCglyZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCBhdHRyRGVjbC0+cmVmLCBhdHRyRGVjbC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJICAgIAlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2wsIGF0dHJEZWNsLT5ub2RlLAoJCSJyZWYiLCBhdHRyRGVjbC0+cmVmLCBhdHRyRGVjbC0+cmVmTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHhtbFNjaGVtYUF0dHJGaXh1cChyZWYsIGN0eHQsIE5VTEwpOwogICAgICAgIGF0dHJEZWNsLT5zdWJ0eXBlcyA9IHJlZi0+c3VidHlwZXM7CiAgICB9IGVsc2UgewoJYXR0ckRlY2wtPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7ICAgICAgICAKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBwYXJzZSBhIHNjaGVtYSBkZWZpbml0aW9uIHJlc291cmNlIGFuZCBidWlsZCBhbiBpbnRlcm5hbAogKiBYTUwgU2hlbWEgc3RydXR1cmUgd2hpY2ggY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgaW5zdGFuY2VzLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFQdHIgcmV0ID0gTlVMTDsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CiAgICBpbnQgbmJlcnJvcnM7CiAgICBpbnQgcHJlc2VydmUgPSAwOwoKICAgIC8qCiAgICAqIFRoaXMgb25lIGlzIHVzZWQgaWYgdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgCiAgICAqIHRoZSBBUEk7IGkuZS4gbm90IGF1dG9tYXRpY2FsbHkgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSBkb2N1bWVudC4KICAgICovCgogICAgeG1sU2NoZW1hSW5pdFR5cGVzKCk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG5iZXJyb3JzID0gY3R4dC0+bmJlcnJvcnM7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5jb3VudGVyID0gMDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IE5VTEw7CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgaWYgKGN0eHQtPlVSTCAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZEZpbGUoKGNvbnN0IGNoYXIgKikgY3R4dC0+VVJMLCBOVUxMLCAKCSAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IGxvYWQgJyVzJy5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+VVJMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKGN0eHQtPmJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0geG1sUmVhZE1lbW9yeShjdHh0LT5idWZmZXIsIGN0eHQtPnNpemUsIE5VTEwsIE5VTEwsCgkgICAgICAgICAgICAgICAgICAgIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICAgICAgaWYgKGRvYyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCQkgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9QQVJTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZS5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIGRvYy0+VVJMID0geG1sU3RyZHVwKEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIik7CiAgICAgICAgY3R4dC0+VVJMID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIsIC0xKTsKICAgIH0gZWxzZSBpZiAoY3R4dC0+ZG9jICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSBjdHh0LT5kb2M7CglwcmVzZXJ2ZSA9IDE7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVEhJTkdfVE9fUEFSU0UsCgkJICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgcGFyc2UuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBhbmQgU2NoZW1hIHBhcnNlIGl0CiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAiVGhlIHNjaGVtYSBoYXMgbm8gZG9jdW1lbnQgZWxlbWVudC5cbiIsIE5VTEwsIE5VTEwpOwoJaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIFRoZW4gZG8gdGhlIHBhcnNpbmcgZm9yIGdvb2QKICAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VTY2hlbWEoY3R4dCwgcm9vdCk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+cHJlc2VydmUgPSBwcmVzZXJ2ZTsKICAgIGN0eHQtPnNjaGVtYSA9IHJldDsKICAgIGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0ckRlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBncm91cCBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyZ3JwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyR3JwRml4dXAsCiAgICAgICAgICAgICAgICBjdHh0KTsKCiAgICAvKgogICAgKiBDaGVjayBhdHRyaWJ1dGUgZ3JvdXBzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgCgl4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIsIGN0eHQpOwoKICAgIC8qCiAgICAqIFRoZW4gZml4dXAgYWxsIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFHcm91cERlZkZpeHVwLCBjdHh0KTsKICAgIAogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIHR5cGVzIHByb3BlcnRpZXMKICAgICAqLyAgICAKICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUZpeHVwLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXggcmVmZXJlbmNlcyBvZiBlbGVtZW50IGRlY2xhcmF0aW9uOyBhcHBseSBjb25zdHJhaW50cy4KICAgICAqLyAgICAKICAgIHhtbEhhc2hTY2FuRnVsbChyZXQtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lckZ1bGwpIHhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2ssIGN0eHQpOwoKICAgICAvKgogICAgKiBDaGVjayBtb2RlbCBncm91cHMgZGVmbml0aW9ucyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmdyb3VwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSAKCXhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhciwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gYnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGFsbCBjb21wbGV4IHR5cGVzCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsCiAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBjaGVjayB0aGUgZGVmYXVsdHMgcGFydCBvZiB0aGUgdHlwZSBsaWtlIGZhY2V0cyB2YWx1ZXMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0RlZmF1bHRzLAogICAgICAgICAgICAgICAgY3R4dCk7CgoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZShyZXQpOwogICAgICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgY2FsbGJhY2sKICogQHdhcm46ICB0aGUgd2FybmluZyBjYWxsYmFjawogKiBAY3R4OiAgY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzCiAqCiAqIFNldCB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIFhNbC1TY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGNhbGxiYWNrIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgY2FsbGJhY2sgcmVzdWx0CiAqIEBjdHg6IGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcyByZXN1bHQKICoKICogR2V0IHRoZSBjYWxsYmFjayBpbmZvcm1hdGlvbiB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGZhaWx1cmUsIDAgb3RoZXJ3aXNlCiAqLwppbnQgCnhtbFNjaGVtYUdldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuICgicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKCJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKCJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuICgidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKCJJbnRlcm5hbCBFcnJvciIpOwp9CgpzdGF0aWMgeG1sQ2hhciAqCnhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKGNvbnN0IHhtbENoYXIgKnZhbHVlKSB7CiAgICBjb25zdCB4bWxDaGFyICpjdXIgPSB2YWx1ZTsgICAgCiAgICB4bWxDaGFyICpyZXQgPSBOVUxMLCAqbWN1cjsgCgogICAgaWYgKHZhbHVlID09IE5VTEwpIAoJcmV0dXJuKE5VTEwpOwogICAgCiAgICB3aGlsZSAoKCpjdXIgIT0gMCkgJiYgCgkoKCgqY3VyKSAhPSAweGQpICYmICgoKmN1cikgIT0gMHg5KSAmJiAoKCpjdXIpICE9IDB4YSkpKSB7CgljdXIrKzsKICAgIH0KICAgIGlmICgqY3VyID09IDApCglyZXR1cm4gKE5VTEwpOwogICAgcmV0ID0geG1sU3RyZHVwKHZhbHVlKTsKICAgIC8qIFRPRE8gRklYTUU6IEkgZ3Vlc3MgZ2NjIHdpbGwgYmFyayBhdCB0aGlzLiAqLwogICAgbWN1ciA9ICh4bWxDaGFyICopICAocmV0ICsgKGN1ciAtIHZhbHVlKSk7CiAgICBkbyB7CglpZiAoICgoKm1jdXIpID09IDB4ZCkgfHwgKCgqbWN1cikgPT0gMHg5KSB8fCAoKCptY3VyKSA9PSAweGEpICkKCSAgICAqbWN1ciA9ICcgJzsKCW1jdXIrKzsKICAgIH0gd2hpbGUgKCptY3VyICE9IDApOwkgICAgCiAgICByZXR1cm4ocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW5jOwoKICAgIC8qIAogICAgKiBUaGUgbm9ybWFsaXphdGlvbiB0eXBlIGNhbiBiZSBjaGFuZ2VkIG9ubHkgZm9yIHR5cGVzIHdoaWNoIGFyZSBkZXJpdmVkIAogICAgKiBmcm9tIHhzZDpzdHJpbmcuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgJiYKICAgICAgICAgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PUk1TVFJJTkcpKQoKCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfUFJFU0VSVkUpOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3IAoJICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0byAKCSAgICAqIGNvbGxhcHNlCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpOwoJfQkJICAgCSAgICAKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJLyoKCSogRm9yIGxpc3QgdHlwZXMgdGhlIGZhY2V0ICJ3aGl0ZVNwYWNlIiBpcyBmaXhlZCB0byAiY29sbGFwc2UiLiAKCSovCglyZXR1cm4gKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXJldHVybiAoLTEpOwogICAgfSBlbHNlIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGFueVNUOwoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbjsKCgkvKgoJKiBBdG9taWMgdHlwZXMuCgkqLwoJYW55U1QgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCWFuYyA9IHR5cGUtPmJhc2VUeXBlOwoJZG8gewoJICAgIC8qCgkgICAgKiBGb3IgYWxsILdhdG9taWO3IGRhdGF0eXBlcyBvdGhlciB0aGFuIHN0cmluZyAoYW5kIHR5cGVzILdkZXJpdmVktyAKCSAgICAqIGJ5ILdyZXN0cmljdGlvbrcgZnJvbSBpdCkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2UgaXMgZml4ZWQgdG8gCgkgICAgKiBjb2xsYXBzZQoJICAgICovCgkgICAgaWYgKChhbmMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJCShhbmMtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykpIHsKCQkKCQlsaW4gPSB0eXBlLT5mYWNldFNldDsKCQlkbyB7CgkJICAgIGlmIChsaW4tPmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQlpZiAobGluLT5mYWNldC0+d2hpdGVzcGFjZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKSB7CgkJCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpOyAgCgkJCX0gZWxzZSBpZiAobGluLT5mYWNldC0+d2hpdGVzcGFjZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0UpIHsgCgkJCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfVkFMX1dUU1BfUkVQTEFDRSk7CgkJCX0gZWxzZQoJCQkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1BSRVNFUlZFKTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgbGluID0gbGluLT5uZXh0OwoJCX0gd2hpbGUgKGxpbiAhPSBOVUxMKTsJCgkJYnJlYWs7CgkgICAgfQoJICAgIGFuYyA9IGFuYy0+YmFzZVR5cGU7Cgl9IHdoaWxlIChhbmMgIT0gYW55U1QpOwoJcmV0dXJuIChYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSk7CQogICAgfSAgCiAgICByZXR1cm4gKC0xKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHR5cGUgaG9sZGluZyB0aGUgZmFjZXRzCiAqIEBmYWNldHM6ICB0aGUgbGlzdCBvZiBmYWNldHMgdG8gY2hlY2sKICogQHZhbHVlOiAgdGhlIGxleGljYWwgcmVwciBvZiB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICogQHZhbDogIHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKiBAZmlyZUVycm9yczogIGlmIDAsIG9ubHkgaW50ZXJuYWwgZXJyb3JzIHdpbGwgYmUgZmlyZWQ7CiAqCQkgb3RoZXJ3aXNlIGFsbCBlcnJvcnMgd2lsbCBiZSBmaXJlZC4KICoKICogQ2hlY2sgYSB2YWx1ZSBhZ2FpbnN0IGFsbCBmYWNldCBjb25kaXRpb25zCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJY29uc3QgeG1sQ2hhciAqIHZhbHVlLAoJCQkJdW5zaWduZWQgbG9uZyBsZW5ndGgsCgkJCQlpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldCA9IDA7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxTY2hlbWFUeXBlUHRyICBiaVR5cGU7IC8qIFRoZSBidWlsZC1pbiB0eXBlLiAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciB0bXBUeXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluazsKICAgIGludCByZXRGYWNldCwgaGFzRmFjZXQ7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCiNpZmRlZiBERUJVR19VTklPTl9WQUxJREFUSU9OCiAgICBwcmludGYoIkZhY2V0cyBvZiB0eXBlOiAnJXMnXG4iLCAoY29uc3QgY2hhciAqKSB0eXBlLT5uYW1lKTsKICAgIHByaW50ZigiICBmaXJlRXJyb3JzOiAlZFxuIiwgZmlyZUVycm9ycyk7CiNlbmRpZgogICAgICAgIAogICAgbm9kZSA9IGN0eHQtPm5vZGU7CiAgICAvKgogICAgKiBOT1RFOiBEbyBub3QganVtcCBhd2F5LCBpZiB0aGUgZmFjZXRTZXQgb2YgdGhlIGdpdmVuIHR5cGUgaXMKICAgICogZW1wdHk6IHVudGlsIG5vdywgInBhdHRlcm4iIGZhY2V0cyBvZiB0aGUgKmJhc2UgdHlwZXMqIG5lZWQgdG8KICAgICogYmUgY2hlY2tlZCBhcyB3ZWxsLgogICAgKi8KICAgIGJpVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgd2hpbGUgKChiaVR5cGUgIT0gTlVMTCkgJiYgKGJpVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJYmlUeXBlID0gYmlUeXBlLT5iYXNlVHlwZTsKICAgIGlmIChiaVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwJCSAgICAKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCSAgICAidGhlIGJhc2UgdHlwZSBheGlzIG9mIHRoZSBnaXZlbiB0eXBlICclcycgZG9lcyBub3QgcmVzb2x2ZSB0byAiCgkgICAgImEgYnVpbHQtaW4gdHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CQoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgCiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7Cgl3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgLyoKCSAgICAqIFNraXAgdGhlIHBhdHRlcm4gIndoaXRlU3BhY2UiOiBpdCBpcyB1c2VkIHRvIAoJICAgICogZm9ybWF0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBiZWZvcmVoYW5kLgoJICAgICovCSAgICAKCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDogCgkJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTGlzdFNpbXBsZVR5cGVGYWNldChmYWNldCwKCQkJICAgIHZhbHVlLCBsZW5ndGgsIDApOwoJCQlsZW4gPSBsZW5ndGg7CgkJICAgIH0gZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxlbmd0aEZhY2V0KGJpVHlwZSwgZmFjZXQsCgkJCSAgICB2YWx1ZSwgY3R4dC0+dmFsdWUsICZsZW4pOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXQsIHZhbHVlLCAKCQkJY3R4dC0+dmFsdWUpOwoJICAgIH0KCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldCBvZiB0eXBlICclcycuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQlicmVhazsKCSAgICB9IGVsc2UgaWYgKChyZXQgPiAwKSAmJiAoZmlyZUVycm9ycykpIHsKCQl4bWxTY2hlbWFWRmFjZXRFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgbGVuLAoJCSAgICB0eXBlLCBmYWNldCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoKCSAgICBmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQ7Cgl9CglpZiAocmV0ID49IDApIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyBlbnVtZXJhdGlvbnMuCgkgICAgKi8KCSAgICByZXRGYWNldCA9IDA7CgkgICAgZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CgkgICAgd2hpbGUgKGZhY2V0TGluayAhPSBOVUxMKSB7CgkJaWYgKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJCSAgICByZXRGYWNldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmlUeXBlLCBmYWNldExpbmstPmZhY2V0LCAKCQkJdmFsdWUsIGN0eHQtPnZhbHVlKTsJCQoJCSAgICBpZiAocmV0RmFjZXQgPD0gMCkKCQkJYnJlYWs7CgkJfQoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHJldEZhY2V0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRDsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwKCQkJdmFsdWUsIDAsIHR5cGUsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0RmFjZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0IG9mIHR5cGUgJyVzJy5cbiIsCgkJICAgIEJBRF9DQVNUICJlbnVtZXJhdGlvbiIsIE5VTEwpOwoJCSAgICByZXQgPSAtMTsJCQoJICAgIH0JCQoJfQogICAgfQogICAgaWYgKHJldCA+PSAwKSB7CgkvKgoJKiBQcm9jZXNzIHBhdHRlcnMuIFBhdHRlcm4gZmFjZXRzIGFyZSBPUmVkIGF0IHR5cGUgbGV2ZWwgCgkqIGFuZCBBTkRlZCBpZiBkZXJpdmVkLiBXYWxrIHRoZSBiYXNlIHR5cGUgYXhpcy4KCSovCgloYXNGYWNldCA9IDA7Cgl0bXBUeXBlID0gdHlwZTsKCWZhY2V0ID0gTlVMTDsKCWRvIHsKCSAgICByZXRGYWNldCA9IDA7CgkgICAgZm9yIChmYWNldExpbmsgPSB0bXBUeXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7IAoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikKCQkgICAgY29udGludWU7CgkJcmV0RmFjZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgCgkJICAgIHZhbHVlLCBjdHh0LT52YWx1ZSk7CgkJaWYgKHJldEZhY2V0ID09IDApIAoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXRGYWNldCA8IDApIHsKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJCSJ2YWxpZGF0aW5nICdwYXR0ZXJuJyBmYWNldCAnJXMnIG9mIHR5cGUgJyVzJy5cbiIsCgkJCWZhY2V0TGluay0+ZmFjZXQtPnZhbHVlLCB0bXBUeXBlLT5uYW1lKTsKCQkgICAgcmV0ID0gLTE7CgkJICAgIGJyZWFrOwoJCX0gZWxzZQoJCSAgICAvKiBTYXZlIHRoZSBsYXN0IG5vbi12YWxpZGF0aW5nIGZhY2V0LiAqLwoJCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgfQoJICAgIGlmIChyZXRGYWNldCAhPSAwKQoJCWJyZWFrOwkJICAgIAoJICAgIHRtcFR5cGUgPSB0bXBUeXBlLT5iYXNlVHlwZTsKCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJaWYgKHJldEZhY2V0ID4gMCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19QQVRURVJOX1ZBTElEOwoJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIDAsIHR5cGUsIGZhY2V0LCAKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQogICAgfQkgICAgCiAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU2ltcGxlIHR5cGUgdmFsaWRhdGlvbgkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRE9NIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpOwoKCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0clN0YXRlczoKICogQHN0YXRlOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZSBzdGF0ZXMKICoKICogRnJlZSB0aGUgZ2l2ZW4gbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBzdGF0ZSkKewogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKICAgIHdoaWxlIChzdGF0ZSAhPSBOVUxMKSB7Cgl0bXAgPSBzdGF0ZTsKCXN0YXRlID0gc3RhdGUtPm5leHQ7CQoJeG1sRnJlZSh0bXApOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAYXR0cnM6ICBhIGxpc3Qgb2YgYXR0cmlidXRlcwogKgogKiBSZWdpc3RlciB0aGUgbGlzdCBvZiBhdHRyaWJ1dGVzIGFzIHRoZSBzZXQgdG8gYmUgdmFsaWRhdGVkIG9uIHRoYXQgZWxlbWVudAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sQXR0clB0ciBhdHRycykKewogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCiAgICBjdHh0LT5hdHRyID0gTlVMTDsKICAgIGN0eHQtPmF0dHJUb3AgPSBOVUxMOwogICAgd2hpbGUgKGF0dHJzICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHJzLT5ucyAhPSBOVUxMKSAmJgogICAgICAgICAgICAoeG1sU3RyRXF1YWwoYXR0cnMtPm5zLT5ocmVmLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkpIHsKICAgICAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJaWYgKHRtcCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgYXR0cmlidXRlcyIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbWVtc2V0KHRtcCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJdG1wLT5hdHRyID0gYXR0cnM7Cgl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOwoJdG1wLT5uZXh0ID0gTlVMTDsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIAogICAgICAgICAgICBjdHh0LT5hdHRyID0gdG1wOwoJZWxzZQoJICAgIGN0eHQtPmF0dHJUb3AtPm5leHQgPSB0bXA7CgljdHh0LT5hdHRyVG9wID0gdG1wOwogICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgojaWYgMCAvKiBDdXJyZW50bHkgbm90IHVzZWQgKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdAogKiBAbm9kZWxpc3Q6IHRoZSBsaXN0IG9mIG5vZGVzCiAqCiAqIENoZWNrIHRoZSBub2RlIGxpc3QgaXMgb25seSBtYWRlIG9mIHRleHQgbm9kZXMgYW5kIGVudGl0aWVzIHBvaW50aW5nCiAqIHRvIHRleHQgbm9kZXMKICoKICogUmV0dXJucyAxIGlmIHRydWUsIDAgaWYgZmFsc2UgYW5kIC0xIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0KHhtbE5vZGVQdHIgbm9kZWxpc3QpCnsKICAgIHdoaWxlIChub2RlbGlzdCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKG5vZGVsaXN0LT50eXBlID09IFhNTF9FTlRJVFlfUkVGX05PREUpIHsKICAgICAgICAgICAgVE9ETyAgICAgICAgICAgICAgICAvKiBpbXBsZW1lbnQgcmVjdXJzaW9uIGluIHRoZSBlbnRpdHkgY29udGVudCAqLwogICAgICAgIH0KICAgICAgICBpZiAoKG5vZGVsaXN0LT50eXBlICE9IFhNTF9URVhUX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ09NTUVOVF9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1BJX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkgewogICAgICAgICAgICByZXR1cm4gKDApOwogICAgICAgIH0KICAgICAgICBub2RlbGlzdCA9IG5vZGVsaXN0LT5uZXh0OwogICAgfQogICAgcmV0dXJuICgxKTsKfQojZW5kaWYKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBvc3RTY2hlbWFBc3NlbWJsZUZpeHVwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaW50IGksIG5iSXRlbXM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sICppdGVtczsKCgogICAgLyoKICAgICogRHVyaW5nIHRoZSBBc3NlbWJsZSBvZiB0aGUgc2NoZW1hIGN0eHQtPmN1ckl0ZW1zIGhhcwogICAgKiBiZWVuIGZpbGxlZCB3aXRoIHRoZSByZWxldmFudCBuZXcgaXRlbXMuIEZpeCB0aG9zZSB1cC4KICAgICovCiAgICBuYkl0ZW1zID0gY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXM7CiAgICBpdGVtcyA9ICh4bWxTY2hlbWFUeXBlUHRyICopIGN0eHQtPmFzc2VtYmxlLT5pdGVtczsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJCXhtbFNjaGVtYUF0dHJGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJCXhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2soKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0sIGN0eHQsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQl4bWxTY2hlbWFBdHRyR3JwRml4dXAoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLCAKCQkgICAgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hR3JvdXBEZWZGaXh1cChpdGVtLCBjdHh0LCBOVUxMKTsgICAgICAgICAgICAKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogQ2lyY3VsYXJpdHkgY2hlY2tzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewkgICAgCgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcigKCQkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogRml4dXAgZm9yIGFsbCBvdGhlciBpdGVtLiAKICAgICogVE9ETzogSG1tLCBub3Qgc3VyZSBpZiBzdGFydGluZyBmcm9tIGNvbXBsZXgvc2ltcGxlIHR5cGVzLAogICAgKiBhbGwgc3Vic2VxdWVudCBpdGVtcyB3aWxsIGJlIHJlYWNoZWQuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBDaGVjayBmYWNldCB2YWx1ZXMuIE5vdGUgdGhhdCBmYWNldHMgYXJlCiAgICAqIGhvbGQgYnkgY29tcGxleCBhbmQgc2ltcGxlIHR5cGUgY29tcG9uZW50cyBvbmx5LgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewkgCgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyhpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogQnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGNvbXBsZXggdHlwZXMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9ICAgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbjoKICogQHBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHZjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBleGlzdGluZyBzY2hlbWEKICogQG5vZGU6IHRoZSBub2RlIHRoYXQgZmlyZWQgdGhlIGFzc2VtYmxpbmcKICogQG5zTmFtZTogdGhlIG5hbWVzcGFjZSBuYW1lIG9mIHRoZSBuZXcgc2NoZW1hCiAqIEBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICoKICogRXhwYW5kcyBhbiBleGlzdGluZyBzY2hlbWEgYnkgYW4gYWRkaXRpb25hbCBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LCAKCQkJICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCQkJICAgIAoJCQkgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgeG1sTm9kZVB0ciBub2RlLAoJCQkgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSwKCQkJICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbikKewogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TnMsICpvbGR0bnM7IAogICAgeG1sRG9jUHRyIGRvYywgb2xkZG9jOwogICAgaW50IG9sZGZsYWdzLCByZXQgPSAwLCByZXVzZUN0eHQ7CiAgICB4bWxOb2RlUHRyIGRvY0VsZW07CiAgICAvKgogICAgKiBUaGlzIHNob3VsZCBiZSB1c2VkOgogICAgKiAxLiBvbiA8aW1wb3J0PihzKQogICAgKiAyLiBpZiByZXF1ZXN0ZWQgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSAKICAgICogMy4gaWYgcmVxdWVzdGVkIHZpYSB0aGUgQVBJCiAgICAqLwogICAgaWYgKChwY3R4dCA9PSBOVUxMKSAmJiAodmN0eHQgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIENyZWF0ZSBhIHRlbXBvcmFyeSBwYXJzZXIgY29udGV4dC4KICAgICogVE9ETzogd2hhdCB0byBzZXQgZXhhY2x0eSBmb3IgdGhlIFVSTCBhcmd1bWVudCBoZXJlPyAKICAgICovCiAgICBpZiAocGN0eHQgPT0gTlVMTCkgewoJcmV1c2VDdHh0ID0gMDsKCXBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoKGNvbnN0IGNoYXIgKikgbG9jYXRpb24sIHNjaGVtYS0+ZGljdCk7CglpZiAocGN0eHQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJ4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24sIGFsbG9jYXRpbmcgbmV3IHBhcnNlciAiCgkJImNvbnRlbnQgZm9yIGR5bmFtaWMgY29uc3RydWN0aW9uIG9mIHNjaGVtYXRhIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7CQkKCX0KCXBjdHh0LT5lcnJvciA9IHZjdHh0LT5lcnJvcjsKCXBjdHh0LT53YXJuaW5nID0gdmN0eHQtPndhcm5pbmc7CiAgICB9IGVsc2UKCXJldXNlQ3R4dCA9IDE7ICAgICAgICAKICAgIC8qCiAgICAqIEFjcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHBjdHh0LCBzY2hlbWEsIG5vZGUsCgluc05hbWUsIGxvY2F0aW9uLCAmZG9jLCAmdGFyZ2V0TnMsIDApOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAoZG9jICE9IE5VTEwpCgkgICAgeG1sRnJlZURvYyhkb2MpOwogICAgfSBlbHNlIGlmIChkb2MgIT0gTlVMTCkgewoJZG9jRWxlbSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CgkvKgoJKiBTYXZlIGFuZCByZXNldCB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCglvbGRmbGFncyA9IHNjaGVtYS0+ZmxhZ3M7CglvbGR0bnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCW9sZGRvYyA9IHNjaGVtYS0+ZG9jOwoJCgl4bWxTY2hlbWFDbGVhclNjaGVtYURlZmF1bHRzKHNjaGVtYSk7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IHRhcmdldE5zOwoJLyogc2NoZW1hLT5uYkN1ckl0ZW1zID0gMDsgKi8KCXBjdHh0LT5zY2hlbWEgPSBzY2hlbWE7CglpZiAocGN0eHQtPmFzc2VtYmxlID09IE5VTEwpIHsKCSAgICBwY3R4dC0+YXNzZW1ibGUgPSB4bWxTY2hlbWFOZXdBc3NlbWJsZSgpOwoJICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiTWVtb3J5IGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24sICIKCQkiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglwY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwoJcGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwoJCgl4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKHBjdHh0LCBwY3R4dC0+c2NoZW1hLCBkb2NFbGVtKTsJCQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgcGN0eHQtPnNjaGVtYSwgZG9jRWxlbS0+Y2hpbGRyZW4pOwoJeG1sU2NoZW1hUG9zdFNjaGVtYUFzc2VtYmxlRml4dXAocGN0eHQpOwoJLyoKCSogRnJlZSB0aGUgbGlzdCBvZiBhc3NlbWJsZWQgY29tcG9uZW50cy4KCSovCgl4bWxGcmVlKHBjdHh0LT5hc3NlbWJsZS0+aXRlbXMpOwoJLyoKCSogUmVzdG9yZSB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCglzY2hlbWEtPmZsYWdzID0gb2xkZmxhZ3M7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IG9sZHRuczsKCXNjaGVtYS0+ZG9jID0gb2xkZG9jOwoJcmV0ID0gcGN0eHQtPmVycjsKICAgIH0gICAgIAogICAgaWYgKHJldXNlQ3R4dCA9PSAwKSB7CglwY3R4dC0+ZGljdCA9IE5VTEw7CQoJeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQocGN0eHQpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHI6CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAeHNpQXR0cjogYW4geHNpIGF0dHJpYnV0ZQogKiBAbm9OYW1lc3BhY2U6IHdoZXRoZXIgYSBzY2hlbWEgd2l0aCBubyB0YXJnZXQgbmFtZXNwYWNlIGlzIGV4cHRlY3RlZAogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZQogKiBvZiBhbiBpbnN0YW5jZS4gSWYgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gaXMgdXNlZCwgQG5vTmFtZXNwYWNlCiAqIG11c3QgYmUgc2V0IHRvIDEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJIHhtbEF0dHJQdHIgeHNpQXR0ciwKCQkJIGludCBub05hbWVzcGFjZSkKewogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBjb25zdCB4bWxDaGFyICpuc25hbWUgPSBOVUxMLCAqbG9jYXRpb247CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IHJldCA9IDA7CiAgICAKICAgIGlmICh4c2lBdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCSAgICBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBQYXJzZSB0aGUgdmFsdWU7IHdlIHdpbGwgYXNzdW1lIGFuIGV2ZW4gbnVtYmVyIG9mIHZhbHVlcwogICAgKiB0byBiZSBnaXZlbiAodGhpcyBpcyBob3cgWGVyY2VzIGFuZCBYU1Ygd29yaykuCiAgICAqLwogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgeHNpQXR0cik7CSAgICAKICAgIGN1ciA9IHZhbHVlOwogICAgZG8gewkKCWlmIChub05hbWVzcGFjZSAhPSAxKSB7CgkgICAgLyoKCSAgICAqIEdldCB0aGUgbmFtZXNwYWNlIG5hbWUuCgkgICAgKi8KCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIGNvdW50Kys7CgkgICAgbnNuYW1lID0geG1sRGljdExvb2t1cCh2Y3R4dC0+c2NoZW1hLT5kaWN0LCBjdXIsIGVuZCAtIGN1cik7CQkKCSAgICBjdXIgPSBlbmQ7Cgl9CgkvKgoJKiBHZXQgdGhlIFVSSS4KCSovCgl3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkgICAgY3VyKys7CgllbmQgPSBjdXI7Cgl3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCSAgICBlbmQrKzsKCWlmIChlbmQgPT0gY3VyKQoJICAgIGJyZWFrOwoJY291bnQrKzsKCWxvY2F0aW9uID0geG1sRGljdExvb2t1cCh2Y3R4dC0+c2NoZW1hLT5kaWN0LCBjdXIsIGVuZCAtIGN1cik7CgljdXIgPSBlbmQ7CQkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbihOVUxMLCB2Y3R4dCwgdmN0eHQtPnNjaGVtYSwgCgkgICAgeHNpQXR0ci0+cGFyZW50LCBuc25hbWUsIGxvY2F0aW9uKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKHZjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkoeG1sTm9kZVB0cikgeHNpQXR0ciwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyLCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hdGEiLCBOVUxMKTsKCSAgICBpZiAodmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKHZhbHVlKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW06CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogYW4gZWxlbWVudCBub2RlIHBvc3NpYmx5IGhvbGRpbmcgeHNpIGF0dHJpYnV0ZXMKICogQG5vTmFtZXNwYWNlOiB3aGV0aGVyIGEgc2NoZW1hIHdpdGggbm8gdGFyZ2V0IG5hbWVzcGFjZSBpcyBleHB0ZWN0ZWQKICoKICogQXNzZW1ibGVzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZXMKICogb2YgdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsICAKCQkJIHhtbE5vZGVQdHIgZWxlbSkKeyAgICAKICAgIGludCByZXQgPSAwLCByZXROcyA9IDA7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJldE5zID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDApOwoJaWYgKHJldE5zID09IC0xKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDEpOwoJaWYgKHJldCA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChyZXROcyAhPSAwKQoJcmV0dXJuIChyZXROcyk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGRldGVjdGVkIChtaWdodCBiZSBOVUxMKQogKiBAdHlwZTogIHRoZSB0eXBlCiAqCiAqIEEgdHJhbnNpdGlvbiBoYXMgYmVlbiBtYWRlIGluIHRoZSBhdXRvbWF0YSBhc3NvY2lhdGVkIHRvIGFuIGVsZW1lbnQKICogY29udGVudCBtb2RlbAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgeG1sTm9kZVB0ciBvbGRub2RlID0gY3R4dC0+bm9kZTsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazogJXMsICVzLCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLT5uYW1lLCBub2RlLT5uYW1lKTsKI2VuZGlmCiAgICAvKgogICAgKiBAdHlwZS0+dHlwZSB3aWxsIGJlIFhNTF9TQ0hFTUFfVFlQRV9BTlkgb3IgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQuCiAgICAqLwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICBjdHh0LT5ub2RlID0gbm9kZTsgICAgCiAgICBjdHh0LT5jdXIgPSBub2RlLT5jaGlsZHJlbjsKICAgIC8qCiAgICAqIEFzc2VtYmxlIG5ldyBzY2hlbWF0YSB1c2luZyB4c2kuCiAgICAqLwogICAgaWYgKGN0eHQtPm9wdGlvbnMgJiBYTUxfU0NIRU1BX1ZBTF9YU0lfQVNTRU1CTEUpIHsKCWludCByZXQ7CgkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9ICAgIAogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOiB7CgkgICAgLyoKCSAgICAqIE5PVEU6IFRoZSBidWlsZCBvZiB0aGUgY29udGVudCBtb2RlbCAKCSAgICAqICh4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwpIGVuc3VyZXMgdGhhdCB0aGUgZWxlbWVudCAKCSAgICAqIGRlY2xhcmF0aW9uIChhbmQgbm90IGEgcmVmZXJlbmNlIHRvIGl0KSB3aWxsIGJlIGdpdmVuLgoJICAgICovCgkgICAgaWYgKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgY3R4dC0+dHlwZSktPnJlZiAhPSBOVUxMKSB7CgkJLyoKCQkqIFRoaXMgaXMgcGFyYW5vaWQgY29kaW5nIDstKS4uLiBpdCBzaG91bGQgbm90CgkJKiBoYXBwZW4gaGVyZSBhbnkgbW9yZS4KCQkqLwoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkgICAgbm9kZSwgTlVMTCwJCQkJCQkKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCAiCgkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9uICdyZWZlcmVuY2UnIGVuY291bnRlcmVkLCAiCgkJICAgICJidXQgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiB3YXMgZXhwZWN0ZWQiLCAKCQkgICAgTlVMTCk7CgkJcmV0dXJuOwoJICAgIH0KCSAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIAoJCSh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlKTsKCSAgICBicmVhazsKCX0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZChjdHh0LCB0eXBlKTsKICAgICAgICAgICAgYnJlYWs7CglkZWZhdWx0OiAKCSAgICBicmVhazsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7Cn0gIAoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdmFsdWU6IHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQKICogQGZpcmVFcnJvcnM6IHNoYWxsIGVycm9ycyBiZSByZXBvcnRlZD8KICogQGFwcGx5RmFjZXRzOiBzaGFsbCBmYWNldHMgYmUgYXBwbGllZD8KICogQG5vcm1hbGl6ZTogc2hhbGwgdGhlIHZhbHVlIGJlIG5vcm1hbGl6ZWQ/CiAqIEBjaGVja05vZGVzOiBzaGFsbCB0aGUgY29udGVudCBub2RlcyBiZSBjaGVja2VkPwogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBieSB0aGUgZ2l2ZW4gdHlwZSAodXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluKS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJIGNvbnN0IHhtbENoYXIgKnZhbHVlLAkJCQkgCgkJCQkgaW50IGZpcmVFcnJvcnMsCQkJCSAKCQkJCSBpbnQgYXBwbHlGYWNldHMsCgkJCQkgaW50IG5vcm1hbGl6ZSwKCQkJCSBpbnQgY2hlY2tOb2RlcykKewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IHJldCA9IDA7ICAKICAgIHhtbENoYXIgKm5vcm1WYWx1ZSA9IE5VTEw7CiAgICBpbnQgd3RzcDsgICAgICAgCiAKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogU2F2ZSB0aGUgY3VycmVudCB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gdHlwZS4gKi8KICAgIHd0c3AgPSBjdHh0LT52YWx1ZVdTOwogICAgLyoKICAgICogTm9ybWFsaXplIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAobm9ybWFsaXplICYmIAoJKGN0eHQtPnZhbHVlV1MgIT0gWE1MX1NDSEVNQVNfVkFMX1dUU1BfQ09MTEFQU0UpKSB7CglpbnQgbm9ybSA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwoJCglpZiAoKG5vcm0gIT0gLTEpICYmIChub3JtID4gY3R4dC0+dmFsdWVXUykpIHsKCSAgICBpZiAobm9ybSA9PSBYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSkKCQlub3JtVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkgICAgZWxzZQoJCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKHZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZVdTID0gbm9ybTsKCSAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBub3JtVmFsdWU7Cgl9CQkKICAgIH0gICAgCiAgICAvKgogICAgKiBUaGUgbm9kZXMgb2YgYSBjb250ZW50IG11c3QgYmUgY2hlY2tlZCBvbmx5IG9uY2UsCiAgICAqIHRoaXMgaXMgbm90IHdvcmtpbmcgc2luY2UgbGlzdCB0eXBlcyB3aWxsIGZpcmUgdGhpcwogICAgKiBtdWx0aXBsZSB0aW1lcy4KICAgICovCiAgICBpZiAoKGNoZWNrTm9kZXMgPT0gMSkgJiYgKGN0eHQtPmN1ciAhPSBOVUxMKSkgewoJeG1sTm9kZVB0ciBjdXIgPSBjdHh0LT5jdXI7CgoJZG8gewoJICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgoJICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKCSAgICBjYXNlIFhNTF9QSV9OT0RFOgoJICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9FTkQ6CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfRU5USVRZX1JFRl9OT0RFOgoJICAgIGNhc2UgWE1MX0VOVElUWV9OT0RFOgoJCS8qIFRPRE86IFNjb3VyIHRoZSBlbnRpdGllcyBmb3IgaWxsZWdhbCBub2Rlcy4gKi8KCQlUT0RPIGJyZWFrOwoJICAgIGNhc2UgWE1MX0VMRU1FTlRfTk9ERTogewoJICAgIC8qIE5PVEU6IENoYW5nZWQgdG8gYW4gaW50ZXJuYWwgZXJyb3IsIHNpbmNlIHRoZSAKCSAgICAqIGV4aXN0ZW5jZSBvZiBhbiBlbGVtZW50IG5vZGUgd2lsbCBiZSBhbHJlYWR5IGNoZWNrZWQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSBhbmQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUuCgkJKi8KCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgLyogWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLCAqLwoJCSAgICBub2RlLCB0eXBlLAoJCSAgICAiRWxlbWVudCAnJXMnIGZvdW5kIGluIHNpbXBsZSB0eXBlIGNvbnRlbnQiLCAKCQkgICAgY3VyLT5uYW1lKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFWX0lOVEVSTkFMKTsKCQkJCSAgIH0KCSAgICBjYXNlIFhNTF9BVFRSSUJVVEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX1RZUEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9GUkFHX05PREU6CgkgICAgY2FzZSBYTUxfTk9UQVRJT05fTk9ERToKCSAgICBjYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CgkgICAgY2FzZSBYTUxfRFREX05PREU6CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9ERUNMOgoJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9ERUNMOgoJICAgIGNhc2UgWE1MX0VOVElUWV9ERUNMOgoJICAgIGNhc2UgWE1MX05BTUVTUEFDRV9ERUNMOgojaWZkZWYgTElCWE1MX0RPQ0JfRU5BQkxFRAoJICAgIGNhc2UgWE1MX0RPQ0JfRE9DVU1FTlRfTk9ERTogCiNlbmRpZgkJICAgIAkJICAgIAkJICAgIAoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sICovCgkJICAgIG5vZGUsIE5VTEwsCgkJICAgICJOb2RlIG9mIHVuZXhwZWN0ZWQgdHlwZSBmb3VuZCBpbiBzaW1wbGUgdHlwZSBjb250ZW50IiwKCQkgICAgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BVl9JTlRFUk5BTCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlLCBhbnlUeXBlOwoKCWFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCgliYXNlID0gdHlwZS0+YmFzZVR5cGU7Cgl3aGlsZSAoKGJhc2UgIT0gTlVMTCkgJiYgCgkgICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgJiYKCSAgICAoYmFzZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkgICAgKGJhc2UgIT0gYW55VHlwZSkpIHsKCSAgICBiYXNlID0gYmFzZS0+YmFzZVR5cGU7Cgl9CglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBiYXNlLCB2YWx1ZSwgMSwgMCwgMSwgMCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGNvbXBsZXggdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgLyogCgkgICAgKiBDaGVjayBmYWNldHMuCgkgICAgKi8JICAgIAoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHNvbWVob3cgbm90IG5pY2UsIHNpbmNlIGlmIGFuIGVycm9yIG9jY3VycwoJICAgICogdGhlIHJlcG9ydGVkIHR5cGUgd2lsbCBiZSB0aGUgY29tcGxleCB0eXBlOyB0aGUgc3BlYwoJICAgICogd2FudHMgYSBzaW1wbGUgdHlwZSB0byBiZSBjcmVhdGVkIG9uIHRoZSBjb21wbGV4IHR5cGUKCSAgICAqIGlmIGl0IGhhcyBhIHNpbXBsZSBjb250ZW50LiBGb3Igbm93IHdlIGhhdmUgdG8gbGl2ZSB3aXRoCgkgICAgKiBpdC4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgY29tcGxleCB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkgICAgfQkKCX0JCiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgoJaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwoJICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKCX0KCS8qCgkqIFNUUkVBTS1SRUFELUNISUxEUkVOLgoJKi8JICAgIAkJCglyZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybSh0eXBlLCB2YWx1ZSwgJihjdHh0LT52YWx1ZSksIG5vZGUpOwoJaWYgKHJldCA+IDApIHsJICAgIAoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSAKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgZWxzZQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsJICAgIAoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgYnVpbHQtaW4gdHlwZSAnJXMnXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSB7ICAgICAgICAKCS8qIDEuMi4xIGlmIHt2YXJpZXR5fSBpcyC3YXRvbWljtyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IAoJKiBhIGxpdGVyYWwgaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259IAoJKi8JCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLT5iYXNlVHlwZSwgdmFsdWUsIDAsIDAsIDAsIDApOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBhdG9taWMgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewkgICAgCgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwkKCX0gZWxzZSBpZiAoKGFwcGx5RmFjZXRzKSAmJiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICAvKiAKCSAgICAqIENoZWNrIGZhY2V0cy4KCSAgICAqLwkgICAgCSAgICAJICAgIAoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgYXRvbWljIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCQkvKgoJCSBEaXNhYmxlZCwgc2luY2UgdGhlIGZhY2V0IHZhbGlkYXRpb24gYWxyZWFkeSByZXBvcnRzIGVycm9ycy4KCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkJKi8KCSAgICB9CQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CiAgICAgICAgCgl4bWxTY2hlbWFUeXBlUHRyIHRtcFR5cGU7Cgljb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXA7Cgl1bnNpZ25lZCBsb25nIGxlbiA9IDA7CgoJLyogMS4yLjIgaWYge3ZhcmlldHl9IGlzILdsaXN0tyB0aGVuIHRoZSBzdHJpbmcgbXVzdCBiZSBhIHNlcXVlbmNlIAoJKiBvZiB3aGl0ZSBzcGFjZSBzZXBhcmF0ZWQgdG9rZW5zLCBlYWNoIG9mIHdoaWNoILdtYXRjaLdlcyBhIGxpdGVyYWwgCgkqIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSAKCSovCgkKCXRtcFR5cGUgPSB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUpOwkKCWN1ciA9IHZhbHVlOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgbGVuKys7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdG1wVHlwZSwgdG1wLCAwLCAxLCAwLCAwKTsKCSAgICB4bWxGcmVlKHRtcCk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGFuIGl0ZW0gb2YgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsJCgkJYnJlYWs7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCQlicmVhazsKCSAgICB9CQoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CgkvKiAKCSogQ2hlY2sgZmFjZXRzLgoJKi8KCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykpIHsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCBsZW4sIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJLyoKCQkgRGlzYWJsZWQsIHNpbmNlIHRoZSBmYWNldCB2YWxpZGF0aW9uIGFscmVhZHkgcmVwb3J0cyBlcnJvcnMuCgkJaWYgKGZpcmVFcnJvcnMpIAoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIGN0eHQtPmN1ciwgdmFsdWUsIHR5cGUpOwoJCSovCgkgICAgfQkgCSAgIAoJICAgCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXJMaW5rOwoKCS8qCgkqIFRPRE86IEZvciBhbGwgZGF0YXR5cGVzILdkZXJpdmVktyBieSC3dW5pb263ICB3aGl0ZVNwYWNlIGRvZXMgCgkqIG5vdCBhcHBseSBkaXJlY3RseTsgaG93ZXZlciwgdGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utyAKCSogdHlwZXMgaXMgY29udHJvbGxlZCBieSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUgCgkqILdtZW1iZXJUeXBlc7cgYWdhaW5zdCB3aGljaCB0aGUgt3VuaW9utyBpcyBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkLiAKCSoKCSogVGhpcyBtZWFucyB0aGF0IHRoZSB2YWx1ZSBpcyBub3JtYWxpemVkIGJ5IHRoZSBmaXJzdCB2YWxpZGF0aW5nCgkqIG1lbWJlciB0eXBlLCB0aGVuIHRoZSBmYWNldHMgb2YgdGhlIHVuaW9uIHR5cGUgYXJlIGFwcGxpZWQuIFRoaXMKCSogbmVlZHMgY2hhbmdpbmcgb2YgdGhlIHZhbHVlIQoJKi8JCgkKCS8qCgkqIDEuMi4zIGlmIHt2YXJpZXR5fSBpcyC3dW5pb263IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgYSAKCSogbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIGF0IGxlYXN0IG9uZSBtZW1iZXIgb2YgCgkqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gCgkqLwojaWZkZWYgREVCVUdfVU5JT05fVkFMSURBVElPTgoJcHJpbnRmKCJVbmlvbiBTVCAgICAgOiAnJXMnXG4iLCAoY29uc3QgY2hhciAqKSB0eXBlLT5uYW1lKTsKCXByaW50ZigiICBmaXJlRXJyb3JzIDogJWRcbiIsIGZpcmVFcnJvcnMpOwoJcHJpbnRmKCIgIGFwcGx5RmFjZXRzOiAlZFxuIiwgYXBwbHlGYWNldHMpOwojZW5kaWYKCW1lbWJlckxpbmsgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlKTsKCWlmIChtZW1iZXJMaW5rID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidW5pb24gc2ltcGxlIHR5cGUgJyVzJyBoYXMgbm8gbWVtYmVyIHR5cGVzXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIHJldCA9IC0xOwoJfSAKCWlmIChyZXQgPT0gMCkgewoJICAgIHdoaWxlIChtZW1iZXJMaW5rICE9IE5VTEwpIHsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBtZW1iZXJMaW5rLT50eXBlLCAKCQkgICAgdmFsdWUsIDAsIDEsIDEsIDApOwoJCWlmICgocmV0IDw9IDApIHx8IChyZXQgPT0gMCkpCgkJICAgIGJyZWFrOwkgICAgCgkJbWVtYmVyTGluayA9IG1lbWJlckxpbmstPm5leHQ7CgkgICAgfSAgICAgCgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIG1lbWJlcnMgb2YgdW5pb24gc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCSAgICB9Cgl9CgkvKgoJKiBBcHBseSBmYWNldHMgKHBhdHRlcm4sIGVudW1lcmF0aW9uKS4JCgkqLwoJaWYgKChyZXQgPT0gMCkgJiYgKGFwcGx5RmFjZXRzKSAmJiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICBpbnQgbXdzOwoJICAgIC8qCgkgICAgKiBUaGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkgCgkgICAgKiB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUgt21lbWJlclR5cGVztyAKCSAgICAqIGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4gCgkgICAgKi8JCSAgICAKCSAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ0aGUgdmFsdWUgd2FzIGFscmVhZHkgbm9ybWFsaXplZCBmb3IgdGhlIHVuaW9uIHNpbXBsZSAiCgkJICAgICJ0eXBlICclcycuXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9CgkgICAgbXdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUobWVtYmVyTGluay0+dHlwZSk7CgkgICAgaWYgKG13cyA+IGN0eHQtPnZhbHVlV1MpIHsKCQlpZiAobXdzID09IFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX0NPTExBUFNFKQoJCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkJZWxzZQoJCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSk7CgkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCSAgICB2YWx1ZSA9IChjb25zdCB4bWxDaGFyICopIG5vcm1WYWx1ZTsKCSAgICB9CgoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgdW5pb24gc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJCS8qCgkJaWYgKGZpcmVFcnJvcnMpCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkJKi8KCSAgICB9CQoJfQogICAgfSAgICAgICAgICAgCiAgICBjdHh0LT52YWx1ZVdTID0gd3RzcDsKICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUobm9ybVZhbHVlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIGVsZW1lbnQgbm9kZSB0byBiZSB2YWxpZGF0ZWQuCiAqCiAqIFZhbGlkYXRlIHRoZSBlbGVtZW50IGFnYWluc3QgYSBzaW1wbGUgdHlwZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sTm9kZVB0ciBjdXI7CiAgICBpbnQgcmV0ID0gMCwgcmV0dmFsID0gMDsKICAgICAgICAKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIE5VTEwsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOyAgICAKICAgIH0KCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogCiAgICAqIGN2Yy10eXBlOiAzLjEuMiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBDaGlsZCBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIGN1ciA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkvKgoJKiBUT0RPOiBFbnRpdGllcywgd2lsbCB0aGV5IHByb2R1Y2UgZWxlbWVudHMgYXMgd2VsbD8KCSovCglpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzIsCgkJbm9kZSwgdHlwZSwJCQoJCSJObyBlbGVtZW50IGNvbnRlbnQgYWxsb3dlZCIsIE5VTEwpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8yOwoJfQoJY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgCiAgICAvKgogICAgKiBjdmMtdHlwZSAzLjEuMToKICAgICoKICAgICogVGhlIGF0dHJpYnV0ZXMgb2YgbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nIHRob3NlIHdob3NlIG5hbWVzcGFjZSBuYW1lIAogICAgKiBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kIHdob3NlIGxvY2FsIAogICAgKiBuYW1lIGlzIG9uZSBvZiB0eXBlLCBuaWwsIHNjaGVtYUxvY2F0aW9uIG9yIG5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBBdHRyaWJ1dGUgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB8fAogICAgICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmlsIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbAogICAgICAgICAgICAgIChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIpKSkpIHsKCSAgICB4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGF0dHIpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8xOwogICAgICAgIH0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogVGhpcyB3aWxsIHNraXAgdmFsaWRhdGlvbiBpZiB0aGUgdHlwZSBpcyAnYW55U2ltcGxlVHlwZScuCiAgICAqLwogICAgaWYgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgfHwKCSh0eXBlLT5idWlsdEluVHlwZSAhPSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkgewoJeG1sQ2hhciAqdmFsdWU7CQoKCXZhbHVlID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CgkvKgoJKiBOT1RFOiBUaGlzIGNhbGwgd2lsbCBub3QgY2hlY2sgdGhlIGNvbnRlbnQgbm9kZXMsIHNpbmNlCgkqIHRoaXMgc2hvdWxkIGJlIGNoZWNrZWQgaGVyZSBhbHJlYWR5LgoJKi8KCXJldHZhbCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUsIHZhbHVlLCAKCSAgICAxLCAxLCAxLCAwKTsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgIHhtbEZyZWUodmFsdWUpOwoJaWYgKHJldHZhbCAhPSAwKQoJICAgIHJldCA9IHJldHZhbDsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsUU5hbWVBY3F1aXJlOgogKiBAdmFsdWU6IHRoZSBsZXhpY2FsIHJlcHJlc2FudGF0aW9uIG9mIHRoZSBRTmFtZSB2YWx1ZQogKiBAbm9kZTogdGhlIG5vZGUgdG8gc2VhcmNoIGZvciB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24KICogQG5zTmFtZTogdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgbmFtZSBpZiBmb3VuZAogKgogKiBDaGVja3MgdGhhdCBhIHZhbHVlIGNvbmZvcm1zIHRvIHRoZSBsZXhpY2FsIHNwYWNlIG9mIHRoZSB0eXBlIFFOYW1lOwogKiBpZiB2YWxpZCwgdGhlIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIG5hbWUgaXMgc2VhcmNoZWQgYW5kIHJldHVyZWQgCiAqIGFzIGEgY29weSBpbiBAbnNOYW1lLiBUaGUgbG9jYWwgbmFtZSBpcyByZXR1cm5lZCBpbiBAbG9jYWxOYW1lIGFzCiAqIGEgY29weS4KICoKICogUmV0dXJucyAwIGlmIHZhbGlkLCAxIGlmIG5vdCB2YWxpZCBieSB0eXBlLCAyIGlmIG5vIGNvcnJlc3BvbmRpbmcgCiAqIG5hbWVzcGFjZSBkZWNsYXJhdGlvbiB3YXMgZm91bmQgaW4gc2NvcGU7IC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgCiAqIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsUU5hbWVBY3F1aXJlKGNvbnN0IHhtbENoYXIgKnZhbHVlLCB4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbENoYXIgKipuc05hbWUsIHhtbENoYXIgKipsb2NhbE5hbWUpCnsKICAgIGludCByZXQ7CiAgICB4bWxDaGFyICpsb2NhbCA9IE5VTEw7CgogICAgaWYgKChuc05hbWUgPT0gTlVMTCkgfHwgKGxvY2FsTmFtZSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOyAgCiAgICAqbnNOYW1lID0gTlVMTDsgICAKICAgICpsb2NhbE5hbWUgPSBOVUxMOwogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ID09IDApIHsKCXhtbENoYXIgKnByZWZpeDsKCQoJbG9jYWwgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CglpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxOc1B0ciBuczsKCSAgICAKCSAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKCSAgICBpZiAobnMgPT0gTlVMTCkKCQlyZXQgPSAyOwoJICAgIGVsc2UgewoJCSpuc05hbWUgPSB4bWxTdHJkdXAobnMtPmhyZWYpOwoJCSpsb2NhbE5hbWUgPSB4bWxTdHJkdXAobG9jYWwpOwoJICAgIH0KCX0KCWlmIChsb2NhbCAhPSBOVUxMKQoJICAgIHhtbEZyZWUobG9jYWwpOwoJaWYgKHByZWZpeCAhPSBOVUxMKQoJICAgIHhtbEZyZWUocHJlZml4KTsKICAgIH0gZWxzZQoJcmV0dXJuICgxKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IHR5cGUuCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbE5vZGVQdHIgZWxlbTsKICAgIGludCByZXQ7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sQ2hhciAqYXR0clZhbHVlOyAKICAgIGludCBuaWxsZWQgPSAwOwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsLCAKICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlIGFuZCB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQuCiAgICAqCiAgICAqIEBjdHh0LT50eXBlIHdpbGwgYmUgdGhlIGVsZW1lbnQncyBkZWNsYXJhdGlvbi4KICAgICovCgogICAgaWYgKGN0eHQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgTlVMTCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkgICAgImJhZCBhcmd1bWVudHMuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGVsZW0gPSBjdHh0LT5ub2RlOyAgIAoKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDEKICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwgCgkgICAgZWxlbSwgTlVMTCwKCSAgICAiTm8gbWF0Y2hpbmcgZGVjbGFyYXRpb24gYXZhaWxhYmxlIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMgogICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7Cgl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF8yLAoJICAgIGVsZW0sIE5VTEwsIAoJICAgICJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgICAKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDMKICAgICogSGFuZGxlICd4c2k6bmlsJy4KICAgICovCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJuaWwiLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsJCglhdHRyVmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgYXR0cik7CQoJY3R4dC0+bm9kZSA9ICh4bWxOb2RlUHRyKSBhdHRyOwoJY3R4dC0+Y3VyID0gYXR0ci0+Y2hpbGRyZW47CQoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQk9PTEVBTiksCgkgICAgQkFEX0NBU1QgYXR0clZhbHVlLCAxLCAxLCAxLCAxKTsKCWN0eHQtPm5vZGUgPSBlbGVtOwoJY3R4dC0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbDsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyB0aGUgYXR0cmlidXRlICd4c2k6bmlsJyIsIE5VTEwpOwoJICAgIGlmIChhdHRyVmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKGF0dHJWYWx1ZSk7CgkgICAgcmV0dXJuICgtMSk7Cgl9IAoJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFKSA9PSAwKSB7CgkgICAgLyogCgkgICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjEgCgkgICAgKi8KCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfM18xLCAKCQllbGVtLCBOVUxMLAoJCSJUaGUgZWxlbWVudCBpcyBub3QgJ25pbGxhYmxlJyIsIE5VTEwpOwkKCX0gZWxzZSB7CQkgICAgCgkgICAgaWYgKHhtbFN0ckVxdWFsKEJBRF9DQVNUIGF0dHJWYWx1ZSwgQkFEX0NBU1QgInRydWUiKSB8fAoJCXhtbFN0ckVxdWFsKEJBRF9DQVNUIGF0dHJWYWx1ZSwgQkFEX0NBU1QgIjEiKSkgewoJCW5pbGxlZCA9IDE7CgkJcmV0ID0gMDsKCQkvKiAKCQkqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMi4xIAoJCSovCgkJaWYgKHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pID09IDEpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMSwgCgkJCS8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwgKi8KCQkJZWxlbSwgTlVMTCwKCQkJIlRoZSAnbmlsbGVkJyBlbGVtZW50IG11c3QgaGF2ZSBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudCAiCgkJCSJjb250ZW50IiwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzE7CgkJfQoJCS8qIAoJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjIgCgkJKi8KCQlpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCgkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCAKCQkJLyogWE1MX1NDSEVNQVNfRVJSX0hBVkVERUZBVUxULCAqLwoJCQllbGVtLCBOVUxMLAoJCQkiVGhlcmUgaXMgYSBmaXhlZCB2YWx1ZSBjb25zdHJhaW50IGRlZmluZWQgZm9yICIKCQkJInRoZSAnbmlsbGVkJyBlbGVtZW50IiwgTlVMTCk7CQkgICAgCgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzI7CgkJfQoJCQoJICAgIH0KCX0KCWlmIChhdHRyVmFsdWUgIT0gTlVMTCkKCSAgICB4bWxGcmVlKGF0dHJWYWx1ZSk7CiAgICB9CiAgICAKICAgIC8qIAogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA0IAogICAgKiBIYW5kbGUgJ3hzaTp0eXBlJy4KICAgICovCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJ0eXBlIiwgIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewkKCXhtbENoYXIgKm5zTmFtZSA9IE5VTEwsICpsb2NhbCA9IE5VTEw7CgoJLyoKCSogVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhICp3YXJuaW5nKiB0aGF0IHRoZSB0eXBlIHdhcyBvdmVycmlkZW4KCSogYnkgdGhlIGluc3RhbmNlLgoJKi8KCgkvKiAKCSogY3ZjLWVsdCAoMy4zLjQpIDogNC4xIAoJKi8KCWF0dHJWYWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KCh4bWxOb2RlUHRyKSBhdHRyKTsKCXJldCA9IHhtbFNjaGVtYVZhbFFOYW1lQWNxdWlyZShhdHRyVmFsdWUsIGF0dHItPnBhcmVudCwJCgkgICAgJm5zTmFtZSwgJmxvY2FsKTsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyB0aGUgYXR0cmlidXRlICd4c2k6dHlwZSciLCBOVUxMKTs7CgkgICAgRlJFRV9BTkRfTlVMTChhdHRyVmFsdWUpCgkgICAgRlJFRV9BTkRfTlVMTChuc05hbWUpCgkgICAgRlJFRV9BTkRfTlVMTChsb2NhbCkKCSAgICByZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID09IDEpIHsKCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwKCQkoeG1sTm9kZVB0cikgYXR0ciwgYXR0clZhbHVlLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSkpOwoJfSBlbHNlIGlmIChyZXQgPT0gMikgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJKHhtbE5vZGVQdHIpIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vICIKCQkiY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUiLCAKCQlhdHRyVmFsdWUpOwkgICAgCSAgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDQuMiAKCSAgICAqLwoJICAgIHR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbG9jYWwsIG5zTmFtZSk7CgkgICAgaWYgKHR5cGUgPT0gTlVMTCkgewkgIAoJCXhtbENoYXIgKnN0ckEgPSBOVUxMOwoKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8yLAoJICAgIAkgICAgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJICAgICJUaGUgdmFsdWUgJXMgZG9lcyBub3QgcmVzb2x2ZSB0byBhIHR5cGUgIgoJCSAgICAiZGVmaW5pdGlvbiIsIAoJCSAgICB4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHJBLCBuc05hbWUsIGxvY2FsKSk7CgkJRlJFRV9BTkRfTlVMTChzdHJBKTsgICAgCgkgICAgfSBlbHNlIHsKCQlUT0RPCgkJLyoKCQkqIFRPRE86IGN2Yy1lbHQgKDMuMy40KSA6IDQuMyAoVHlwZSBEZXJpdmF0aW9uIE9LKQoJCSovCQkKCSAgICB9Cgl9CglGUkVFX0FORF9OVUxMKGF0dHJWYWx1ZSkKCUZSRUVfQU5EX05VTEwobnNOYW1lKQoJRlJFRV9BTkRfTlVMTChsb2NhbCkKICAgIH0gZWxzZSB7Cgl0eXBlID0gZWxlbURlY2wtPnN1YnR5cGVzOwoJLyogVE9ETzogQ2hhbmdlIHRoZSBoYW5kbGluZyBvZiBtaXNzaW5nIHR5cGVzIGFjY29yZGluZyB0bwoJKiB0aGUgc3BlYy4KCSovCglpZiAodHlwZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCS8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RZUEUgKi8KCQllbGVtLCBOVUxMLAoJCSJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBoYXMgbm8gdHlwZSBhc3NpZ25lZCIsIE5VTEwpOyAgICAgICAgCgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICAgIAogICAgLyoKICAgICogVE9ETzogU2luY2UgdGhpcyBzaG91bGQgYmUgYWxyZWFkeSBjaGVja2VkIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbiwKICAgICogYW5kIHdlIHdhbnQgdG8gZ2V0IHJpZCBvZiB0aGUgWE1MX1NDSEVNQVNfRVJSLi4uIHR5cGVzLCB0aGUgZXJyb3IgY29kZQogICAgKiBoYXMgYmVlbiBjaGFuZ2VkIHRvIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLgogICAgKi8KICAgIC8qCiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewogICAgICAgIGlmIChkZWNsLT5taW5PY2N1cnMgPiAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLCAKCQkiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlc1xuIiwKCQlub2RlLT5uYW1lLCBkZWNsLT5uYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAKICAgICovCiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IG1hdGNoZXMKICAgICAqIFRPRE8sIEZJWE1FOiBDYW4gdGhpcyBzdGlsbCBoYXBwZW4gaGVyZT8gSXNuJ3QgdGhpcyBhbHJlYWR5IGNoZWNrZWQKICAgICAqIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbj8gICAgICAgICAKICAgIGlmICgheG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIGRlY2wtPm5hbWUpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycjMoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIFhNTF9TQ0hFTUFTX0VSUl9XUk9OR0VMRU0sIAoJICAgICJFbGVtZW50ICVzOiBtaXNzaW5nIGNoaWxkICVzIGZvdW5kICVzXG4iLAoJICAgIG5vZGUtPm5hbWUsIGRlY2wtPm5hbWUsIGNoaWxkLT5uYW1lKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAqLwogICAgLyoKICAgICogVVJHRU5UIFRPRE86IExvb2sgdXAgd2hhdCB0byBkbyBpZiB0aGUgdHlwZSBpcyBub3QgYXZhaWxhYmxlLgogICAgKi8KICAgIGlmICh0eXBlICE9IE5VTEwpCgl4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgdHlwZSk7CiAgICAKICAgIGN0eHQtPm5vZGUgPSBlbGVtOwogICAgY3R4dC0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbDsKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFJlcHJlc2VudHMgdGhlIHJlY3Vyc2l2ZSBwb3J0aW9uIG9mIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQuIAogKiBOb3QgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBvdGhlciBmdW5jdGlvbnMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCQkgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCAKCQkJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsgICAgICAgIAogICAgY29uc3QgeG1sQ2hhciAqdXJpOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwoKICAgIGlmIChjdHh0LT5vcHRpb25zICYgWE1MX1NDSEVNQV9WQUxfWFNJX0FTU0VNQkxFKSB7CQoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW0oY3R4dCwgY3R4dC0+bm9kZSk7CglpZiAocmV0ID09IC0xKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQljdHh0LT5ub2RlLCBOVUxMLCAJCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQsICIKCQkiYXNzZW1ibGluZyBzY2hlbWEgYnkgeHNpIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiBOT1RFOiBXZSB3b24ndCByZWFjdCBvbiBzY2hlbWEgcGFyc2VyIGVycm9ycyBoZXJlLgoJKiBUT0RPOiBCdXQgYSB3YXJuaW5nIHdvdWxkIGJlIG5pY2UuCgkqLwogICAgfSAgICAKICAgIGlmICh3aWxkLT5wcm9jZXNzQ29udGVudHMgIT0gWE1MX1NDSEVNQVNfQU5ZX1NLSVApIHsKCXhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCA9IE5VTEw7CgoJaWYgKG5vZGUtPm5zICE9IE5VTEwpCgkgICAgZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCgkgICAgbm9kZS0+bmFtZSwgbm9kZS0+bnMtPmhyZWYsIE5VTEwpOwoJZWxzZSAKCSAgICBkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwgbm9kZS0+bmFtZSwgTlVMTCwgTlVMTCk7CglpZiAoZGVjbCAhPSBOVUxMKSB7CQkgICAgCgkgICAgY3R4dC0+bm9kZSA9IG5vZGU7CQoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZGVjbCk7CgkgICAgaWYgKHJldCA8IDApIHsJCQoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBbnlJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBhbiBlbGVtZW50IGluIHRoZSBjb250ZXh0IG9mIGEgd2lsZGNhcmQuIiwKCQkgICAgTlVMTCwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKQoJCXJldHVybiAocmV0KTsKCX0gZWxzZSBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpIHsKCSAgICAvKiBUT0RPOiBDaGFuZ2UgdG8gcHJvcGVyIGVycm9yIGNvZGUuICovCgkgICAgeG1sU2NoZW1hVldpbGRjYXJkRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwKCQlub2RlLCB3aWxkLCAiTm8gbWF0Y2hpbmcgZ2xvYmFsIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIpOwoJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKCX0KICAgIH0KICAgIGlmIChub2RlLT5jaGlsZHJlbiAhPSBOVUxMKSB7CSAgIAoJY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKCWRvIHsKCSAgICBpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJCWlmIChjaGlsZC0+bnMgIT0gTlVMTCkKCQkgICAgdXJpID0gY2hpbGQtPm5zLT5ocmVmOwoJCWVsc2UKCQkgICAgdXJpID0gTlVMTDsKCQlpZiAoeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnMod2lsZCwgdXJpKSA9PSAwKSB7CgkJICAgIC8qIFRPRE86IGVycm9yIGNvZGUuICovCgkJICAgIHhtbFNjaGVtYVZXaWxkY2FyZEVycihjdHh0LCBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCWNoaWxkLCB3aWxkLCAKCQkJIlRoZSBuYW1lc3BhY2Ugb2YgdGhlIGVsZW1lbnQgaXMgbm90IGFsbG93ZWQiKTsKCQkgICAgcmV0dXJuIChjdHh0LT5lcnIpOyAgCgkJfQoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbChjdHh0LCAKCQkgICAgd2lsZCwgY2hpbGQpOwoJCWlmIChyZXQgIT0gMCkKCQkgICAgcmV0dXJuIChyZXQpOwkJCgkgICAgfQoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IHdoaWxlICAoY2hpbGQgIT0gTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50Q29udEJ5V2lsZGNhcmQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAgICAKICAgIGlmICgodHlwZSA9PSBOVUxMKSB8fCAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQU5ZKSB8fAoJKGN0eHQtPm5vZGUgPT0gTlVMTCkpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgY3R4dC0+bm9kZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICByZXR1cm4oeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsKGN0eHQsIAoJICAgIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCBjdHh0LT5ub2RlKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUFueVR5cGVDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIGN1cnJlbnQgZWxlbWVudAogKgogKiBUaGlzIG9uZSB2YWxpZGF0ZXMgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBvZiB0aGUgdHlwZQogKiAnYW55VHlwZScuIFRoZSBwcm9jZXNzIGNvbnRlbnRzIG9mIHRoZSB3aWxkY2FyZCBvZiAnYW55VHlwZScgaXMgImxheCIsIAogKiB0aHVzIGVsZW1lbnRzIGluIHRoZSBzdWJ0cmVlIHdpbGwgYmUgdmFsaWRhdGVkLCBpZiBhIGNvcnJlc3BvbmRpbmcKICogZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYSBleGlzdHMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBhbmQgaXRzIHN1YnRyZWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeUFueVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb2xkdHlwZTsKICAgIHhtbE5vZGVQdHIgdG9wLCBjdXI7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2w7CiAgICBpbnQgc2tpcENvbnRlbnQsIHJldDsKCiAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKGN0eHQtPm5vZGUgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsKCiAgICBpZiAoY3R4dC0+bm9kZS0+Y2hpbGRyZW4gPT0gTlVMTCkgCglyZXR1cm4gKDApOwoKICAgIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgdG9wID0gY3R4dC0+bm9kZTsgICAgICAgIAogICAgLyoKICAgICogU1RSRUFNOiBDaGlsZCBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIGN1ciA9IGN0eHQtPm5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7Cglza2lwQ29udGVudCA9IDA7CglpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICAvKgoJICAgICogVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIGlzICJsYXgiLCB0aHVzCgkgICAgKiB3ZSBuZWVkIHRvIHZhbGlkYXRlIHRoZSBlbGVtZW50IGlmIGEgZGVjbGFyYXRpb24KCSAgICAqIGV4aXN0cy4KCSAgICAqLwkJCgkgICAgaWYgKGN1ci0+bnMgIT0gTlVMTCkKCQlkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKCQkgICAgY3VyLT5uYW1lLCBjdXItPm5zLT5ocmVmLCBOVUxMKTsKCSAgICBlbHNlIAoJCWRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLCBjdXItPm5hbWUsIE5VTEwsIE5VTEwpOwkgICAgCgkgICAgaWYgKGRlY2wgIT0gTlVMTCkgewkJICAgIAoJCWN0eHQtPm5vZGUgPSBjdXI7CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbihjdHh0LCBkZWNsKTsKCQljdHh0LT5ub2RlID0gdG9wOwoJCWlmIChyZXQgPCAwKSB7CQkKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdXIsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQW55VHlwZUNvbnRlbnQsICIKCQkJInZhbGlkYXRpbmcgYW4gZWxlbWVudCBpbiB0aGUgY29udGV4dCBvZiBhIHdpbGRjYXJkLiIsCgkJCU5VTEwsIE5VTEwpOwoJCSAgICByZXR1cm4gKHJldCk7CgkJfSBlbHNlIGlmIChyZXQgPiAwKQoJCSAgICByZXR1cm4gKHJldCk7CgkJc2tpcENvbnRlbnQgPSAxOwoJICAgIH0KCX0gICAKCS8qCgkqIEJyb3dzZSB0aGUgZnVsbCBzdWJ0cmVlLCBkZWVwIGZpcnN0LgoJKi8KICAgICAgICBpZiAoKHNraXBDb250ZW50ID09IDApICYmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpKSB7CgkgICAgLyogZGVlcCBmaXJzdCAqLwoJICAgIGN1ciA9IGN1ci0+Y2hpbGRyZW47Cgl9IGVsc2UgaWYgKChjdXIgIT0gdG9wKSAmJiAoY3VyLT5uZXh0ICE9IE5VTEwpKSB7CgkgICAgLyogdGhlbiBzaWJsaW5ncyAqLwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0gZWxzZSBpZiAoY3VyICE9IHRvcCkgewoJICAgIC8qIGdvIHVwIHRvIHBhcmVudHMtPm5leHQgaWYgbmVlZGVkICovCgkgICAgd2hpbGUgKGN1ciAhPSB0b3ApIHsKCSAgICAgICAgaWYgKGN1ci0+cGFyZW50ICE9IE5VTEwpCgkJICAgIGN1ciA9IGN1ci0+cGFyZW50OwoJCWlmICgoY3VyICE9IHRvcCkgJiYgKGN1ci0+bmV4dCAhPSBOVUxMKSkgewoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJICAgIGJyZWFrOwoJCX0KCQlpZiAoY3VyLT5wYXJlbnQgPT0gTlVMTCkgewoJCSAgICBjdXIgPSBOVUxMOwoJCSAgICBicmVhazsKCQl9CgkgICAgfQoJICAgIC8qIGV4aXQgY29uZGl0aW9uICovCgkgICAgaWYgKGN1ciA9PSB0b3ApIAoJICAgICAgICBjdXIgPSBOVUxMOwoJfSBlbHNlCgkgICAgYnJlYWs7CiAgICB9CiAgICBjdHh0LT50eXBlID0gb2xkdHlwZTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFIYXNFbGVtT3JDaGFyQ29udGVudDogCiAqIEBub2RlOiAgdGhlIG5vZGUKICoKICogU2NvdXJzIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBub2RlIGZvciBlbGVtZW50CiAqIGFuZCBjaGFyYWN0ZXIgbm9kZXMuCiAqCiAqIFJldHVybnMgMSBpZiBhbiBlbGVtZW50IG9yIGNoYXJhY3RlciBub2RlIGlzIGZvdW5kLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGN1cjsKCiAgICBpZiAobm9kZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIGN1ciA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CglpZiAoKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB8fAoJLyogCgkqIFRPRE86IEFzayBEYW5pZWwgaWYgdGhlc2UgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkqLwoJKGN1ci0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSB8fAkJICAgIAoJKGN1ci0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSB8fAoJLyoKCSogVE9ETzogSG93IFhNTF9FTlRJVFlfTk9ERXMgZXZhbHVhdGVkPwoJKi8KCShjdXItPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgfHwKCShjdXItPnR5cGUgPT0gWE1MX0VOVElUWV9OT0RFKSkgewoJICAgIHJldHVybiAoMSk7Cgl9CgljdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBjb21wbGV4IHR5cGUgdHlwZQogKiB4bWxzY2hlbWEtMS5odG1sI2N2Yy1jb21wbGV4LXR5cGUKICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICogTm90ZSBvbiByZXBvcnRlZCBlcnJvcnM6IEFsdGhvdWdoIGl0IG1pZ2h0IGJlIG5pY2UgdG8gcmVwb3J0CiAqIHRoZSBuYW1lIG9mIHRoZSBzaW1wbGUvY29tcGxleCB0eXBlLCB1c2VkIHRvIHZhbGlkYXRlIHRoZSBjb250ZW50CiAqIG9mIGEgbm9kZSwgaXQgaXMgcXVpdGUgdW5uZWNlc3Nhcnk6IGZvciBnbG9iYWwgZGVmaW5lZCB0eXBlcwogKiB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBlcXVhbCB0byB0aGUgTkNOYW1lIG9mIHRoZSB0eXBlLAogKiBmb3IgbG9jYWwgZGVmaW5lZCB0eXBlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBvdXRwdXQgdGhlIGludGVybmFsCiAqIGNvbXB1dGVkIG5hbWUgb2YgdGhlIHR5cGUuIFRPRE86IEluc3RlYWQsIG9uZSBzaG91bGQgYXR0YWNoIHRoZSAKICogc3RydWN0IG9mIHRoZSB0eXBlIGludm9sdmVkIHRvIHRoZSBlcnJvciBoYW5kbGVyIC0gdGhpcyBhbGxvd3MKICogdGhlIHJlcG9ydCBvZiBhbnkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBieSB0aGUgdXNlci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb2xkdHlwZTsgICAgCiAgICB4bWxOb2RlUHRyIGVsZW0sIGNoaWxkOwogICAgaW50IHJldCA9IDA7CiAgICBjb25zdCB4bWxDaGFyICpuc1VyaTsgICAgCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cnMgPSBOVUxMLCBhdHRyVG9wID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKQoJcmV0dXJuICgtMSk7CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIGVsZW0gPSBjdHh0LT5ub2RlOwoKCiAgICAvKgogICAgKiBWZXJpZnkgdGhlIGF0dHJpYnV0ZXMKICAgICovCiAgICAvKgogICAgKiBUT0RPOiBUaGlzICJhdHRyVG9wIiB0aGluZyBpcyBub3QgbmVlZGVkIGFueSBtb3JlLgogICAgKi8gICAgCiAgICBhdHRycyA9IGN0eHQtPmF0dHI7ICAgIAogICAgYXR0clRvcCA9IGN0eHQtPmF0dHJUb3A7ICAgCiAgICAvKgogICAgKiBTVFJFQU06IEF0dHJpYnV0ZSBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlcyhjdHh0LCBlbGVtLT5wcm9wZXJ0aWVzKTsgICAgIAogICAgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIGVsZW0sIHR5cGUpOwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBjdHh0LT5hdHRyID0gYXR0cnM7ICAgIAogICAgY3R4dC0+YXR0clRvcCA9IGF0dHJUb3A7CgogICAgLyoKICAgICogRklYTUUgVE9ETzogVGhpcyBvbmUgY3JlYXRlcyBhIHJlZ2V4cCBldmVuIGlmIG5vIGNvbnRlbnQKICAgICogbW9kZWwgd2FzIGRlZmluZWQuIFNvbWVob3cgLT5jb250TW9kZWwgaXMgYWx3YXlzIG5vdCBOVUxMCiAgICAqIGZvciBjb21wbGV4IHR5cGVzLCBldmVuIGlmIHRoZXkgYXJlIGVtcHR5LgogICAgKi8gICAgCiAgICAvKgogICAgKiBGSVhNRSBUT0RPIFVSR0VOVDogTW92ZSB0aGUgY29udGVudCBtb2RlbCB0byB0aGUKICAgICogdHlwZSBkZWZpbml0aW9uLgogICAgKi8gICAgICAKICAgIHN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOiB7CgkgICAgLyoKCSAgICAqIDEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVtcHR5LCB0aGVuIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIAoJICAgICogaXRlbSBoYXMgbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgoJICAgICovCgkgICAgLyoKCSAgICAqIFRPRE86IElzIHRoZSBlbnRpdHkgc3R1ZmYgY29ycmVjdD8KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFIYXNFbGVtT3JDaGFyQ29udGVudChlbGVtKSA9PSAxKSB7CSAgICAJICAgIAoJCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzEsCgkJICAgIGVsZW0sIHR5cGUsIAoJCSAgICAiQ2hhcmFjdGVyIG9yIGVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgIgoJCSAgICAiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVtcHR5Iik7CiAgICAgICAgICAgIH0JIAogICAgICAgICAgICBicmVhazsKCX0KCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgoJICAgIGlmICgodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgJiYgCgkJKHR5cGUtPmJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSkgewoJCS8qCgkJKiBUaGUgdHlwZSBoYXMgJ2FueVR5cGUnIGFzIGl0cyBiYXNlIGFuZCBubyBjb250ZW50IG1vZGVsCgkJKiBpcyBkZWZpbmVkIC0+IHVzZSAnYW55VHlwZScgYXMgdGhlIHR5cGUgdG8gdmFsaWRhdGUKCQkqIGFnYWluc3QuCgkJKi8KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeUFueVR5cGUoY3R4dCwgdHlwZS0+YmFzZVR5cGUpOwoJCS8qIFRPRE86IEhhbmRsZSAtMS4gKi8KCQlicmVhazsKCSAgICB9CgkgICAgLyogTm8gYnJlYWsgb24gcHVycG9zZS4gKi8KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICB7CgkgICAgeG1sUmVnRXhlY0N0eHRQdHIgb2xkcmVnZXhwID0gTlVMTDsKCgkgICAgCgkgICAgLyoKCSAgICAqIENvbnRlbnQgbW9kZWwgY2hlY2sgaW5pdGlhbGl6YXRpb24uCgkgICAgKi8KCSAgICBpZiAodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpIHsJCQkJCQoJCW9sZHJlZ2V4cCA9IGN0eHQtPnJlZ2V4cDsKCQljdHh0LT5yZWdleHAgPSB4bWxSZWdOZXdFeGVjQ3R4dCh0eXBlLT5jb250TW9kZWwsCgkJICAgICh4bWxSZWdFeGVjQ2FsbGJhY2tzKQoJCSAgICB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCBjdHh0KTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICI9PT09PiAlc1xuIiwgZWxlbS0+bmFtZSk7CiNlbmRpZgoJICAgIH0KCSAgICAvKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgZWxlbURlY2wtPnN1YnR5cGVzKTsgKi8KCSAgICAKCSAgICAKCSAgICAvKgoJICAgICogU1RSRUFNOiBDaGlsZHJlbiBhcmUgcHJvY2Vzc2VkLgoJICAgICovCgkgICAgY2hpbGQgPSBlbGVtLT5jaGlsZHJlbjsKCSAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewkJCgkJaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQkgICAgaWYgKGNoaWxkLT5ucyAhPSBOVUxMKQoJCQluc1VyaSA9IGNoaWxkLT5ucy0+aHJlZjsKCQkgICAgZWxzZQoJCQluc1VyaSA9IE5VTEw7CgkJICAgIHJldCA9IHhtbFJlZ0V4ZWNQdXNoU3RyaW5nMihjdHh0LT5yZWdleHAsCgkJCWNoaWxkLT5uYW1lLCBuc1VyaSwgY2hpbGQpOwoJCSAgICAvKgoJCSAgICAqIFVSR0VOVCBUT0RPOiBDb3VsZCB3ZSBhbmNob3IgYW4gZXJyb3IgcmVwb3J0CgkJICAgICogaGVyZSB0byBub3RpZnkgb2YgaW52YWxpZCBlbGVtZW50cz8KCQkgICAgKi8KI2lmZGVmIERFQlVHX0FVVE9NQVRBCQkgICAgCgkJICAgIGlmIChyZXQgPCAwKQoJCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkJIiAgLS0+ICVzIEVycm9yXG4iLCBjaGlsZC0+bmFtZSk7CgkJICAgIGVsc2UKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlc1xuIiwgY2hpbGQtPm5hbWUpOwojZW5kaWYKCQl9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpICYmIAoJCSAgICAvKiAKCQkgICAgKiBUT0RPOiBBc2sgRGFuaWVsIGlmIHRoaXMgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkJICAgICovCgkJICAgICgoKGNoaWxkLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICghSVNfQkxBTktfTk9ERShjaGlsZCkpKSB8fAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwJCSAgICAJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSB8fAkJICAgIAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSkgewkJICAgIAoJCSAgICAvKiAKCQkgICAgKiAyLjMgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVsZW1lbnQtb25seSwgdGhlbiB0aGUgCgkJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBbY2hpbGRyZW5dIG90aGVyIHRoYW4gdGhvc2Ugd2hvc2UgW2NoYXJhY3RlciAKCQkgICAgKiBjb2RlXSBpcyBkZWZpbmVkIGFzIGEgd2hpdGUgc3BhY2UgaW4gW1hNTCAxLjAgKFNlY29uZCAKCQkgICAgKiBFZGl0aW9uKV0uCgkJICAgICovCQkJCgkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzMsCgkJCWVsZW0sIHR5cGUsIAoJCQkiQ2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkJImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbGVtZW50LW9ubHkiKTsJCSAgICAKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CQkgICAgCgkgICAgfSAgICAKCSAgICAvKgoJICAgICogQ29udGVudCBtb2RlbCBjaGVjayBmaW5hbGl6YXRpb24uCgkgICAgKi8KICAgICAgIAkgICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CgkJcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJICAgICI9PT09PiAlcyA6ICVkXG4iLCBlbGVtLT5uYW1lLCByZXQpOwojZW5kaWYKCQlpZiAocmV0ID09IDApIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCWVsZW0sIHR5cGUsICJUaGUgZWxlbWVudCBjb250ZW50IGlzIG5vdCB2YWxpZCIsIE5VTEwpOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwKCQkJZWxlbSwgdHlwZSwgIlRoZSBlbGVtZW50IGNvbnRlbnQgaXMgbm90IHZhbGlkIiwgTlVMTCk7CiNpZmRlZiBERUJVR19DT05URU5UCgkJfSBlbHNlIHsKCQkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgc3VjY2VlZGVkXG4iLAoJCQllbGVtLT5uYW1lKTsKCQkgICAgCiNlbmRpZgoJCX0KCQl4bWxSZWdGcmVlRXhlY0N0eHQoY3R4dC0+cmVnZXhwKTsKCQljdHh0LT5yZWdleHAgPSBvbGRyZWdleHA7CgkgICAgfQoJfQogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzp7CgkgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwoJICAgIC8qCgkgICAgKiBXZSBoaXQgYSBjb21wbGV4VHlwZSB3aXRoIGEgc2ltcGxlQ29udGVudCByZXNvbHZpbmcKCSAgICAqIHRvIGEgdXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluIHNpbXBsZSB0eXBlLgoJICAgICovCgkgICAgLyogCgkgICAgKiAyLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgCgkgICAgKiB0aGVuIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGVsZW1lbnQgCgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0sIGFuZCB0aGUgt25vcm1hbGl6ZWQgdmFsdWW3IAoJICAgICogb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyC3dmFsaWS3IHdpdGggcmVzcGVjdCAKCSAgICAqIHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKCSAgICAqIFZhbGlkICinMy4xNC40KS4KCSAgICAqLwkgIAoJICAgIC8qCgkgICAgKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkgICAgKi8KCSAgICBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOwoJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CgkJLyoKCQkqIFRPRE86IENvdWxkIHRoZSBlbnRpdHkgc3R1ZmYgcHJvZHVjZSBlbGVtZW50cwoJCSogYXMgd2VsbD8KCQkqLwogICAgICAgICAgICAgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAKCQkJIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgYmVjYXVzZSAiCgkJCSJ0aGUgY29udGVudCB0eXBlIGlzIGEgc2ltcGxlIHR5cGUiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJICAgIGJyZWFrOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwkJICAgIAoJICAgIH0JCgkgICAgY3R4dC0+bm9kZSA9IGVsZW07CgkgICAgY3R4dC0+Y3VyID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyoKCQkqIFZhbGlkYXRlIHRoZSBjaGFyYWN0ZXIgY29udGVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCgkJKi8KCQkvKgoJCSogU1RSRUFNOiBDaGlsZHJlbiBhcmUgcHJvY2Vzc2VkLgoJCSovCgkJaWYgKGVsZW0tPmNoaWxkcmVuID09IE5VTEwpCgkJICAgIHZhbHVlID0gTlVMTDsKCQllbHNlCgkJICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoZWxlbSk7IAoJCS8qCgkJKiBVUkdFTlQgVE9ETzogU2hvdWxkIGZhY2V0cyBmb3IgdGhlIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gYmUgCgkJKiBkaXNhYmxlZCwgaWYgdGhlIGRlcml2YXRpb24gb2YgZmFjZXRzIGZvciBjb21wbGV4IHR5cGVzIAoJCSogaXMgaW1wbGVtZW50ZWQ/CgkJKi8KCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIHdvbid0IGNoZWNrIHRoZSBjb3JyZWN0IHR5cGVzIG9mIHRoZQoJCSogY29udGVudCBub2Rlcywgc2luY2UgdGhpcyBzaG91bGQgYmUgZG9uZSBoZXJlLgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUsIDEsIDEsIDEsIDApOwoJCWlmIChyZXQgPiAwKSB7CQoJCSAgICAvKgoJCSAgICAqIE5PVEU6IEFsdGhvdWdoIGFuIGVycm9yIHdpbGwgYmUgcmVwb3J0ZWQgYnkgCgkJICAgICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsIHRoZSBzcGVjIHdhbnRzCgkJICAgICogYSBzcGVjaWZpYyBjb21wbGV4IHR5cGUgZXJyb3IgdG8gYmUgcmVwb3J0ZWQgCgkJICAgICogYWRkaXRpb25hbGx5LgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnLlxuIiwKCQkJZWxlbS0+bmFtZSwgdHlwZS0+bmFtZSk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQkgICAgCgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyogCgkJKiBBcHBseSBmYWNldHMgb2YgdGhlIGNvbXBsZXhUeXBlLiBCZSBzdXJlIHRvIHBhc3MgdGhlIAoJCSogYnVpbHQtaW4gdHlwZSB0byB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLgoJCSovCSAgICAKCQkvKiBVUkdFTlQgVE9ETzogSSBkb24ndCBrbm93IHlldCBpZiB0aGUgZmFjZXRzIG9mIHRoZSBzaW1wbGUgdHlwZQoJCSogYXJlIHVzZWQsIG9yIGlmIHRoZSBmYWNldHMsIGRlZmluZWQgYnkgdGhpcyBjb21wbGV4IHR5cGUsCgkJKiBhcmUgdG8gYmUgdXNlZCBvbmx5LiBUaGlzIGhlcmUgYXBwbGllcyBib3RoIGZhY2V0IHNldHMuCgkJKi8JICAgIAoKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIAoJCSAgICB0eXBlLCB2YWx1ZSwgMCwgMSk7CgkJaWYgKHJldCA+IDApIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMiwKCQkJZWxlbSwgdHlwZSwgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnOyBmYWlsZWQgdG8gIgoJCQkiYXBwbHkgZmFjZXRzLlxuIiwKCQkJdHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCXhtbEZyZWUodmFsdWUpOyAgICAKCSAgICBicmVhazsKCX0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUT0RPIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5pbXBsZW1lbnRlZCBjb250ZW50IHR5cGUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgbGlzdCBvZiB0eXBlIGRlY2xhcmF0aW9ucwogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGFnYWluc3QgdGhlIHR5cGVzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpbnQgcmV0OwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24iLgogICAgKiBJdCB3aWxsIGZvcndhcmQgdG8gdGhlIHByb3BlciB2YWxpZGF0aW9uIAogICAgKiBwcm9jZWR1cmVzIGZvciB0aGUgZ2l2ZW4gdHlwZS4KICAgICovCiAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKGN0eHQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICAKICAgIC8qCiAgICAqIEBlbGVtRGVjbC0+c3VidHlwZXMgd2lsbCBiZSBvZiB0eXBlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYLAogICAgKiBYTUxfU0NIRU1BX1RZUEVfU0lNUExFIG9yIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQy4KICAgICovCiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUoY3R4dCwgdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoY3R4dCwgdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgkgICAgaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKGN0eHQsIHR5cGUpOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoY3R4dCwgdHlwZSk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldCA9IC0xOwoJICAgIGJyZWFrOwogICAgfQkKICAgIGlmIChyZXQgPT0gLTEpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UKCXJldHVybiAoY3R4dC0+ZXJyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBjb21wbGV4VHlwZSBob2xkaW5nIHRoZSBhdHRyaWJ1dGUgdXNlcwogKgogKiBWYWxpZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiBhbiBlbGVtZW50LgogKgogKiAxLiBFeGlzdGVudCwgaW52YWxpZCBhdHRyaWJ1dGVzIGFyZSByZXBvcnRlZCBpbiB0aGUgZm9ybSAKICogICAgInByZWZpeDpsb2NhbE5hbWUiLiAKICogICAgUmVhc29uOiByZWFkYWJpbGl0eSAtIGl0IGlzIGVhc2llciB0byBmaW5kIHRoZSBhY3R1YWwgWE1MIAogKiAgICByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXR0cmlidXRlcyBRTmFtZS4KICogMi4gTWlzc2luZyBhdHRyaWJ1dGVzIGFyZSByZXBvcnRlZCBpbiB0aGUgZm9ybSAKICogICAgeyJVUkkiLCAibG9jYWxOYW1lIn0uCiAqICAgIFRoaXMgaXMgbmVjZXNzYXJ5LCBzaW5jZSB0aGUgdGhlIHByZWZpeCBuZWVkIG5vdCB0byBiZSBkZWNsYXJlZAogKiAgICBhdCBhbGwsIGFuZCB0aHVzIGlzIG5vdCBjb21wdXRhYmxlLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0sIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJldDsKICAgIHhtbEF0dHJQdHIgYXR0cjsgLyogQW4gYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50LiAqLwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpuc1VSSTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2w7CiAgICBpbnQgZm91bmQ7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgY3VyU3RhdGUsIHJlcUF0dHJTdGF0ZXMgPSBOVUxMLCByZXFBdHRyU3RhdGVzVG9wID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZTsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaW50IHJlZHVuZGFudCA9IDA7CiNlbmRpZgoKICAgIC8qIAogICAgKiBOT1RFOiBUaGlzIG9uZSB1c2VzIGF0dHItPnN1YnR5cGVzIHRvIGdldCB0aGUgdHlwZSBkZWNsLiAtIHJlZ2FyZGxlc3MKICAgICogaWYgd2UgaGF2ZSBhbiBhdHRyaWJ1dGUgcmVmZXJlbmNlIG9yIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi4KICAgICovICAgIAogICAgLyoKICAgICogQWxsb3cgYWxsIGF0dHJpYnV0ZXMgaWYgdGhlIHR5cGUgaXMgYW55VHlwZS4KICAgICovCiAgICBpZiAodHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKSkKCXJldHVybiAoMCk7CgogICAgb2xkbm9kZSA9IGN0eHQtPm5vZGU7CiAgICBpZiAodHlwZSAhPSBOVUxMKQoJYXR0clVzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CiAgICB3aGlsZSAoYXR0clVzZSAhPSBOVUxMKSB7CiAgICAgICAgZm91bmQgPSAwOyAgICAKCWF0dHJEZWNsID0gYXR0clVzZS0+YXR0cjsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJcHJpbnRmKCJhdHRyIHVzZSAtIG5hbWU6ICVzXG4iLCB4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoYXR0ckRlY2wpKTsKCXByaW50ZigiYXR0ciB1c2UgLSB1c2U6ICVkXG4iLCBhdHRyRGVjbC0+b2NjdXJzKTsKI2VuZGlmCiAgICAgICAgZm9yIChjdXJTdGF0ZSA9IGN0eHQtPmF0dHI7IGN1clN0YXRlICE9IE5VTEw7IGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQpIHsJCSAgICAKCgkgICAgaWYgKGN1clN0YXRlLT5kZWNsID09IGF0dHJVc2UtPmF0dHIpIHsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJCXJlZHVuZGFudCA9IDE7CiNlbmRpZgogICAgICAgIH0KCSAgICBhdHRyID0gY3VyU3RhdGUtPmF0dHI7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImF0dHIgLSBuYW1lOiAlc1xuIiwgYXR0ci0+bmFtZSk7CgkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpCgkJcHJpbnRmKCJhdHRyIC0gbnM6ICVzXG4iLCBhdHRyLT5ucy0+aHJlZik7CgkgICAgZWxzZQoJCXByaW50ZigiYXR0ciAtIG5zOiBub25lXG4iKTsKI2VuZGlmCgkgICAgLyogVE9ETzogQ2FuIHRoaXMgZXZlciBoYXBwZW4/ICovCiAgICAgICAgICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+cmVmKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKChhdHRyRGVjbC0+cmVmTnMgPT0gTlVMTCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgYXR0ckRlY2wtPnJlZk5zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyRGVjbC0+cmVmTnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+bmFtZSkpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaGFuZGxlIHRoZSBuYW1lc3BhY2VzIGNoZWNrcyBoZXJlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICAqIGFjY2VwdCBhbiB1bnF1YWxpZmllZCBhdHRyaWJ1dGUgb25seSBpZiB0aGUgdGFyZ2V0CgkJICAgICAqIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyYXRpb24gaXMgYWJzZW50LgoJCSAgICAgKi8KCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKCQkJLyogCgkJCSAqIFRoaXMgY2hlY2sgd2FzIHJlbW92ZWQsIHNpbmNlIHRoZSB0YXJnZXQgbmFtZXNwYWNlCgkJCSAqIHdhcyBldmFsdWF0ZWQgZHVyaW5nIHBhcnNpbmcgYW5kIGFscmVhZHkgdG9vawoJCQkgKiAiYXR0cmlidXRlRm9ybURlZmF1bHQiIGludG8gYWNjb3VudC4KCQkJICovCgkJICAgICAgICAvKiAoKGF0dHJpYnV0ZXMtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9OU0RFRkFVTFQpID09IDApKSAqLwoJCSAgICAgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkKCQkgICAgICAgIGNvbnRpbnVlOwoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJICAgICAgICAgICAgICAgICAgICAgYXR0ci0+bnMtPmhyZWYpKQoJCQljb250aW51ZTsKCQl9CiAgICAgICAgICAgIH0KI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigiZm91bmRcbiIpOwojZW5kaWYKICAgICAgICAgICAgZm91bmQgPSAxOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGlmIChhdHRyRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewoJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQ7CgkJY3VyU3RhdGUtPmRlY2wgPSBhdHRyRGVjbDsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IGF0dHJpYnV0ZSAlcyB0eXBlIG5vdCByZXNvbHZlZFxuIiwKCQkJICAgICAgYXR0ci0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwoJICAgIGN0eHQtPm5vZGUgPSAoeG1sTm9kZVB0cikgYXR0cjsKCSAgICBjdHh0LT5jdXIgPSBhdHRyLT5jaGlsZHJlbjsKCSAgICAvKgoJICAgICogTk9URTogVGhpcyBjYWxsIGFsc28gY2hlY2tzIHRoZSBjb250ZW50IG5vZGVzIGZvciBjb3JyZWN0IHR5cGUuCgkgICAgKi8KICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgYXR0ckRlY2wtPnN1YnR5cGVzLCAKCQl2YWx1ZSwgMSwgMSwgMSwgMSk7CiAgICAgICAgICAgIGlmIChyZXQgIT0gMCkgCgkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFOyAgIAkJCQkKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxGcmVlKHZhbHVlKTsKICAgICAgICAgICAgfQkgICAgCiAgICAgICAgfQogICAgICAgIGlmICgoIWZvdW5kKSAmJiAoYXR0ckRlY2wtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCSAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigicmVxdWlyZWQgYXR0ciBub3QgZm91bmRcbiIpOwojZW5kaWYKCSAgICAvKgoJICAgICAqIEFkZCBhIG5ldyBkdW1teSBhdHRyaWJ1dGUgc3RhdGUuCgkgICAgICovCQoJICAgIHRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CgkgICAgaWYgKHRtcCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyIsIE5VTEwpOwoJCWN0eHQtPm5vZGUgPSBvbGRub2RlOwoJCXJldHVybiAoLTEpOwogICAgICAgICAgICB9ICAgICAgICAgICAgCgkgICAgdG1wLT5hdHRyID0gTlVMTDsKCSAgICB0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HOwoJICAgIHRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIHRtcC0+bmV4dCA9IE5VTEw7CiAgICAgICAgIAoJICAgIGlmIChyZXFBdHRyU3RhdGVzID09IE5VTEwpIHsKCQlyZXFBdHRyU3RhdGVzID0gdG1wOwoJCXJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CiAgICAgICAgICAgIH0gZWxzZSB7CgkJcmVxQXR0clN0YXRlc1RvcC0+bmV4dCA9IHRtcDsKCQlyZXFBdHRyU3RhdGVzVG9wID0gdG1wOwogICAgICAgICAgICB9CgkKCX0KICAgICAgICBhdHRyVXNlID0gYXR0clVzZS0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAgKiBBZGQgcmVxdWlyZWQgYXR0cmlidXRlcyB0byB0aGUgYXR0cmlidXRlIHN0YXRlcyBvZiB0aGUgY29udGV4dC4KICAgICAqLwogICAgaWYgKHJlcUF0dHJTdGF0ZXMgIT0gTlVMTCkgewoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgewoJICAgIGN0eHQtPmF0dHIgPSByZXFBdHRyU3RhdGVzOwoJfSBlbHNlIHsJCQoJICAgIGN0eHQtPmF0dHJUb3AtPm5leHQgPSByZXFBdHRyU3RhdGVzOwoJfQoJY3R4dC0+YXR0clRvcCA9IHJlcUF0dHJTdGF0ZXNUb3A7CiAgICB9CiAgICAvKgogICAgKiBQcm9jZXNzIHdpbGRjYXJkcy4KICAgICovCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSB7CQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5zOwkKCXByaW50ZigibWF0Y2hpbmcgd2lsZGNhcmQ6IFslZF0gb2YgY29tcGxleFR5cGU6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+bmFtZSk7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBsYXhcbiIpOwoJZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfU1RSSUNUKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBzdHJpY3RcbiIpOwoJZWxzZQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBza2lwXG4iKTsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+YW55KQoJICAgIHByaW50ZigidHlwZTogYW55XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgcHJpbnRmKCJ0eXBlOiBuZWdhdGVkXG4iKTsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKQoJCXByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCSAgICBlbHNlCgkJcHJpbnRmKCJuczogJXNcbiIsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUpOwoJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogc2V0XG4iKTsKCSAgICBucyA9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uc1NldDsKCSAgICB3aGlsZSAobnMgIT0gTlVMTCkgewoJCWlmIChucy0+dmFsdWUgPT0gTlVMTCkKCQkgICAgcHJpbnRmKCJuczogKGFic2VudClcbiIpOwoJCWVsc2UKCQkgICAgcHJpbnRmKCJuczogJXNcbiIsIG5zLT52YWx1ZSk7CgkJbnMgPSBucy0+bmV4dDsKCSAgICB9CSAgICAKCX0gZWxzZQoJICAgIHByaW50ZigiZW1wdHlcbiIpOwoKCiNlbmRpZgkKCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlIChjdXJTdGF0ZSAhPSBOVUxMKSB7CgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pIHsJCQoJCWlmIChjdXJTdGF0ZS0+YXR0ci0+bnMgIT0gTlVMTCkgCgkJICAgIG5zVVJJID0gY3VyU3RhdGUtPmF0dHItPm5zLT5ocmVmOwoJCWVsc2UKCQkgICAgbnNVUkkgPSBOVUxMOwkJCgkJaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQkgICAgbnNVUkkpKSB7CgkJICAgIC8qCgkJICAgICogSGFuZGxlIHByb2Nlc3NDb250ZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQlYTUxfU0NIRU1BU19BTllfTEFYKSB8fAoJCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkpIHsKCQkJCgkJCWF0dHIgPSBjdXJTdGF0ZS0+YXR0cjsJCQkJCQkKCQkJYXR0ckRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCAKCQkJICAgIGF0dHItPm5hbWUsIG5zVVJJKTsJCQoJCQlpZiAoYXR0ckRlY2wgIT0gTlVMTCkgewoJCQkgICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhlbGVtLT5kb2MsIAoJCQkJYXR0ci0+Y2hpbGRyZW4sIDEpOwoJCQkgICAgY3R4dC0+bm9kZSA9ICh4bWxOb2RlUHRyKSBhdHRyOwoJCQkgICAgY3R4dC0+Y3VyID0gYXR0ci0+Y2hpbGRyZW47CgkJCSAgICAvKgoJCQkgICAgKiBOT1RFOiBUaGlzIGNhbGwgYWxzbyBjaGVja3MgdGhlIGNvbnRlbnQgbm9kZXMgCgkJCSAgICAqIGZvciBjb3JyZWN0IHR5cGUuCgkJCSAgICAqLwoJCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgCgkJCQlhdHRyRGVjbC0+c3VidHlwZXMsIHZhbHVlLCAxLCAxLCAxLCAxKTsKCQkJICAgIGlmIChyZXQgIT0gMCkgCgkJCQljdXJTdGF0ZS0+c3RhdGUgPSAKCQkJCVhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCQkJICAgIGVsc2UKCQkJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCQkJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCSAgICBpZiAodmFsdWUgIT0gTlVMTCkgewoJCQkJeG1sRnJlZSh2YWx1ZSk7CgkJCSAgICB9CSAgICAKCQkJICAgIAoJCQl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJCSAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJCX0JCQkJCQkJCQkJCQoJCSAgICB9IGVsc2UKCQkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCX0JCQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgKiBSZXBvcnQgbWlzc2luZyBhbmQgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpIHsKCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlICgoY3VyU3RhdGUgIT0gTlVMTCkgJiYgKGN1clN0YXRlICE9IGN0eHQtPmF0dHJUb3AtPm5leHQpKSB7CgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQpIHsKCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CgkJaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX01JU1NJTkcpCgkJICAgIHhtbFNjaGVtYVZNaXNzaW5nQXR0ckVycihjdHh0LCBlbGVtLCBjdXJTdGF0ZS0+ZGVjbCk7CQkgICAgCgkJZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikgewoJCSAgICAvKiBUT0RPOiAicHJvaGliaXRlZCIgd29uJ3QgZXZlciBiZSB0b3VjaGVkIGhlcmUhLiAKCQkgICAgICAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfUFJPSElCSVRFRCkpCgkJICAgICovCgkJICAgIC8qCgkJICAgICogVE9ETzogT25lIG1pZ2h0IHJlcG9ydCBkaWZmZXJlbnQgZXJyb3IgbWVzc2FnZXMgCgkJICAgICogZm9yIHRoZSBmb2xsb3dpbmcgZXJyb3JzLgoJCSAgICAqLwoJCSAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpKSB7CgkJCXhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfM18yXzEsIGF0dHIpOwoJCSAgICB9IGVsc2UgewoJCQl4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8yLCBhdHRyKTsKCQkgICAgfQoJCX0KCSAgICB9CQoJICAgIGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQ7Cgl9ICAKICAgIH0KI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaWYgKHJlZHVuZGFudCkKCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6IHJlZHVuZGFudCBjYWxsIGJ5IHR5cGU6ICVzXG4iLAoJICAgICAgICAgICAgICAgIHR5cGUtPm5hbWUpOwojZW5kaWYKICAgIGN0eHQtPm5vZGUgPSBvbGRub2RlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICoKICogVmFsaWRhdGUgYW4gZWxlbWVudCBpbiBhIHRyZWUKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbDsgICAgCiAgICBpbnQgcmV0OwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCBhbmQKICAgICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50LgogICAgKi8gIAogICAgLyoKICAgICogQXNzZW1ibGUgbmV3IHNjaGVtYXRhIHVzaW5nIHhzaS4KICAgICovCiAgICBpZiAoY3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1hTSV9BU1NFTUJMRSkgewkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogTk9URTogV2Ugd29uJ3QgcmVhY3Qgb24gc2NoZW1hIHBhcnNlciBlcnJvcnMgaGVyZS4KCSogVE9ETzogQnV0IGEgd2FybmluZyB3b3VsZCBiZSBuaWNlLgoJKi8KICAgIH0KICAgIAkgICAgCiAgICBpZiAoY3R4dC0+bm9kZS0+bnMgIT0gTlVMTCkKCWVsZW1EZWNsID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGN0eHQtPm5vZGUtPm5hbWUsIGN0eHQtPm5vZGUtPm5zLT5ocmVmKTsKICAgIGVsc2UKCWVsZW1EZWNsID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGN0eHQtPm5vZGUtPm5hbWUsIE5VTEwpOwogICAKICAgIGlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzEsCgkgICAgY3R4dC0+bm9kZSwgTlVMTCwgCSAgCgkgICAgIk5vIG1hdGNoaW5nIGdsb2JhbCBkZWNsYXJhdGlvbiBhdmFpbGFibGUiLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX0VMVF8xKTsKICAgIH0gIAogICAgICAgICAgICAgICAKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZWxlbURlY2wpOwogICAgaWYgKHJldCA8IDApIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgY3R4dC0+bm9kZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJICAgICJjYWxsaW5nIHZhbGlkYXRpb24gYnkgZGVjbGFyYXRpb24iLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsgICAKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZU9uZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudCBub2RlCiAqCiAqIFZhbGlkYXRlIGEgYnJhbmNoIG9mIGEgdHJlZSwgc3RhcnRpbmcgd2l0aCB0aGUgZ2l2ZW4gQGVsZW0uCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBhbmQgaXRzIHN1YnRyZWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgCiAqIGNvZGUgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0pCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZWxlbSA9PSBOVUxMKSB8fCAoZWxlbS0+dHlwZSAhPSBYTUxfRUxFTUVOVF9OT0RFKSkKCXJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGVsZW0tPmRvYzsKICAgIGN0eHQtPmVyciA9IDA7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5ub2RlID0gZWxlbTsKICAgIHJldHVybiAoeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KGN0eHQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBkb2M6ICBhIHBhcnNlZCBkb2N1bWVudCB0cmVlCiAqIEB4c2lBc3NlbWJsZTogc2hvdWxkIHNjaGVtYXRhIGJlIGFkZGVkIGlmIHJlcXVlc3RlZCBieSB0aGUgaW5zdGFuY2U/CiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykKewogICAgeG1sTm9kZVB0ciByb290OwogICAgIAogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BVl9ET0NVTUVOVF9FTEVNRU5UX01JU1NJTkcsCgkgICAgKHhtbE5vZGVQdHIpIGRvYywgTlVMTCwKCSAgICAiVGhlIGRvY3VtZW50IGhhcyBubyBkb2N1bWVudCBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAgICAKICAgIC8qCiAgICAgKiBPa2F5LCBzdGFydCB0aGUgcmVjdXJzaXZlIHZhbGlkYXRpb24KICAgICAqLwogICAgY3R4dC0+bm9kZSA9IHJvb3Q7CiAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoY3R4dCk7CgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEKICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsgICAgCiAgICByZXQtPmF0dHJUb3AgPSBOVUxMOwogICAgcmV0LT5hdHRyID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4Owp9CgovKioKICogeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnM6CiAqIEBjdHh0OglhIFhNTC1TY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6IHRoZSBlcnJvciBmdW5jdGlvbiByZXN1bHQKICogQHdhcm46IHRoZSB3YXJuaW5nIGZ1bmN0aW9uIHJlc3VsdAogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQgcmVzdWx0CiAqCiAqIEdldCB0aGUgZXJyb3IgYW5kIHdhcm5pbmcgY2FsbGJhY2sgaW5mb3JtYXRpb25zCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciBhbmQgMCBvdGhlcndpc2UKICovCmludAp4bWxTY2hlbWFHZXRWYWxpZEVycm9ycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCQkJeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgKiB3YXJuLCB2b2lkICoqY3R4KQp7CglpZiAoY3R4dCA9PSBOVUxMKQoJCXJldHVybiAoLTEpOwoJaWYgKGVyciAhPSBOVUxMKQoJCSplcnIgPSBjdHh0LT5lcnJvcjsKCWlmICh3YXJuICE9IE5VTEwpCgkJKndhcm4gPSBjdHh0LT53YXJuaW5nOwoJaWYgKGN0eCAhPSBOVUxMKQoJCSpjdHggPSBjdHh0LT51c2VyRGF0YTsKCXJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIFdpbGwgYmUgZW5hYmxlZCBpZiBpdCBpcyBjbGVhciB3aGF0IG9wdGlvbnMgYXJlIG5lZWRlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG9wdGlvbnM6IGEgY29tYmluYXRpb24gb2YgeG1sU2NoZW1hVmFsaWRPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgdmFsaWRhdGlvbi4KICoKICogUmV0dXJucyAwIGluIGNhc2Ugb2Ygc3VjY2VzcywgLTEgaW4gY2FzZSBvZiBhbgogKiBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkQ3R4dFNldE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSAgICAgaW50IG9wdGlvbnMpCgkJCQkJCnsKICAgIGludCBpOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIC8qCiAgICAqIFdBUk5JTkc6IENoYW5nZSB0aGUgc3RhcnQgdmFsdWUgaWYgYWRkaW5nIHRvIHRoZQogICAgKiB4bWxTY2hlbWFWYWxpZE9wdGlvbi4KICAgICovCiAgICBmb3IgKGkgPSAxOyBpIDw9IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CQogICAgICAgIGlmIChvcHRpb25zICYgMTw8aSkgewoJICAgIHJldHVybiAoLTEpOyAgIAogICAgICAgIH0JCiAgICB9CiAgICBjdHh0LT5vcHRpb25zID0gb3B0aW9uczsKICAgIHJldHVybiAoMCk7ICAgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHRHZXRPcHRpb25zOgogKiBAY3R4dDoJYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0IAogKgogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb2YgdGhlIHZhbGlkYXRpb24gY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKCQkJCQkKeyAgICAKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UgCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOyAgICAKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvYzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGRvYzogIGEgcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxEb2NQdHIgZG9jKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIGN0eHQtPmVyciA9IDA7IAogICAgY3R4dC0+bmJlcnJvcnMgPSAwOyAKICAgICAgICAKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoY3R4dCwgZG9jKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU3RyZWFtOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAaW5wdXQ6ICB0aGUgaW5wdXQgdG8gdXNlIGZvciByZWFkaW5nIHRoZSBkYXRhCiAqIEBlbmM6ICBhbiBvcHRpb25hbCBlbmNvZGluZyBpbmZvcm1hdGlvbgogKiBAc2F4OiAgYSBTQVggaGFuZGxlciBmb3IgdGhlIHJlc3VsdGluZyBldmVudHMKICogQHVzZXJfZGF0YTogIHRoZSBjb250ZXh0IHRvIHByb3ZpZGUgdG8gdGhlIFNBWCBoYW5kbGVyLgogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFBhcnNlcklucHV0QnVmZmVyUHRyIGlucHV0LCB4bWxDaGFyRW5jb2RpbmcgZW5jLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTQVhIYW5kbGVyUHRyIHNheCwgdm9pZCAqdXNlcl9kYXRhKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGlucHV0ID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwogICAgY3R4dC0+aW5wdXQgPSBpbnB1dDsKICAgIGN0eHQtPmVuYyA9IGVuYzsKICAgIGN0eHQtPnNheCA9IHNheDsKICAgIGN0eHQtPnVzZXJfZGF0YSA9IHVzZXJfZGF0YTsKICAgIFRPRE8gcmV0dXJuICgwKTsKfQoKI2VuZGlmIC8qIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQgKi8K