LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKiAKICogVE9ETzoKICogICAtIHdoZW4gdHlwZXMgYXJlIHJlZGVmaW5lZCBpbiBpbmNsdWRlcywgY2hlY2sgdGhhdCBhbGwKICogICAgIHR5cGVzIGluIHRoZSByZWRlZiBsaXN0IGFyZSBlcXVhbAogKiAgICAgLT4gbmVlZCBhIHR5cGUgZXF1YWxpdHkgb3BlcmF0aW9uLgogKiAgIC0gaWYgd2UgZG9uJ3QgaW50ZW5kIHRvIHVzZSB0aGUgc2NoZW1hIGZvciBzY2hlbWFzLCB3ZSAKICogICAgIG5lZWQgdG8gdmFsaWRhdGUgYWxsIHNjaGVtYSBhdHRyaWJ1dGVzIChyZWYsIHR5cGUsIG5hbWUpCiAqICAgICBhZ2FpbnN0IHRoZWlyIHR5cGVzLgogKi8KI2RlZmluZSBJTl9MSUJYTUwKI2luY2x1ZGUgImxpYnhtbC5oIgoKI2lmZGVmIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQKCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CiNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CgojaW5jbHVkZSA8bGlieG1sL3htbHNjaGVtYXMuaD4KI2luY2x1ZGUgPGxpYnhtbC9zY2hlbWFzSW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hc3R5cGVzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sYXV0b21hdGEuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxyZWdleHAuaD4KI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CiNpZmRlZiBMSUJYTUxfUEFUVEVSTl9FTkFCTEVECiNpbmNsdWRlIDxsaWJ4bWwvcGF0dGVybi5oPgojZW5kaWYKCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKLyogI2RlZmluZSBERUJVR19VTklPTl9WQUxJREFUSU9OIDEgKi8KCiNkZWZpbmUgRUxFTV9JTkZPX0VOQUJMRUQgMSAKCiNkZWZpbmUgSURDX0VOQUJMRUQgMQoKI2RlZmluZSBJRENfVkFMVUVfU1VQUE9SVCAxCgojZGVmaW5lIElEQ19YUEFUSF9TVVBQT1JUIDEKCi8qICNkZWZpbmUgREVCVUdfSURDIDEgKi8KCgojZGVmaW5lIFVOQk9VTkRFRCAoMSA8PCAzMCkKI2RlZmluZSBUT0RPIAkJCQkJCQkJXAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCQkJCVwKCSAgICAiVW5pbXBsZW1lbnRlZCBibG9jayBhdCAlczolZFxuIiwJCQkJXAogICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOwoKI2RlZmluZSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikgIiMjIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgcmVmLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkF0dHJpYnV0ZSBkZWNsLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiQXR0cmlidXRlIHJlZi4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc1NUID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJzaW1wbGUgdHlwZSI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQ1QgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImNvbXBsZXggdHlwZSI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtTW9kZWxHckRlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiTW9kZWwgZ3JvdXAiOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbU1vZGVsR3JSZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIk1vZGVsIGdyb3VwIHJlZi4iOwoKI2RlZmluZSBJU19TQ0hFTUEobm9kZSwgdHlwZSkJCQkJCQlcCiAgICgobm9kZSAhPSBOVUxMKSAmJiAobm9kZS0+bnMgIT0gTlVMTCkgJiYJCQkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIChjb25zdCB4bWxDaGFyICopIHR5cGUpKSAmJgkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKQoKI2RlZmluZSBGUkVFX0FORF9OVUxMKHN0cikJCQkJCQlcCiAgICBpZiAoc3RyICE9IE5VTEwpIHsJCQkJCQkJXAoJeG1sRnJlZShzdHIpOwkJCQkJCQlcCglzdHIgPSBOVUxMOwkJCQkJCQlcCiAgICB9CgojZGVmaW5lIElTX0FOWVRZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgIFwKICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpICAgCgojZGVmaW5lIElTX0NPTVBMRVhfVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8ICAgIFwKICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCgojZGVmaW5lIElTX1NJTVBMRV9UWVBFKGl0ZW0pICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwgICAgIFwKICAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpKSAKCi8qCiNkZWZpbmUgWE1MX1NDSEVNQVNfVkFMX1dUU1BfUFJFU0VSVkUgMAojZGVmaW5lIFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1JFUExBQ0UgIDEKI2RlZmluZSBYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSAyCiovCgojZGVmaW5lIFhNTF9TQ0hFTUFTX1BBUlNFX0VSUk9SCQkxCgojZGVmaW5lIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyBYTUxfUEFSU0VfTk9FTlQKCgovKgoqIFhNTF9TQ0hFTUFfVkFMX0xPQ0FURV9CWV9OU05BTUUgPSAxPDwyCiogbG9jYXRlIHNjaGVtYXRhIHRvIGJlIGltcG9ydGVkCiogdXNpbmcgdGhlIG5hbWVzcGFjZSBuYW1lOyBvdGhlcndpc2UKKiB0aGUgbG9jYXRpb24gVVJJIHdpbGwgYmUgdXNlZCAqLwoKLyoKKiB4bWxTY2hlbWFQYXJzZXJPcHRpb246CioKKiBUaGlzIGlzIHRoZSBzZXQgb2YgWE1MIFNjaGVtYSBwYXJzZXIgb3B0aW9ucy4KKgp0eXBlZGVmIGVudW0gewogICAgWE1MX1NDSEVNQV9QQVJfTE9DQVRFX0JZX05TTkFNRQk9IDE8PDAKCSogbG9jYXRlIHNjaGVtYXRhIHRvIGJlIGltcG9ydGVkCgkqIHVzaW5nIHRoZSBuYW1lc3BhY2UgbmFtZTsgb3RoZXJ3aXNlCgkqIHRoZSBsb2NhdGlvbiBVUkkgd2lsbCBiZSB1c2VkICoKfSB4bWxTY2hlbWFQYXJzZXJPcHRpb247CiovCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQXNzZW1ibGUgeG1sU2NoZW1hQXNzZW1ibGU7CnR5cGVkZWYgeG1sU2NoZW1hQXNzZW1ibGUgKnhtbFNjaGVtYUFzc2VtYmxlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUFzc2VtYmxlIHsKICAgIHZvaWQgKippdGVtczsgIC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBuYkl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgc2l6ZUl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCn07CgpzdHJ1Y3QgX3htbFNjaGVtYVBhcnNlckN0eHQgewogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFNjaGVtYVZhbGlkRXJyb3IgZXJyOwogICAgaW50IG5iZXJyb3JzOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHRvcHNjaGVtYTsJLyogVGhlIG1haW4gc2NoZW1hICovCiAgICB4bWxIYXNoVGFibGVQdHIgbmFtZXNwYWNlczsJLyogSGFzaCB0YWJsZSBvZiBuYW1lc3BhY2VzIHRvIHNjaGVtYXMgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIGNvbnN0IHhtbENoYXIgKmNvbnRhaW5lcjsgICAvKiB0aGUgY3VycmVudCBlbGVtZW50LCBncm91cCwgLi4uICovCiAgICBpbnQgY291bnRlcjsKCiAgICBjb25zdCB4bWxDaGFyICpVUkw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHByZXNlcnZlOwkJLyogV2hldGhlciB0aGUgZG9jIHNob3VsZCBiZSBmcmVlZCAgKi8KCiAgICBjb25zdCBjaGFyICpidWZmZXI7CiAgICBpbnQgc2l6ZTsKCiAgICAvKgogICAgICogVXNlZCB0byBidWlsZCBjb21wbGV4IGVsZW1lbnQgY29udGVudCBtb2RlbHMKICAgICAqLwogICAgeG1sQXV0b21hdGFQdHIgYW07CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBlbmQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXRlOwoKICAgIHhtbERpY3RQdHIgZGljdDsJCS8qIGRpY3Rpb25uYXJ5IGZvciBpbnRlcm5lZCBzdHJpbmcgbmFtZXMgKi8KICAgIGludCAgICAgICAgaW5jbHVkZXM7CS8qIHRoZSBpbmNsdXNpb24gbGV2ZWwsIDAgZm9yIHJvb3Qgb3IgaW1wb3J0cyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHBhcmVudEl0ZW07IC8qIFRoZSBjdXJyZW50IHBhcmVudCBzY2hlbWEgaXRlbSAqLwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzZW1ibGU7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORyA0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFIDUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEIDYKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfRklYRURfVkFMVUUgNwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCA4CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRSA5CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX05PX0RFQ0wgMTAKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7Cn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQmFzaWNJdGVtIHhtbFNjaGVtYUJhc2ljSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFCYXNpY0l0ZW0gKnhtbFNjaGVtYUJhc2ljSXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFCYXNpY0l0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1RTlJlZiB4bWxTY2hlbWFJdGVtUU5SZWY7CnR5cGVkZWYgeG1sU2NoZW1hSXRlbVFOUmVmICp4bWxTY2hlbWFJdGVtUU5SZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSXRlbVFOUmVmIHsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKfTsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJREMgeG1sU2NoZW1hSURDOwp0eXBlZGVmIHhtbFNjaGVtYUlEQyAqeG1sU2NoZW1hSURDUHRyOwoKLyoqCiAqIHhtbFNjaGVtYUlEQ1NlbGVjdDoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgImZpZWxkIiBhbmQgInNlbGVjdG9yIiBpdGVtLCBob2xkaW5nIHRoZQogKiBYUGF0aCBleHByZXNzaW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1NlbGVjdCB4bWxTY2hlbWFJRENTZWxlY3Q7CnR5cGVkZWYgeG1sU2NoZW1hSURDU2VsZWN0ICp4bWxTY2hlbWFJRENTZWxlY3RQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU2VsZWN0IHsgICAgCiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgbmV4dDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGM7CiAgICBpbnQgaW5kZXg7IC8qIGFuIGluZGV4IHBvc2l0aW9uIGlmIHNpZ25pZmljYW50IGZvciBJREMga2V5LXNlcXVlbmNlcyAqLwogICAgY29uc3QgeG1sQ2hhciAqeHBhdGg7IC8qIHRoZSBYUGF0aCBleHByZXNzaW9uICovCiAgICB2b2lkICp4cGF0aENvbXA7IC8qIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCn07CgovKioKICogeG1sU2NoZW1hSURDOgogKgogKiBUaGUgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIGNvbXBvbmVudC4KICovCgpzdHJ1Y3QgX3htbFNjaGVtYUlEQyB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFJRENQdHIgbmV4dDsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7ICAgIAogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbGVjdG9yOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGZpZWxkczsKICAgIGludCBuYkZpZWxkczsKICAgIHhtbFNjaGVtYUl0ZW1RTlJlZlB0ciByZWY7Cn07CgovKioKICogeG1sU2NoZW1hSURDQXVnOgogKgogKiBUaGUgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbiB1c2VkIGZvciB2YWxpZGF0aW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ0F1ZyB4bWxTY2hlbWFJRENBdWc7CnR5cGVkZWYgeG1sU2NoZW1hSURDQXVnICp4bWxTY2hlbWFJRENBdWdQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDQXVnIHsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBuZXh0OyAvKiBuZXh0IGluIGEgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDUHRyIGRlZjsgLyogdGhlIElEQyBkZWZpbml0aW9uICovCiAgICBpbnQgYnViYmxlRGVwdGg7IC8qIHRoZSBsb3dlc3QgbGV2ZWwgdG8gd2hpY2ggSURDIAogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZXMgbmVlZCB0byBiZSBidWJibGVkIHVwd2FyZHMgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDS2V5U2VxdWVuY2U6CiAqCiAqIFRoZSBrZXkgc2VxdWVuY2Ugb2YgYSBub2RlIHRhYmxlIGl0ZW0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB4bWxTY2hlbWFQU1ZJSURDS2V5Owp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENLZXkgKnhtbFNjaGVtYVBTVklJRENLZXlQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxTY2hlbWFWYWxQdHIgY29tcFZhbHVlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENOb2RlOgogKgogKiBUaGUgbm9kZSB0YWJsZSBpdGVtIG9mIGEgbm9kZSB0YWJsZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDTm9kZSB4bWxTY2hlbWFQU1ZJSURDTm9kZTsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDTm9kZSAqeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ05vZGUgewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5czsKfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZzoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgYmluZGluZyBpdGVtIG9mIHRoZSBbaWRlbnRpdHktY29uc3RyYWludCB0YWJsZV0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmc7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgKnhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENCaW5kaW5nIHsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIG5leHQ7IC8qIG5leHQgYmluZGluZyBvZiBhIHNwZWNpZmljIG5vZGUgKi8KICAgIHhtbFNjaGVtYUlEQ1B0ciBkZWZpbml0aW9uOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICpub2RlVGFibGU7IC8qIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMgKi8KICAgIGludCBuYk5vZGVzOyAvKiBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IHNpemVOb2RlczsgLyogc2l6ZSBvZiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IG5iRHVwbHM7IC8qIG51bWJlciBvZiBhbHJlYWR5IGlkZW50aWZpZWQgZHVwbGljYXRlcyBpbiB0aGUgbm9kZSAKICAgICAgICAgICAgICAgICAgICB0YWJsZSAqLwogICAgLyogaW50IG5iS2V5czsgbnVtYmVyIG9mIGtleXMgaW4gZWFjaCBrZXktc2VxdWVuY2UgKi8KfTsKCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SIDEKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQgMgoKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfTUFUQ0hFUyAtMgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9CTE9DS0VEIC0zCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDTWF0Y2hlciB4bWxTY2hlbWFJRENNYXRjaGVyOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ01hdGNoZXIgKnhtbFNjaGVtYUlEQ01hdGNoZXJQdHI7CgovKioKICogeG1sU2NoZW1hSURDU3RhdGVPYmo6CiAqCiAqIFRoZSBzdGF0ZSBvYmplY3QgdXNlZCB0byBldmFsdWF0ZSBYUGF0aCBleHByZXNzaW9ucy4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENTdGF0ZU9iaiB4bWxTY2hlbWFJRENTdGF0ZU9iajsKdHlwZWRlZiB4bWxTY2hlbWFJRENTdGF0ZU9iaiAqeG1sU2NoZW1hSURDU3RhdGVPYmpQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU3RhdGVPYmogewogICAgaW50IHR5cGU7ICAgIAogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgbmV4dDsgLyogbmV4dCBpZiBpbiBhIGxpc3QgKi8KICAgIGludCBkZXB0aDsgLyogZGVwdGggb2YgY3JlYXRpb24gKi8KICAgIGludCAqaGlzdG9yeTsgLyogbGlzdCBvZiAoZGVwdGgsIHN0YXRlLWlkKSB0dXBsZXMgKi8KICAgIGludCBuYkhpc3Rvcnk7CiAgICBpbnQgc2l6ZUhpc3Rvcnk7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7IC8qIHRoZSBjb3JyZXNwb25kZW50IGZpZWxkL3NlbGVjdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXIgKi8KICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWw7CiAgICB2b2lkICp4cGF0aEN0eHQ7Cn07CgojZGVmaW5lIElEQ19NQVRDSEVSIDAKCi8qKgogKiB4bWxTY2hlbWFJRENNYXRjaGVyOgogKgogKiBVc2VkIHRvICBJREMgc2VsZWN0b3JzIChhbmQgZmllbGRzKSBzdWNjZXNzaXZlbHkuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ01hdGNoZXIgewogICAgaW50IHR5cGU7CiAgICBpbnQgZGVwdGg7IC8qIHRoZSB0cmVlIGRlcHRoIGF0IGNyZWF0aW9uIHRpbWUgKi8KICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbmV4dDsgLyogbmV4dCBpbiB0aGUgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7IC8qIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gKi8KICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiprZXlTZXFzOyAvKiB0aGUga2V5LXNlcXVlbmNlcyBvZiB0aGUgdGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgKi8KICAgIGludCBzaXplS2V5U2VxczsKICAgIGludCB0YXJnZXREZXB0aDsKfTsKCi8qCiogRWxlbWVudCBpbmZvIGZsYWdzLgoqLwojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX1ZBTFVFX05FRURFRCAxPDwwCgovKioKICogeG1sU2NoZW1hRWxlbUluZm86CiAqCiAqIEhvbGRzIGluZm9ybWF0aW9uIG9mIGFuIGVsZW1lbnQgbm9kZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFFbGVtSW5mbyB4bWxTY2hlbWFFbGVtSW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFFbGVtSW5mbyAqeG1sU2NoZW1hRWxlbUluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hRWxlbUluZm8gewogICAgaW50IGRlcHRoOwogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBlbGVtZW50IGluZm8gZmxhZ3MgKi8KICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWU7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWY7IC8qIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24gaWYgYW55ICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIGRlY2w7IC8qIHRoZSBlbGVtZW50L2F0dHJpYnV0ZSBkZWNsYXJhdGlvbiAqLwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbHVlOyAvKiB0aGUgcHJlLWNvbXB1dGVkIHZhbHVlIGlmIGFueSAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgaWRjVGFibGU7IC8qIHRoZSB0YWJsZSBvZiBQU1ZJIElEQyBiaW5kaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciB0aGUgc2NvcGUgZWxlbWVudCovCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIGlkY01hdGNoZXJzOyAvKiB0aGUgSURDIG1hdGNoZXJzIGZvciB0aGUgc2NvcGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHQ6CiAqCiAqIEEgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQKICovCgpzdHJ1Y3QgX3htbFNjaGVtYVZhbGlkQ3R4dCB7CiAgICB2b2lkICp1c2VyRGF0YTsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CiAgICB4bWxDaGFyRW5jb2RpbmcgZW5jOwogICAgeG1sU0FYSGFuZGxlclB0ciBzYXg7CiAgICB2b2lkICp1c2VyX2RhdGE7CgogICAgeG1sRG9jUHRyIG15RG9jOwogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKCiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleHA7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsdWU7CgogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHJUb3A7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cjsKICAgIC8qIHhtbE5vZGVQdHIgc2NvcGU7IG5vdCB1c2VkICovCiAgICBpbnQgdmFsdWVXUzsKICAgIGludCBvcHRpb25zOwogICAgeG1sTm9kZVB0ciB2YWxpZGF0aW9uUm9vdDsgICAgCiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgaW50IHhzaUFzc2VtYmxlOwojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYUVsZW1JbmZvUHRyICplbGVtSW5mb3M7IC8qIGFycmF5IG9mIGVsZW1lbnQgaW5mb3JtYXRpb25zICovCiAgICBpbnQgc2l6ZUVsZW1JbmZvczsKICAgIHhtbFNjaGVtYUVsZW1JbmZvUHRyIG5vZGVJbmZvOyAvKiB0aGUgY3VycmVudCBlbGVtZW50IGluZm9ybWF0aW9uICovCiAgICB4bWxTY2hlbWFFbGVtSW5mb1B0ciBhdHRySW5mbzsgLyogbm9kZSBpbmZvciBmb3IgdGhlIGN1cnJlbnQgYXR0cmlidXRlICovCiNlbmRpZgojaWZkZWYgSURDX0VOQUJMRUQKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjczsgLyogYSBsaXN0IG9mIGF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb25zICovCgogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgeHBhdGhTdGF0ZXM7IC8qIGZpcnN0IGFjdGl2ZSBzdGF0ZSBvYmplY3QuICovCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlUG9vbDsgLyogZmlyc3Qgc3RvcmVkIHN0YXRlIG9iamVjdC4gKi8KICAgIAogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKmlkY05vZGVzOyAvKiBsaXN0IG9mIGFsbCBJREMgbm9kZS10YWJsZSBlbnRyaWVzKi8KICAgIGludCBuYklkY05vZGVzOwogICAgaW50IHNpemVJZGNOb2RlczsKCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICppZGNLZXlzOyAvKiBsaXN0IG9mIGFsbCBJREMgbm9kZS10YWJsZSBlbnRyaWVzICovCiAgICBpbnQgbmJJZGNLZXlzOwogICAgaW50IHNpemVJZGNLZXlzOwojZW5kaWYKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBpbiB0aGUgc2NoZW1hcyBpbXBvcnRTY2hlbWFzIGhhc2ggdGFibGUKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgeG1sU2NoZW1hSW1wb3J0Owp0eXBlZGVmIHhtbFNjaGVtYUltcG9ydCAqeG1sU2NoZW1hSW1wb3J0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUltcG9ydCB7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7IC8qIG5vdCB1c2VkIGFueSBtb3JlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IGlzTWFpbjsKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBhc3NvY2lhdGVkIHRvIGluY2x1ZGVzIGluIGEgc2NoZW1hcwogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgeG1sU2NoZW1hSW5jbHVkZTsKdHlwZWRlZiB4bWxTY2hlbWFJbmNsdWRlICp4bWxTY2hlbWFJbmNsdWRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxEb2NQdHIgZG9jOwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVBhcnRpY2xlIHhtbFNjaGVtYVBhcnRpY2xlOwp0eXBlZGVmIHhtbFNjaGVtYVBhcnRpY2xlICp4bWxTY2hlbWFQYXJ0aWNsZVB0cjsKc3RydWN0IF94bWxTY2hlbWFQYXJ0aWNsZSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgbmV4dDsgLyogdGhlIG5leHQgcGFydGljbGUgaWYgaW4gYSBsaXN0ICovCiAgICBpbnQgbWluT2NjdXJzOwogICAgaW50IG1heE9jY3VyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdGVybTsKfTsKCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB4bWxTY2hlbWFNb2RlbEdyb3VwOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXAgKnhtbFNjaGVtYU1vZGVsR3JvdXBQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgaW50IGNvbXBvc2l0b3I7IC8qIG9uZSBvZiBhbGwsIGNob2ljZSBvciBzZXF1ZW5jZSAqLwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGVzOyAvKiBsaXN0IG9mIHBhcnRpY2xlcyAqLwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7Cn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWYgKnhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgbW9kZWxHcm91cDsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNvbWUgcHJlZGVjbGFyYXRpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCQkgaW50IGZpcmVFcnJvcnMsCgkJCQkgaW50IGFwcGx5RmFjZXRzLAoJCQkJIGludCBub3JtYWxpemUsCgkJCQkgaW50IGNoZWNrTm9kZXMpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKTsgCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCURhdGF0eXBlIGVycm9yIGhhbmRsZXJzCQkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hUEVyck1lbW9yeToKICogQG5vZGU6IGEgY29udGV4dCBub2RlCiAqIEBleHRyYTogIGV4dHJhIGluZm9ybWF0aW9ucwogKgogKiBIYW5kbGUgYW4gb3V0IG9mIG1lbW9yeSBjb25kaXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnJNZW1vcnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpCiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1AsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSBwYXJzZXIgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyMjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQG5vZGU6IHRoZSBjdXJyZW50IGNoaWxkCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycjIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIGlmIChjaGlsZCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwogICAgZWxzZQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7Cn0KCgovKioKICogeG1sU2NoZW1hUEVyckV4dDoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQHN0ckRhdGExOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMjogZXh0cmEgZGF0YQogKiBAc3RyRGF0YTM6IGV4dHJhIGRhdGEKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMSwgY29uc3QgeG1sQ2hhciAqIHN0ckRhdGEyLCAKCQljb25zdCB4bWxDaGFyICogc3RyRGF0YTMsIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHIyLCBjb25zdCB4bWxDaGFyICogc3RyMywgY29uc3QgeG1sQ2hhciAqIHN0cjQsCgkJY29uc3QgeG1sQ2hhciAqIHN0cjUpCnsKCiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwoJc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0ckRhdGExLCAoY29uc3QgY2hhciAqKSBzdHJEYXRhMiwgCgkJICAgIChjb25zdCBjaGFyICopIHN0ckRhdGEzLCAwLCAwLCBtc2csIHN0cjEsIHN0cjIsIAoJCSAgICBzdHIzLCBzdHI0LCBzdHI1KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWVHlwZUVyck1lbW9yeToKICogQG5vZGU6IGEgY29udGV4dCBub2RlCiAqIEBleHRyYTogIGV4dHJhIGluZm9ybWF0aW9ucwogKgogKiBIYW5kbGUgYW4gb3V0IG9mIG1lbW9yeSBjb25kaXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnJNZW1vcnkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY3R4dC0+ZXJyID0gWE1MX1NDSEVNQVZfSU5URVJOQUw7CiAgICB9CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNWLCBYTUxfRVJSX05PX01FTU9SWSwgbm9kZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgZXh0cmEpOwp9CgovKioKICogeG1sU2NoZW1hVkVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnIzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBvbGQgc2NoZW1hIGVycm9yIGNvZGVzIGhhdmUgYmVlbiAKICAgICogc3Vic3RpdHV0ZWQgZm9yIHRoZSBnbG9iYWwgZXJyb3IgY29kZXMuCiAgICAqCiAgICAqIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7IAogICAgKi8KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1YsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyMywgMCwgMCwKICAgICAgICAgICAgICAgICAgICBtc2csIHN0cjEsIHN0cjIsIHN0cjMpOwp9CgovKioKICogeG1sU2NoZW1hVkVyckV4dDoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnJFeHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCSBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCAKCQkgY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCAKCQkgY29uc3QgeG1sQ2hhciAqIHN0cjQsIGNvbnN0IHhtbENoYXIgKiBzdHI1KQp7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CiAgICB9CiAgICAvKiByZWFqdXN0IHRvIGdsb2JhbCBlcnJvciBudW1iZXJzICovCiAgICAgLyogUmVtb3ZlZCwgc2luY2UgdGhlIG9sZCBzY2hlbWEgZXJyb3IgY29kZXMgaGF2ZSBiZWVuIAogICAgKiBzdWJzdGl0dXRlZCBmb3IgdGhlIGdsb2JhbCBlcnJvciBjb2Rlcy4KICAgICoKICAgICogZXJyb3IgKz0gWE1MX1NDSEVNQVZfTk9ST09UIC0gWE1MX1NDSEVNQVNfRVJSX05PUk9PVDsKICAgICovCiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLCBOVUxMLCBOVUxMLCBOVUxMLCAwLCAwLCAKCQkgICAgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0LCBzdHI1KTsKfQovKioKICogeG1sU2NoZW1hVkVycjoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBvbGQgc2NoZW1hIGVycm9yIGNvZGVzIGhhdmUgYmVlbiAKICAgICogc3Vic3RpdHV0ZWQgZm9yIHRoZSBnbG9iYWwgZXJyb3IgY29kZXMuCiAgICAqCiAgICAqIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICAqLwogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTViwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyTmFtZToKICogQGF0dHI6ICB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKgogKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGU7IGlmIHRoZSBhdHRyaWJ1dGUKICogaXMgYSByZWZlcmVuY2UsIHRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGdsb2JhbCB0eXBlIHdpbGwgYmUgcmV0dXJuZWQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldEF0dHJOYW1lKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKSAKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKSAKCXJldHVybihhdHRyLT5yZWYpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPm5hbWUpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSToKICogQHR5cGU6ICB0aGUgdHlwZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCiAqCiAqIFJldHVybnMgdGhlIHRhcmdldCBuYW1lc3BhY2UgVVJJIG9mIHRoZSB0eXBlOyBpZiB0aGUgdHlwZSBpcyBhIHJlZmVyZW5jZSwKICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHJlZmVyZW5jZWQgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsgIAogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKQoJcmV0dXJuIChhdHRyLT5yZWZOcyk7CiAgICBlbHNlCglyZXR1cm4oYXR0ci0+dGFyZ2V0TmFtZXNwYWNlKTsgIAp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQHVyaTogIHRoZSBuYW1lc3BhY2UgVVJJCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBVUkkgdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4KICoKICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcsIGlmIEBucyBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8gIApzdGF0aWMgY29uc3QgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCh4bWxDaGFyICoqYnVmLAoJCQkgICBjb25zdCB4bWxDaGFyICp1cmksIGNvbnN0IHhtbENoYXIgKmxvY2FsKQp7CiAgICBpZiAoKmJ1ZiAhPSBOVUxMKQoJeG1sRnJlZSgqYnVmKTsKICAgIGlmICh1cmkgPT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyciKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbG9jYWwpOwogICAgfSBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIHVyaSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInLCAnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsJCiAgICB9CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInfSIpOwogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWw6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBuczogIHRoZSBuYW1lc3BhY2UKICogQGxvY2FsOiB0aGUgbG9jYWwgbmFtZQogKgogKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIFVSSSB1c2VkCiAqIGZvciBlcnJvciByZXBvcnRzLgogKgogKiBSZXR1cm5zIGFuIGVtcHR5IHN0cmluZywgaWYgQG5zIGlzIE5VTEwsIGEgZm9ybWF0dGVkCiAqIHN0cmluZyBvdGhlcndpc2UuCiAqLyAgCnN0YXRpYyBjb25zdCB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKHhtbENoYXIgKipidWYsCgkJCSAgICAgIHhtbE5zUHRyIG5zLCBjb25zdCB4bWxDaGFyICpsb2NhbCkKewogICAgaWYgKCpidWYgIT0gTlVMTCkgewoJeG1sRnJlZSgqYnVmKTsKCSpidWYgPSBOVUxMOwogICAgfQogICAgaWYgKChucyA9PSBOVUxMKSB8fCAobnMtPnByZWZpeCA9PSBOVUxMKSkKCXJldHVybihsb2NhbCk7CiAgICBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAobnMtPnByZWZpeCk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsKICAgIH0KICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmc6CiAqIEBwYzogdGhlIHR5cGUgb2YgcHJvY2Vzc0NvbnRlbnRzCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUgb2YgCiAqIHByb2Nlc3NDb250ZW50cy4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKGludCBwYykKewogICAgc3dpdGNoIChwYykgewoJY2FzZSBYTUxfU0NIRU1BU19BTllfU0tJUDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJza2lwIik7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9MQVg6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAibGF4Iik7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1Q6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAic3RyaWN0Iik7CglkZWZhdWx0OgoJICAgIHJldHVybiAoQkFEX0NBU1QgImludmFsaWQgcHJvY2VzcyBjb250ZW50cyIpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgaXRlbQogKiBAaXRlbU5hbWU6IHRoZSBuYW1lIG9mIHRoZSBpdGVtCiAqIEBpdGVtOiB0aGUgaXRlbSBhcyBhbiBvYmplY3QgCiAqIEBpdGVtTm9kZTogdGhlIG5vZGUgb2YgdGhlIGl0ZW0KICogQGxvY2FsOiB0aGUgbG9jYWwgbmFtZQogKiBAcGFyc2luZzogaWYgdGhlIGZ1bmN0aW9uIGlzIHVzZWQgZHVyaW5nIHRoZSBwYXJzZQogKgogKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIGl0ZW0gdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4gCiAqCiAqIFRoZSBmb2xsb3dpbmcgb3JkZXIgaXMgdXNlZCB0byBidWlsZCB0aGUgcmVzdWx0aW5nIAogKiBkZXNpZ25hdGlvbiBpZiB0aGUgYXJndW1lbnRzIGFyZSBub3QgTlVMTDoKICogMWEuIElmIGl0ZW1EZXMgbm90IE5VTEwgLT4gaXRlbURlcwogKiAxYi4gSWYgKGl0ZW1EZXMgbm90IE5VTEwpIGFuZCAoaXRlbU5hbWUgbm90IE5VTEwpCiAqICAgICAtPiBpdGVtRGVzICsgaXRlbU5hbWUKICogMi4gSWYgdGhlIHByZWNlZGluZyB3YXMgTlVMTCBhbmQgKGl0ZW0gbm90IE5VTEwpIC0+IGl0ZW0KICogMy4gSWYgdGhlIHByZWNlZGluZyB3YXMgTlVMTCBhbmQgKGl0ZW1Ob2RlIG5vdCBOVUxMKSAtPiBpdGVtTm9kZQogKiAKICogSWYgdGhlIGl0ZW1Ob2RlIGlzIGFuIGF0dHJpYnV0ZSBub2RlLCB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIHdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHJlc3VsdC4KICoKICogUmV0dXJucyB0aGUgZm9ybWF0dGVkIHN0cmluZyBhbmQgc2V0cyBAYnVmIHRvIHRoZSByZXN1bHRpbmcgdmFsdWUuCiAqLyAgCnN0YXRpYyB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KHhtbENoYXIgKipidWYsCQkgICAgIAoJCSAgICAgY29uc3QgeG1sQ2hhciAqaXRlbURlcywKCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgIHhtbE5vZGVQdHIgaXRlbU5vZGUsCgkJICAgICBpbnQgcGFyc2luZykKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTDsKICAgIGludCBuYW1lZCA9IDE7CgogICAgaWYgKCpidWYgIT0gTlVMTCkgewoJeG1sRnJlZSgqYnVmKTsKCSpidWYgPSBOVUxMOwogICAgfQogICAgICAgICAgICAKICAgIGlmIChpdGVtRGVzICE9IE5VTEwpIHsKCSpidWYgPSB4bWxTdHJkdXAoaXRlbURlcyk7CQogICAgfSBlbHNlIGlmIChpdGVtICE9IE5VTEwpIHsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgkgICAgaWYgKGl0ZW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJ2FueVR5cGUnIik7CgkgICAgZWxzZSBpZiAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInYW55U2ltcGxlVHlwZSciKTsKCSAgICBlbHNlIHsKCQkvKiAqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJiaSAiKTsgKi8KCQkvKiAqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUVsZW1EZXNTVCk7ICovCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc1NUKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzU1QpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNDVCk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0NUKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6IHsKCQl4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cjsKCSAgICAKCQlhdHRyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbTsJICAgIAoJCWlmICgoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkgfHwKCQkgICAgKGF0dHItPnJlZiA9PSBOVUxMKSkgewoJCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgYXR0ci0+bmFtZSk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQl9IGVsc2UgewoJCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNBdHRyUmVmKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5yZWZQcmVmaXgpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgYXR0ci0+cmVmKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCX0JCgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDogewoJCXhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbTsKCgkJZWxlbSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtOwkgICAgCgkJaWYgKChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSB8fCAKCQkgICAgKGVsZW0tPnJlZiA9PSBOVUxMKSkgewoJCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNFbGVtRGVjbCk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+bmFtZSk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCQl9IGVsc2UgewoJCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNFbGVtUmVmKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5yZWZQcmVmaXgpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+cmVmKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCX0KCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUY6CQkKCSAgICBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX1VOSVFVRSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJ1bmlxdWUgJyIpOwoJICAgIGVsc2UgaWYgKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVkpCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAia2V5ICciKTsKCSAgICBlbHNlCgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAia2V5UmVmICciKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsICgoeG1sU2NoZW1hSURDUHRyKSBpdGVtKS0+bmFtZSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKCSAgICAqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYVdpbGRjYXJkUENUb1N0cmluZygKCQkgICAgKCh4bWxTY2hlbWFXaWxkY2FyZFB0cikgaXRlbSktPnByb2Nlc3NDb250ZW50cykpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiB3aWxkY2FyZCIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkgICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiZmFjZXQgJyIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoaXRlbS0+dHlwZSkpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgoJICAgICpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIm5vdGF0aW9uIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbU1vZGVsR3JEZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1Nb2RlbEdyUmVmKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+cmVmKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfQoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICBuYW1lZCA9IDA7Cgl9CiAgICB9IGVsc2UgCgluYW1lZCA9IDA7CgogICAgaWYgKChuYW1lZCA9PSAwKSAmJiAoaXRlbU5vZGUgIT0gTlVMTCkpIHsKCXhtbE5vZGVQdHIgZWxlbTsKCglpZiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIGVsZW0gPSBpdGVtTm9kZS0+cGFyZW50OwoJZWxzZSAKCSAgICBlbGVtID0gaXRlbU5vZGU7CgkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJFbGVtZW50ICciKTsKCWlmIChwYXJzaW5nKQoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgZWxlbS0+bmFtZSk7CgllbHNlCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCAKCQl4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHIsIGVsZW0tPm5zLCBlbGVtLT5uYW1lKSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CiAgICB9CiAgICBpZiAoKGl0ZW1Ob2RlICE9IE5VTEwpICYmIChpdGVtTm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpKSB7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsIGF0dHJpYnV0ZSAnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ciwgCgkgICAgaXRlbU5vZGUtPm5zLCBpdGVtTm9kZS0+bmFtZSkpOwoJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChzdHIpOwogICAgCiAgICByZXR1cm4gKCpidWYpOwp9CgovKioKICogeG1sU2NoZW1hUEZvcm1hdEl0ZW1EZXM6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBpdGVtOiB0aGUgaXRlbSBhcyBhIHNjaGVtYSBvYmplY3QKICogQGl0ZW1Ob2RlOiB0aGUgaXRlbSBhcyBhIG5vZGUKICoKICogSWYgdGhlIHBvaW50ZXIgdG8gQGJ1ZiBpcyBub3QgTlVMTCBhbmQgQGJ1dCBob2xkcyBubyB2YWx1ZSwKICogdGhlIHZhbHVlIGlzIHNldCB0byBhIGl0ZW0gZGVzaWduYXRpb24gdXNpbmcgCiAqIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQuIFRoaXMgb25lIGF2b2lkcyBhZGRpbmcKICogYW4gYXR0cmlidXRlIGRlc2lnbmF0aW9uIHBvc3RmaXguCiAqCiAqIFJldHVybnMgYSBzdHJpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFJlcXVlc3RJdGVtRGVzKHhtbENoYXIgKipidWYsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgICAgeG1sTm9kZVB0ciBpdGVtTm9kZSkKewogICAgaWYgKChidWYgPT0gMCkgfHwgKCpidWYgIT0gTlVMTCkpIAoJcmV0dXJuOwogICAgaWYgKGl0ZW1Ob2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCWl0ZW1Ob2RlID0gaXRlbU5vZGUtPnBhcmVudDsKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoYnVmLCBOVUxMLCBpdGVtLCBpdGVtTm9kZSwgMSk7CQp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0OgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAdHlwZTogdGhlIHR5cGUgaG9sZGluZyB0aGUgZW51bWVyYXRpb24gZmFjZXRzCiAqCiAqIEJ1aWxkcyBhIHN0cmluZyBjb25zaXN0aW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICoKICogUmV0dXJucyBhIHN0cmluZyBvZiBhbGwgZW51bWVyYXRpb24gZWxlbWVudHMuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldCh4bWxDaGFyICoqYnVmLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBsaW5rOwoKICAgIGlmICgqYnVmICE9IE5VTEwpCgl4bWxGcmVlKCpidWYpOyAgICAKICAgICpidWYgPSBOVUxMOwogICAgZm9yIChsaW5rID0gdHlwZS0+ZmFjZXRTZXQ7IGxpbmsgIT0gTlVMTDsgbGluayA9IGxpbmstPm5leHQpIHsKCWlmIChsaW5rLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgaWYgKCpidWYgPT0gTlVMTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxpbmstPmZhY2V0LT52YWx1ZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiLCAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBsaW5rLT5mYWNldC0+dmFsdWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gKChjb25zdCB4bWxDaGFyICopICpidWYpOwp9CgovKioKICogeG1sU2NoZW1hVkZhY2V0RXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG5vZGU6IHRoZSBub2RlIHRvIGJlIHZhbGlkYXRlZCAgCiAqIEB2YWx1ZTogdGhlIHZhbHVlIG9mIHRoZSBub2RlCiAqIEB0eXBlOiB0aGUgdHlwZSBob2xkaW5nIHRoZSBmYWNldAogKiBAZmFjZXQ6IHRoZSBmYWNldAogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2Ugb2YgTlVMTAogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiBAc3RyMzogZXh0cmEgZGF0YQogKgogKiBSZXBvcnRzIGEgZmFjZXQgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWRmFjZXRFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCSAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICB4bWxOb2RlUHRyIG5vZGUsCQkgICAKCQkgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkgICB1bnNpZ25lZCBsb25nIGxlbmd0aCwKCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCQkgICAKCQkgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjEsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMiwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIHhtbFNjaGVtYVR5cGVUeXBlIGZhY2V0VHlwZTsKCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsIE5VTEwsIG5vZGUsIDApOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsIGZhY2V0ICciKTsKICAgIGlmIChlcnJvciA9PSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQpIHsKCWZhY2V0VHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CgkvKgoJKiBJZiBlbnVtZXJhdGlvbnMgYXJlIHZhbGlkYXRlZCwgb25lIG11c3Qgbm90IGV4cGVjdCB0aGUKCSogZmFjZXQgdG8gYmUgZ2l2ZW4uCgkqLwkKICAgIH0gZWxzZQkKCWZhY2V0VHlwZSA9IGZhY2V0LT50eXBlOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXRUeXBlKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJ106ICIpOwogICAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgewoJLyoKCSogVXNlIGEgZGVmYXVsdCBtZXNzYWdlLgoJKi8KCWlmICgoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKSB8fAoJICAgIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEgpIHx8CgkgICAgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSCkpIHsKCgkgICAgY2hhciBsZW5bMjVdLCBhY3RMZW5bMjVdOwoKCSAgICAvKiBGSVhNRSwgVE9ETzogV2hhdCBpcyB0aGUgbWF4IGV4cGVjdGVkIHN0cmluZyBsZW5ndGggb2YgdGhlCgkgICAgKiB0aGlzIHZhbHVlPwoJICAgICovCgkgICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgkgICAgZWxzZQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgaGFzIGEgbGVuZ3RoIG9mICclcyc7ICIpOwoKCSAgICBzbnByaW50ZihsZW4sIDI0LCAiJWx1IiwgeG1sU2NoZW1hR2V0RmFjZXRWYWx1ZUFzVUxvbmcoZmFjZXQpKTsKCSAgICBzbnByaW50ZihhY3RMZW4sIDI0LCAiJWx1IiwgbGVuZ3RoKTsKCgkgICAgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBkaWZmZXJzIGZyb20gdGhlIGFsbG93ZWQgbGVuZ3RoIG9mICclcycuXG4iKTsgICAgIAoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyBleGNlZWRzIHRoZSBhbGxvd2VkIG1heGltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEgpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgCgkJQkFEX0NBU1QgInRoaXMgdW5kZXJydW5zIHRoZSBhbGxvd2VkIG1pbmltdW0gbGVuZ3RoIG9mICclcycuXG4iKTsKCSAgICAKCSAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJeG1sU2NoZW1hVkVyckV4dChjdHh0LCBub2RlLCBlcnJvciwKCQkgICAgKGNvbnN0IGNoYXIgKikgbXNnLAoJCSAgICB2YWx1ZSwgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4sCgkJICAgIE5VTEwsIE5VTEwpOwoJICAgIGVsc2UgCgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgIAoJCSAgICAoY29uc3QgY2hhciAqKSBtc2csCgkJICAgIChjb25zdCB4bWxDaGFyICopIGFjdExlbiwgKGNvbnN0IHhtbENoYXIgKikgbGVuKTsKCQoJfSBlbHNlIGlmIChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgYW4gZWxlbWVudCAiCgkJIm9mIHRoZSBzZXQgeyVzfS5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCXhtbFNjaGVtYUZvcm1hdEZhY2V0RW51bVNldCgmc3RyLCB0eXBlKSk7Cgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIHsKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlICclcycgaXMgbm90IGFjY2VwdGVkICIKCQkiYnkgdGhlIHBhdHRlcm4gJyVzJy5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIAoJCWZhY2V0LT52YWx1ZSk7CSAgICAgICAKCX0gZWxzZSBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsJCQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgZmFjZXQtdmFsaWQuXG4iKTsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsKCX0gZWxzZSB7CSAgICAKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiVGhlIHZhbHVlIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7Cgl9CiAgICB9IGVsc2UgewoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7Cgl4bWxTY2hlbWFWRXJyMyhjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKICAgIH0gICAgICAgIAogICAgRlJFRV9BTkRfTlVMTChzdHIpCiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgdHlwZSB1c2VkIGZvciB2YWxpZGF0aW9uCiAqIEBub2RlOiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgdmFsdWUKICogQHZhbHVlOiB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqCiAqIFJlcG9ydHMgYSBzaW1wbGUgdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKiBUT0RPOiBTaG91bGQgdGhpcyByZXBvcnQgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgYXMgd2VsbD8KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCQoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCWNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZtc2csIE5VTEwsICBOVUxMLCBub2RlLCAwKTsgICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwogICAgaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXTogVGhlIHZhbHVlICclcycgaXMgbm90IHZhbGlkLlxuIik7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHZhbHVlLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiXTogVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIpOwoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIEZSRUVfQU5EX05VTEwoc3RyKQkKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBub2RlOiB0aGUgbm9kZSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgdmFsdWUKICogQHR5cGU6IHRoZSBjb21wbGV4IHR5cGUgdXNlZCBmb3IgdmFsaWRhdGlvbgogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhIGNvbXBsZXggdHlwZSB2YWxpZGF0aW9uIGVycm9yLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwJCQkKCQkJY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgIE5VTEwsIG5vZGUsIDApOwogICAgLyogU3BlY2lmeSB0aGUgY29tcGxleCB0eXBlIG9ubHkgaWYgaXQgaXMgZ2xvYmFsLiAqLwogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkgewoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdIik7CiAgICB9CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiOiAlcy5cbiIpOyAgIAogICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLAoJKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSwgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKHN0cikJCiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWQ29tcGxleFR5cGVFbGVtRXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG5vZGU6IHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIHZhbGlkYXRlZCB2YWx1ZQogKiBAdHlwZTogdGhlIGNvbXBsZXggdHlwZSB1c2VkIGZvciB2YWxpZGF0aW9uCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGEgY29tcGxleCB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWQ29tcGxleFR5cGVFbGVtRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwJCQkKCQkJY29uc3QgY2hhciAqbWVzc2FnZSwKCQkJaW50IG5idmFsLAoJCQlpbnQgbmJuZWcsCgkJCXhtbENoYXIgKip2YWx1ZXMpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgeG1sQ2hhciAqbG9jYWxOYW1lLCAqbnNOYW1lOwogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kOwogICAgaW50IGk7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgIE5VTEwsIG5vZGUsIDApOwogICAgLyogU3BlY2lmeSB0aGUgY29tcGxleCB0eXBlIG9ubHkgaWYgaXQgaXMgZ2xvYmFsLiAqLwogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkgewoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdIik7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICI6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICAvKgogICAgKiBOb3RlIHRoYXQgaXMgZG9lcyBub3QgbWFrZSBzZW5zZSB0byByZXBvcnQgdGhhdCB3ZSBoYXZlIGEKICAgICogd2lsZGNhcmQgaGVyZSwgc2luY2UgdGhlIHdpbGRjYXJkIG1pZ2h0IGJlIHVuZm9sZGVkIGludG8KICAgICogbXVsdGlwbGUgdHJhbnNpdGlvbnMuCiAgICAqLwogICAgaWYgKG5idmFsICsgbmJuZWcgPiAwKSB7CglpZiAobmJ2YWwgKyBuYm5lZyA+IDEpIHsKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIi4gRXhwZWN0ZWQgaXMgb25lIG9mICggIik7Cgl9IGVsc2UKCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIi4gRXhwZWN0ZWQgaXMgKCAiKTsKCW5zTmFtZSA9IE5VTEw7CiAgICAJICAgIAoJZm9yIChpID0gMDsgaSA8IG5idmFsICsgbmJuZWc7IGkrKykgewoJICAgIGN1ciA9IHZhbHVlc1tpXTsKCSAgICAvKgoJICAgICogR2V0IHRoZSBsb2NhbCBuYW1lLgoJICAgICovCgkgICAgbG9jYWxOYW1lID0gTlVMTDsKCSAgICAKCSAgICBlbmQgPSBjdXI7CgkgICAgaWYgKCplbmQgPT0gJyonKSB7CgkJbG9jYWxOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICIqIik7CgkJKmVuZCsrOwoJICAgIH0gZWxzZSB7CgkJd2hpbGUgKCgqZW5kICE9IDApICYmICgqZW5kICE9ICd8JykpCgkJICAgIGVuZCsrOwoJCWxvY2FsTmFtZSA9IHhtbFN0cm5jYXQobG9jYWxOYW1lLCBCQURfQ0FTVCBjdXIsIGVuZCAtIGN1cik7CgkgICAgfQkJCgkgICAgaWYgKCplbmQgIT0gMCkgewkJICAgIAoJCSplbmQrKzsKCQkvKgoJCSogU2tpcCAiKnwqIiBpZiB0aGV5IGNvbWUgd2l0aCBuZWdhdGVkIGV4cHJlc3Npb25zLCBzaW5jZQoJCSogdGhleSByZXByZXNlbnQgdGhlIHNhbWUgbmVnYXRlZCB3aWxkY2FyZC4KCQkqLwoJCWlmICgobmJuZWcgPT0gMCkgfHwgKCplbmQgIT0gJyonKSB8fCAoKmxvY2FsTmFtZSAhPSAnKicpKSB7CgkJICAgIC8qCgkJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCQkgICAgKi8KCQkgICAgY3VyID0gZW5kOwoJCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQkJbnNOYW1lID0geG1sU3RyZHVwKEJBRF9DQVNUICJ7Kn0iKTsKCQkgICAgfSBlbHNlIHsKCQkJd2hpbGUgKCplbmQgIT0gMCkKCQkJICAgIGVuZCsrOwoJCQkKCQkJaWYgKGkgPj0gbmJ2YWwpCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsjI290aGVyOiIpOwoJCQllbHNlCgkJCSAgICBuc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsiKTsKCQkJCgkJCW5zTmFtZSA9IHhtbFN0cm5jYXQobnNOYW1lLCBCQURfQ0FTVCBjdXIsIGVuZCAtIGN1cik7CgkJCW5zTmFtZSA9IHhtbFN0cmNhdChuc05hbWUsIEJBRF9DQVNUICJ9Iik7CgkJICAgIH0KCQkgICAgc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgbnNOYW1lKTsKCQkgICAgRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJfSBlbHNlIHsKCQkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCSAgICBjb250aW51ZTsKCQl9CgkgICAgfQkgICAgICAgIAoJICAgIHN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUIGxvY2FsTmFtZSk7CgkgICAgRlJFRV9BTkRfTlVMTChsb2NhbE5hbWUpOwoJCQoJICAgIGlmIChpIDwgbmJ2YWwgKyBuYm5lZyAtMSkKCQlzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiLCAiKTsKCX0JCglzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCAiICkiKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUIHN0cik7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0gICAgCiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOyAgICAJCiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lck5hbWU6IHRoZSBuYW1lIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5vZGU6IHRoZSBwYXJlbnQgZWxlbWVudCBub2RlIG9mIHRoZSBtaXNzaW5nIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkgY29uc3QgY2hhciAqbmFtZSwKCQkJIGNvbnN0IGNoYXIgKm1lc3NhZ2UpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgICAgCiAgICBpZiAobWVzc2FnZSAhPSBOVUxMKQoJeG1sU2NoZW1hUEVycihjdHh0LCBvd25lckVsZW0sIGVycm9yLCAiJXM6ICVzLlxuIiwgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBtZXNzYWdlKTsKICAgIGVsc2UJCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsIAoJICAgICIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nLlxuIiwgCgkgICAgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwp9CgovKioKICogeG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZzoKICogQHR5cGU6IHRoZSB0eXBlIG9mIHRoZSBzY2hlbWEgaXRlbQogKgogKiBSZXR1cm5zIHRoZSBjb21wb25lbnQgbmFtZSBvZiBhIHNjaGVtYSBpdGVtLgogKi8Kc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpCnsKICAgIHN3aXRjaCAodHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIHJldHVybigic2ltcGxlIHR5cGUgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICByZXR1cm4oImNvbXBsZXggdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIHJldHVybigiZWxlbWVudCBkZWNsYXJhdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgoJICAgIHJldHVybigiYXR0cmlidXRlIGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICByZXR1cm4oIm1vZGVsIGdyb3VwIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJICAgIHJldHVybigiYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgoJICAgIHJldHVybigibm90YXRpb24gZGVjbGFyYXRpb24iKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuKCJOb3QgYSBzY2hlbWEgY29tcG9uZW50Iik7CiAgICB9Cn0KLyoqCiAqIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEBvd25lckVsZW06IHRoZSBvd25lciBhcyBhbiBlbGVtZW50IG5vZGUKICogQG5hbWU6IHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgUU5hbWUgCiAqIEByZWZOYW1lOiB0aGUgcmVmZXJlbmNlZCBsb2NhbCBuYW1lCiAqIEByZWZVUkk6IHRoZSByZWZlcmVuY2VkIG5hbWVzcGFjZSBVUkkKICogQG1lc3NhZ2U6IG9wdGlvbmFsIG1lc3NhZ2UKICoKICogVXNlZCB0byByZXBvcnQgUU5hbWUgYXR0cmlidXRlIHZhbHVlcyB0aGF0IGZhaWxlZCB0byByZXNvbHZlCiAqIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbE5vZGVQdHIgb3duZXJFbGVtLAoJCQkgY29uc3QgY2hhciAqbmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZk5hbWUsCgkJCSBjb25zdCB4bWxDaGFyICpyZWZVUkksCgkJCSB4bWxTY2hlbWFUeXBlVHlwZSByZWZUeXBlLAoJCQkgY29uc3QgY2hhciAqcmVmVHlwZVN0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlCglkZXMgPSAqb3duZXJEZXM7CiAgICBpZiAocmVmVHlwZVN0ciA9PSBOVUxMKQoJcmVmVHlwZVN0ciA9IHhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmcocmVmVHlwZSk7ICAgIAoJeG1sU2NoZW1hUEVyckV4dChjdHh0LCBvd25lckVsZW0sIGVycm9yLCAKCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJICAgICIlcywgYXR0cmlidXRlICclcyc6IFRoZSBRTmFtZSB2YWx1ZSAlcyBkb2VzIG5vdCByZXNvbHZlIHRvIGEobikgIgoJICAgICIlcy5cbiIsIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZSwgCgkgICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyQSwgcmVmVVJJLCByZWZOYW1lKSwgCgkgICAgQkFEX0NBU1QgcmVmVHlwZVN0ciwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQogICAgRlJFRV9BTkRfTlVMTChzdHJBKQp9CgovKioKICogeG1sU2NoZW1hUEN1c3RvbUF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlIAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlIGR1cmluZyB0aGUgcGFyc2UuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCXhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCXhtbENoYXIgKipvd25lckRlcywKCQkJeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCXhtbEF0dHJQdHIgYXR0ciwKCQkJY29uc3QgY2hhciAqbXNnKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgICAKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJIiVzLCBhdHRyaWJ1dGUgJyVzJzogJXMuXG4iLCAKCUJBRF9DQVNUIGRlcywgYXR0ci0+bmFtZSwgKGNvbnN0IHhtbENoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBhdHRyaWJ1dGUncyBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgYXR0cmlidXRlJ3Mgb3duZXIgaXRlbQogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUgCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxBdHRyUHRyIGF0dHIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJBID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAgCiAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgCgkiJXM6IFRoZSBhdHRyaWJ1dGUgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsIEJBRF9DQVNUIGRlcywgCgl4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHJBLCBhdHRyLT5ucywgYXR0ci0+bmFtZSkpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckEpOwp9CgovKioKICogeG1sU2NoZW1hUEFxdWlyZURlczoKICogQGRlczogdGhlIGZpcnN0IGRlc2lnbmF0aW9uIAogKiBAaXRlbURlczogdGhlIHNlY29uZCBkZXNpZ25hdGlvbgogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtIAogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKgogKiBDcmVhdGVzIGEgZGVzaWduYXRpb24gZm9yIGFuIGl0ZW0uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQXF1aXJlRGVzKHhtbENoYXIgKipkZXMsCgkJICAgIHhtbENoYXIgKippdGVtRGVzLCAKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtKQp7CiAgICBpZiAoaXRlbURlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChkZXMsIE5VTEwsIGl0ZW0sIGl0ZW1FbGVtLCAxKTsKICAgIGVsc2UgaWYgKCppdGVtRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoaXRlbURlcywgTlVMTCwgaXRlbSwgaXRlbUVsZW0sIDEpOwoJKmRlcyA9ICppdGVtRGVzOwogICAgfSBlbHNlIAoJKmRlcyA9ICppdGVtRGVzOyAgCn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjI6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMzogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMiwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMykKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtRWxlbSk7ICAgCiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKChpdGVtRWxlbSA9PSBOVUxMKSAmJiAoaXRlbSAhPSBOVUxMKSkKCWl0ZW1FbGVtID0gaXRlbS0+bm9kZTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbUVsZW0sIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLCAKCShjb25zdCBjaGFyICopIG1zZywgQkFEX0NBU1QgZGVzLCBzdHIxLCBzdHIyLCBzdHIzLCBOVUxMKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiB0aGUgb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgZHVyaW5nIHBhcnNpbmcuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ3VzdG9tRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSkKewogICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LCBlcnJvciwgaXRlbURlcywgaXRlbSwgaXRlbUVsZW0sIG1lc3NhZ2UsCglzdHIxLCBOVUxMLCBOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBBdHRyVXNlRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSB0eXBlCiAqIEBpdGVtOiB0aGUgc2NoZW1hIHR5cGUKICogQGl0ZW1FbGVtOiB0aGUgbm9kZSBvZiB0aGUgc2NoZW1hIHR5cGUKICogQGF0dHI6IHRoZSBpbnZhbGlkIHNjaGVtYSBhdHRyaWJ1dGUKICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiB0aGUgb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYW4gYXR0cmlidXRlIHVzZSBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBBdHRyVXNlRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkgICAgeG1sTm9kZVB0ciBpdGVtRWxlbSwKCQkgICAgY29uc3QgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIsCgkJICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgIGNvbnN0IHhtbENoYXIgKnN0cjEpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJBID0gTlVMTCwgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtRWxlbSk7CiAgICB4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHJBLCB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYXR0ciksIAoJeG1sU2NoZW1hR2V0QXR0ck5hbWUoYXR0cikpOwogICAgbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlcywgYXR0ci4gdXNlICVzOiAiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwogICAgaWYgKChpdGVtRWxlbSA9PSBOVUxMKSAmJiAoaXRlbSAhPSBOVUxMKSkKCWl0ZW1FbGVtID0gaXRlbS0+bm9kZTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbUVsZW0sIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLCAKCShjb25zdCBjaGFyICopIG1zZywgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBzdHJBLCBzdHIxLCBOVUxMLCBOVUxMKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckEpOwogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxGYWNldEF0b21pY0VycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSB0eXBlCiAqIEBpdGVtOiB0aGUgc2NoZW1hIHR5cGUKICogQGJhc2VJdGVtOiB0aGUgYmFzZSB0eXBlIG9mIHR5cGUKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIGF0b21pYyBzaW1wbGUgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCQkgIHhtbENoYXIgKippdGVtRGVzLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VJdGVtLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgaXRlbS0+bm9kZSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXM6IFRoZSBmYWNldCAnJXMnIGlzIG5vdCBhbGxvd2VkIG9uIHR5cGVzIGRlcml2ZWQgZnJvbSB0aGUgIgoJInR5cGUgJXMuXG4iLAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJULCBOVUxMLCBiYXNlSXRlbSwgTlVMTCwgMSksCglOVUxMLCBOVUxMKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0clQpOwp9CgovKioKICogeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBzY2hlbWEgaXRlbSBpbnZvbHZlZAogKiBAaXRlbTogdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBmYWNldDogdGhlIGlsbGVnYWwgZmFjZXQKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGZhY2V0IGZvciA8bGlzdD4gYW5kIDx1bmlvbj4uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCQkgIHhtbENoYXIgKippdGVtRGVzLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKCQkJICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0clQgPSBOVUxMOwoKICAgIHhtbFNjaGVtYVBBcXVpcmVEZXMoJmRlcywgaXRlbURlcywgaXRlbSwgaXRlbS0+bm9kZSk7CiAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGl0ZW0tPm5vZGUsIGVycm9yLCAKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQuXG4iLCAKCUJBRF9DQVNUIGRlcywgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpKTsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKHN0clQpOwp9CgovKioKICogeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAZWxlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudCBub2RlCiAqIEBhdHRyOiB0aGUgYmFkIGF0dHJpYnV0ZSBub2RlCiAqIEB0eXBlOiB0aGUgY29ycmVzcG9uZGluZyB0eXBlIG9mIHRoZSBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sQXR0clB0ciBhdHRyLAkJCSAKCQkJIGNvbnN0IGNoYXIgKm5hbWUxLAoJCQkgY29uc3QgY2hhciAqbmFtZTIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsJCiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgCiAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGF0dHJpYnV0ZXMgJyVzJyBhbmQgJyVzJyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLlxuIiwgCglCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUxLCBCQURfQ0FTVCBuYW1lMiwgTlVMTCwgTlVMTCk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQp9CgovKioKICogeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAdHlwZTogdGhlIHR5cGUgc3BlY2lmaWVyCiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBvd25lcgogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBpZiBleGlzdGVudCAKICogQG5vZGU6IHRoZSB2YWxpZGF0ZWQgbm9kZQogKiBAdmFsdWU6IHRoZSB2YWxpZGF0ZWQgdmFsdWUKICoKICogUmVwb3J0cyBhIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqIFRPRE86IFNob3VsZCB0aGlzIHJlcG9ydCB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBhcyB3ZWxsPwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQl4bWxDaGFyICoqb3duZXJEZXMsCgkJCXhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQl4bWxOb2RlUHRyIG5vZGUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJY29uc3QgY2hhciAqdHlwZURlcywKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCWNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjEsCgkJCWNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJBID0gTlVMTCwgKnN0clQgPSBOVUxMOyAgICAKICAgIAogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFQUmVxdWVzdEl0ZW1EZXMoJmRlcywgb3duZXJJdGVtLCBub2RlKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQUmVxdWVzdEl0ZW1EZXMob3duZXJEZXMsIG93bmVySXRlbSwgbm9kZSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgCiAgICBpZiAodHlwZSAhPSBOVUxMKQoJdHlwZURlcyA9IChjb25zdCBjaGFyICopIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0clQsIE5VTEwsIHR5cGUsIE5VTEwsIDEpOwogICAgaWYgKG1lc3NhZ2UgPT0gTlVMTCkgewoJLyoKCSogVXNlIGRlZmF1bHQgbWVzc2FnZXMuCgkqLwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CgkgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCQkiJXMsIGF0dHJpYnV0ZSAnJXMnIFslc106IFRoZSB2YWx1ZSAnJXMnIGlzIG5vdCAiCgkJInZhbGlkLlxuIiwgCgkJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHJBLCBub2RlLT5ucywgCgkJbm9kZS0+bmFtZSksIEJBRF9DQVNUIHR5cGVEZXMsIHZhbHVlLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgCgkJIiVzIFslc106IFRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQuXG4iLAoJCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgdHlwZURlcyk7Cgl9CiAgICB9IGVsc2UgewoJeG1sQ2hhciAqbXNnOwoKCW1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXMiKTsKCWlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCSAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLCBhdHRyaWJ1dGUgJyVzJyIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiBbJXNdOiAiKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKSB7CgkgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCQkoY29uc3QgY2hhciAqKSBtc2csIAoJCUJBRF9DQVNUIGRlcywgeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyQSwgCgkJbm9kZS0+bnMsIG5vZGUtPm5hbWUpLCBCQURfQ0FTVCB0eXBlRGVzLCBzdHIxLCBzdHIyKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCQkoY29uc3QgY2hhciAqKSBtc2csIAoJCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgdHlwZURlcywgc3RyMSwgc3RyMiwgTlVMTCk7Cgl9Cgl4bWxGcmVlKG1zZyk7CiAgICB9CiAgICAvKiBDbGVhbnVwLiAqLwogICAgRlJFRV9BTkRfTlVMTChzdHJBKQogICAgRlJFRV9BTkRfTlVMTChzdHJUKQogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKfQoKLyoqCiAqIHhtbFNjaGVtYVBDb250ZW50RXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBvbndlckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGl0ZW0gb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAb3duZXJFbGVtOiB0aGUgbm9kZSBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBjaGlsZDogdGhlIGludmFsaWQgY2hpbGQgbm9kZQogKiBAbWVzc2FnZTogdGhlIG9wdGlvbmFsIGVycm9yIG1lc3NhZ2UKICogQGNvbnRlbnQ6IHRoZSBvcHRpb25hbCBzdHJpbmcgZGVzY3JpYmluZyB0aGUgY29ycmVjdCBjb250ZW50CiAqCiAqIFJlcG9ydHMgYW4gZXJyb3IgY29uY2VybmluZyB0aGUgY29udGVudCBvZiBhIHNjaGVtYSBlbGVtZW50LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUENvbnRlbnRFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkgICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkgICAgIHhtbENoYXIgKipvd25lckRlcywKCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCSAgICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCQkgICAgIAoJCSAgICAgeG1sTm9kZVB0ciBjaGlsZCwKCQkgICAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgICBjb25zdCBjaGFyICpjb250ZW50KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwogICAgCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwgCgkgICAgIiVzOiAlcy5cbiIsIAoJICAgIEJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbWVzc2FnZSk7CiAgICBlbHNlIHsKCWlmIChjb250ZW50ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwgCgkJIiVzOiBUaGUgY29udGVudCBpcyBub3QgdmFsaWQuIEV4cGVjdGVkIGlzICVzLlxuIiwgCgkJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBjb250ZW50KTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgb3duZXJFbGVtLCBjaGlsZCwgZXJyb3IsIAoJCSIlczogVGhlIGNvbnRlbnQgaXMgbm90IHZhbGlkLlxuIiwgCgkJQkFEX0NBU1QgZGVzLCBOVUxMKTsKCX0KICAgIH0KICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0gICAKCi8qKgogKiB4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZQogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgYXR0cmlidXRlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sQXR0clB0ciBhdHRyKQp7CiAgICB4bWxDaGFyICpzdHJFID0gTlVMTCwgKnN0ckEgPSBOVUxMOwogICAgCiAgICB4bWxTY2hlbWFWRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCAJCgllcnJvciwKCS8qIFhNTF9TQ0hFTUFTX0VSUl9BVFRSVU5LTk9XTiwgKi8KCSIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckUsIE5VTEwsIE5VTEwsIGF0dHItPnBhcmVudCwgMCksCgl4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHJBLCBhdHRyLT5ucywgYXR0ci0+bmFtZSkpOwogICAgRlJFRV9BTkRfTlVMTChzdHJFKQogICAgRlJFRV9BTkRfTlVMTChzdHJBKQp9CgoKc3RhdGljIGludAp4bWxTY2hlbWFJc0dsb2JhbEl0ZW0oeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkKCQlyZXR1cm4oMSk7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOgoJICAgIGlmICggKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtKS0+ZmxhZ3MgJiAKCQlYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkKCQlyZXR1cm4oMSk7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSktPmZsYWdzICYgCgkJWE1MX1NDSEVNQVNfQVRUUl9HTE9CQUwpCgkJcmV0dXJuKDEpOwoJICAgIGJyZWFrOwoJLyogTm90ZSB0aGF0IGF0dHJpYnV0ZSBncm91cHMgYXJlIGFsd2F5cyBnbG9iYWwuICovCglkZWZhdWx0OgoJICAgIHJldHVybigxKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB0eXBlOiB0aGUgc2NoZW1hIHR5cGUgb2YgdGhlIHZhbGlkYXRlZCBub2RlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgbWVzc2FnZQogKgogKiBSZXBvcnRzIGEgdmFsaWRhdGlvbiBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDdXN0b21FcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgICAgCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgaWYgKG5vZGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVkN1c3RvbUVyciwgbm8gbm9kZSAiCgkgICAgImdpdmVuLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm47CiAgICB9CiAgICAvKiBUT0RPOiBBcmUgdGhlIEhUTUwgYW5kIERPQ0IgZG9jIG5vZGVzIGV4cGVjdGVkIGhlcmU/ICovCiAgICBpZiAobm9kZS0+dHlwZSAhPSBYTUxfRE9DVU1FTlRfTk9ERSkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCBOVUxMLCBub2RlLCAwKTsKCWlmICgodHlwZSAhPSBOVUxMKSAmJiAoeG1sU2NoZW1hSXNHbG9iYWxJdGVtKHR5cGUpKSkgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdIik7Cgl9Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiOiAiKTsKICAgIH0gZWxzZQoJbXNnID0geG1sU3RyZHVwKChjb25zdCB4bWxDaGFyICopICIiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIChjb25zdCB4bWxDaGFyICopIG1lc3NhZ2UpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIi5cbiIpOyAgIAogICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBzdHIxLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKQogICAgRlJFRV9BTkRfTlVMTChzdHIpCn0KCi8qKgogKiB4bWxTY2hlbWFWV2lsZGNhcmRFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBub2RlOiB0aGUgdmFsaWRhdGVkIG5vZGUKICogQHdpbGQ6IHRoZSB3aWxkY2FyZCB1c2VkCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGFuIHZhbGlkYXRpb24tYnktd2lsZGNhcmQgZXJyb3IuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWV2lsZGNhcmRFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgICAgCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKm1zZyA9IE5VTEw7CgogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBOVUxMLCBub2RlLCAwKTsKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXMgWyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKHdpbGQtPnByb2Nlc3NDb250ZW50cykpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiB3aWxkY2FyZF06ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIEJBRF9DQVNUIGRlcywgTlVMTCk7CiAgICBGUkVFX0FORF9OVUxMKGRlcyk7CiAgICBGUkVFX0FORF9OVUxMKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogdGhlIHBhcmVudCBlbGVtZW50IG5vZGUgb2YgdGhlIG1pc3NpbmcgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSB4bWxOb2RlUHRyIGVsZW0sCgkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgdHlwZSkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSwgKnVyaTsKICAgIHhtbENoYXIgKnN0ckUgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKHR5cGUtPnJlZiAhPSBOVUxMKSB7CQkJCQoJbmFtZSA9IHR5cGUtPnJlZjsKCXVyaSA9IHR5cGUtPnJlZk5zOwogICAgfSBlbHNlIHsKCW5hbWUgPSB0eXBlLT5uYW1lOwoJdXJpID0gdHlwZS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgfQkJCSAgICAKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgCglYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzQsCgkvKiBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywgKi8KCSIlczogVGhlIGF0dHJpYnV0ZSAlcyBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJFLCBOVUxMLCBOVUxMLCBlbGVtLCAwKSwKCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIHVyaSwgbmFtZSkpOwogICAgRlJFRV9BTkRfTlVMTChzdHJFKQogICAgRlJFRV9BTkRfTlVMTChzdHJBKQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJQWxsb2NhdGlvbiBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3U2NoZW1hRm9yUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEFsbG9jYXRlIGEgbmV3IFNjaGVtYSBzdHJ1Y3R1cmUuCiAqCiAqIFJldHVybnMgdGhlIG5ld2x5IGFsbG9jYXRlZCBzdHJ1Y3R1cmUgb3IgTlVMTCBpbiBjYXNlIG9yIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXNzZW1ibGVQdHIKeG1sU2NoZW1hTmV3QXNzZW1ibGUodm9pZCkKewogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBc3NlbWJsZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgLyogeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7ICovCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBc3NlbWJsZSkpOwogICAgcmV0LT5pdGVtcyA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIHhtbEZyZWUoYW5ub3QpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUltcG9ydDoKICogQGltcG9ydDogIGEgc2NoZW1hIGltcG9ydCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhbiBpbXBvcnQgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW1wb3J0KHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQpCnsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sU2NoZW1hRnJlZShpbXBvcnQtPnNjaGVtYSk7CiAgICB4bWxGcmVlRG9jKGltcG9ydC0+ZG9jKTsKICAgIHhtbEZyZWUoaW1wb3J0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbmNsdWRlOgogKiBAaW5jbHVkZTogIGEgc2NoZW1hIGluY2x1ZGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYW4gaW5jbHVkZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJbmNsdWRlKHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZSkKewogICAgaWYgKGluY2x1ZGUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sRnJlZURvYyhpbmNsdWRlLT5kb2MpOwogICAgeG1sRnJlZShpbmNsdWRlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdDoKICogQGluY2x1ZGVzOiAgYSBzY2hlbWEgaW5jbHVkZSBsaXN0CiAqCiAqIERlYWxsb2NhdGUgYW4gaW5jbHVkZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdCh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGVzKQp7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIG5leHQ7CgogICAgd2hpbGUgKGluY2x1ZGVzICE9IE5VTEwpIHsKICAgICAgICBuZXh0ID0gaW5jbHVkZXMtPm5leHQ7Cgl4bWxTY2hlbWFGcmVlSW5jbHVkZShpbmNsdWRlcyk7CglpbmNsdWRlcyA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlTm90YXRpb246CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBub3RhdGlvbiBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBOb3RhdGlvbiBzdHJ1Y3R1cmUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlTm90YXRpb24oeG1sU2NoZW1hTm90YXRpb25QdHIgbm90YSkKewogICAgaWYgKG5vdGEgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICB4bWxGcmVlKG5vdGEpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZToKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZSh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKewogICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0ci0+YW5ub3QgIT0gTlVMTCkgCgl4bWxTY2hlbWFGcmVlQW5ub3QoYXR0ci0+YW5ub3QpOwogICAgaWYgKGF0dHItPmRlZlZhbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGF0dHItPmRlZlZhbCk7CiAgICB4bWxGcmVlKGF0dHIpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQ6CiAqIHNldDogIGEgc2NoZW1hIHdpbGRjYXJkIG5hbWVzcGFjZQogKgogKiBEZWFsbG9jYXRlcyBhIGxpc3Qgb2Ygd2lsZGNhcmQgY29uc3RyYWludCBzdHJ1Y3R1cmVzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBzZXQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbmV4dDsKICAgIAogICAgd2hpbGUgKHNldCAhPSBOVUxMKSB7CgluZXh0ID0gc2V0LT5uZXh0OwoJeG1sRnJlZShzZXQpOwoJc2V0ID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZDoKICogQHdpbGRjYXJkOiAgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZXMgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZCh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkY2FyZCkKewogICAgaWYgKHdpbGRjYXJkID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHdpbGRjYXJkLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdCh3aWxkY2FyZC0+YW5ub3QpOwogICAgaWYgKHdpbGRjYXJkLT5uc1NldCAhPSBOVUxMKSAKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHdpbGRjYXJkLT5uc1NldCk7ICAgIAogICAgaWYgKHdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSAKCXhtbEZyZWUod2lsZGNhcmQtPm5lZ05zU2V0KTsgICAgCiAgICB4bWxGcmVlKHdpbGRjYXJkKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBncm91cCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIGlmICgoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSAmJiAKCShhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZChhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCk7CgogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0OgogKiBAYXR0clVzZTogIGFuIGF0dHJpYnV0ZSBsaW5rCiAqCiAqIERlYWxsb2NhdGUgYSBsaXN0IG9mIHNjaGVtYSBhdHRyaWJ1dGUgdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0KHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBuZXh0OwoKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKCW5leHQgPSBhdHRyVXNlLT5uZXh0OwoJeG1sRnJlZShhdHRyVXNlKTsKCWF0dHJVc2UgPSBuZXh0OwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3Q6CiAqIEBhbGluazogYSB0eXBlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2YgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmspCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJbmV4dCA9IGxpbmstPm5leHQ7Cgl4bWxGcmVlKGxpbmspOwoJbGluayA9IG5leHQ7CiAgICB9ICAgIAp9CgojaWZkZWYgSURDX0VOQUJMRUQKc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdCh4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8pCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIG5leHQ7CiAgICB3aGlsZSAoc3RvICE9IE5VTEwpIHsKCW5leHQgPSBzdG8tPm5leHQ7CglpZiAoc3RvLT5oaXN0b3J5ICE9IE5VTEwpCgkgICAgeG1sRnJlZShzdG8tPmhpc3RvcnkpOwoJaWYgKHN0by0+eHBhdGhDdHh0ICE9IE5VTEwpCgkgICAgeG1sRnJlZVN0cmVhbUN0eHQoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCXhtbEZyZWUoc3RvKTsKCXN0byA9IG5leHQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSURDOgogKiBAaWRjOiBhIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKgogKiBEZWFsbG9jYXRlcyBhbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24uCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSURDKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYpCnsKICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBjdXIsIHByZXY7CgogICAgaWYgKGlkY0RlZiA9PSBOVUxMKQoJcmV0dXJuOwogICAgaWYgKGlkY0RlZi0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoaWRjRGVmLT5hbm5vdCk7CiAgICBpZiAoaWRjRGVmLT5yZWYgIT0gTlVMTCkKCXhtbEZyZWUoaWRjRGVmLT5yZWYpOwogICAgLyogU2VsZWN0b3IgKi8KICAgIGlmIChpZGNEZWYtPnNlbGVjdG9yICE9IE5VTEwpIHsKCWlmIChpZGNEZWYtPnNlbGVjdG9yLT54cGF0aENvbXAgIT0gTlVMTCkKCSAgICB4bWxGcmVlUGF0dGVybigoeG1sUGF0dGVyblB0cikgaWRjRGVmLT5zZWxlY3Rvci0+eHBhdGhDb21wKTsKCXhtbEZyZWUoaWRjRGVmLT5zZWxlY3Rvcik7CiAgICB9CiAgICAvKiBGaWVsZHMgKi8KICAgIGlmIChpZGNEZWYtPmZpZWxkcyAhPSBOVUxMKSB7CgljdXIgPSBpZGNEZWYtPmZpZWxkczsKCWRvIHsKCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCSAgICBpZiAocHJldi0+eHBhdGhDb21wICE9IE5VTEwpCgkJeG1sRnJlZVBhdHRlcm4oKHhtbFBhdHRlcm5QdHIpIHByZXYtPnhwYXRoQ29tcCk7CgkgICAgeG1sRnJlZShwcmV2KTsJICAgIAoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQogICAgeG1sRnJlZShpZGNEZWYpOwp9CiNlbmRpZiAvKiBJRENfRU5BQkxFRCAqLwoKLyoqCiAqIHhtbFNjaGVtYUZyZWVFbGVtZW50OgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgZWxlbWVudCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBFbGVtZW50IHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVFbGVtZW50KHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbSkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoZWxlbS0+YW5ub3QgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQW5ub3QoZWxlbS0+YW5ub3QpOwogICAgaWYgKGVsZW0tPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHhtbFJlZ0ZyZWVSZWdleHAoZWxlbS0+Y29udE1vZGVsKTsKICAgIGlmIChlbGVtLT5kZWZWYWwgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShlbGVtLT5kZWZWYWwpOwogICAgeG1sRnJlZShlbGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVGYWNldDoKICogQGZhY2V0OiAgYSBzY2hlbWEgZmFjZXQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRmFjZXQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIGlmIChmYWNldCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChmYWNldC0+dmFsICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGZhY2V0LT52YWwpOwogICAgaWYgKGZhY2V0LT5yZWdleHAgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGZhY2V0LT5yZWdleHApOwogICAgaWYgKGZhY2V0LT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChmYWNldC0+YW5ub3QpOwogICAgeG1sRnJlZShmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZToKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBuZXh0OwoKICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICBuZXh0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgICAgIGZhY2V0ID0gbmV4dDsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodHlwZS0+YXR0cmlidXRlVXNlcyk7CglpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkgICAgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fAoJICAgICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRCkpKSB7CgkgICAgLyoKCSAgICAqIE5PVEU6IFRoZSBvbmx5IGNhc2Ugd2hlcmUgYW4gYXR0cmlidXRlIHdpbGRjYXJkCgkgICAgKiBpcyBub3Qgb3duZWQsIGlzIGlmIGEgY29tcGxleCB0eXBlIGluaGVyaXRzIGl0CgkgICAgKiBmcm9tIGEgYmFzZSB0eXBlLgoJICAgICovCgkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKTsKCX0KICAgIH0KICAgIGlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVR5cGVMaW5rTGlzdCh0eXBlLT5tZW1iZXJUeXBlcyk7CiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRMaW5rUHRyIG5leHQsIGxpbms7CgoJbGluayA9IHR5cGUtPmZhY2V0U2V0OwoJZG8gewoJICAgIG5leHQgPSBsaW5rLT5uZXh0OwoJICAgIHhtbEZyZWUobGluayk7CgkgICAgbGluayA9IG5leHQ7Cgl9IHdoaWxlIChsaW5rICE9IE5VTEwpOwogICAgfSAgCiAgICBpZiAodHlwZS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cCh0eXBlLT5jb250TW9kZWwpOwogICAgeG1sRnJlZSh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlzdDoKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZVR5cGVMaXN0KHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBuZXh0OwoKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKICAgICAgICBuZXh0ID0gdHlwZS0+cmVkZWY7Cgl4bWxTY2hlbWFGcmVlVHlwZSh0eXBlKTsKCXR5cGUgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZToKICogQHNjaGVtYTogIGEgc2NoZW1hIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRnJlZSh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5ub3RhRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlTm90YXRpb24pOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUpOwogICAgaWYgKHNjaGVtYS0+YXR0cmdycERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmF0dHJncnBEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUVsZW1lbnQpOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPnR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVUeXBlTGlzdCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmdyb3VwRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlVHlwZSk7CiNpZmRlZiBJRENfRU5BQkxFRAogICAgaWYgKHNjaGVtYS0+aWRjRGVmICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5pZGNEZWYsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZUlEQyk7CiNlbmRpZgogICAgaWYgKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgIT0gTlVMTCkKCXhtbEhhc2hGcmVlKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCgkJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVJbXBvcnQpOwogICAgaWYgKHNjaGVtYS0+aW5jbHVkZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdCgoeG1sU2NoZW1hSW5jbHVkZVB0cikgc2NoZW1hLT5pbmNsdWRlcyk7CiAgICB9CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChzY2hlbWEtPmFubm90KTsKICAgIGlmIChzY2hlbWEtPmRvYyAhPSBOVUxMICYmICFzY2hlbWEtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2Moc2NoZW1hLT5kb2MpOwogICAgeG1sRGljdEZyZWUoc2NoZW1hLT5kaWN0KTsgICAgCiAgICB4bWxGcmVlKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlEZWJ1ZyBmdW5jdGlvbnMJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmZGVmIExJQlhNTF9PVVRQVVRfRU5BQkxFRAoKLyoqCiAqIHhtbFNjaGVtYUVsZW1lbnREdW1wOgogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKgogKiBEdW1wIHRoZSBlbGVtZW50CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFbGVtZW50RHVtcCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sIEZJTEUgKiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCgkJICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlIEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIGlmIChlbGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fUkVGKSB7CglmcHJpbnRmKG91dHB1dCwgIlBhcnRpY2xlOiAlcyIsIG5hbWUpOwoJZnByaW50ZihvdXRwdXQsICIsIHRlcm0gZWxlbWVudDogJXMiLCBlbGVtLT5yZWYpOwoJaWYgKGVsZW0tPnJlZk5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICIgbnMgJXMiLCBlbGVtLT5yZWZOcyk7CiAgICB9IGVsc2UgeyAKCWZwcmludGYob3V0cHV0LCAiRWxlbWVudCIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCgkgICAgZnByaW50ZihvdXRwdXQsICIgKGdsb2JhbCkiKTsKCWZwcmludGYob3V0cHV0LCAiOiAlcyAiLCBlbGVtLT5uYW1lKTsKCWlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIm5zICVzIiwgbmFtZXNwYWNlKTsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgoZWxlbS0+bWluT2NjdXJzICE9IDEpIHx8IChlbGVtLT5tYXhPY2N1cnMgIT0gMSkpIHsKCWZwcmludGYob3V0cHV0LCAiICBtaW4gJWQgIiwgZWxlbS0+bWluT2NjdXJzKTsKICAgICAgICBpZiAoZWxlbS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6IHVuYm91bmRlZFxuIik7CiAgICAgICAgZWxzZSBpZiAoZWxlbS0+bWF4T2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiAlZFxuIiwgZWxlbS0+bWF4T2NjdXJzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIC8qCiAgICAqIE1pc2Mgb3RoZXIgcHJvcGVydGllcy4KICAgICovCiAgICBpZiAoKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgfHwKCShlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHx8CgkoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSB8fAoJKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9ERUZBVUxUKSB8fAoJKGVsZW0tPmlkICE9IE5VTEwpKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgcHJvcHM6ICIpOwoJaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIltmaXhlZF0gIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0RFRkFVTFQpCgkgICAgZnByaW50ZihvdXRwdXQsICJbZGVmYXVsdF0gIik7CglpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKQoJICAgIGZwcmludGYob3V0cHV0LCAiW2Fic3RyYWN0XSAiKTsKCWlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpCgkgICAgZnByaW50ZihvdXRwdXQsICJbbmlsbGFibGVdICIpOwoJaWYgKGVsZW0tPmlkICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICJbaWQ6ICclcyddICIsIGVsZW0tPmlkKTsKCWZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIC8qCiAgICAqIERlZmF1bHQvZml4ZWQgdmFsdWUuCiAgICAqLwogICAgaWYgKGVsZW0tPnZhbHVlICE9IE5VTEwpCglmcHJpbnRmKG91dHB1dCwgIiAgdmFsdWU6ICclcydcbiIsIGVsZW0tPnZhbHVlKTsKICAgIC8qCiAgICAqIFR5cGUuCiAgICAqLwogICAgaWYgKGVsZW0tPm5hbWVkVHlwZSAhPSBOVUxMKSB7CglmcHJpbnRmKG91dHB1dCwgIiAgdHlwZTogJXMgIiwgZWxlbS0+bmFtZWRUeXBlKTsKCWlmIChlbGVtLT5uYW1lZFR5cGVOcyAhPSBOVUxMKQoJICAgIGZwcmludGYob3V0cHV0LCAibnMgJXNcbiIsIGVsZW0tPm5hbWVkVHlwZU5zKTsKCWVsc2UKCSAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICB9CiAgICAvKgogICAgKiBTdWJzdGl0dXRpb24gZ3JvdXAuCiAgICAqLwogICAgaWYgKGVsZW0tPnN1YnN0R3JvdXAgIT0gTlVMTCkgewoJZnByaW50ZihvdXRwdXQsICIgIHN1YnN0aXR1dGlvbkdyb3VwOiAlcyAiLCBlbGVtLT5zdWJzdEdyb3VwKTsKCWlmIChlbGVtLT5zdWJzdEdyb3VwTnMgIT0gTlVMTCkKCSAgICBmcHJpbnRmKG91dHB1dCwgIm5zICVzXG4iLCBlbGVtLT5zdWJzdEdyb3VwTnMpOwoJZWxzZQoJICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUFubm90RHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAYW5ub3Q6ICBhIGFubm90YXRpb24KICoKICogRHVtcCB0aGUgYW5ub3RhdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQW5ub3REdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICB4bWxDaGFyICpjb250ZW50OwoKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBjb250ZW50ID0geG1sTm9kZUdldENvbnRlbnQoYW5ub3QtPmNvbnRlbnQpOwogICAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogJXNcbiIsIGNvbnRlbnQpOwogICAgICAgIHhtbEZyZWUoY29udGVudCk7CiAgICB9IGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgQW5ub3Q6IGVtcHR5XG4iKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEB0eXBlOiAgYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEdW1wIGEgU2NoZW1hVHlwZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVEdW1wKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgRklMRSAqIG91dHB1dCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiVHlwZTogTlVMTFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiAiKTsKICAgIGlmICh0eXBlLT5uYW1lICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcyAiLCB0eXBlLT5uYW1lKTsKICAgIGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm5vIG5hbWUgIik7CiAgICBpZiAodHlwZS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKG91dHB1dCwgIm5zICVzICIsIHR5cGUtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYmFzaWNdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3NpbXBsZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2NvbXBsZXhdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2VxdWVuY2VdICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW2Nob2ljZV0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbYWxsXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3VyXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Jlc3RyaWN0aW9uXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltleHRlbnNpb25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlt1bmtub3duIHR5cGUgJWRdICIsIHR5cGUtPnR5cGUpOwogICAgICAgICAgICBicmVhazsKICAgIH0gICAgCiAgICBmcHJpbnRmKG91dHB1dCwgImNvbnRlbnQ6ICIpOwogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiW3Vua25vd25dICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbZW1wdHldICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbZWxlbWVudF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlttaXhlZF0gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgoJLyogbm90IHVzZWQuICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIltiYXNpY10gIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJbc2ltcGxlXSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQU5ZOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIlthbnldICIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgodHlwZS0+bWluT2NjdXJzICE9IDEpIHx8ICh0eXBlLT5tYXhPY2N1cnMgIT0gMSkpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgbWluOiAlZCAiLCB0eXBlLT5taW5PY2N1cnMpOwogICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogdW5ib3VuZGVkXG4iKTsKICAgICAgICBlbHNlIGlmICh0eXBlLT5tYXhPY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6ICVkXG4iLCB0eXBlLT5tYXhPY2N1cnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBiYXNlIHR5cGU6ICVzIiwgdHlwZS0+YmFzZSk7CglpZiAodHlwZS0+YmFzZU5zICE9IE5VTEwpCgkgICAgZnByaW50ZihvdXRwdXQsICIgbnMgJXNcbiIsIHR5cGUtPmJhc2VOcyk7CgllbHNlCgkgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hQW5ub3REdW1wKG91dHB1dCwgdHlwZS0+YW5ub3QpOwogICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YiA9IHR5cGUtPnN1YnR5cGVzOwoKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgc3VidHlwZXM6ICIpOwogICAgICAgIHdoaWxlIChzdWIgIT0gTlVMTCkgewogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiVzICIsIHN1Yi0+bmFtZSk7CiAgICAgICAgICAgIHN1YiA9IHN1Yi0+bmV4dDsKICAgICAgICB9CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQoKfQoKLyoqCiAqIHhtbFNjaGVtYUR1bXA6CiAqIEBvdXRwdXQ6ICB0aGUgZmlsZSBvdXRwdXQKICogQHNjaGVtYTogIGEgc2NoZW1hIHN0cnVjdHVyZQogKgogKiBEdW1wIGEgU2NoZW1hIHN0cnVjdHVyZS4KICovCnZvaWQKeG1sU2NoZW1hRHVtcChGSUxFICogb3V0cHV0LCB4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICBpZiAob3V0cHV0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6ICIpOwogICAgaWYgKHNjaGVtYS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMsICIsIHNjaGVtYS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lLCAiKTsKICAgIGlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMiLCAoY29uc3QgY2hhciAqKSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyB0YXJnZXQgbmFtZXNwYWNlIik7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHNjaGVtYS0+YW5ub3QpOwoKICAgIHhtbEhhc2hTY2FuKHNjaGVtYS0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUR1bXAsCiAgICAgICAgICAgICAgICBvdXRwdXQpOwogICAgeG1sSGFzaFNjYW5GdWxsKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkgeG1sU2NoZW1hRWxlbWVudER1bXAsIG91dHB1dCk7Cn0KCiNpZmRlZiBJRENfRU5BQkxFRAojaWZkZWYgREVCVUdfSURDCi8qKgogKiB4bWxTY2hlbWFEZWJ1Z0R1bXBJRENUYWJsZTogCiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRGlzcGxheXMgdGhlIGN1cnJlbnQgSURDIHRhYmxlIGZvciBkZWJ1ZyBwdXJwb3Nlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlKEZJTEUgKiBvdXRwdXQsCgkJCSAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUsCgkJCSAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZSwKCQkJICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKnZhbHVlOyAgICAKICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIHRhYjsKICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5OwogICAgaW50IGksIGosIHJlczsKICAgIAogICAgZnByaW50ZihvdXRwdXQsICJJREM6IFRBQkxFUyBvbiAlc1xuIiwgCgl4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHIsIG5hbWVzcGFjZU5hbWUsIGxvY2FsTmFtZSkpOwogICAgRlJFRV9BTkRfTlVMTChzdHIpCgogICAgaWYgKGJpbmQgPT0gTlVMTCkKCXJldHVybjsKICAgIGRvIHsKCWZwcmludGYob3V0cHV0LCAiSURDOiAgIEJJTkRJTkcgJXNcbiIsIAoJICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgYmluZC0+ZGVmaW5pdGlvbi0+dGFyZ2V0TmFtZXNwYWNlLAoJICAgIGJpbmQtPmRlZmluaXRpb24tPm5hbWUpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQkKCWZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCSAgICB0YWIgPSBiaW5kLT5ub2RlVGFibGVbaV07CgkgICAgZnByaW50ZihvdXRwdXQsICIgICAgICAgICAoICIpOwoJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaisrKSB7CgkJa2V5ID0gdGFiLT5rZXlzW2pdOwkJCgkJaWYgKChrZXkgIT0gTlVMTCkgJiYgKGtleS0+Y29tcFZhbHVlICE9IE5VTEwpKSB7CiNpZmRlZiBJRENfVkFMVUVfU1VQUE9SVAoJCSAgICByZXMgPSB4bWxTY2hlbWFHZXRDYW5vblZhbHVlKGtleS0+Y29tcFZhbHVlLCAmdmFsdWUpOwojZWxzZQoJCSAgICB2YWx1ZSA9IHhtbFN0cmR1cChCQURfQ0FTVCAiZHVtbXktdmFsdWUiKTsKCQkgICAgcmVzID0gMDsKI2VuZGlmCgkJICAgIGlmIChyZXMgPj0gMCkKCQkJZnByaW50ZihvdXRwdXQsICJcIiVzXCIgIiwgdmFsdWUpOwoJCSAgICBlbHNlCgkJCWZwcmludGYob3V0cHV0LCAiQ0FOT04tVkFMVUUtRkFJTEVEICIpOwoJCSAgICBpZiAocmVzID09IDApIAoJCQlGUkVFX0FORF9OVUxMKHZhbHVlKQoJCX0gZWxzZSBpZiAoa2V5ICE9IE5VTEwpCgkJICAgIGZwcmludGYob3V0cHV0LCAiKG5vIHZhbCksICIpOwoJCWVsc2UKCQkgICAgZnByaW50ZihvdXRwdXQsICIoa2V5IG1pc3NpbmcpLCAiKTsKCSAgICB9CgkgICAgZnByaW50ZihvdXRwdXQsICIpXG4iKTsKCX0KCWJpbmQgPSBiaW5kLT5uZXh0OwogICAgfSB3aGlsZSAoYmluZCAhPSBOVUxMKTsKfQojZW5kaWYgLyogREVCVUdfSURDICovCiNlbmRpZiAvKiBJRENfRU5BQkxFRCAqLwojZW5kaWYgLyogTElCWE1MX09VVFBVVF9FTkFCTEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKiAJCQlVdGlsaXRpZXMJCQkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hR2V0UHJvcE5vZGU6CiAqIEBub2RlOiB0aGUgZWxlbWVudCBub2RlIAogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIG5hbWUgb2YgQG5hbWUgaW4KICogbm8gbmFtZXNwYWNlLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4gCiAqLwpzdGF0aWMgeG1sQXR0clB0cgp4bWxTY2hlbWFHZXRQcm9wTm9kZSh4bWxOb2RlUHRyIG5vZGUsIGNvbnN0IGNoYXIgKm5hbWUpIAp7CiAgICB4bWxBdHRyUHRyIHByb3A7CgogICAgaWYgKChub2RlID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKSAKCXJldHVybihOVUxMKTsKICAgIHByb3AgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKHByb3AgIT0gTlVMTCkgewogICAgICAgIGlmICgocHJvcC0+bnMgPT0gTlVMTCkgJiYgeG1sU3RyRXF1YWwocHJvcC0+bmFtZSwgQkFEX0NBU1QgbmFtZSkpCSAgICAKCSAgICByZXR1cm4ocHJvcCk7Cglwcm9wID0gcHJvcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQcm9wTm9kZU5zOgogKiBAbm9kZTogdGhlIGVsZW1lbnQgbm9kZSAKICogQHVyaTogdGhlIHVyaQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKgogKiBTZWVrcyBhbiBhdHRyaWJ1dGUgd2l0aCBhIGxvY2FsIG5hbWUgb2YgQG5hbWUgYW5kCiAqIGEgbmFtZXNwYWNlIFVSSSBvZiBAdXJpLgogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgb3IgTlVMTCBpZiBub3QgcHJlc2VudC4gCiAqLwpzdGF0aWMgeG1sQXR0clB0cgp4bWxTY2hlbWFHZXRQcm9wTm9kZU5zKHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgY2hhciAqdXJpLCBjb25zdCBjaGFyICpuYW1lKSAKewogICAgeG1sQXR0clB0ciBwcm9wOwoKICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkgCglyZXR1cm4oTlVMTCk7CiAgICBwcm9wID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChwcm9wICE9IE5VTEwpIHsKCWlmICgocHJvcC0+bnMgIT0gTlVMTCkgJiYKCSAgICB4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBCQURfQ0FTVCBuYW1lKSAmJgoJICAgIHhtbFN0ckVxdWFsKHByb3AtPm5zLT5ocmVmLCBCQURfQ0FTVCB1cmkpKQoJICAgIHJldHVybihwcm9wKTsKCXByb3AgPSBwcm9wLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXROb2RlQ29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybihOVUxMKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRQcm9wOgogKiBAY3R4dDogdGhlIHBhcnNlciBjb250ZXh0CiAqIEBub2RlOiB0aGUgbm9kZQogKiBAbmFtZTogdGhlIHByb3BlcnR5IG5hbWUKICogCiAqIFJlYWQgYSBhdHRyaWJ1dGUgdmFsdWUgYW5kIGludGVybmFsaXplIHRoZSBzdHJpbmcKICoKICogUmV0dXJucyB0aGUgc3RyaW5nIG9yIE5VTEwgaWYgbm90IHByZXNlbnQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldFByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmFtZSkKewogICAgeG1sQ2hhciAqdmFsOwogICAgY29uc3QgeG1sQ2hhciAqcmV0OwoKICAgIHZhbCA9IHhtbEdldFByb3Aobm9kZSwgQkFEX0NBU1QgbmFtZSk7CiAgICBpZiAodmFsID09IE5VTEwpCiAgICAgICAgcmV0dXJuKE5VTEwpOwogICAgcmV0ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKICAgIHhtbEZyZWUodmFsKTsKICAgIHJldHVybihyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJUGFyc2luZyBmdW5jdGlvbnMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hR2V0RWxlbToKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUKICogQG5zOiAgdGhlIGVsZW1lbnQgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uIGluIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFHZXRFbGVtKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgCiAgICAgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJgoJICAgIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpKSB7CiAgICAgICAgICAgIHJldHVybiAocmV0KTsKICAgIH0gZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAgKiBUaGlzIG9uZSB3YXMgcmVtb3ZlZCwgc2luY2UgdG9wIGxldmVsIGVsZW1lbnQgZGVjbGFyYXRpb25zIGhhdmUKICAgICAqIHRoZSB0YXJnZXQgbmFtZXNwYWNlIHNwZWNpZmllZCBpbiB0YXJnZXROYW1lc3BhY2Ugb2YgdGhlIDxzY2hlbWE+CiAgICAgKiBpbmZvcm1hdGlvbiBlbGVtZW50LCBldmVuIGlmIGVsZW1lbnRGb3JtRGVmYXVsdCBpcyAidW5xdWFsaWZpZWQiLgogICAgICovCiAgICAKICAgIC8qIGVsc2UgaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfUVVBTElGX0VMRU0pID09IDApIHsKICAgICAgICBpZiAoeG1sU3RyRXF1YWwobmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpCgkgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgTlVMTCk7CgllbHNlCgkgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJgoJICAgICgobGV2ZWwgPT0gMCkgfHwgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1RPUExFVkVMKSkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwoJfQogICAgKi8KICAgIAogICAgLyoKICAgICogUmVtb3ZlZCBzaW5jZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgaG9sZCBieSB0aGUgbWFpbiBzY2hlbWEgb25seS4KICAgICoKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0RWxlbShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlLCBsZXZlbCArIDEpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRUeXBlOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMgY29udGV4dAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5zOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIHR5cGUgaW4gdGhlIHNjaGVtYXMgb3IgdGhlIHByZWRlZmluZWQgdHlwZXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFR5cGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQ7CgogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgaWYgKHNjaGVtYSAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfQogICAgcmV0ID0geG1sU2NoZW1hR2V0UHJlZGVmaW5lZFR5cGUobmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmIChyZXQgIT0gTlVMTCkKCXJldHVybiAocmV0KTsKICAgIC8qCiAgICAqIFJlbW92ZWQsIHNpbmNlIHRoZSBpbXBvcnRlZCBjb21wb25lbnRzIHdpbGwgYmUgZ3JhZnRlZCBvbiB0aGUKICAgICogbWFpbiBzY2hlbWEgb25seS4gICAgCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCiAgICBpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldFR5cGUoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkgewoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIHR5cGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzOiVzIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UpOwogICAgfQojZW5kaWYKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJpYnV0ZToKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEgCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlIAogKgogKiBMb29rdXAgYSBhbiBhdHRyaWJ1dGUgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIKeG1sU2NoZW1hR2V0QXR0cmlidXRlKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgCiAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7IAogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQsIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwkKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQogICAgKi8KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0QXR0cmlidXRlR3JvdXA6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hIAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUgZ3JvdXAKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGF0dHJpYnV0ZSBncm91cCAKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQ7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgCiAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmF0dHJncnBEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSkKCXJldHVybiAocmV0KTsgIAogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIC8qCiAgICAqIFJlbW92ZWQgc2luY2UgaW1wb3J0ZWQgY29tcG9uZW50cyB3aWxsIGJlIGhvbGQgYnkgdGhlIG1haW4gc2NoZW1hIG9ubHkuCiAgICAqCiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRSk7CiAgICBlbHNlCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CQogICAgaWYgKGltcG9ydCAhPSBOVUxMKSB7CglyZXQgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTCkpCgkgICAgcmV0dXJuIChyZXQpOwoJZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICAqLwojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSBncm91cCAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEgCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGdyb3VwCiAqIEBuczogIHRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBncm91cCAKICoKICogTG9va3VwIGEgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGdyb3VwIGRlZmluaXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRHcm91cCh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+Z3JvdXBEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7ICAKICAgIGVsc2UKCXJldCA9IE5VTEw7CiAgICAvKgogICAgKiBSZW1vdmVkIHNpbmNlIGltcG9ydGVkIGNvbXBvbmVudHMgd2lsbCBiZSBob2xkIGJ5IHRoZSBtYWluIHNjaGVtYSBvbmx5LgogICAgKgogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UpOwogICAgZWxzZQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwkKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0R3JvdXAoaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSk7CglpZiAoKHJldCAhPSBOVUxMKSAmJiAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgICovCiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgSVNfQkxBTktfTk9ERShuKQkJCQkJCVwKICAgICgoKG4pLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICh4bWxTY2hlbWFJc0JsYW5rKChuKS0+Y29udGVudCkpKQoKLyoqCiAqIHhtbFNjaGVtYUlzQmxhbms6CiAqIEBzdHI6ICBhIHN0cmluZwogKgogKiBDaGVjayBpZiBhIHN0cmluZyBpcyBpZ25vcmFibGUKICoKICogUmV0dXJucyAxIGlmIHRoZSBzdHJpbmcgaXMgTlVMTCBvciBtYWRlIG9mIGJsYW5rcyBjaGFycywgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNCbGFuayh4bWxDaGFyICogc3RyKQp7CiAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgxKTsKICAgIHdoaWxlICgqc3RyICE9IDApIHsKICAgICAgICBpZiAoIShJU19CTEFOS19DSCgqc3RyKSkpCiAgICAgICAgICAgIHJldHVybiAoMCk7CiAgICAgICAgc3RyKys7CiAgICB9CiAgICByZXR1cm4gKDEpOwp9CgovKioKICogeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAaXRlbTogIHRoZSBpdGVtCiAqCiAqIEFkZCBhIGl0ZW0gdG8gdGhlIHNjaGVtYSdzIGxpc3Qgb2YgY3VycmVudCBpdGVtcy4KICogVGhpcyBpcyB1c2VkIGlmIHRoZSBzY2hlbWEgd2FzIGFscmVhZHkgY29uc3RydWN0ZWQgYW5kCiAqIG5ldyBzY2hlbWF0YSBuZWVkIHRvIGJlIGFkZGVkIHRvIGl0LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlLgogKgogKiBSZXR1cm5zIDAgaWYgc3VjZWVkcyBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtKQp7CiAgICBzdGF0aWMgaW50IGdyb3dTaXplID0gMTAwOwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzOwoKICAgIGFzcyA9IGN0eHQtPmFzc2VtYmxlOwogICAgaWYgKGFzcy0+c2l6ZUl0ZW1zIDwgMCkgewoJLyogSWYgZGlzYWJsZWQuICovCglyZXR1cm4gKDApOwogICAgfQogICAgaWYgKGFzcy0+c2l6ZUl0ZW1zIDw9IDApIHsKCWFzcy0+aXRlbXMgPSAodm9pZCAqKikgeG1sTWFsbG9jKGdyb3dTaXplICogc2l6ZW9mKHhtbFNjaGVtYVR5cGVQdHIpKTsKCWlmIChhc3MtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsCgkJImFsbG9jYXRpbmcgbmV3IGl0ZW0gYnVmZmVyIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CQoJYXNzLT5zaXplSXRlbXMgPSBncm93U2l6ZTsKICAgIH0gZWxzZSBpZiAoYXNzLT5zaXplSXRlbXMgPD0gYXNzLT5uYkl0ZW1zKSB7Cglhc3MtPnNpemVJdGVtcyAqPSAyOwoJYXNzLT5pdGVtcyA9ICh2b2lkICoqKSB4bWxSZWFsbG9jKGFzcy0+aXRlbXMsIAoJICAgIGFzcy0+c2l6ZUl0ZW1zICogc2l6ZW9mKHhtbFNjaGVtYVR5cGVQdHIpKTsKCWlmIChhc3MtPml0ZW1zID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsCgkJImdyb3dpbmcgaXRlbSBidWZmZXIiLCBOVUxMKTsKCSAgICBhc3MtPnNpemVJdGVtcyA9IDA7CgkgICAgcmV0dXJuICgtMSk7Cgl9CQogICAgfQogICAgLyogYXNzLT5pdGVtc1thc3MtPm5iSXRlbXMrK10gPSAodm9pZCAqKSBpdGVtOyAqLwogICAgKCh4bWxTY2hlbWFUeXBlUHRyICopIGFzcy0+aXRlbXMpW2Fzcy0+bmJJdGVtcysrXSA9ICh2b2lkICopIGl0ZW07CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQWRkTm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIGFubm90YXRpb24gZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm90YXRpb25QdHIKeG1sU2NoZW1hQWRkTm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lKQp7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ub3RhRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPm5vdGFEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hTm90YXRpb25QdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZCBhbm5vdGF0aW9uIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFOb3RhdGlvbikpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+bm90YURlY2wsIG5hbWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CgkvKgoJKiBUT0RPOiBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIHNpbmNlIGEgdW5pcXVlIG5hbWUgd2lsbCBiZSBjb21wdXRlZC4KCSogSWYgaXQgZmFpbHMsIHRoZW4gYW4gb3RoZXIgaW50ZXJuYWwgZXJyb3IgbXVzdCBoYXZlIG9jY3VyZWQuCgkqLwoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9OT1RBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICJBbm5vdGF0aW9uIGRlY2xhcmF0aW9uICclcycgaXMgYWxyZWFkeSBkZWNsYXJlZC5cbiIsCiAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYUFkZEF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSwKCQkgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIGF0dHJpYnV0ZSAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmF0dHJEZWNsID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0gbmFtZXNwYWNlOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJaWYgKHRvcExldmVsKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1JFREVGSU5FRF9BVFRSLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkEgZ2xvYmFsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyAiCgkJImFscmVhZHkgZXhpc3QiLCBuYW1lKTsKCSAgICB4bWxGcmVlKHJldCk7CSAgICAKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIHsKCSAgICBjaGFyIGJ1ZlszMF07CgkgICAgLyoKCSAgICAqIFVzaW5nIHRoZSBjdHh0LT5jb250YWluZXIgZm9yIHhtbEhhc2hBZGRFbnRyeTMgaXMgYW1iaWdpb3VzCgkgICAgKiBpbiB0aGUgc2NlbmFyaW86CgkgICAgKiAxLiBtdWx0aXBsZSB0b3AtbGV2ZWwgY29tcGxleCB0eXBlcyBoYXZlIGRpZmZlcmVudCB0YXJnZXQKCSAgICAqICAgIG5hbWVzcGFjZXMgYnV0IGhhdmUgdGhlIFNBTUUgTkFNRTsgdGhpcyBjYW4gaGFwcGVuIGlmCgkgICAgKgkgc2NoZW1hdGEgYXJlICBpbXBvcnRlZAoJICAgICogMi4gdGhvc2UgY29tcGxleCB0eXBlcyBjb250YWluIGF0dHJpYnV0ZXMgd2l0aCBhbiBlcXVhbCBuYW1lCgkgICAgKiAzLiB0aG9zZSBhdHRyaWJ1dGVzIGFyZSBpbiBubyBuYW1lc3BhY2UgCgkgICAgKiBXZSB3aWxsIGNvbXB1dGUgYSBuZXcgY29udGV4dCBzdHJpbmcuCgkgICAgKi8JICAgIAoJICAgIHNucHJpbnRmKGJ1ZiwgMjksICIjYUNvbnQlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwKCQluYW1lc3BhY2UsIHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgYnVmLCAtMSksIHJldCk7CgoJICAgIGlmICh2YWwgIT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWRkQXR0cmlidXRlLCAiCgkJICAgICJhIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCQkgICAgImNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgaGFzaC4iLCBuYW1lKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9CSAgICAKCX0KICAgIH0KICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQoJeG1sU2NoZW1hQWRkQXNzZW1ibGVkSXRlbShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0KTsgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGVHcm91cDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5hdHRyZ3JwRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPQogICAgICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikKICAgICAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSBncm91cCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJncnBEZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX0FUVFJHUk9VUCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJBIGdsb2JhbCBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5IGV4aXN0IiwgbmFtZSk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkJCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkRWxlbWVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSB0eXBlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBFbGVtZW50IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hQWRkRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UsCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIGVsZW1lbnQgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5lbGVtRGVjbCA9IHhtbEhhc2hDcmVhdGVEaWN0KDEwLCBjdHh0LT5kaWN0KTsKICAgIGlmIChzY2hlbWEtPmVsZW1EZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGVsZW1lbnQiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUVsZW1lbnQpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJaWYgKHRvcExldmVsKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1JFREVGSU5FRF9FTEVNRU5ULAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkEgZ2xvYmFsIGVsZW1lbnQgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgIgoJCSJhbHJlYWR5IGV4aXN0IiwgbmFtZSk7CiAgICAgICAgICAgIHhtbEZyZWUocmV0KTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgY2hhciBidWZbMzBdOyAKCgkgICAgc25wcmludGYoYnVmLCAyOSwgIiNlQ29udCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgkgICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCAKCQluYW1lc3BhY2UsICh4bWxDaGFyICopIGJ1ZiwgcmV0KTsKCSAgICBpZiAodmFsICE9IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZEVsZW1lbnQsICIKCQkgICAgImEgZHVibGljYXRlIGVsZW1lbnQgZGVjbGFyYXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCQkgICAgImNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgaGFzaC4iLCBuYW1lKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9Cgl9CiAgICAgICAgCiAgICB9CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkJCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQWRkVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSBuYW1lc3BhY2UKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgaXRlbQogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUFkZFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lLCBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLAoJCSB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgdHlwZSAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPnR5cGVEZWNsID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+dHlwZURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgdHlwZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICByZXQtPnJlZGVmID0gTlVMTDsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7CQogICAgICAgIGlmIChjdHh0LT5pbmNsdWRlcyA9PSAwKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX1RZUEUsCgkJTlVMTCwgTlVMTCwgbm9kZSwgCgkJIkEgZ2xvYmFsIHR5cGUgZGVmaW5pdGlvbiB3aXRoIHRoZSBuYW1lICclcycgZG9lcyBhbHJlYWR5IGV4aXN0IiwgbmFtZSk7ICAgICAgICAgICAgCSAgICAKCSAgICB4bWxGcmVlKHJldCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciBwcmV2OwoKCSAgICBwcmV2ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKCSAgICBpZiAocHJldiA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFkZFR5cGUsIG9uIHR5cGUgIgoJCSAgICAiJyVzJy5cbiIsCgkJICAgIG5hbWUsIE5VTEwpOwoJCXhtbEZyZWUocmV0KTsKCQlyZXR1cm4gKE5VTEwpOwoJICAgIH0KCSAgICByZXQtPnJlZGVmID0gcHJldi0+cmVkZWY7CgkgICAgcHJldi0+cmVkZWYgPSByZXQ7Cgl9CiAgICB9CiAgICByZXQtPm1pbk9jY3VycyA9IDE7CiAgICByZXQtPm1heE9jY3VycyA9IDE7CiAgICByZXQtPmF0dHJpYnV0ZVVzZXMgPSBOVUxMOwogICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IE5VTEw7CiAgICBpZiAoY3R4dC0+YXNzZW1ibGUgIT0gTlVMTCkJCgl4bWxTY2hlbWFBZGRBc3NlbWJsZWRJdGVtKGN0eHQscmV0KTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBncm91cCBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hQWRkR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2VOYW1lLAoJCSAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+Z3JvdXBEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5ncm91cERlY2wgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZGluZyBncm91cCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPQogICAgICAgIHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5ncm91cERlY2wsIG5hbWUsIG5hbWVzcGFjZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUkVERUZJTkVEX0dST1VQLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkEgZ2xvYmFsIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIG5hbWUpOyAgICAKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKICAgIGlmIChjdHh0LT5hc3NlbWJsZSAhPSBOVUxMKQkKCXhtbFNjaGVtYUFkZEFzc2VtYmxlZEl0ZW0oY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmROc1B0cgp4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyKSAKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmROcykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJjcmVhdGluZyB3aWxkY2FyZCBuYW1lc3BhY2UgY29uc3RyYWludCIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsgICAgCiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQWRkcyBhIHdpbGRjYXJkLiBJdCBjb3JyZXNwb25kcyB0byBhIAogKiB4c2Q6YW55QXR0cmlidXRlIGFuZCBpcyB1c2VkIGFzIHN0b3JhZ2UgZm9yIG5hbWVzcGFjZSAKICogY29uc3RyYWludHMgb24gYSB4c2Q6YW55LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmRQdHIKeG1sU2NoZW1hQWRkV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciByZXQgPSBOVUxMOwoKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hV2lsZGNhcmRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZGluZyB3aWxkY2FyZCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmQpKTsKICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKgkJVXRpbGl0aWVzIGZvciBwYXJzaW5nCQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxHZXRRTmFtZVByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSByZXN1bHQgbmFtZXNwYWNlIGlmIGFueQogKgogKiBFeHRyYWN0IGEgUU5hbWUgQXR0cmlidXRlIHZhbHVlCiAqCiAqIFJldHVybnMgdGhlIE5DTmFtZSBvciBOVUxMIGlmIG5vdCBmb3VuZCwgYW5kIGFsc28gdXBkYXRlIEBuYW1lc3BhY2UKICogICAgd2l0aCB0aGUgbmFtZXNwYWNlIFVSSQogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxHZXRRTmFtZVByb3AoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBjb25zdCB4bWxDaGFyICoqIG5hbWVzcGFjZSkKewogICAgY29uc3QgeG1sQ2hhciAqdmFsOwogICAgeG1sTnNQdHIgbnM7CiAgICBjb25zdCB4bWxDaGFyICpyZXQsICpwcmVmaXg7CiAgICBpbnQgbGVuOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgICpuYW1lc3BhY2UgPSBOVUxMOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoTlVMTCk7CiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKCFzdHJjaHIoKGNoYXIgKikgdmFsLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgMCk7CglpZiAobnMpIHsKCSAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJICAgIHJldHVybiAodmFsKTsKCX0KICAgIH0KICAgIHJldCA9IHhtbFNwbGl0UU5hbWUzKHZhbCwgJmxlbik7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKHZhbCk7CiAgICB9CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHJldCwgLTEpOwogICAgcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIGxlbik7CgogICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CiAgICBpZiAobnMgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1BSRUZJWF9VTkRFRklORUQsIAoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIE5VTEwsIHZhbCwKCSAgICAiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlICIKCSAgICAiZGVjbGFyYXRpb24gaW4gc2NvcGUiLCB2YWwsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBwYXJlbnQgYXMgYSBzY2hlbWEgb2JqZWN0CiAqIEB2YWx1ZTogIHRoZSBRTmFtZSB2YWx1ZSAKICogQGxvY2FsOiB0aGUgcmVzdWx0aW5nIGxvY2FsIHBhcnQgaWYgZm91bmQsIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb3RoZXJ3aXNlCiAqIEB1cmk6ICB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBVUkkgaWYgZm91bmQKICoKICogRXh0cmFjdHMgdGhlIGxvY2FsIG5hbWUgYW5kIHRoZSBVUkkgb2YgYSBRTmFtZSB2YWx1ZSBhbmQgdmFsaWRhdGVzIGl0LgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIG9uIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdAogKiBzaG91bGQgcmVzb2x2ZSB0byBzY2hlbWEgY29tcG9uZW50cy4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnByZWZpeCwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnByZWY7CiAgICB4bWxOc1B0ciBuczsKICAgIGludCBsZW4sIHJldDsKICAgIAogICAgKnVyaSA9IE5VTEw7CiAgICAqbG9jYWwgPSBOVUxMOwogICAgaWYgKHByZWZpeCAhPSAwKQoJKnByZWZpeCA9IE5VTEw7CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPiAwKSB7CQkKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJICAgIG93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksIAoJICAgICJRTmFtZSIsIHZhbHVlLCAKCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsJCgkqbG9jYWwgPSB2YWx1ZTsKCXJldHVybiAoY3R4dC0+ZXJyKTsgCiAgICB9IGVsc2UgaWYgKHJldCA8IDApCglyZXR1cm4gKC0xKTsKICAgCiAgICBpZiAoIXN0cmNocigoY2hhciAqKSB2YWx1ZSwgJzonKSkgewkKCW5zID0geG1sU2VhcmNoTnMoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQsIDApOwoJaWYgKG5zKQoJICAgICp1cmkgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5zLT5ocmVmLCAtMSk7CgllbHNlIGlmIChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlMpIHsKCSAgICAvKgoJICAgICogVGhpcyBvbmUgdGFrZXMgY2FyZSBvZiBpbmNsdWRlZCBzY2hlbWFzIHdpdGggbm8KCSAgICAqIHRhcmdldCBuYW1lc3BhY2UuCgkgICAgKi8KCSAgICAqdXJpID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9CQoJKmxvY2FsID0gdmFsdWU7CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogQXQgdGhpcyBwb2ludCB4bWxTcGxpdFFOYW1lMyBoYXMgdG8gcmV0dXJuIGEgbG9jYWwgbmFtZS4KICAgICovCiAgICAqbG9jYWwgPSB4bWxTcGxpdFFOYW1lMyh2YWx1ZSwgJmxlbik7CiAgICAqbG9jYWwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsICpsb2NhbCwgLTEpOwogICAgcHJlZiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsdWUsIGxlbik7CiAgICBpZiAocHJlZml4ICE9IDApCgkqcHJlZml4ID0gcHJlZjsKICAgIG5zID0geG1sU2VhcmNoTnMoYXR0ci0+ZG9jLCBhdHRyLT5wYXJlbnQsIHByZWYpOwogICAgaWYgKG5zID09IE5VTEwpIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgb3duZXJEZXMsIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwgIlFOYW1lIiwgdmFsdWUsCgkgICAgIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSAiCgkgICAgImRlY2xhcmF0aW9uIGluIHNjb3BlIiwgdmFsdWUsIE5VTEwpOwoJcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSBlbHNlIHsKICAgICAgICAqdXJpID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZToKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyIGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgbm9kZQogKiBAbG9jYWw6IHRoZSByZXN1bHRpbmcgbG9jYWwgcGFydCBpZiBmb3VuZCwgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBvdGhlcndpc2UKICogQHVyaTogIHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIFVSSSBpZiBmb3VuZAogKgogKiBFeHRyYWN0cyBhbmQgdmFsaWRhdGVzIHRoZSBRTmFtZSBvZiBhbiBhdHRyaWJ1dGUgdmFsdWUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgb24gYXR0cmlidXRlIHZhbHVlcyB0aGF0CiAqIHNob3VsZCByZXNvbHZlIHRvIHNjaGVtYSBjb21wb25lbnRzLgogKgogKiBSZXR1cm5zIDAsIGluIGNhc2UgdGhlIFFOYW1lIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogaWYgbm90IHZhbGlkIGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCQkgICAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkJICAgICAgIGNvbnN0IHhtbENoYXIgKip1cmksCgkJCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnByZWZpeCwKCQkJCSAgICAgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZVZhbHVlKGN0eHQsIHNjaGVtYSwgCglvd25lckRlcywgb3duZXJJdGVtLCBhdHRyLCB2YWx1ZSwgdXJpLCBwcmVmaXgsIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0clFOYW1lOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIEBsb2NhbDogdGhlIHJlc3VsdGluZyBsb2NhbCBwYXJ0IGlmIGZvdW5kLCB0aGUgYXR0cmlidXRlIHZhbHVlIG90aGVyd2lzZQogKiBAdXJpOiAgdGhlIHJlc3VsdGluZyBuYW1lc3BhY2UgVVJJIGlmIGZvdW5kCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIFFOYW1lIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBRTmFtZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0clFOYW1lKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCAKCQkJCSAgIHhtbENoYXIgKipvd25lckRlcywKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkJICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCQkgICBjb25zdCBjaGFyICpuYW1lLAoJCQkJICAgY29uc3QgeG1sQ2hhciAqKnVyaSwKCQkJCSAgIGNvbnN0IHhtbENoYXIgKipwcmVmaXgsCgkJCQkgICBjb25zdCB4bWxDaGFyICoqbG9jYWwpCnsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUob3duZXJFbGVtLCBuYW1lKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCSpsb2NhbCA9IE5VTEw7CgkqdXJpID0gTlVMTDsKCXJldHVybiAoMCk7ICAgIAogICAgfQogICAgcmV0dXJuICh4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsIAoJb3duZXJEZXMsIG93bmVySXRlbSwgYXR0ciwgdXJpLCBwcmVmaXgsIGxvY2FsKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0cklEOgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBzY2hlbWE6IHRoZSBzY2hlbWEgY29udGV4dAogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAb3duZXJFbGVtOiAgdGhlIHBhcmVudCBub2RlIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgdGhlIElEIG9mIGFuIGF0dHJpYnV0ZSB2YWx1ZS4KICoKICogUmV0dXJucyAwLCBpbiBjYXNlIHRoZSBJRCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIG5vdCB2YWxpZCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0cklEKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkgICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJICAgIGNvbnN0IHhtbENoYXIgKm5hbWUpCnsKICAgIGludCByZXQ7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIHhtbEF0dHJQdHIgYXR0cjsgCgogICAgdmFsdWUgPSB4bWxHZXROb05zUHJvcChvd25lckVsZW0sIG5hbWUpOwogICAgaWYgKHZhbHVlID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShvd25lckVsZW0sIChjb25zdCBjaGFyICopIG5hbWUpOwogICAgaWYgKGF0dHIgPT0gTlVMTCkKCXJldHVybiAoLTEpOwoKICAgIHJldCA9IHhtbFZhbGlkYXRlTkNOYW1lKEJBRF9DQVNUIHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gMCkgewkKCS8qCgkqIE5PVEU6IHRoZSBJRG5lc3MgbWlnaHQgaGF2ZSBhbHJlYWR5IGJlIGRlY2xhcmVkIGluIHRoZSBEVEQKCSovCglpZiAoYXR0ci0+YXR5cGUgIT0gWE1MX0FUVFJJQlVURV9JRCkgewoJICAgIHhtbElEUHRyIHJlczsKCSAgICB4bWxDaGFyICpzdHJpcDsKCSAgICAKCSAgICAvKiAKCSAgICAqIFRPRE86IFVzZSB4bWxTY2hlbWFTdHJpcCBoZXJlOyBpdCdzIG5vdCBleHBvcnRlZCBhdCB0aGlzCgkgICAgKiBtb21lbnQuCgkgICAgKi8KCSAgICBzdHJpcCA9IHhtbFNjaGVtYUNvbGxhcHNlU3RyaW5nKEJBRF9DQVNUIHZhbHVlKTsJICAgIAoJICAgIGlmIChzdHJpcCAhPSBOVUxMKQoJCXZhbHVlID0gc3RyaXA7CQkKICAgIAkgICAgcmVzID0geG1sQWRkSUQoTlVMTCwgb3duZXJFbGVtLT5kb2MsIEJBRF9DQVNUIHZhbHVlLCBhdHRyKTsKCSAgICBpZiAocmVzID09IE5VTEwpIHsKCQlyZXQgPSBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFOwoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLCAKCQkgICAgb3duZXJEZXMsIG93bmVySXRlbSwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19JRCksIAoJCSAgICBOVUxMLCBOVUxMLCAiVGhlIElEICclcycgaXMgYWxyZWFkeSBkZWZpbmVkIiwKCQkgICAgQkFEX0NBU1QgdmFsdWUsIE5VTEwpOwoJICAgIH0gZWxzZQoJCWF0dHItPmF0eXBlID0gWE1MX0FUVFJJQlVURV9JRDsKCSAgICBpZiAoc3RyaXAgIT0gTlVMTCkKCQl4bWxGcmVlKHN0cmlwKTsKCX0KICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJcmV0ID0gWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJICAgIG93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19JRCksIAoJICAgIE5VTEwsIEJBRF9DQVNUIHZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsJCiAgICB9CiAgICB4bWxGcmVlKHZhbHVlKTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxHZXRNYXhPY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtYXhPY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNYXhPY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWF4T2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewoJaWYgKG1heCAhPSBVTkJPVU5ERUQpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCS8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJCU5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCQl2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoZGVmKTsKCX0gZWxzZSAKCSAgICByZXR1cm4gKFVOQk9VTkRFRCk7ICAvKiBlbmNvZGluZyBpdCB3aXRoIC0xIG1pZ2h0IGJlIGFub3RoZXIgb3B0aW9uICovCiAgICB9CgogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKGRlZik7CiAgICB9CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICAvKgogICAgKiBUT0RPOiBSZXN0cmljdCB0aGUgbWF4aW1hbCB2YWx1ZSB0byBJbnRlZ2VyLgogICAgKi8KICAgIGlmICgoKmN1ciAhPSAwKSB8fCAocmV0IDwgbWluKSB8fCAoKG1heCAhPSAtMSkgJiYgKHJldCA+IG1heCkpKSB7Cgl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJICAgIC8qIFhNTF9TQ0hFTUFQX0lOVkFMSURfTUlOT0NDVVJTLCAqLwoJICAgIE5VTEwsIE5VTEwsICh4bWxOb2RlUHRyKSBhdHRyLCBOVUxMLCBleHBlY3RlZCwKCSAgICB2YWwsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoZGVmKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbEdldE1pbk9jY3VyczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBHZXQgdGhlIG1pbk9jY3VycyBwcm9wZXJ0eQogKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IGlmIG5vdCBmb3VuZCwgb3IgdGhlIHZhbHVlCiAqLwpzdGF0aWMgaW50CnhtbEdldE1pbk9jY3Vycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgCgkJaW50IG1pbiwgaW50IG1heCwgaW50IGRlZiwgY29uc3QgY2hhciAqZXhwZWN0ZWQpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAibWluT2NjdXJzIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJcmV0dXJuIChkZWYpOwogICAgdmFsID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkgICAgLyogWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsICovCgkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIE5VTEwsIGV4cGVjdGVkLAoJICAgIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChkZWYpOwogICAgfQogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgLyoKICAgICogVE9ETzogUmVzdHJpY3QgdGhlIG1heGltYWwgdmFsdWUgdG8gSW50ZWdlci4KICAgICovCiAgICBpZiAoKCpjdXIgIT0gMCkgfHwgKHJldCA8IG1pbikgfHwgKChtYXggIT0gLTEpICYmIChyZXQgPiBtYXgpKSkgewoJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCSAgICAvKiBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywgKi8KCSAgICBOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgTlVMTCwgZXhwZWN0ZWQsCgkgICAgdmFsLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGRlZik7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG93bmVyRGVzOiAgb3duZXIgZGVzaWduYXRpb24KICogQG93bmVySXRlbTogIHRoZSBvd25lciBhcyBhIHNjaGVtYSBpdGVtCiAqIEBub2RlOiB0aGUgbm9kZSBob2xkaW5nIHRoZSB2YWx1ZQogKgogKiBDb252ZXJ0cyBhIGJvb2xlYW4gc3RyaW5nIHZhbHVlIGludG8gMSBvciAwLgogKgogKiBSZXR1cm5zIDAgb3IgMS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUEdldEJvb2xOb2RlVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAkJCSAgIAoJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbHVlID0gTlVMTDsKICAgIGludCByZXMgPSAwOwogICAKICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7CiAgICAvKiAKICAgICogMy4yLjIuMSBMZXhpY2FsIHJlcHJlc2VudGF0aW9uCiAgICAqIEFuIGluc3RhbmNlIG9mIGEgZGF0YXR5cGUgdGhhdCBpcyBkZWZpbmVkIGFzILdib29sZWFutyAKICAgICogY2FuIGhhdmUgdGhlIGZvbGxvd2luZyBsZWdhbCBsaXRlcmFscyB7dHJ1ZSwgZmFsc2UsIDEsIDB9LgogICAgKi8KICAgIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICByZXMgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgdmFsdWUsIEJBRF9DQVNUICJmYWxzZSIpKQogICAgICAgIHJlcyA9IDA7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjEiKSkKCXJlcyA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgQkFEX0NBU1QgIjAiKSkKICAgICAgICByZXMgPSAwOyAgICAKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQk9PTEVBTiwKCSAgICBvd25lckRlcywgb3duZXJJdGVtLCBub2RlLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwgCgkgICAgIigxIHwgMCB8IHRydWUgfCBmYWxzZSkiLCBCQURfQ0FTVCB2YWx1ZSwgCgkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXMpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEV2YWx1YXRlIGlmIGEgYm9vbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqIDEgaWYgZm91bmQgdG8gYmUgdHJ1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRCb29sZWFuUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGludCBkZWYpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbDsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoZGVmKTsKICAgIC8qIAogICAgKiAzLjIuMi4xIExleGljYWwgcmVwcmVzZW50YXRpb24KICAgICogQW4gaW5zdGFuY2Ugb2YgYSBkYXRhdHlwZSB0aGF0IGlzIGRlZmluZWQgYXMgt2Jvb2xlYW63IAogICAgKiBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGxlZ2FsIGxpdGVyYWxzIHt0cnVlLCBmYWxzZSwgMSwgMH0uCiAgICAqLwogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiMSIpKQoJZGVmID0gMTsKICAgIGVsc2UgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgIjAiKSkKICAgICAgICBkZWYgPSAwOyAgICAKICAgIGVsc2UgeyAgICAKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0JPT0xFQU4sCgkgICAgb3duZXJEZXMsIG93bmVySXRlbSwgCgkgICAgKHhtbE5vZGVQdHIpIHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsIG5hbWUpLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0JPT0xFQU4pLCAKCSAgICAiKDEgfCAwIHwgdHJ1ZSB8IGZhbHNlKSIsIHZhbCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKGRlZik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKgkJU2hlbWEgZXh0cmFjdGlvbiBmcm9tIGFuIEluZm9zZXQJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCAKCQkJCQkJICBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUFsbCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCQkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUNob2ljZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKTsKCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZToKICogCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50CiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IG93bmVyIGlmIGV4aXN0ZW50CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgbm9kZSBiZWluZyB2YWxpZGF0ZWQKICogQHZhbHVlOiB0aGUgdmFsdWUKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0IAogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlLgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGludGVybmFsbHkgZm9yIHZhbGlkYXRpb24KICogb2Ygc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZXMgZHVyaW5nIHBhcnNpbmcgb2YgdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbENoYXIgKipvd25lckRlcywKCQkJICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCQkJICAgCgkJCSAgIHhtbEF0dHJQdHIgYXR0ciwKCQkJICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgCiAgICBpbnQgcmV0ID0gMDsgCgogICAgLyoKICAgICogTk9URTogU2hvdWxkIHdlIG1vdmUgdGhpcyB0byB4bWxzY2hlbWF0eXBlcy5jPyBIbW0sIGJ1dCB0aGlzCiAgICAqIG9uZSBpcyByZWFsbHkgbWVhbnQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5LCBzbyBiZXR0ZXIgbm90LgogICAgKi8gICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkgfHwgKGF0dHIgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsgICAKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQVmFsQXR0ck5vZGVWYWx1ZSwgdGhlIGdpdmVuICIKCSAgICAidHlwZSAnJXMnIGlzIG5vdCBhIGJ1aWx0LWluIHR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgc3dpdGNoICh0eXBlLT5idWlsdEluVHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BU19OQ05BTUU6CgljYXNlIFhNTF9TQ0hFTUFTX1FOQU1FOgoJY2FzZSBYTUxfU0NIRU1BU19BTllVUkk6CgljYXNlIFhNTF9TQ0hFTUFTX1RPS0VOOgoJY2FzZSBYTUxfU0NIRU1BU19MQU5HVUFHRToKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZSh0eXBlLCB2YWx1ZSwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGJyZWFrOwoKCS8qCgljYXNlIFhNTF9TQ0hFTUFTX05DTkFNRToKCSAgICByZXQgPSB4bWxWYWxpZGF0ZU5DTmFtZSh2YWx1ZSwgMSk7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFTX1FOQU1FOgoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUHZhbHVlQXR0ck5vZGUsIHVzZSAiCgkJInRoZSBmdW5jdGlvbiB4bWxTY2hlbWFFeHRyYWN0U2NoZW1hUU5hbWVQcm9wdmFsdWVpZGF0ZWQgIgoJCSJmb3IgZXh0cmFjdGluZyBRTmFtZSB2YWx1ZXVlcyBpbnN0ZWFkLlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZVVJJOgoJICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7CgkJeG1sVVJJUHRyIHVyaSA9IHhtbFBhcnNlVVJJKChjb25zdCBjaGFyICopIHZhbHVlKTsKCQlpZiAodXJpID09IE5VTEwpCgkJICAgIHJldCA9IDE7CgkJZWxzZQoJCSAgICB4bWxGcmVlVVJJKHVyaSk7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BU19UT0tFTjogewoJICAgIGNvbnN0IHhtbENoYXIgKmN1ciA9IHZhbHVlOwoKCQlpZiAoSVNfQkxBTktfQ0goKmN1cikpIHsKICAgICAgICAgICAgICAgICAgICByZXQgPSAxOwkJICAgICAgIAoJCX0gZWxzZSB3aGlsZSAoKmN1ciAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCgqY3VyID09IDB4ZCkgfHwgKCpjdXIgPT0gMHhhKSB8fCAoKmN1ciA9PSAweDkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IDE7CgkJCWJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKmN1ciA9PSAnICcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKmN1ciA9PSAwKSB8fCAoKmN1ciA9PSAnICcpKSB7CgkJCSAgICByZXQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjdXIrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BU19MQU5HVUFHRToKCSAgICBpZiAoeG1sQ2hlY2tMYW5ndWFnZUlEKHZhbHVlKSAhPSAxKSAKCQlyZXQgPSAxOwoJICAgIGJyZWFrOwoJKi8KCWRlZmF1bHQ6IHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUsICIKCQkgICAgInZhbHVlaWRhdGlvbiB1c2luZyB0aGUgdHlwZSAnJXMnIGlzIG5vdCBpbXBsZW1lbnRlZCAiCgkJICAgICJ5ZXQuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0gICAgICAgICAgICAgIAogICAgLyoKICAgICogVE9ETzogU2hvdWxkIHdlIHVzZSB0aGUgUzRTIGVycm9yIGNvZGVzIGluc3RlYWQ/CiAgICAqLwogICAgaWYgKHJldCA8IDApIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUFZhbEF0dHJOb2RlVmFsdWUsICIKCSAgICAiZmFpbGVkIHRvIHZhbGlkYXRlIGEgc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZS5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgeyAJCglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewkgICAKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzIsIAoJCW93bmVyRGVzLCBvd25lckl0ZW0sICh4bWxOb2RlUHRyKSBhdHRyLCAKCQl0eXBlLCBOVUxMLCB2YWx1ZSwgCgkJTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMik7Cgl9IGVsc2UgewkgICAgCgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLCAKCQlvd25lckRlcywgb3duZXJJdGVtLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJdHlwZSwgTlVMTCwgdmFsdWUsIAoJCU5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybihYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEpOwoJfQkKICAgIH0gICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ck5vZGU6CiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBwYXJlbnQgZWxlbWVudAogKiBAb3duZXJJdGVtOiB0aGUgc2NoZW1hIG9iamVjdCBvd25lciBpZiBleGlzdGVudAogKiBAYXR0cjogIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUgYmVpbmcgdmFsaWRhdGVkCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdAogKiBAdmFsdWU6IHRoZSByZXN1bHRpbmcgdmFsdWUgaWYgYW55CiAqCiAqIEV4dHJhY3RzIGFuZCB2YWxpZGF0ZXMgYSB2YWx1ZSBhZ2FpbnN0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlLgogKiBUaGlzIG9uZSBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGludGVybmFsbHkgZm9yIHZhbGlkYXRpb24KICogb2Ygc2NoZW1hIGF0dHJpYnV0ZSB2YWx1ZXMgZHVyaW5nIHBhcnNpbmcgb2YgdGhlIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ck5vZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAkJCSAgIAoJCQkgICB4bWxBdHRyUHRyIGF0dHIsCQkJICAgCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlKQp7ICAgIAogICAgY29uc3QgeG1sQ2hhciAqdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSB8fCAoYXR0ciA9PSBOVUxMKSkKCXJldHVybiAoLTEpOyAgIAogICAgICAgCiAgICB2YWwgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCSp2YWx1ZSA9IHZhbDsKCiAgICByZXR1cm4gKHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIG93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsCgl2YWwsIHR5cGUpKTsgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0cjoKICogCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5vZGU6IHRoZSBlbGVtZW50IG5vZGUgb2YgdGhlIGF0dHJpYnV0ZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgcGFyZW50IGVsZW1lbnQKICogQG93bmVySXRlbTogdGhlIHNjaGVtYSBvYmplY3Qgb3duZXIgaWYgZXhpc3RlbnQKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBzY2hlbWEgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBidWlsdC1pbiB0eXBlIHRvIGJlIHZhbGlkYXRlZCBhZ2FpbnN0CiAqIEB2YWx1ZTogdGhlIHJlc3VsdGluZyB2YWx1ZSBpZiBhbnkKICoKICogRXh0cmFjdHMgYW5kIHZhbGlkYXRlcyBhIHZhbHVlIGFnYWluc3QgdGhlIGdpdmVuIGJ1aWx0LWluIHR5cGUuCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBmb3IgdmFsaWRhdGlvbgogKiBvZiBzY2hlbWEgYXR0cmlidXRlIHZhbHVlcyBkdXJpbmcgcGFyc2luZyBvZiB0aGUgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBWYWxBdHRyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwJCSAgICAgICAKCQkgICAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkgICAgICAgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsCgkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlKQp7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICAqdmFsdWUgPSBOVUxMOwoJcmV0dXJuICgtMSk7ICAgCiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQVmFsQXR0ciwgdGhlIGdpdmVuICIKCSAgICAidHlwZSAnJXMnIGlzIG5vdCBhIGJ1aWx0LWluIHR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUob3duZXJFbGVtLCBuYW1lKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCWlmICh2YWx1ZSAhPSBOVUxMKQoJICAgICp2YWx1ZSA9IE5VTEw7CglyZXR1cm4gKDApOwogICAgfSAgICAKICAgIHJldHVybiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIG93bmVyRGVzLCBvd25lckl0ZW0sIGF0dHIsIAoJdHlwZSwgdmFsdWUpKTsKfQovKioKICogeG1sU2NoZW1hUGFyc2VBdHRyRGVjbHM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHR5cGU6ICB0aGUgaG9zdGluZyB0eXBlCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBhdHRyRGVjbHMgZGVjbGFyYXRpb24gY29ycmVzcG9uZGluZyB0bwogKiA8IUVOVElUWSAlIGF0dHJEZWNscyAgCiAqICAgICAgICcoKCVhdHRyaWJ1dGU7fCAlYXR0cmlidXRlR3JvdXA7KSosKCVhbnlBdHRyaWJ1dGU7KT8pJz4KICovCnN0YXRpYyB4bWxOb2RlUHRyCnhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZCwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgbGFzdGF0dHIsIGF0dHI7CgogICAgbGFzdGF0dHIgPSBOVUxMOwogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkpIHsKICAgICAgICBhdHRyID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKICAgICAgICAgICAgYXR0ciA9IHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewogICAgICAgICAgICBhdHRyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfQogICAgICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3RhdHRyID09IE5VTEwpIHsKCQlpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApCgkJICAgICgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIHR5cGUpLT5hdHRyaWJ1dGVzID0gYXR0cjsKCQllbHNlCiAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzID0gYXR0cjsKICAgICAgICAgICAgICAgIGxhc3RhdHRyID0gYXR0cjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3RhdHRyLT5uZXh0ID0gYXR0cjsKICAgICAgICAgICAgICAgIGxhc3RhdHRyID0gYXR0cjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSAgICAKICAgIHJldHVybiAoY2hpbGQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBiYXJrZWQgPSAwOwoKICAgIC8qCiAgICAqIElORk86IFM0UyBjb21wbGV0ZWQuCiAgICAqLwogICAgLyoKICAgICogaWQgPSBJRAogICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CiAgICAqIENvbnRlbnQ6IChhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqCiAgICAqLwogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldCA9IHhtbFNjaGVtYU5ld0Fubm90KGN0eHQsIG5vZGUpOwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJiAKCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSkgfHwKCSAgICAoKGF0dHItPm5zICE9IE5VTEwpICYmIAoJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKSB7CgkgICAgCgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXBwaW5mbyIpKSB7CgkgICAgLyogVE9ETzogbWFrZSBhdmFpbGFibGUgdGhlIGNvbnRlbnQgb2YgImFwcGluZm8iLiAqLwoJICAgIC8qIAoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoKChhdHRyLT5ucyA9PSBOVUxMKSAmJiAKCQkgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInNvdXJjZSIpKSkgfHwKCQkgICAgICgoYXR0ci0+bnMgIT0gTlVMTCkgJiYgCgkJICAgICAgeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkpIHsKCgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCU5VTEwsIE5VTEwsIGF0dHIpOwoJCX0KCQlhdHRyID0gYXR0ci0+bmV4dDsKCSAgICB9CgkgICAgeG1sU2NoZW1hUFZhbEF0dHIoY3R4dCwgTlVMTCwgTlVMTCwgY2hpbGQsICJzb3VyY2UiLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCBOVUxMKTsJICAgIAoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImRvY3VtZW50YXRpb24iKSkgewoJICAgIC8qIFRPRE86IG1ha2UgYXZhaWxhYmxlIHRoZSBjb250ZW50IG9mICJkb2N1bWVudGF0aW9uIi4gKi8KCSAgICAvKgoJICAgICogc291cmNlID0gYW55VVJJCgkgICAgKiB7YW55IGF0dHJpYnV0ZXMgd2l0aCBub24tc2NoZW1hIG5hbWVzcGFjZSAuIC4gLn0+CgkgICAgKiBDb250ZW50OiAoe2FueX0pKgoJICAgICovCgkgICAgYXR0ciA9IGNoaWxkLT5wcm9wZXJ0aWVzOwoJICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCQlpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzb3VyY2UiKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwKCQkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykgfHwKCQkJKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJsYW5nIikgJiYKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgWE1MX1hNTF9OQU1FU1BBQ0UpKSkpIHsKCQkJCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CgkJICAgIH0KCQl9CgkJYXR0ciA9IGF0dHItPm5leHQ7CgkgICAgfQoJICAgIC8qCgkgICAgKiBBdHRyaWJ1dGUgInhtbDpsYW5nIi4KCSAgICAqLwoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZU5zKGNoaWxkLCAoY29uc3QgY2hhciAqKSBYTUxfWE1MX05BTUVTUEFDRSwgImxhbmciKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKQoJCXhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0xBTkdVQUdFKSwgTlVMTCk7CSAgICAKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIHsKCSAgICBpZiAoIWJhcmtlZCkKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhcHBpbmZvIHwgZG9jdW1lbnRhdGlvbikqIik7CgkgICAgYmFya2VkID0gMTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgfQogICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUZhY2V0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBGYWNldCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIG5ldyB0eXBlIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFGYWNldFB0cgp4bWxTY2hlbWFQYXJzZUZhY2V0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWx1ZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGZhY2V0ID0geG1sU2NoZW1hTmV3RmFjZXQoKTsKICAgIGlmIChmYWNldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBmYWNldCIsIG5vZGUpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBmYWNldC0+bm9kZSA9IG5vZGU7CiAgICB2YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInZhbHVlIik7CiAgICBpZiAodmFsdWUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9GQUNFVF9OT19WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAiRmFjZXQgJXMgaGFzIG5vIHZhbHVlXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5JbmNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWluRXhjbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtYXhFeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAidG90YWxEaWdpdHMiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJmcmFjdGlvbkRpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgInBhdHRlcm4iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImVudW1lcmF0aW9uIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT047CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAid2hpdGVTcGFjZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heExlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5MZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg7CiAgICB9IGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gZmFjZXQgdHlwZSAlc1xuIiwgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgeG1sU2NoZW1hRnJlZUZhY2V0KGZhY2V0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLAoJKHhtbFNjaGVtYVR5cGVQdHIpIGZhY2V0LCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIGZhY2V0LT52YWx1ZSA9IHZhbHVlOwogICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsKCWNvbnN0IHhtbENoYXIgKmZpeGVkOwoKCWZpeGVkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKCWlmIChmaXhlZCAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGZpeGVkLCBCQURfQ0FTVCAidHJ1ZSIpKQoJCWZhY2V0LT5maXhlZCA9IDE7Cgl9CiAgICB9ICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgZmFjZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgdW5leHBlY3RlZCBjaGlsZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHdpbGRjOiAgdGhlIHdpbGRjYXJkLCBhbHJlYWR5IGNyZWF0ZWQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgdGhlIGF0dHJpYnV0ZSAicHJvY2Vzc0NvbnRlbnRzIiBhbmQgIm5hbWVzcGFjZSIKICogb2YgYSB4c2Q6YW55QXR0cmlidXRlIGFuZCB4c2Q6YW55LgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgMCBpZiBldmVyeXRoaW5nIGdvZXMgZmluZSwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIGlmIHNvbWV0aGluZyBpcyBub3QgdmFsaWQgYW5kIC0xIGlmIGFuIGludGVybmFsIGVycm9yIG9jY3Vycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VXaWxkY2FyZE5zKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkYywKCQkJIHhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqcGMsICpucywgKmRpY3Ruc0l0ZW07CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbENoYXIgKm5zSXRlbTsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgdG1wLCBsYXN0TnMgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgCiAgICBwYyA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInByb2Nlc3NDb250ZW50cyIpOwogICAgaWYgKChwYyA9PSBOVUxMKQogICAgICAgIHx8ICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInN0cmljdCIpKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU1RSSUNUOwogICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChwYywgKGNvbnN0IHhtbENoYXIgKikgInNraXAiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocGMsIChjb25zdCB4bWxDaGFyICopICJsYXgiKSkgewogICAgICAgIHdpbGRjLT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfTEFYOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1BST0NFU1NDT05URU5UX0NISUxELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgTlVMTCwgIihzdHJpY3QgfCBza2lwIHwgbGF4KSIsIHBjLCAKCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICB3aWxkYy0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDsKCXJldCA9IFhNTF9TQ0hFTUFQX1VOS05PV05fUFJPQ0VTU0NPTlRFTlRfQ0hJTEQ7CiAgICB9CiAgICAvKgogICAgICogQnVpbGQgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cy4KICAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lc3BhY2UiKTsKICAgIG5zID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwogICAgaWYgKChucyA9PSBOVUxMKSB8fCAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI2FueSIpKSkKCXdpbGRjLT5hbnkgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwobnMsIEJBRF9DQVNUICIjI290aGVyIikpIHsKCXdpbGRjLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHdpbGRjLT5uZWdOc1NldCA9PSBOVUxMKSB7CSAgICAJICAgIAoJICAgIHJldHVybiAoLTEpOwoJfQoJd2lsZGMtPm5lZ05zU2V0LT52YWx1ZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOyAKICAgIH0gZWxzZSB7ICAgIAoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyOwoKCWN1ciA9IG5zOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgbnNJdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7ICAgIAkgICAgCgkgICAgaWYgKCh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI290aGVyIikpIHx8CgkJICAgICh4bWxTdHJFcXVhbChuc0l0ZW0sIEJBRF9DQVNUICIjI2FueSIpKSkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9XSUxEQ0FSRF9JTlZBTElEX05TX01FTUJFUiwKCQkgICAgTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsIAoJCSAgICAiKCgjI2FueSB8ICMjb3RoZXIpIHwgTGlzdCBvZiAoYW55VVJJIHwgIgoJCSAgICAiKCMjdGFyZ2V0TmFtZXNwYWNlIHwgIyNsb2NhbCkpKSIsIAoJCSAgICBuc0l0ZW0sIE5VTEwsIE5VTEwsIE5VTEwpOwoJCXJldCA9IFhNTF9TQ0hFTUFQX1dJTERDQVJEX0lOVkFMSURfTlNfTUVNQkVSOwoJICAgIH0gZWxzZSB7CgkJaWYgKHhtbFN0ckVxdWFsKG5zSXRlbSwgQkFEX0NBU1QgIiMjdGFyZ2V0TmFtZXNwYWNlIikpIHsKCQkgICAgZGljdG5zSXRlbSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobnNJdGVtLCBCQURfQ0FTVCAiIyNsb2NhbCIpKSB7CgkJICAgIGRpY3Ruc0l0ZW0gPSBOVUxMOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogVmFsaWRhdGUgdGhlIGl0ZW0gKGFueVVSSSkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVBWYWxBdHRyTm9kZVZhbHVlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsIAoJCQluc0l0ZW0sIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSkpOwoJCSAgICBkaWN0bnNJdGVtID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuc0l0ZW0sIC0xKTsKCQl9CgkJLyoKCQkqIEF2b2lkIGR1YmxpY2F0ZSBuYW1lc3BhY2VzLgoJCSovCgkJdG1wID0gd2lsZGMtPm5zU2V0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewoJCSAgICBpZiAoZGljdG5zSXRlbSA9PSB0bXAtPnZhbHVlKQoJCQlicmVhazsKCQkgICAgdG1wID0gdG1wLT5uZXh0OwoJCX0KCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCQl4bWxGcmVlKG5zSXRlbSk7CQkJCgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIHRtcC0+dmFsdWUgPSBkaWN0bnNJdGVtOwoJCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJCSAgICBpZiAod2lsZGMtPm5zU2V0ID09IE5VTEwpIAoJCQl3aWxkYy0+bnNTZXQgPSB0bXA7CgkJICAgIGVsc2UKCQkJbGFzdE5zLT5uZXh0ID0gdG1wOwoJCSAgICBsYXN0TnMgPSB0bXA7CgkJfQoKCSAgICB9CQoJICAgIHhtbEZyZWUobnNJdGVtKTsKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOyAgICAKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKc3RhdGljIGludAp4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwgCgkJCQkgeG1sTm9kZVB0ciBub2RlLAoJCQkJIGludCBtaW5PY2N1cnMsCgkJCQkgaW50IG1heE9jY3VycykgewoKICAgIGlmIChtYXhPY2N1cnMgIT0gVU5CT1VOREVEKSB7CgkvKgoJKiBUT0RPOiBNYWJ5IHdlIHNob3VsZCBiZXR0ZXIgbm90IGNyZWF0ZSB0aGUgcGFydGljbGUsIAoJKiBpZiBtaW4vbWF4IGlzIGludmFsaWQsIHNpbmNlIGl0IGNvdWxkIGNvbmZ1c2UgdGhlIGJ1aWxkIG9mIHRoZSAKCSogY29udGVudCBtb2RlbC4KCSovCgkvKiAKCSogMy45LjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBQYXJ0aWNsZSBDb3JyZWN0CgkqCgkqLwoJaWYgKG1heE9jY3VycyA8IDEpIHsgCgkgICAgLyogCgkgICAgKiAyLjIge21heCBvY2N1cnN9IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzIsCgkJTlVMTCwgaXRlbSwgeG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm1heE9jY3VycyIpLAoJCSJUaGUgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMSIpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUF9QUk9QU19DT1JSRUNUXzJfMik7Cgl9IGVsc2UgaWYgKG1pbk9jY3VycyA+IG1heE9jY3VycykgewoJICAgIC8qCgkgICAgKiAyLjEge21pbiBvY2N1cnN9IG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB7bWF4IG9jY3Vyc30uCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzEsIAoJCU5VTEwsIGl0ZW0sIHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJtaW5PY2N1cnMiKSwKCQkiVGhlIHZhbHVlIG11c3Qgbm90IGJlIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUgb2YgJ21heE9jY3VycyciKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1BfUFJPUFNfQ09SUkVDVF8yXzEpOwoJfQogICAgfQkKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQW55IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VBbnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRjOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBtYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAKCSIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgbWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAKCSJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIGlmICgobWluT2NjdXJzID09IDApICYmIChtYXhPY2N1cnMgPT0gMCkpCglyZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiI2FueSVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWTsgICAgCiAgICAKICAgIC8qCiAgICAqIFRPRE86IFVzZSBhIHBhcnRpY2xlIGNvbXBvbmVudCBoZXJlLgogICAgKi8KICAgIHdpbGRjID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCk7CiAgICAvKgogICAgKiBDaGVjayBtaW4vbWF4IHNhbml0eS4KICAgICovCiAgICB0eXBlLT5tYXhPY2N1cnMgPSBtYXhPY2N1cnM7CiAgICB0eXBlLT5taW5PY2N1cnMgPSBtaW5PY2N1cnM7CiAgICB4bWxTY2hlbWFQQ2hlY2tQYXJ0aWNsZUNvcnJlY3RfMihjdHh0LCB0eXBlLCAKCSAgICBub2RlLCB0eXBlLT5taW5PY2N1cnMsIHR5cGUtPm1heE9jY3Vycyk7ICAgIAogICAgLyoKICAgICogVGhpcyBpcyBub3QgbmljZSwgc2luY2UgaXQgaXMgd29uJ3QgYmUgdXNlZCBhcyBhIGF0dHJpYnV0ZSB3aWxkY2FyZCwKICAgICogYnV0IGJldHRlciB0aGFuIGFkZGluZyBhIGZpZWxkIHRvIHRoZSBzdHJ1Y3R1cmUuCiAgICAqLwogICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB3aWxkYzsKICAgIHhtbFNjaGVtYVBhcnNlV2lsZGNhcmROcyhjdHh0LCBzY2hlbWEsIHdpbGRjLCBub2RlKTsgICAgCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOyAgICAKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1NFUVVFTkNFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTZXF1ZW5jZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZU5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBOb3RhdGlvbiBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYVBhcnNlTm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9OT1RBVElPTl9OT19OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICJOb3RhdGlvbiBoYXMgbm8gbmFtZVxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldCA9IHhtbFNjaGVtYUFkZE5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgbmFtZSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT50YXJnZXROYW1lc3BhY2UgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsCglub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9OT1RBVElPTl9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAibm90YXRpb24gJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgbmFtZSwgTlVMTCk7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEFueUF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIGEgd2lsZGNhcmQgb3IgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0KTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJwcm9jZXNzQ29udGVudHMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogUGFyc2UgdGhlIG5hbWVzcGFjZSBsaXN0LgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFQYXJzZVdpbGRjYXJkTnMoY3R4dCwgc2NoZW1hLCByZXQsIG5vZGUpICE9IDApIHsKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZChyZXQpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0gIAogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCgovKioKICogeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJyaWJ1dGUgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICphdHRyVmFsdWU7CiAgICB4bWxDaGFyICpyZXBOYW1lID0gTlVMTDsgLyogVGhlIHJlcG9ydGVkIGRlc2lnbmF0aW9uLiAqLwogICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOyAgICAKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CiAgICBpbnQgaXNSZWYgPSAwOwoKICAgIC8qCiAgICAgKiBOb3RlIHRoYXQgdGhlIHczYyBzcGVjIGFzc3VtZXMgdGhlIHNjaGVtYSB0byBiZSB2YWxpZGF0ZWQgd2l0aCBzY2hlbWEKICAgICAqIGZvciBzY2hlbWFzIGJlZm9yZWhhbmQuCiAgICAgKgogICAgICogMy4yLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBBdHRyaWJ1dGUgRGVjbGFyYXRpb25zCiAgICAgKi8KCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJyZWYiKTsKICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCiAgICBpZiAoKGF0dHIgPT0gTlVMTCkgJiYgKG5hbWVBdHRyID09IE5VTEwpKSB7CgkvKiAKCSogMy4yLjMgOiAzLjEKCSogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJKi8KCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMSwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIE5VTEwsIG5vZGUsIE5VTEwsIAoJICAgICJPbmUgb2YgdGhlIGF0dHJpYnV0ZXMgJ3JlZicgb3IgJ25hbWUnIG11c3QgYmUgcHJlc2VudCIpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICgodG9wTGV2ZWwpIHx8IChhdHRyID09IE5VTEwpKSB7CglpZiAobmFtZUF0dHIgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCAKCQkoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNBdHRyRGVjbCwgTlVMTCwgbm9kZSwgCgkJIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQkKICAgIH0gZWxzZQoJaXNSZWYgPSAxOwkKICAgIAogICAgaWYgKGlzUmVmKSB7CgljaGFyIGJ1Zls1MF07IAoJY29uc3QgeG1sQ2hhciAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTCwgKnJlZlByZWZpeCA9IE5VTEw7IAoKCS8qCgkqIFBhcnNlIGFzIGF0dHJpYnV0ZSByZWZlcmVuY2UuCgkqLwkJCglpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLCAKCSAgICAoeG1sQ2hhciAqKikgJnhtbFNjaGVtYUVsZW1EZXNBdHRyUmVmLCBOVUxMLCBhdHRyLCAmcmVmTnMsIAoJICAgICZyZWZQcmVmaXgsICZyZWYpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQkKICAgICAgICBzbnByaW50ZihidWYsIDQ5LCAiI2FSZWYlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgICAgIG5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSwgMCk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CglyZXQtPm5vZGUgPSBub2RlOwoJcmV0LT5yZWZOcyA9IHJlZk5zOwoJcmV0LT5yZWZQcmVmaXggPSByZWZQcmVmaXg7CglyZXQtPnJlZiA9IHJlZjsJCQoJLyoKCXhtbFNjaGVtYUZvcm1hdFR5cGVSZXAoJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIE5VTEwsIE5VTEwpOwoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKQoJICAgIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMSwgCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5hbWVBdHRyLCAKCQkicmVmIiwgIm5hbWUiKTsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSB8fAoJCSAgICB4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSB7CgkJICAgIC8qIAoJCSAgICAqIDMuMi4zIDogMy4yCgkJICAgICogSWYgcmVmIGlzIHByZXNlbnQsIHRoZW4gYWxsIG9mIDxzaW1wbGVUeXBlPiwKCQkgICAgKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LiAKCQkgICAgKi8KCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzNfMiwgJnJlcE5hbWUsIAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCQl9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJ1c2UiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJiAKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYgCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCSAgICAKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsJCQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0JCiAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHhtbENoYXIgKm5zID0gTlVMTDsKCQoJLyoKCSogUGFyc2UgYXMgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8JCQkKCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wsIE5VTEwsIG5hbWVBdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgkvKgoJeG1sU2NoZW1hRm9ybWF0VHlwZVJlcCgmcmVwTmFtZSwgTlVMTCwgeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsLCBuYW1lKTsKCSovCgkvKiAKCSogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiB4bWxucyBOb3QgQWxsb3dlZCAKCSovCglpZiAoeG1sU3RyRXF1YWwobmFtZSwgQkFEX0NBU1QgInhtbG5zIikpIHsKCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9OT19YTUxOUywgCgkJJnJlcE5hbWUsIE5VTEwsICh4bWxOb2RlUHRyKSBuYW1lQXR0ciwgCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgIk5DTmFtZSIsIE5VTEwsCgkJIlRoZSB2YWx1ZSBtdXN0IG5vdCBtYXRjaCAneG1sbnMnIiwgCgkJTlVMTCwgTlVMTCk7CSAgICAKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JICAgIAoJLyogCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlIAoJKi8JCglpZiAodG9wTGV2ZWwpIHsKCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJfSBlbHNlIHsKCSAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgImZvcm0iKTsKCSAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJCQkmcmVwTmFtZSwgTlVMTCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCQlOVUxMLCAiKHF1YWxpZmllZCB8IHVucXVhbGlmaWVkKSIsIAoJCQlhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwkJCQoJCX0KCSAgICB9IGVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikKCQlucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwkJCgl9CQogICAgICAgIHJldCA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIG5hbWUsIG5zLCBub2RlLCB0b3BMZXZlbCk7CglpZiAocmV0ID09IE5VTEwpIHsKCSAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJCXhtbEZyZWUocmVwTmFtZSk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU7CglyZXQtPm5vZGUgPSBub2RlOwkKCWlmICh0b3BMZXZlbCkKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMOwoJLyogCgkqIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeHNpOiBOb3QgQWxsb3dlZCAKCSovCQoJaWYgKHhtbFN0ckVxdWFsKHJldC0+dGFyZ2V0TmFtZXNwYWNlLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfTk9fWFNJLAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLAoJCSJUaGUgdGFyZ2V0IG5hbWVzcGFjZSBtdXN0IG5vdCBtYXRjaCAnJXMnIiwgCgkJeG1sU2NoZW1hSW5zdGFuY2VOcyk7CSAgICAgICAgCgl9CgkvKgoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLiAKCSovCQoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsJCQoJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJiAKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZGVmYXVsdCIpKSAmJiAJCQkJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpeGVkIikpICYmCQkgICAgCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSkgewoJCSAgICBpZiAoKHRvcExldmVsKSB8fAkJCQkJCSAgICAJCQoJCSAgICAgICAgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZvcm0iKSkgJiYKCQkJICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInVzZSIpKSkpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwkKCQkgICAgfQoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCXhtbFNjaGVtYVBWYWxBdHRyUU5hbWUoY3R4dCwgc2NoZW1hLCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCSAgICBub2RlLCAidHlwZSIsICZyZXQtPnR5cGVOcywgTlVMTCwgJnJldC0+dHlwZU5hbWUpOwogICAgfSAgICAgICAgCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsCglub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAiZml4ZWQiLgogICAgKi8KICAgIHJldC0+ZGVmVmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwogICAgaWYgKHJldC0+ZGVmVmFsdWUgIT0gTlVMTCkKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9GSVhFRDsKICAgIC8qIAogICAgKiBBdHRyaWJ1dGUgImRlZmF1bHQiLgogICAgKi8KICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZGVmYXVsdCIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJLyogCgkqIDMuMi4zIDogMQoJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJKi8KCWlmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgewoJICAgIHhtbFNjaGVtYVBNdXR1YWxFeGNsQXR0ckVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzEsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIsICJkZWZhdWx0IiwgImZpeGVkIik7Cgl9IGVsc2UKCSAgICByZXQtPmRlZlZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkJCiAgICB9ICAgIAogICAgaWYgKHRvcExldmVsID09IDApIHsKCS8qIAoJKiBBdHRyaWJ1dGUgInVzZSIuIAoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidXNlIik7CglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJvcHRpb25hbCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CgkgICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAicHJvaGliaXRlZCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRDsKCSAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsdWUsIEJBRF9DQVNUICJyZXF1aXJlZCIpKQoJCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQ7CgkgICAgZWxzZQoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfVVNFLCAKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgTlVMTCwgIihvcHRpb25hbCB8IHByb2hpYml0ZWQgfCByZXF1aXJlZCkiLCAKCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsJCQkJCgl9IGVsc2UKCSAgICByZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMOwoJLyogCgkqIDMuMi4zIDogMgoJKiBJZiBkZWZhdWx0IGFuZCB1c2UgYXJlIGJvdGggcHJlc2VudCwgdXNlIG11c3QgaGF2ZQoJKiB0aGUgYWN0dWFsIHZhbHVlIG9wdGlvbmFsLgoJKi8KCWlmICgocmV0LT5vY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmIAoJICAgIChyZXQtPmRlZlZhbHVlICE9IE5VTEwpICYmIAoJICAgICgocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpID09IDApKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX0FUVFJJQlVURV8yLCAKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCU5VTEwsICIob3B0aW9uYWwgfCBwcm9oaWJpdGVkIHwgcmVxdWlyZWQpIiwgTlVMTCwgCgkJIlRoZSB2YWx1ZSBtdXN0IGJlICdvcHRpb25hbCcgaWYgdGhlIGF0dHJpYnV0ZSAiCgkJIidkZWZhdWx0JyBpcyBwcmVzZW50IGFzIHdlbGwiLCBOVUxMLCBOVUxMKTsJICAgIAoJfQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gICAgCiAgICBpZiAoaXNSZWYpIHsKCWlmIChjaGlsZCAhPSBOVUxMKSB7CSAgICAKCSAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKQoJCS8qIAoJCSogMy4yLjMgOiAzLjIKCQkqIElmIHJlZiBpcyBwcmVzZW50LCB0aGVuIGFsbCBvZiA8c2ltcGxlVHlwZT4sCgkJKiBmb3JtIGFuZCB0eXBlIG11c3QgYmUgYWJzZW50LiAKCQkqLwoJCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIFhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfM18yLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJICAgICIoYW5ub3RhdGlvbj8pIik7CgkgICAgZWxzZSAKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSAgICAiKGFubm90YXRpb24/KSIpOyAgCgl9CiAgICB9IGVsc2UgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmIChyZXQtPnR5cGVOYW1lICE9IE5VTEwpIHsKCQkvKiAKCQkqIDMuMi4zIDogNAoJCSogdHlwZSBhbmQgPHNpbXBsZVR5cGU+IG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4gCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCBYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFXzQsCgkJICAgICZyZXBOYW1lLCAgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICd0eXBlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkJICAgICJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIHNpbXBsZVR5cGU/KSIpOwogICAgfQogICAgLyoKICAgICogQ2xlYW51cC4KICAgICovCiAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJeG1sRnJlZShyZXBOYW1lKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEF0dHJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGVHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgIGludCB0b3BMZXZlbCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBuYW1lQXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZiIpOyAgIAogICAgaWYgKCh0b3BMZXZlbCkgfHwgKGF0dHIgPT0gTlVMTCkpIHsKCS8qCgkqIFBhcnNlIGFzIGFuIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uLgoJKiBOb3RlIHRoYXQgdGhvc2UgYXJlIGFsbG93ZWQgYXQgdG9wIGxldmVsIG9ubHkuCgkqLwoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCU5VTEwsIE5VTEwsIG5vZGUsICJuYW1lIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbmFtZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBuYW1lQXR0cik7CgkvKgoJKiBUaGUgbmFtZSBpcyBjcnVjaWFsLCBleGl0IGlmIGludmFsaWQuIAoJKi8KCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwKCSAgICBOVUxMLCBOVUxMLCBuYW1lQXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfTkNOQU1FKSwgJm5hbWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBuYW1lLCBub2RlKTsKCWlmIChyZXQgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOwoJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMOwoJcmV0LT5ub2RlID0gbm9kZTsKCXJldC0+dGFyZ2V0TmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICB9IGVsc2UgeyAgICAKCWNoYXIgYnVmWzUwXTsKCWNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEwsICpyZWZQcmVmaXg7CgoJLyoKCSogUGFyc2UgYXMgYW4gYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLgoJKi8KCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJTlVMTCwgTlVMTCwgbm9kZSwgInJlZiIsIE5VTEwpOwoJfQkKCXhtbFNjaGVtYVBWYWxBdHRyTm9kZVFOYW1lKGN0eHQsIHNjaGVtYSwKCSAgICBOVUxMLCBOVUxMLCBhdHRyLCAmcmVmTnMsICZyZWZQcmVmaXgsICZyZWYpOwoJIAogICAgICAgIHNucHJpbnRmKGJ1ZiwgNDksICIjYWdSZWYlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKCWlmIChuYW1lID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJjcmVhdGluZyBpbnRlcm5hbCBuYW1lIGZvciBhbiAiCgkJImF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIHJlZmVyZW5jZSIsIG5vZGUpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KCXJldCA9IHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwKGN0eHQsIHNjaGVtYSwgbmFtZSwgbm9kZSk7CglpZiAocmV0ID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDsKCXJldC0+cmVmID0gcmVmOwoJcmV0LT5yZWZOcyA9IHJlZk5zOwoJLyogVE9ETzogSXMgQHJlZlByZWZpeCBjdXJyZW50bHkgdXNlZD8gKi8KCXJldC0+cmVmUHJlZml4ID0gcmVmUHJlZml4OwoJcmV0LT5ub2RlID0gbm9kZTsKICAgIH0gICAgCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCgodG9wTGV2ZWwgPT0gMCkgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAicmVmIikpKSB8fAoJCSAodG9wTGV2ZWwgJiYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSkpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkpIAoJICAgIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyogVE9ETzogVmFsaWRhdGUgImlkIiA/ICovICAKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOyAgICAKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICByZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAodG9wTGV2ZWwpIHsKCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7IAoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CgkgICAgcmV0LT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwgCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsIAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQVmFsQXR0ckZvcm1EZWZhdWx0OgogKiBAdmFsdWU6ICB0aGUgdmFsdWUKICogQGZsYWdzOiB0aGUgZmxhZ3MgdG8gYmUgbW9kaWZpZWQKICogQGZsYWdRdWFsaWZpZWQ6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAicXVhbGlmaWVkIgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCAxIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUFZhbEF0dHJGb3JtRGVmYXVsdChjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICBpbnQgKmZsYWdzLAoJCQkgICAgIGludCBmbGFnUXVhbGlmaWVkKQp7CiAgICBpZiAoeG1sU3RyRXF1YWwodmFsdWUsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJaWYgICgoKmZsYWdzICYgZmxhZ1F1YWxpZmllZCkgPT0gMCkKCSAgICAqZmxhZ3MgfD0gZmxhZ1F1YWxpZmllZDsKICAgIH0gZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHZhbHVlLCBCQURfQ0FTVCAidW5xdWFsaWZpZWQiKSkKCXJldHVybiAoMSk7ICAgIAoJCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsOgogKiBAdmFsdWU6ICB0aGUgdmFsdWUKICogQGZsYWdzOiB0aGUgZmxhZ3MgdG8gYmUgbW9kaWZpZWQKICogQGZsYWdBbGw6IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiI2FsbCIKICogQGZsYWdFeHRlbnNpb246IHRoZSBzcGVjaWZpYyBmbGFnIGZvciAiZXh0ZW5zaW9uIgogKiBAZmxhZ1Jlc3RyaWN0aW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInJlc3RyaWN0aW9uIgogKiBAZmxhZ1N1YnN0aXR1dGlvbjogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJzdWJzdGl0dXRpb24iCiAqIEBmbGFnTGlzdDogdGhlIHNwZWNpZmljIGZsYWcgZm9yICJsaXN0IgogKiBAZmxhZ1VuaW9uOiB0aGUgc3BlY2lmaWMgZmxhZyBmb3IgInVuaW9uIgogKgogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgImZpbmFsIiBhbmQgImJsb2NrIi4gVGhlIHZhbHVlCiAqIGlzIGNvbnZlcnRlZCBpbnRvIHRoZSBzcGVjaWZpZWQgZmxhZyB2YWx1ZXMgYW5kIHJldHVybmVkIGluIEBmbGFncy4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgMSBvdGhlcndpc2UuCiAqLwoKc3RhdGljIGludAp4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICBpbnQgKmZsYWdzLAkJCQoJCQkgICAgaW50IGZsYWdBbGwsCgkJCSAgICBpbnQgZmxhZ0V4dGVuc2lvbiwKCQkJICAgIGludCBmbGFnUmVzdHJpY3Rpb24sCgkJCSAgICBpbnQgZmxhZ1N1YnN0aXR1dGlvbiwKCQkJICAgIGludCBmbGFnTGlzdCwKCQkJICAgIGludCBmbGFnVW5pb24pCQkJCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAqIFRPRE86IFRoaXMgZG9lcyBub3QgY2hlY2sgZm9yIGR1YmxpY2F0ZSBlbnRyaWVzLgogICAgKi8KICAgIGlmICh2YWx1ZSA9PSBOVUxMKQoJcmV0dXJuICgxKTsKICAgIGlmICh4bWxTdHJFcXVhbCh2YWx1ZSwgQkFEX0NBU1QgIiNhbGwiKSkgewoJaWYgKGZsYWdBbGwgIT0gLTEpCgkgICAgKmZsYWdzIHw9IGZsYWdBbGw7CgllbHNlIHsKCSAgICBpZiAoZmxhZ0V4dGVuc2lvbiAhPSAtMSkgCgkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247IAoJICAgIGlmIChmbGFnUmVzdHJpY3Rpb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnUmVzdHJpY3Rpb247CgkgICAgaWYgKGZsYWdTdWJzdGl0dXRpb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnU3Vic3RpdHV0aW9uOwoJICAgIGlmIChmbGFnTGlzdCAhPSAtMSkgCgkJKmZsYWdzIHw9IGZsYWdMaXN0OwoJICAgIGlmIChmbGFnVW5pb24gIT0gLTEpIAoJCSpmbGFncyB8PSBmbGFnVW5pb247Cgl9CiAgICB9IGVsc2UgewoJY29uc3QgeG1sQ2hhciAqZW5kLCAqY3VyID0gdmFsdWU7Cgl4bWxDaGFyICppdGVtOwoJCglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBpdGVtID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7ICAgIAkgICAgCgkgICAgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJleHRlbnNpb24iKSkgewoJCWlmIChmbGFnRXh0ZW5zaW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ0V4dGVuc2lvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdFeHRlbnNpb247CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInJlc3RyaWN0aW9uIikpIHsKCQlpZiAoZmxhZ1Jlc3RyaWN0aW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1Jlc3RyaWN0aW9uKSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ1Jlc3RyaWN0aW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGl0ZW0sIEJBRF9DQVNUICJzdWJzdGl0dXRpb24iKSkgewoJCWlmIChmbGFnU3Vic3RpdHV0aW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1N1YnN0aXR1dGlvbikgPT0gMCkKCQkJKmZsYWdzIHw9IGZsYWdTdWJzdGl0dXRpb247CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImxpc3QiKSkgewoJCWlmIChmbGFnTGlzdCAhPSAtMSkgewoJCSAgICBpZiAoKCpmbGFncyAmIGZsYWdMaXN0KSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ0xpc3Q7CgkJfSBlbHNlIAoJCSAgICByZXQgPSAxOwoJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInVuaW9uIikpIHsKCQlpZiAoZmxhZ1VuaW9uICE9IC0xKSB7CgkJICAgIGlmICgoKmZsYWdzICYgZmxhZ1VuaW9uKSA9PSAwKQoJCQkqZmxhZ3MgfD0gZmxhZ1VuaW9uOwoJCX0gZWxzZSAKCQkgICAgcmV0ID0gMTsKCSAgICB9IGVsc2UgCgkJcmV0ID0gMTsKCSAgICBpZiAoaXRlbSAhPSBOVUxMKQoJCXhtbEZyZWUoaXRlbSk7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKHJldCA9PSAwKSAmJiAoKmN1ciAhPSAwKSk7IAogICAgfSAgICAKICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgojaWZkZWYgSURDX0VOQUJMRUQKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NTZWxlY3RvclhQYXRoKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICAgeG1sU2NoZW1hSURDUHRyIGlkYywKCQkJICAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsZWN0b3IsCgkJCSAgICAgeG1sQXR0clB0ciBhdHRyLAoJCQkgICAgIGludCBpc0ZpZWxkKQp7CiAgICB4bWxOb2RlUHRyIG5vZGU7CgogICAgLyoKICAgICogYy1zZWxlY3Rvci14cGF0aDogCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2VsZWN0b3IgVmFsdWUgT0sKICAgICoKICAgICogVE9ETzogMSBUaGUge3NlbGVjdG9yfSBtdXN0IGJlIGEgdmFsaWQgWFBhdGggZXhwcmVzc2lvbiwgYXMgZGVmaW5lZCAKICAgICogaW4gW1hQYXRoXS4KICAgICovCiAgICBpZiAoc2VsZWN0b3IgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBpZGMtPm5vZGUsIAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aCwgIgoJICAgICJ0aGUgc2VsZWN0b3IgaXMgbm90IHNwZWNpZmllZC5cbiIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAoYXR0ciA9PSBOVUxMKQoJbm9kZSA9IGlkYy0+bm9kZTsKICAgIGVsc2UKCW5vZGUgPSAoeG1sTm9kZVB0cikgYXR0cjsKICAgIGlmIChzZWxlY3Rvci0+eHBhdGggPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIC8qIFRPRE86IEFkanVzdCBlcnJvciBjb2RlLiAqLwoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgICJUaGUgWFBhdGggZXhwcmVzc2lvbiBvZiB0aGUgc2VsZWN0b3IgaXMgbm90IHZhbGlkIiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUpOwogICAgfSBlbHNlIHsKCWNvbnN0IHhtbENoYXIgKipuc0FycmF5ID0gTlVMTDsKCXhtbE5zUHRyICpuc0xpc3QgPSBOVUxMOwoJLyoKCSogQ29tcGlsZSB0aGUgWFBhdGggZXhwcmVzc2lvbi4KCSovCgkvKgoJKiBUT0RPOiBXZSBuZWVkIHRoZSBhcnJheSBvZiBpbi1zY29wZSBuYW1lc3BhY2VzIGZvciBjb21waWxhdGlvbi4KCSogVE9ETzogQ2FsbCB4bWxQYXR0ZXJuY29tcGlsZSB3aXRoIGRpZmZlcmVudCBvcHRpb25zIGZvciBzZWxlY3Rvci8KCSogZmllbGQuCgkqLwoJbnNMaXN0ID0geG1sR2V0TnNMaXN0KGF0dHItPmRvYywgYXR0ci0+cGFyZW50KTsKCS8qCgkqIEJ1aWxkIGFuIGFycmF5IG9mIHByZWZpeGVzIGFuZCBuYW1lc3BhY2VzLgoJKi8KCWlmIChuc0xpc3QgIT0gTlVMTCkgewoJICAgIGludCBpLCBjb3VudCA9IDA7CgkgICAgeG1sTnNQdHIgbnM7CgoJICAgIGZvciAoaSA9IDA7IG5zTGlzdFtpXSAhPSBOVUxMOyBpKyspCgkJY291bnQrKzsKCgkgICAgbnNBcnJheSA9IChjb25zdCB4bWxDaGFyICoqKSB4bWxNYWxsb2MoCgkJKGNvdW50ICogMiArIDEpICogc2l6ZW9mKGNvbnN0IHhtbENoYXIgKikpOwoJICAgIGlmIChuc0FycmF5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGEgbmFtZXNwYWNlIGFycmF5IiwKCQkgICAgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJbnMgPSBuc0xpc3RbaV07CgkJbnNBcnJheVsyICogaV0gPSBuc0xpc3RbaV0tPmhyZWY7CgkJbnNBcnJheVsyICogaSArIDFdID0gbnNMaXN0W2ldLT5wcmVmaXg7CgkgICAgfQoJICAgIG5zQXJyYXlbY291bnQgKiAyXSA9IE5VTEw7CgkgICAgeG1sRnJlZShuc0xpc3QpOwoJfQoJaWYgKGlzRmllbGQpCgkgICAgc2VsZWN0b3ItPnhwYXRoQ29tcCA9ICh2b2lkICopIHhtbFBhdHRlcm5jb21waWxlKHNlbGVjdG9yLT54cGF0aCwKCQlOVUxMLCAxLCBuc0FycmF5KTsKCWVsc2UKCSAgICBzZWxlY3Rvci0+eHBhdGhDb21wID0gKHZvaWQgKikgeG1sUGF0dGVybmNvbXBpbGUoc2VsZWN0b3ItPnhwYXRoLAoJCU5VTEwsIDEsIG5zQXJyYXkpOwoJaWYgKG5zQXJyYXkgIT0gTlVMTCkKCSAgICB4bWxGcmVlKCh4bWxDaGFyICoqKSBuc0FycmF5KTsKCQojaWZkZWYgSURDX1hQQVRIX1NVUFBPUlQKCWlmIChzZWxlY3Rvci0+eHBhdGhDb21wID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJLyogVE9ETzogQWRqdXN0IGVycm9yIGNvZGU/ICovCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwgCgkJTlVMTCwgTlVMTCwgbm9kZSwgCgkJIlRoZSBYUGF0aCBleHByZXNzaW9uICclcycgY291bGQgbm90IGJlICIKCQkiY29tcGlsZWQiLCBzZWxlY3Rvci0+eHBhdGgpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSk7Cgl9CQkKI2VuZGlmICAKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NpZ25Bbm5vdGF0aW9uOgogKiBAaXRlbTogdGhlIHNjaGVtYSBjb21wb25lbnQKICogQGFubm90OiB0aGUgYW5ub3RhdGlvbgogKgogKiBBZGRzIHRoZSBhbm5vdGF0aW9uIHRvIHRoZSBnaXZlbiBzY2hlbWEgY29tcG9uZW50LgogKgogKiBSZXR1cm5zIHRoZSBnaXZlbiBhbm5vdGFpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hQW5ub3RQdHIKeG1sU2NoZW1hQXNzaWduQW5ub3RhdGlvbih4bWxTY2hlbWFCYXNpY0l0ZW1QdHIgaXRlbSwKCQkJICB4bWxTY2hlbWFBbm5vdFB0ciBhbm5vdCkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgY3VyID0gaXRlbS0+YW5ub3Q7CgogICAgaWYgKGl0ZW0tPmFubm90ID09IE5VTEwpIHsKCWl0ZW0tPmFubm90ID0gYW5ub3Q7CglyZXR1cm4gKGFubm90KTsKICAgIH0KICAgIGN1ciA9IGl0ZW0tPmFubm90OwogICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CgljdXIgPSBjdXItPm5leHQ7CQogICAgfQogICAgY3VyLT5uZXh0ID0gYW5ub3Q7CiAgICByZXR1cm4gKGFubm90KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBQYXJzZXMgYSBYTUwgU2NoZW1hIGlkZW50aXR5LWNvbnRyYWludCBkZWZpbml0aW9uJ3MKICogPHNlbGVjdG9yPiBhbmQgPGZpZWxkPiBlbGVtZW50cy4KICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFJRENTZWxlY3RQdHIKeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICB4bWxTY2hlbWFJRENQdHIgaWRjLAoJCQkgIHhtbE5vZGVQdHIgbm9kZSwKCQkJICBpbnQgaXNGaWVsZCkKewogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIAogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAieHBhdGgiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0gICAgICAKICAgIC8qCiAgICAqIENyZWF0ZSB0aGUgaXRlbS4KICAgICovICAgICAgIAogICAgaXRlbSA9ICh4bWxTY2hlbWFJRENTZWxlY3RQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDU2VsZWN0KSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCSAgICAiYWxsb2NhdGluZyBhICdzZWxlY3Rvcicgb2YgYW4gaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIiwgCgkgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChpdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDU2VsZWN0KSk7ICAgCiAgICAvKgogICAgKiBBdHRyaWJ1dGUgInhwYXRoIiAobWFuZGF0b3J5KS4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInhwYXRoIik7CiAgICBpZiAoYXR0ciA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsCgkgICAgIm5hbWUiLCBOVUxMKTsKICAgIH0gZWxzZSB7CglpdGVtLT54cGF0aCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCS8qCgkqIFVSR0VOVCBUT0RPOiAiZmllbGQicyBoYXZlIGFuIG90aGVyIHN5bnRheCB0aGFuICJzZWxlY3RvciJzLgoJKi8KCglpZiAoeG1sU2NoZW1hQ2hlY2tDU2VsZWN0b3JYUGF0aChjdHh0LCBpZGMsIGl0ZW0sIGF0dHIsCgkgICAgaXNGaWVsZCkgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwJCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkLCAiCgkJInZhbGlkYXRpbmcgdGhlIFhQYXRoIGV4cHJlc3Npb24gb2YgYSBJREMgc2VsZWN0b3IuXG4iLCAKCQlOVUxMLCBOVUxMKTsKCX0KCiAgICB9ICAgIAogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkvKgoJKiBBZGQgdGhlIGFubm90YXRpb24gdG8gdGhlIHBhcmVudCBJREMuCgkqLwoJeG1sU2NoZW1hQXNzaWduQW5ub3RhdGlvbigoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSBpZGMsIAoJICAgIHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKSk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSAgCQkgICAgCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIAogICAgcmV0dXJuIChpdGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlSURDOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIFBhcnNlcyBhIFhNTCBTY2hlbWEgaWRlbnRpdHktY29udHJhaW50IGRlZmluaXRpb24uCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlZCBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hSURDUHRyCnhtbFNjaGVtYVBhcnNlSURDKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCSAgeG1sTm9kZVB0ciBub2RlLAoJCSAgeG1sU2NoZW1hVHlwZVR5cGUgaWRjQ2F0ZWdvcnksCgkJICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpdGVtID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgZmllbGQgPSBOVUxMLCBsYXN0RmllbGQgPSBOVUxMOwogICAgaW50IHJlc0FkZDsKICAgICAgICAKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkoKGlkY0NhdGVnb3J5ICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB8fAoJCSAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJyZWZlciIpKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0gIAogICAgLyoKICAgICogQXR0cmlidXRlICJuYW1lIiAobWFuZGF0b3J5KS4KICAgICovCiAgICBhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGlmIChhdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLCAKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJuYW1lIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCglOVUxMLCBOVUxMLCBhdHRyLCAKCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZuYW1lKSAhPSAwKSB7CglyZXR1cm4gKE5VTEwpOwogICAgfSAgICAKICAgIC8qCiAgICAqIENyZWF0ZSB0aGUgY29tcG9uZW50LgogICAgKi8KICAgIGlmIChzY2hlbWEtPmlkY0RlZiA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+aWRjRGVmID0geG1sSGFzaENyZWF0ZURpY3QoMTAsIGN0eHQtPmRpY3QpOwogICAgaWYgKHNjaGVtYS0+aWRjRGVmID09IE5VTEwpIAogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaXRlbSA9ICh4bWxTY2hlbWFJRENQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDKSk7CiAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCSAgICAiYWxsb2NhdGluZyBhbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24iLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfSAgICAKICAgIC8qCiAgICAqIEFkZCB0aGUgSURDIHRvIHRoZSBsaXN0IG9mIElEQ3Mgb24gdGhlIHNjaGVtYSBjb21wb25lbnQuCiAgICAqLwogICAgcmVzQWRkID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPmlkY0RlZiwgbmFtZSwgdGFyZ2V0TmFtZXNwYWNlLCBpdGVtKTsKICAgIGlmIChyZXNBZGQgIT0gMCkgewkgICAgICAgICAgIAoJeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9UWVBFLAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgICJBbiBpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb24gd2l0aCB0aGUgbmFtZSAnJXMnICIKCSAgICAiYW5kIHRhcmdldE5hbWVzcGFjZSAnJXMnIGRvZXMgYWxyZWFkeSBleGlzdCIsIAoJICAgIG5hbWUsIHRhcmdldE5hbWVzcGFjZSwgTlVMTCk7Cgl4bWxGcmVlKGl0ZW0pOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChpdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDKSk7CiAgICBpdGVtLT5uYW1lID0gbmFtZTsKICAgIGl0ZW0tPnR5cGUgPSBpZGNDYXRlZ29yeTsgIAogICAgaXRlbS0+bm9kZSA9IG5vZGU7CiAgICAvKgogICAgKiBUaGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgcGFyZW50IGVsZW1lbnQgZGVjbGFyYXRpb24uCiAgICAqLwogICAgaXRlbS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOyAgIAogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgaWYgKGlkY0NhdGVnb3J5ID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkvKgoJKiBBdHRyaWJ1dGUgInJlZmVyIiAobWFuZGF0b3J5KS4KCSovCglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgInJlZmVyIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJInJlZmVyIiwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBDcmVhdGUgYSByZWZlcmVuY2UgaXRlbS4KCSAgICAqLwoJICAgIGl0ZW0tPnJlZiA9ICh4bWxTY2hlbWFJdGVtUU5SZWZQdHIpIHhtbE1hbGxvYygKCQlzaXplb2YoeG1sU2NoZW1hSXRlbVFOUmVmKSk7CgkgICAgaWYgKGl0ZW0tPnJlZiA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCQkgICAgImFsbG9jYXRpbmcgYSBRTmFtZSByZWZlcmVuY2UgaXRlbSIsIE5VTEwpOwoJCXJldHVybiAoTlVMTCk7CgkgICAgfQoJICAgIG1lbXNldChpdGVtLT5yZWYsIDAsIHNpemVvZih4bWxTY2hlbWFJdGVtUU5SZWYpKTsKCSAgICB4bWxTY2hlbWFQVmFsQXR0ck5vZGVRTmFtZShjdHh0LCBzY2hlbWEsCgkJTlVMTCwgTlVMTCwgYXR0ciwgCgkJJihpdGVtLT5yZWYtPnRhcmdldE5hbWVzcGFjZSksIDAsIAoJCSYoaXRlbS0+cmVmLT5uYW1lKSk7Cgl9CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJaXRlbS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTUlTU0lORywKCQlOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgCgkJIkEgY2hpbGQgZWxlbWVudCBpcyBtaXNzaW5nIiwKCQkiKGFubm90YXRpb24/LCAoc2VsZWN0b3IsIGZpZWxkKykpIik7CiAgICB9CiAgICAvKgogICAgKiBDaGlsZCBlbGVtZW50IDxzZWxlY3Rvcj4uCiAgICAqLwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlbGVjdG9yIikpIHsgICAgCglpdGVtLT5zZWxlY3RvciA9IHhtbFNjaGVtYVBhcnNlSURDU2VsZWN0b3JBbmRGaWVsZChjdHh0LCBzY2hlbWEsIAoJICAgIGl0ZW0sIGNoaWxkLCAwKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkvKgoJKiBDaGlsZCBlbGVtZW50cyA8ZmllbGQ+LgoJKi8KCWlmIChJU19TQ0hFTUEoY2hpbGQsICJmaWVsZCIpKSB7CgkgICAgZG8gewoJCWZpZWxkID0geG1sU2NoZW1hUGFyc2VJRENTZWxlY3RvckFuZEZpZWxkKGN0eHQsIHNjaGVtYSwgCgkJICAgIGl0ZW0sIGNoaWxkLCAxKTsKCQlpZiAoZmllbGQgIT0gTlVMTCkgewoJCSAgICBmaWVsZC0+aW5kZXggPSBpdGVtLT5uYkZpZWxkczsKCQkgICAgaXRlbS0+bmJGaWVsZHMrKzsKCQkgICAgaWYgKGxhc3RGaWVsZCAhPSBOVUxMKQoJCQlsYXN0RmllbGQtPm5leHQgPSBmaWVsZDsJCSAgICAKCQkgICAgZWxzZQoJCQlpdGVtLT5maWVsZHMgPSBmaWVsZDsKCQkgICAgbGFzdEZpZWxkID0gZmllbGQ7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgfSB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiZmllbGQiKSk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkJTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIAoJCU5VTEwsICIoYW5ub3RhdGlvbj8sIChzZWxlY3RvciwgZmllbGQrKSkiKTsKCX0KICAgIH0gICAgCiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwKCSAgICBOVUxMLCBOVUxMLCBub2RlLCBjaGlsZCwgCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNlbGVjdG9yLCBmaWVsZCspKSIpOwogICAgfQkJCgogICAgcmV0dXJuIChpdGVtKTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEVsZW1lbnQgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBwYXJzZWQgZWxlbWVudCBkZWNsYXJhdGlvbi4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtZW50UHRyCnhtbFNjaGVtYVBhcnNlRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUsIGludCB0b3BMZXZlbCkKewogICAgY29uc3QgeG1sQ2hhciAqbmFtZSA9IE5VTEw7ICAgIAogICAgY29uc3QgeG1sQ2hhciAqYXR0clZhbHVlOwogICAgeG1sQ2hhciAqcmVwTmFtZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIHhtbEF0dHJQdHIgYXR0ciwgbmFtZUF0dHI7CiAgICBpbnQgbWluT2NjdXJzLCBtYXhPY2N1cnM7CiAgICBpbnQgaXNSZWYgPSAwOwojaWZkZWYgSURDX0VOQUJMRUQKICAgIHhtbFNjaGVtYUlEQ1B0ciBjdXJJREMgPSBOVUxMLCBsYXN0SURDID0gTlVMTDsKI2VuZGlmCgogICAgLyogMy4zLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBFbGVtZW50IERlY2xhcmF0aW9ucyAqLwogICAgLyogVE9ETzogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgMy4zLjYgKi8KICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgICAKICAgIG5hbWVBdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAicmVmIik7ICAgCiAgICBpZiAoKHRvcExldmVsKSB8fCAoYXR0ciA9PSBOVUxMKSkgewoJaWYgKG5hbWVBdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9NSVNTSU5HLAoJCSh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsLCBOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbmFtZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBuYW1lQXR0cik7CQkKICAgIH0gZWxzZSB7Cglpc1JlZiA9IDE7CgkKICAgIH0KICAgIC8qIAogICAgKiAuLi4gdW5sZXNzIG1pbk9jY3Vycz1tYXhPY2N1cnM9MCwgaW4gd2hpY2ggY2FzZSB0aGUgaXRlbSBjb3JyZXNwb25kcyAKICAgICogdG8gbm8gY29tcG9uZW50IGF0IGFsbAogICAgKiBUT0RPOiBJdCBtaWdodCBiZSBiZXR0ZXIgdG8gdmFsaWRhdGUgdGhlIGVsZW1lbnQsIGV2ZW4gaWYgaXQgd29uJ3QgYmUgCiAgICAqIHVzZWQuCiAgICAqLyAgICAKICAgIG1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgIm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgbWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgIihub25OZWdhdGl2ZUludGVnZXIgfCB1bmJvdW5kZWQpIik7CiAgICBpZiAoKG1pbk9jY3VycyA9PSAwKSAmJiAobWF4T2NjdXJzID09IDApKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIElmIHdlIGdldCBhICJyZWYiIGF0dHJpYnV0ZSBvbiBhIGxvY2FsIDxlbGVtZW50PiB3ZSB3aWxsIGFzc3VtZSBpdCdzCiAgICAqIGEgcmVmZXJlbmNlIC0gZXZlbiBpZiB0aGVyZSdzIGEgIm5hbWUiIGF0dHJpYnV0ZTsgdGhpcyBzZWVtcyB0byBiZSBtb3JlIAogICAgKiByb2J1c3QuCiAgICAqLwogICAgaWYgKGlzUmVmKSB7CgljaGFyIGJ1Zls1MF07Cgljb25zdCB4bWxDaGFyICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMLCAqcmVmUHJlZml4OwoKCS8qCgkqIFBhcnNlIGFzIGEgcGFydGljbGUuCgkqLwoJeG1sU2NoZW1hUFZhbEF0dHJOb2RlUU5hbWUoY3R4dCwgc2NoZW1hLAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYsIAoJICAgIE5VTEwsIGF0dHIsICZyZWZOcywgJnJlZlByZWZpeCwgJnJlZik7CQkJCgkgCiAgICAgICAgc25wcmludGYoYnVmLCA0OSwgIiNlUmVmJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXJldCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKSBidWYsIE5VTEwsIG5vZGUsIDApOwoJaWYgKHJldCA9PSBOVUxMKSB7CgkgICAgaWYgKHJlcE5hbWUgIT0gTlVMTCkKCQl4bWxGcmVlKHJlcE5hbWUpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDsKCXJldC0+bm9kZSA9IG5vZGU7ICAgICAJCQoJcmV0LT5yZWYgPSByZWY7CglyZXQtPnJlZk5zID0gcmVmTnM7CglyZXQtPnJlZlByZWZpeCA9IHJlZlByZWZpeDsKCXJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9SRUY7CgkvKiAKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCgkvKiAKCSogMy4zLjMgOiAyLjEKCSogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJKi8KCWlmIChuYW1lQXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzJfMSwKCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbmFtZUF0dHIsCgkJInJlZiIsICJuYW1lIik7Cgl9CgkvKiAzLjMuMyA6IDIuMiAqLyAgIAoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikgfHwKCQkgICAgeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpIHx8CgkJICAgIHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkKCQl7CgkJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJCSAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMl8yLAoJCQkmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0ciwgCgkJCSJPbmx5IHRoZSBhdHRyaWJ1dGVzICdtaW5PY2N1cnMnLCAnbWF4T2NjdXJzJyBhbmQgIgoJCQkiJ2lkJyBhcmUgYWxsb3dlZCBpbiBhZGRpdGlvbiB0byAncmVmJyIpOwoJCSAgICBicmVhazsKCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQkgICAgICAKICAgIH0gZWxzZSB7Cgljb25zdCB4bWxDaGFyICpucyA9IE5VTEwsICpmaXhlZDsKCgkvKgoJKiBQYXJzZSBhcyBhbiBlbGVtZW50IGRlY2xhcmF0aW9uLgoJKi8KCWlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wsIE5VTEwsIG5hbWVBdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkKCSAgICByZXR1cm4gKE5VTEwpOwoJLyogCgkqIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KCWlmICh0b3BMZXZlbCkgewoJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7Cgl9IGVsc2UgewoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZm9ybSIpOwoJICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCQlhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CgkJaWYgKHhtbFN0ckVxdWFsKGF0dHJWYWx1ZSwgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwoYXR0clZhbHVlLCBCQURfQ0FTVCAidW5xdWFsaWZpZWQiKSkgewoJCSAgICB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwgCgkJCSZyZXBOYW1lLCBOVUxMLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCU5VTEwsICIocXVhbGlmaWVkIHwgdW5xdWFsaWZpZWQpIiwgCgkJCWF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CQkJCgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKQoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CQkKCX0JCglyZXQgPSB4bWxTY2hlbWFBZGRFbGVtZW50KGN0eHQsIHNjaGVtYSwgbmFtZSwgbnMsIG5vZGUsIHRvcExldmVsKTsKCWlmIChyZXQgPT0gTlVMTCkgewoJICAgIGlmIChyZXBOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShyZXBOYW1lKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJcmV0LT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ7CglyZXQtPm5vZGUgPSBub2RlOwoJcmV0LT50YXJnZXROYW1lc3BhY2UgPSBuczsKCS8qIAoJKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwoJd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgkJCgkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImRlZmF1bHQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZml4ZWQiKSkgJiYJCQoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuaWxsYWJsZSIpKSkgCgkJewkKCQkgICAgaWYgKHRvcExldmVsID09IDApIHsgCQkJCQkJCgkJCWlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtYXhPY2N1cnMiKSkgJiYKCQkJICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSAmJgoJCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZm9ybSIpKSkgCgkJCXsKCQkJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uR3JvdXAiKSkgewoJCQkJLyoKCQkJCSogMy4zLjYgOiAzIElmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gCgkJCQkqIGdyb3VwIGFmZmlsaWF0aW9ufSwgdGhlbiB7c2NvcGV9IG11c3QgYmUgZ2xvYmFsLgoJCQkJKiBUT0RPOiBUaGlzIG9uZSBpcyByZWR1bmRhbnQsIHNpbmNlIHRoZSBTNFMgZG9lcyAKCQkJCSogcHJvaGliaXQgdGhpcyBhdHRyaWJ1dGUgb24gbG9jYWwgZGVjbGFyYXRpb25zIGFscmVhZHk7IAoJCQkJKiBzbyB3aHkgYW4gZXhwbGljaXQgZXJyb3IgY29kZT8gV2VpcmQgc3BlYy4KCQkJCSogVE9ETzogTW92ZSB0aGlzIHRvIHRoZSBwcm9wZXIgY29uc3RyYWludCBsYXllci4KCQkJCSogVE9ETzogT3IgYmV0dGVyIHdhaXQgZm9yIHNwZWMgMS4xIHRvIGNvbWUuCgkJCQkqLwoJCQkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJCQkgICAgWE1MX1NDSEVNQVBfRV9QUk9QU19DT1JSRUNUXzMsCgkJCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIGF0dHIpOwoJCQkgICAgfSBlbHNlIHsKCQkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCQkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyKTsKCQkJICAgIH0KCQkJfQoJCSAgICB9IGVsc2UgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImZpbmFsIikpICYmIAoJCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJhYnN0cmFjdCIpKSAmJiAKCQkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic3Vic3RpdHV0aW9uR3JvdXAiKSkpIHsKCgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CQkgICAgCgkJICAgIH0KCQl9CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkJCgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgYXR0cik7CgkgICAgfQoJICAgIGF0dHIgPSBhdHRyLT5uZXh0OwoJfQkJCgkvKgoJKiBFeHRyYWN0L3ZhbGlkYXRlIGF0dHJpYnV0ZXMuCgkqLwoJaWYgKHRvcExldmVsKSB7CgkgICAgLyogCgkgICAgKiBQcm9jZXNzIHRvcCBhdHRyaWJ1dGVzIG9mIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9ucyBoZXJlLgoJICAgICovCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTDsKCSAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUw7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsICZyZXBOYW1lLCAKCQkoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCAic3Vic3RpdHV0aW9uR3JvdXAiLCAKCQkmKHJldC0+c3Vic3RHcm91cE5zKSwgTlVMTCwgJihyZXQtPnN1YnN0R3JvdXApKTsKCSAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsICAKCQlub2RlLCAiYWJzdHJhY3QiLCAwKSkKCQlyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1Q7IAoJICAgIC8qCgkgICAgKiBBdHRyaWJ1dGUgImZpbmFsIi4KCSAgICAqLwoJICAgIGF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsJICAgIAoJICAgIGlmIChhdHRyID09IE5VTEwpIHsKCQlyZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfQUJTRU5UOwoJICAgIH0gZWxzZSB7CgkJYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkgICAgCgkJaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYocmV0LT5mbGFncyksIAoJCSAgICAtMSwKCQkgICAgWE1MX1NDSEVNQVNfRUxFTV9GSU5BTF9FWFRFTlNJT04sCgkJICAgIFhNTF9TQ0hFTUFTX0VMRU1fRklOQUxfUkVTVFJJQ1RJT04sIC0xLCAtMSwgLTEpICE9IDApIHsKCQkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCU5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLCAKCQkJYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQl9CgkgICAgfQoJfSAgICAKCS8qCgkqIEF0dHJpYnV0ZSAiYmxvY2siLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiYmxvY2siKTsJCglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0JMT0NLX0FCU0VOVDsKCX0gZWxzZSB7CgkgICAgYXR0clZhbHVlID0geG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIpOwkgICAgCgkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYocmV0LT5mbGFncyksIAoJCS0xLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfRVhURU5TSU9OLAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfUkVTVFJJQ1RJT04sIAoJCVhNTF9TQ0hFTUFTX0VMRU1fQkxPQ0tfU1VCU1RJVFVUSU9OLCAtMSwgLTEpICE9IDApIHsKCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgKHhtbE5vZGVQdHIpIGF0dHIsCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8ICIKCQkgICAgInJlc3RyaWN0aW9uIHwgc3Vic3RpdHV0aW9uKSkiLCBhdHRyVmFsdWUsIAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsJCQoJICAgIH0KCX0KCWlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgCgkgICAgbm9kZSwgIm5pbGxhYmxlIiwgMCkpCgkgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFOwkKCgl4bWxTY2hlbWFQVmFsQXR0clFOYW1lKGN0eHQsIHNjaGVtYSwgCgkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIAoJICAgICJ0eXBlIiwgJihyZXQtPm5hbWVkVHlwZU5zKSwgTlVMTCwgJihyZXQtPm5hbWVkVHlwZSkpOwoKCXJldC0+dmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJkZWZhdWx0Iik7ICAgIAoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJmaXhlZCIpOwkKCWlmIChhdHRyICE9IE5VTEwpIHsKCSAgICBmaXhlZCA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyKTsKCSAgICBpZiAocmV0LT52YWx1ZSAhPSBOVUxMKSB7CgkJLyogCgkJKiAzLjMuMyA6IDEgCgkJKiBkZWZhdWx0IGFuZCBmaXhlZCBtdXN0IG5vdCBib3RoIGJlIHByZXNlbnQuIAoJCSovCgkJeG1sU2NoZW1hUE11dHVhbEV4Y2xBdHRyRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19FTEVNRU5UXzEsCgkJICAgICZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBhdHRyLAoJCSAgICAiZGVmYXVsdCIsICJmaXhlZCIpOwoJICAgIH0gZWxzZSB7CgkJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEOwoJCXJldC0+dmFsdWUgPSBmaXhlZDsKCSAgICB9Cgl9CQogICAgfSAgICAgCiAgICAvKgogICAgKiBFeHRyYWN0L3ZhbGlkYXRlIGNvbW1vbiBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgcmV0LT5taW5PY2N1cnMgPSBtaW5PY2N1cnM7CiAgICByZXQtPm1heE9jY3VycyA9IG1heE9jY3VyczsgCiAgICBpZiAodG9wTGV2ZWwgIT0gMSkKCXhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIAoJICAgIG5vZGUsIG1pbk9jY3VycywgbWF4T2NjdXJzKTsgICAgCiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjdHh0LT5jb250YWluZXIgPSByZXQtPm5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewoJcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoaXNSZWYpIHsKCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8yXzIsCgkJJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQlOVUxMLCAiKGFubm90YXRpb24/KSIpOwoJfQogICAgfSBlbHNlIHsJCQkKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgLyogCgkgICAgKiAzLjMuMyA6IDMgCgkgICAgKiAidHlwZSIgYW5kIGVpdGhlciA8c2ltcGxlVHlwZT4gb3IgPGNvbXBsZXhUeXBlPiBhcmUgbXV0dWFsbHkKCSAgICAqIGV4Y2x1c2l2ZSAKCSAgICAqLwoJICAgIGlmIChyZXQtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfU1JDX0VMRU1FTlRfMywKCQkgICAgJnJlcE5hbWUsICh4bWxTY2hlbWFUeXBlUHRyKSByZXQsIG5vZGUsIGNoaWxkLCAKCQkgICAgIlRoZSBhdHRyaWJ1dGUgJ3R5cGUnIGFuZCB0aGUgPGNvbXBsZXhUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CQkKCSAgICB9IGVsc2UKCQlyZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICAvKiAKCSAgICAqIDMuMy4zIDogMyAKCSAgICAqICJ0eXBlIiBhbmQgZWl0aGVyIDxzaW1wbGVUeXBlPiBvciA8Y29tcGxleFR5cGU+IGFyZQoJICAgICogbXV0dWFsbHkgZXhjbHVzaXZlIAoJICAgICovCgkgICAgaWYgKHJldC0+bmFtZWRUeXBlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfRUxFTUVOVF8zLAoJCSAgICAmcmVwTmFtZSwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCwgbm9kZSwgY2hpbGQsIAoJCSAgICAiVGhlIGF0dHJpYnV0ZSAndHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgYXJlICIKCQkgICAgIm11dHVhbGx5IGV4Y2x1c2l2ZSIsIE5VTEwpOwkJCQkKCSAgICB9IGVsc2UKCQlyZXQtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CQoJd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJ1bmlxdWUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHx8IChJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkpIHsKI2lmZGVmIElEQ19FTkFCTEVECgkgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB7CgkJY3VySURDID0geG1sU2NoZW1hUGFyc2VJREMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFLCByZXQtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZLCByZXQtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkgewoJCWN1cklEQyA9IHhtbFNjaGVtYVBhcnNlSURDKGN0eHQsIHNjaGVtYSwgY2hpbGQsCgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGLCByZXQtPnRhcmdldE5hbWVzcGFjZSk7CgkgICAgfQoJICAgIGlmIChsYXN0SURDICE9IE5VTEwpCgkJbGFzdElEQy0+bmV4dCA9IGN1cklEQzsKCSAgICBlbHNlCgkJcmV0LT5pZGNzID0gKHZvaWQgKikgY3VySURDOwoJICAgIGxhc3RJREMgPSBjdXJJREM7CiNlbHNlCgkgICAgVE9ETwojZW5kaWYKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJaWYgKGNoaWxkICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX05PVF9BTExPV0VELAoJCSZyZXBOYW1lLCAoeG1sU2NoZW1hVHlwZVB0cikgcmV0LCBub2RlLCBjaGlsZCwgCgkJTlVMTCwgIihhbm5vdGF0aW9uPywgKChzaW1wbGVUeXBlIHwgY29tcGxleFR5cGUpPywgIgoJCSIodW5pcXVlIHwga2V5IHwga2V5cmVmKSopKSIpOwoJfQkJCgogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgLyoKICAgICogQ2xlYW51cC4KICAgICovCiAgICBpZiAocmVwTmFtZSAhPSBOVUxMKQoJeG1sRnJlZShyZXBOYW1lKTsgICAgCiAgICAvKgogICAgKiBOT1RFOiBFbGVtZW50IERlY2xhcmF0aW9uIFJlcHJlc2VudGF0aW9uIE9LIDQuIHdpbGwgYmUgY2hlY2tlZCBhdCBhIAogICAgKiBkaWZmZXJlbnQgbGF5ZXIuCiAgICAqLwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VVbmlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgVW5pb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVVuaW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiN1bmlvbiVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9VTklPTjsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWVtYmVyVHlwZXMiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEF0dHJpYnV0ZSAibWVtYmVyVHlwZXMiLiBUaGlzIGlzIGEgbGlzdCBvZiBRTmFtZXMuCiAgICAqIFRPRE86IFZhbGlkYXRlIHRoZSBRTmFtZXMuCiAgICAqLwogICAgdHlwZS0+YmFzZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm1lbWJlclR5cGVzIik7CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CQogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCS8qIFRPRE86IFRoaW5rIGFib3V0IHRoZSBlcnJvciBjb2RlLiAqLwoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1VOSU9OX0NISUxELCAKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZSopIik7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VMaXN0OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBMaXN0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VMaXN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjbGlzdCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0xJU1Q7CiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaXRlbVR5cGUiKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgdHlwZSwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCB0eXBlLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQogICAgLyoKICAgICogQXR0cmlidXRlICJpdGVtVHlwZSIuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJRTmFtZShjdHh0LCBzY2hlbWEsIE5VTEwsIE5VTEwsCglub2RlLCAiaXRlbVR5cGUiLCAmKHR5cGUtPmJhc2VOcyksIE5VTEwsICYodHlwZS0+YmFzZSkpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSAgICAJCiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCWlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJCU5VTEwsIHR5cGUsIG5vZGUsIAoJCSJUaGUgYXR0cmlidXRlICdpdGVtVHlwZScgYW5kIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CSAgICAKCX0gZWxzZSB7CQoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7ICAgICAgICAKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkvKiBUT0RPOiBUaGluayBhYm91dCB0aGUgZXJyb3IgY29kZS4gKi8KCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9MSVNUX0NISUxELCAKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwgIihhbm5vdGF0aW9uPywgc2ltcGxlVHlwZT8pIik7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTaW1wbGVUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBTaW1wbGUgVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgb2xkQ3R4dFR5cGUsIG9sZFBhcmVudEl0ZW07CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZSA9IE5VTEw7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgIAogICAgaWYgKHRvcExldmVsKSB7CglhdHRyID0geG1sU2NoZW1hR2V0UHJvcE5vZGUobm9kZSwgIm5hbWUiKTsKCWlmIChhdHRyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTUlTU0lORywgCgkJKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzU1QsIE5VTEwsIG5vZGUsCgkJIm5hbWUiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfSBlbHNlIGlmICh4bWxTY2hlbWFQVmFsQXR0ck5vZGUoY3R4dCwgCgkgICAgKHhtbENoYXIgKiopICZ4bWxTY2hlbWFFbGVtRGVzU1QsIE5VTEwsIGF0dHIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSksICZhdHRyVmFsdWUpICE9IDApIHsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQogICAgfQogICAgICAgICAgICAKICAgIGlmICh0b3BMZXZlbCA9PSAwKSB7CiAgICAgICAgY2hhciBidWZbNDBdOwoKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwogICAgICAgIHNucHJpbnRmKGJ1ZiwgMzksICIjU1QlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCwgbm9kZSk7CglpZiAodHlwZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7Cgl0eXBlLT5ub2RlID0gbm9kZTsKCXR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOwoJLyoKCSogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCglhdHRyID0gbm9kZS0+cHJvcGVydGllczsKCXdoaWxlIChhdHRyICE9IE5VTEwpIHsKCSAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCWlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZkZXMsIHR5cGUsIGF0dHIpOwkJICAgIAoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJCSZkZXMsIHR5cGUsIGF0dHIpOwkKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CiAgICB9IGVsc2UgewkJCgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSoKCSogTm90ZSB0aGF0IGF0dHJWYWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAibmFtZSIgaGVyZS4KCSovCQoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBhdHRyVmFsdWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBub2RlKTsKCWlmICh0eXBlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKCS8qCgkqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCgkqLwoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQlpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmFtZSIpKSAmJgoJCSAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJmaW5hbCIpKSkgewoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkJJmRlcywgdHlwZSwgYXR0cik7CQoJCX0KCSAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgJmRlcywgdHlwZSwgYXR0cik7CQoJICAgIH0KCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCX0KCS8qCgkqIEF0dHJpYnV0ZSAiZmluYWwiLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAiZmluYWwiKTsJCglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9ERUZBVUxUOwoJfSBlbHNlIHsKCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaW5hbCIpOwoJICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0ckJsb2NrRmluYWwoYXR0clZhbHVlLCAmKHR5cGUtPmZsYWdzKSwgCgkJLTEsIC0xLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OLCAtMSwJICAgIAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVCwKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSAhPSAwKSB7CgoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9JTlZBTElEX1ZBTFVFLAoJCSAgICAmZGVzLCB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJICAgIE5VTEwsICIoI2FsbCB8IExpc3Qgb2YgKGxpc3QgfCB1bmlvbiB8IHJlc3RyaWN0aW9uKSIsIAoJCSAgICBhdHRyVmFsdWUsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0KCX0KICAgIH0gICAKICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCB0eXBlLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZEN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CiAgICBvbGRQYXJlbnRJdGVtID0gY3R4dC0+cGFyZW50SXRlbTsKICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7ICAgICAgICAgCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJsaXN0IikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlTGlzdChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJ1bmlvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVVuaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7ICAgIAogICAgaWYgKChjaGlsZCAhPSBOVUxMKSB8fCAoc3VidHlwZSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsIAoJICAgICZkZXMsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLCAKCSAgICAiKGFubm90YXRpb24/LCAocmVzdHJpY3Rpb24gfCBsaXN0IHwgdW5pb24pKSIpOwogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IG9sZFBhcmVudEl0ZW07CiAgICBjdHh0LT5jdHh0VHlwZSA9IG9sZEN0eHRUeXBlOwogICAgRlJFRV9BTkRfTlVMTChkZXMpCgogICAgcmV0dXJuICh0eXBlKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFQYXJzZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBHcm91cCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpucyA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpyZWYgPSBOVUxMLCAqcmVmTnMgPSBOVUxMOwogICAgY2hhciBidWZbNTBdOwogICAgaW50IG1pbk9jY3VycywgbWF4T2NjdXJzOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBUT0RPOiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBldmVuIGlmIG5vIGl0ZW0gaXMgY3JlYXRlZCAKICAgICogKGkuZS4gbWluL21heE9jY3VycyA9PSAwKS4KICAgICovCiAgICBtaW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSwgMCwgLTEsIDEsICJub25OZWdhdGl2ZUludGVnZXIiKTsKICAgIG1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlLCAwLCBVTkJPVU5ERUQsIDEsICIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgaWYgKChtaW5PY2N1cnMgPT0gMCkgJiYgKG1heE9jY3VycyA9PSAwKSkgewoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICh0b3BMZXZlbCkKCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHJlZiA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAicmVmIiwgJnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkJWE1MX1NDSEVNQVBfR1JPVVBfTk9OQU1FX05PUkVGLAoJCSJHcm91cCBkZWZpbml0aW9uIG9yIHBhcnRpY2xlOiBPbmUgb2YgdGhlIGF0dHJpYnV0ZXMgXCJuYW1lXCIgIgoJCSJvciBcInJlZlwiIG11c3QgYmUgcHJlc2VudC5cbiIsIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KCWlmIChyZWZOcyA9PSBOVUxMKQoJICAgIHJlZk5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CiAgICAgICAgc25wcmludGYoYnVmLCA0OSwgIiNnclJlZiVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKICAgIH0KICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUsIG5zLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDsKICAgIGlmICh0b3BMZXZlbCkKICAgICAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsgICAgCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIHR5cGUsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgdHlwZS0+cmVmID0gcmVmOwogICAgdHlwZS0+cmVmTnMgPSByZWZOczsKICAgIHR5cGUtPm1pbk9jY3VycyA9IG1pbk9jY3VyczsKICAgIHR5cGUtPm1heE9jY3VycyA9IG1heE9jY3VyczsKICAgIHhtbFNjaGVtYVBDaGVja1BhcnRpY2xlQ29ycmVjdF8yKGN0eHQsIHR5cGUsCglub2RlLCB0eXBlLT5taW5PY2N1cnMsIHR5cGUtPm1heE9jY3Vycyk7ICAgIAoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUFsbChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoc3VidHlwZSAhPSBOVUxMKQogICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fR1JPVVBfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkdyb3VwIGRlZmluaXRpb24gXCIlc1wiIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFsbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQWxsIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VBbGwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjYWxsJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQUxMOwoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgdHlwZS0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIDEsIDEsICIoMCB8IDEpIik7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMSwgMSwgMSwgIjEiKTsgICAgCiAgICAKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IChjb25zdCB4bWxDaGFyICopIG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewoJICAgIGlmIChzdWJ0eXBlLT5taW5PY2N1cnMgPiAxKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjaGlsZCwgWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsCgkgICAgICAgICAgICAgImludmFsaWQgdmFsdWUgZm9yIG1pbk9jY3VycyAobXVzdCBiZSAwIG9yIDEpLlxuIiwKCQkgICAgIE5VTEwsIE5VTEwpOwoJICAgIGlmIChzdWJ0eXBlLT5tYXhPY2N1cnMgPiAxKQoJICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNoaWxkLCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKCSAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWF4T2NjdXJzIChtdXN0IGJlIDAgb3IgMSkuXG4iLAoJCSAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fQUxMX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICI8YWxsPiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhbnVwRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSByb290IG9mIHRoZSBkb2N1bWVudC4KICoKICogcmVtb3ZlcyB1bndhbnRlZCBub2RlcyBpbiBhIHNjaGVtYXMgZG9jdW1lbnQgdHJlZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYW51cERvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgcm9vdCkKewogICAgeG1sTm9kZVB0ciBkZWxldGUsIGN1cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHJvb3QgPT0gTlVMTCkpIHJldHVybjsKCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICBkZWxldGUgPSBOVUxMOwogICAgY3VyID0gcm9vdDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgewogICAgICAgICAgICBpZiAoSVNfQkxBTktfTk9ERShjdXIpKSB7CiAgICAgICAgICAgICAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIGRlbGV0ZSA9IGN1cjsKICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBTa2lwIHRvIG5leHQgbm9kZQogICAgICAgICAqLwogICAgICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfUkVGX05PREUpICYmCiAgICAgICAgICAgICAgICAoY3VyLT5jaGlsZHJlbi0+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+cGFyZW50SXRlbSA9IE5VTEw7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7Cn0KCnN0YXRpYyB4bWxTY2hlbWFJbXBvcnRQdHIKeG1sU2NoZW1hQWRkSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJICAgeG1sSGFzaFRhYmxlUHRyICppbXBvcnRzLAoJCSAgIGNvbnN0IHhtbENoYXIgKm5zTmFtZSkKewogICAgeG1sU2NoZW1hSW1wb3J0UHRyIHJldDsKCiAgICBpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJKmltcG9ydHMgPSB4bWxIYXNoQ3JlYXRlRGljdCgxMCwgY3R4dC0+ZGljdCk7CglpZiAoKmltcG9ydHMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfRkFJTEVEX0JVSUxEX0lNUE9SVCwKCQlOVUxMLCBOVUxMLCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSJJbnRlcm5hbCBlcnJvcjogZmFpbGVkIHRvIGJ1aWxkIHRoZSBpbXBvcnQgdGFibGUiLAoJCU5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9CiAgICByZXQgPSAoeG1sU2NoZW1hSW1wb3J0KikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJbXBvcnQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBpbXBvcnQgc3RydWN0IiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfSAgIAogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaWYgKG5zTmFtZSA9PSBOVUxMKQoJbnNOYW1lID0gWE1MX1NDSEVNQVNfTk9fTkFNRVNQQUNFOwogICAgeG1sSGFzaEFkZEVudHJ5KCppbXBvcnRzLCBuc05hbWUsIHJldCk7ICAKCiAgICByZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCQkgIGNvbnN0IHhtbENoYXIgKmxvY2F0aW9uLAoJCQkgIHhtbERvY1B0ciAqZG9jLAoJCQkgIGNvbnN0IHhtbENoYXIgKip0YXJnZXROYW1lc3BhY2UsCgkJCSAgaW50IGFic29sdXRlKQp7CiAgICB4bWxQYXJzZXJDdHh0UHRyIHBhcnNlckN0eHQ7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwogICAgY29uc3QgeG1sQ2hhciAqbnM7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CgogICAgLyoKICAgICogTk9URTogVGhpcyB3aWxsIGJlIHVzZWQgZm9yIDxpbXBvcnQ+LCA8eHNpOnNjaGVtYUxvY2F0aW9uPiBhbmQKICAgICogPHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uPi4KICAgICovCiAgICAqZG9jID0gTlVMTDsKICAgIC8qCiAgICAqIEdpdmVuIHRoYXQgdGhlIHNjaGVtYUxvY2F0aW9uIFthdHRyaWJ1dGVdIGlzIG9ubHkgYSBoaW50LCBpdCBpcyBvcGVuIAogICAgKiB0byBhcHBsaWNhdGlvbnMgdG8gaWdub3JlIGFsbCBidXQgdGhlIGZpcnN0IDxpbXBvcnQ+IGZvciBhIGdpdmVuIAogICAgKiBuYW1lc3BhY2UsIHJlZ2FyZGxlc3Mgb2YgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHNjaGVtYUxvY2F0aW9uLCBidXQKICAgICogc3VjaCBhIHN0cmF0ZWd5IHJpc2tzIG1pc3NpbmcgdXNlZnVsIGluZm9ybWF0aW9uIHdoZW4gbmV3CiAgICAqIHNjaGVtYUxvY2F0aW9ucyBhcmUgb2ZmZXJlZC4KICAgICoKICAgICogWFNWICh2ZXIgMi41LTIpIGRvZXMgdXNlIHRoZSBmaXJzdCA8aW1wb3J0PiB3aGljaCByZXNvbHZlcyB0byBhIHZhbGlkIHNjaGVtYS4KICAgICogWGVyY2VzLUogKHZlciAyLjUuMSkgaWdub3JlcyBhbGwgYnV0IHRoZSBmaXJzdCBnaXZlbiA8aW1wb3J0PiAtIHJlZ2FyZGxlc3MgaWYKICAgICogdmFsaWQgb3Igbm90LgogICAgKiBXZSB3aWxsIGZvbGxvdyBYU1YgaGVyZS4gCiAgICAqLwogICAgaWYgKGxvY2F0aW9uID09IE5VTEwpIHsKCS8qCgkqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneToKCSoKCSogMyBCYXNlZCBvbiB0aGUgbmFtZXNwYWNlIG5hbWUsIGlkZW50aWZ5IGFuIGV4aXN0aW5nIHNjaGVtYSBkb2N1bWVudCwKCSogZWl0aGVyIGFzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gWE1MIGRvY3VtZW50IG9yIGEgPHNjaGVtYT4gZWxlbWVudCAKCSogaW5mb3JtYXRpb24gaXRlbSwgaW4gc29tZSBsb2NhbCBzY2hlbWEgcmVwb3NpdG9yeTsgCgkqCgkqIDUgQXR0ZW1wdCB0byByZXNvbHZlIHRoZSBuYW1lc3BhY2UgbmFtZSB0byBsb2NhdGUgc3VjaCBhIHJlc291cmNlLiAKCSoKCSogTk9URTogVGhvc2Ugc3RhdGVnaWVzIGFyZSBub3Qgc3VwcG9ydGVkLCBzbyB3ZSB3aWxsIHNraXAuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIGlmIChuc05hbWUgPT0gTlVMTCkgCglucyA9IFhNTF9TQ0hFTUFTX05PX05BTUVTUEFDRTsKICAgIGVsc2UKCW5zID0gbnNOYW1lOwogICAgCiAgICBpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5zKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewkKCS8qCgkqIFRoZXJlIHdhcyBhIHZhbGlkIHJlc291cmNlIGZvciB0aGUgc3BlY2lmaWVkIG5hbWVzcGFjZSBhbHJlYWR5CgkqIGRlZmluZWQsIHNvIHNraXAuCgkqIFRPRE86IFRoaXMgbWlnaHQgYmUgY2hhbmdlZCBzb21lZGF5IHRvIGFsbG93IGltcG9ydCBvZgoJKiBjb21wb25lbnRzIGZyb20gbXVsdGlwbGUgZG9jdW1lbnRzIGZvciBhIHNpbmdsZSB0YXJnZXQgbmFtZXNwYWNlLgoJKi8KCXJldHVybiAoMCk7CiAgICB9IAogICAKICAgIC8qCiAgICAqIFNjaGVtYSBEb2N1bWVudCBMb2NhdGlvbiBTdHJhdGVneTogCiAgICAqCiAgICAqIDIgQmFzZWQgb24gdGhlIGxvY2F0aW9uIFVSSSwgaWRlbnRpZnkgYW4gZXhpc3Rpbmcgc2NoZW1hIGRvY3VtZW50LCAKICAgICogZWl0aGVyIGFzIGEgcmVzb3VyY2Ugd2hpY2ggaXMgYW4gWE1MIGRvY3VtZW50IG9yIGEgPHNjaGVtYT4gZWxlbWVudCAKICAgICogaW5mb3JtYXRpb24gaXRlbSwgaW4gc29tZSBsb2NhbCBzY2hlbWEgcmVwb3NpdG9yeTsgICAKICAgICoKICAgICogNCBBdHRlbXB0IHRvIHJlc29sdmUgdGhlIGxvY2F0aW9uIFVSSSwgdG8gbG9jYXRlIGEgcmVzb3VyY2Ugb24gdGhlIAogICAgKiB3ZWIgd2hpY2ggaXMgb3IgY29udGFpbnMgb3IgcmVmZXJlbmNlcyBhIDxzY2hlbWE+IGVsZW1lbnQ7CiAgICAqIFRPRE86IEhtbSwgSSBkb24ndCBrbm93IGlmIHRoZSByZWZlcmVuY2Ugc3R1ZmYgaW4gNC4gd2lsbCB3b3JrLgogICAgKgogICAgKi8KICAgIGlmICgoYWJzb2x1dGUgPT0gMCkgJiYgKG5vZGUgIT0gTlVMTCkpIHsKCXhtbENoYXIgKmJhc2UsICpVUkk7CgoJYmFzZSA9IHhtbE5vZGVHZXRCYXNlKG5vZGUtPmRvYywgbm9kZSk7CglpZiAoYmFzZSA9PSBOVUxMKSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIG5vZGUtPmRvYy0+VVJMKTsKCX0gZWxzZSB7CgkgICAgVVJJID0geG1sQnVpbGRVUkkobG9jYXRpb24sIGJhc2UpOwoJICAgIHhtbEZyZWUoYmFzZSk7Cgl9CglpZiAoVVJJICE9IE5VTEwpIHsKCSAgICBsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgVVJJLCAtMSk7CgkgICAgeG1sRnJlZShVUkkpOwoJfQogICAgfQogICAgcGFyc2VyQ3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKICAgIGlmIChwYXJzZXJDdHh0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgInhtbFNjaGVtYVBhcnNlSW1wb3J0OiAiCgkgICAgImFsbG9jYXRpbmcgYSBwYXJzZXIgY29udGV4dCIsIE5VTEwpOwoJcmV0dXJuKC0xKTsKICAgIH0JICAgCiAgICAKICAgIGlmICgoY3R4dC0+ZGljdCAhPSBOVUxMKSAmJiAocGFyc2VyQ3R4dC0+ZGljdCAhPSBOVUxMKSkgewoJeG1sRGljdEZyZWUocGFyc2VyQ3R4dC0+ZGljdCk7CglwYXJzZXJDdHh0LT5kaWN0ID0gY3R4dC0+ZGljdDsKCXhtbERpY3RSZWZlcmVuY2UocGFyc2VyQ3R4dC0+ZGljdCk7CiAgICB9CiAgICAKICAgICpkb2MgPSB4bWxDdHh0UmVhZEZpbGUocGFyc2VyQ3R4dCwgKGNvbnN0IGNoYXIgKikgbG9jYXRpb24sIAoJICAgIE5VTEwsIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CgogICAgLyoKICAgICogMi4xIFRoZSByZWZlcmVudCBpcyAoYSBmcmFnbWVudCBvZikgYSByZXNvdXJjZSB3aGljaCBpcyBhbiAKICAgICogWE1MIGRvY3VtZW50IChzZWUgY2xhdXNlIDEuMSksIHdoaWNoIGluIHR1cm4gY29ycmVzcG9uZHMgdG8gCiAgICAqIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluIGEgd2VsbC1mb3JtZWQgaW5mb3JtYXRpb24gCiAgICAqIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyB0byBhIHZhbGlkIHNjaGVtYS4KICAgICogVE9ETzogV2hhdCB0byBkbyB3aXRoIHRoZSAiZnJhZ21lbnQiIHN0dWZmPwogICAgKgogICAgKiAyLjIgVGhlIHJlZmVyZW50IGlzIGEgPHNjaGVtYT4gZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGluIAogICAgKiBhIHdlbGwtZm9ybWVkIGluZm9ybWF0aW9uIHNldCwgd2hpY2ggaW4gdHVybiBjb3JyZXNwb25kcyAKICAgICogdG8gYSB2YWxpZCBzY2hlbWEuCiAgICAqIE5PVEU6IDIuMiB3b24ndCBhcHBseSwgc2luY2Ugb25seSBYTUwgZG9jdW1lbnRzIHdpbGwgYmUgcHJvY2Vzc2VkIAogICAgKiBoZXJlLgogICAgKi8gICAgICAgCiAgICBpZiAoKmRvYyA9PSBOVUxMKSB7CQoJeG1sRXJyb3JQdHIgbGVycjsKCS8qCgkqIEl0IGlzICpub3QqIGFuIGVycm9yIGZvciB0aGUgYXBwbGljYXRpb24gc2NoZW1hIHJlZmVyZW5jZSAKCSogc3RyYXRlZ3kgdG8gZmFpbC4KCSogCgkqIElmIHRoZSBkb2MgaXMgTlVMTCBhbmQgdGhlIHBhcnNlciBlcnJvciBpcyBhbiBJTyBlcnJvciB3ZQoJKiB3aWxsIGFzc3VtZSB0aGF0IHRoZSByZXNvdXJjZSBjb3VsZCBub3QgYmUgbG9jYXRlZCBvciBhY2Nlc3NlZC4KCSoKCSogVE9ETzogVHJ5IHRvIGZpbmQgc3BlY2lmaWMgZXJyb3IgY29kZXMgdG8gcmVhY3Qgb25seSBvbgoJKiBsb2NhbGlzYXRpb24gZmFpbHVyZXMuCgkqCgkqIFRPRE8sIEZJWE1FOiBDaGVjayB0aGUgc3BlYzogaXMgYSBuYW1lc3BhY2UgYWRkZWQgdG8gdGhlIGltcG9ydGVkCgkqIG5hbWVzcGFjZXMsIGV2ZW4gaWYgdGhlIHNjaGVtYUxvY2F0aW9uIGRpZCBub3QgcHJvdmlkZQoJKiBhIHJlc291cmNlPyBJIGd1ZXNzIHNvLCBzaW5jZSBvbWl0dGluZyB0aGUgInNjaGVtYUxvY2F0aW9uIgoJKiBhdHRyaWJ1dGUsIGltcG9ydHMgYSBuYW1lc3BhY2UgYXMgd2VsbC4KCSovCglsZXJyID0geG1sR2V0TGFzdEVycm9yKCk7CglpZiAoKGxlcnIgIT0gTlVMTCkgJiYgKGxlcnItPmRvbWFpbiA9PSBYTUxfRlJPTV9JTykpIHsJCgkgICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CgkgICAgcmV0dXJuKDApOwoJfQoKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJGYWlsZWQgdG8gcGFyc2UgdGhlIHJlc291cmNlICclcycgZm9yIGltcG9ydCIsCgkgICAgbG9jYXRpb24pOwoJeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CglyZXR1cm4oWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEpOwogICAgfQogICAgeG1sRnJlZVBhcnNlckN0eHQocGFyc2VyQ3R4dCk7CiAgICAKICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudCgqZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIGxvY2F0aW9uKTsJCgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMl8xKTsKICAgIH0JCiAgICAKICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CQogICAgCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzJfMSwKCSAgICBOVUxMLCBOVUxMLCBub2RlLAoJICAgICJUaGUgWE1MIGRvY3VtZW50ICclcycgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGEgWE1MIHNjaGVtYSBkb2N1bWVudCIsCgkgICAgbG9jYXRpb24pOwkKCXhtbEZyZWVEb2MoKmRvYyk7CgkqZG9jID0gTlVMTDsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8yXzEpOwogICAgfQkKICAgICp0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIHJvb3QsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiBJbXBvcnQgQ29uc3RyYWludHMgYW5kIFNlbWFudGljcwogICAgKi8gICAgCiAgICBpZiAobnNOYW1lID09IE5VTEwpIHsKCWlmICgqdGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIFhNTCBzY2hlbWEgdG8gYmUgaW1wb3J0ZWQgaXMgbm90IGV4cGVjdGVkICIKCQkidG8gaGF2ZSBhIHRhcmdldCBuYW1lc3BhY2U7IHRoaXMgZGlmZmVycyBmcm9tICIKCQkiaXRzIHRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJyIsICp0YXJnZXROYW1lc3BhY2UpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMik7Cgl9CiAgICB9IGVsc2UgewoJaWYgKCp0YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgWE1MIHNjaGVtYSB0byBiZSBpbXBvcnRlZCBpcyBleHBlY3RlZCB0byBoYXZlIGEgdGFyZ2V0ICIKCQkibmFtZXNwYWNlIG9mICclcyciLCBuc05hbWUpOwoJICAgIHhtbEZyZWVEb2MoKmRvYyk7CgkgICAgKmRvYyA9IE5VTEw7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSk7Cgl9IGVsc2UgaWYgKCF4bWxTdHJFcXVhbCgqdGFyZ2V0TmFtZXNwYWNlLCBuc05hbWUpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfM18xLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSBYTUwgc2NoZW1hIHRvIGJlIGltcG9ydGVkIGlzIGV4cGVjdGVkIHRvIGhhdmUgYSAiCgkJInRhcmdldCBuYW1lc3BhY2Ugb2YgJyVzJzsgdGhpcyBkaWZmZXJzIGZyb20gIgoJCSJpdHMgdGFyZ2V0IG5hbWVzcGFjZSBvZiAnJXMnIiwgCgkJbnNOYW1lLCAqdGFyZ2V0TmFtZXNwYWNlLCBOVUxMKTsKCSAgICB4bWxGcmVlRG9jKCpkb2MpOwoJICAgICpkb2MgPSBOVUxMOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEpOwoJfQogICAgfQoKICAgIGltcG9ydCA9IHhtbFNjaGVtYUFkZEltcG9ydChjdHh0LCAmKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMpLCBuc05hbWUpOwogICAgaWYgKGltcG9ydCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkgICAgTlVMTCwgTlVMTCwgTlVMTCwJICAgIAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYywgIgoJICAgICJmYWlsZWQgdG8gYnVpbGQgaW1wb3J0IHRhYmxlIiwgTlVMTCk7Cgl4bWxGcmVlRG9jKCpkb2MpOwoJKmRvYyA9IE5VTEw7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBsb2NhdGlvbjsKICAgIGltcG9ydC0+ZG9jID0gKmRvYzsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUltcG9ydDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgSW1wb3J0IGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgaWYgCiAqIG5vdCB2YWxpZCBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBlcnJvci4gCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVBhcnNlSW1wb3J0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgIAogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbiA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp0YXJnZXROYW1lc3BhY2UsICpvbGRUTlMsICp1cmw7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sTm9kZVB0ciByb290OwogICAgaW50IGZsYWdzLCByZXQgPSAwOwoKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICAvKgogICAgKiBDaGVjayBmb3IgaWxsZWdhbCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGF0dHIgPSBub2RlLT5wcm9wZXJ0aWVzOwogICAgd2hpbGUgKGF0dHIgIT0gTlVMTCkgewoJaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCSAgICBpZiAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJuYW1lc3BhY2UiKSkgJiYKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCBOVUxMLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIE5VTEwsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0JCiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAKCSJuYW1lc3BhY2UiLCB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllVUkkpLCAKCSZuYW1lc3BhY2UpICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCSAgICAKCSAgICBYTUxfU0NIRU1BUF9JTVBPUlRfTkFNRVNQQUNFX05PVF9VUkksIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIAoJICAgIE5VTEwsIG5hbWVzcGFjZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0lNUE9SVF9OQU1FU1BBQ0VfTk9UX1VSSSk7CiAgICB9CgogICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIAoJInNjaGVtYUxvY2F0aW9uIiwgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVVJJKSwgCgkmc2NoZW1hTG9jYXRpb24pICE9IDApIHsKCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsCSAgICAKCSAgICBYTUxfU0NIRU1BUF9JTVBPUlRfU0NIRU1BX05PVF9VUkksIAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksIAoJICAgIE5VTEwsIG5hbWVzcGFjZSwgTlVMTCwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0lNUE9SVF9TQ0hFTUFfTk9UX1VSSSk7CiAgICB9ICAgIAogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZSBhbm5vdGF0aW9uIGhlcmUgaXMgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTVBPUlRfQ0hJTEQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPykiKTsKICAgIH0KICAgIC8qCiAgICAqIEFwcGx5IGFkZGl0aW9uYWwgY29uc3RyYWludHMuCiAgICAqLwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKSB7CgkvKgoJKiAxLjEgSWYgdGhlIG5hbWVzcGFjZSBbYXR0cmlidXRlXSBpcyBwcmVzZW50LCB0aGVuIGl0cyC3YWN0dWFsIHZhbHVltyAKCSogbXVzdCBub3QgbWF0Y2ggdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBlbmNsb3NpbmcgPHNjaGVtYT4ncyAKCSogdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLgoJKi8KCWlmICh4bWxTdHJFcXVhbChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgbmFtZXNwYWNlKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzFfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IG5vdCBtYXRjaCAiCgkJInRoZSB0YXJnZXQgbmFtZXNwYWNlICclcycgb2YgdGhlIGltcG9ydGluZyBzY2hlbWEiLAoJCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19JTVBPUlRfMV8xKTsKCX0KICAgIH0gZWxzZSB7CgkvKgoJKiAxLjIgSWYgdGhlIG5hbWVzcGFjZSBbYXR0cmlidXRlXSBpcyBub3QgcHJlc2VudCwgdGhlbiB0aGUgZW5jbG9zaW5nIAoJKiA8c2NoZW1hPiBtdXN0IGhhdmUgYSB0YXJnZXROYW1lc3BhY2UgW2F0dHJpYnV0ZV0uCgkqLwoJaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIGF0dHJpYnV0ZSAnbmFtZXNwYWNlJyBtdXN0IGJlIGV4aXN0ZW50IGlmICIKCQkidGhlIGltcG9ydGluZyBzY2hlbWEgaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLAoJCU5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8xXzIpOwoJfQogICAgfQogICAgLyoKICAgICogTG9jYXRlIGFuZCBhcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKGN0eHQsIHNjaGVtYSwgbm9kZSwgbmFtZXNwYWNlLCAKCXNjaGVtYUxvY2F0aW9uLCAmZG9jLCAmdGFyZ2V0TmFtZXNwYWNlLCAwKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKGRvYyAhPSBOVUxMKQoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCXJldHVybiAocmV0KTsKICAgIH0gZWxzZSBpZiAoZG9jICE9IE5VTEwpIHsgICAgICAgCgkvKgoJKiBTYXZlIGFuZCByZXNldCB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCgl1cmwgPSBjdHh0LT5VUkw7ICAKCS8qIFRPRE86IElzIHVzaW5nIHRoZSBkb2MtPlVSTCBoZXJlIGNvcnJlY3Q/ICovCgljdHh0LT5VUkwgPSBkb2MtPlVSTDsKCWZsYWdzID0gc2NoZW1hLT5mbGFnczsKCW9sZFROUyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJLyoKCSogUGFyc2UgdGhlIHNjaGVtYS4KCSovCglyb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKCXhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMoY3R4dCwgc2NoZW1hLCByb290KTsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TmFtZXNwYWNlOwoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChjdHh0LCBzY2hlbWEsIHJvb3QtPmNoaWxkcmVuKTsKCS8qCgkqIFJlc3RvcmUgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJc2NoZW1hLT5mbGFncyA9IGZsYWdzOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBvbGRUTlM7CgljdHh0LT5VUkwgPSB1cmw7CiAgICB9CiAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUluY2x1ZGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEluY2x1ZGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnNjaGVtYUxvY2F0aW9uLCAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIHhtbFNjaGVtYUluY2x1ZGVQdHIgaW5jbHVkZTsKICAgIGludCB3YXNDb252ZXJ0aW5nTnMgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgaW50IHNhdmVGbGFnczsKICAgIHhtbFBhcnNlckN0eHRQdHIgcGFyc2VyQ3R4dDsKCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iKSkpIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkgICAgTlVMTCwgTlVMTCwgYXR0cik7CQkgICAgCgkgICAgfQoJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSB7CgkgICAgeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQlOVUxMLCBOVUxMLCBhdHRyKTsJCQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwKCW5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgLyoKICAgICAqIFByZWxpbWluYXJ5IHN0ZXAsIGV4dHJhY3QgdGhlIFVSSS1SZWZlcmVuY2UgZm9yIHRoZSBpbmNsdWRlIGFuZAogICAgICogbWFrZSBhbiBVUkkgZnJvbSB0aGUgYmFzZS4KICAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJzY2hlbWFMb2NhdGlvbiIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewogICAgICAgIHhtbENoYXIgKmJhc2UgPSBOVUxMOwogICAgICAgIHhtbENoYXIgKnVyaSA9IE5VTEw7CgoJaWYgKHhtbFNjaGVtYVBWYWxBdHRyTm9kZShjdHh0LCBOVUxMLCBOVUxMLCBhdHRyLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZzY2hlbWFMb2NhdGlvbikgIT0gMCkKCSAgICByZXR1cm4gKC0xKTsKCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIHVyaSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBiYXNlKTsKCSAgICB4bWxGcmVlKGJhc2UpOwoJfQoJaWYgKHVyaSAhPSBOVUxMKSB7CgkgICAgc2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHVyaSwgLTEpOwoJICAgIHhtbEZyZWUodXJpKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9fVVJJLCAKCSAgICBOVUxMLCBOVUxMLCBub2RlLCAic2NoZW1hTG9jYXRpb24iLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZSBhbm5vdGF0aW9ucyBoZXJlIGFyZSBzaW1wbHkgZGlzY2FyZGVkIC4uLgogICAgICAgICAqLwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTkNMVURFX0NISUxELAoJICAgIE5VTEwsIE5VTEwsIG5vZGUsIGNoaWxkLCBOVUxMLAoJICAgICIoYW5ub3RhdGlvbj8pIik7CiAgICB9CgogICAgLyoKICAgICAqIEZpcnN0IHN0ZXAgaXMgdG8gcGFyc2UgdGhlIGlucHV0IGRvY3VtZW50IGludG8gYW4gRE9NL0luZm9zZXQKICAgICAqLwogICAgLyogCiAgICAqIFRPRE86IFVzZSB4bWxDdHh0UmVhZEZpbGUgdG8gc2hhcmUgdGhlIGRpY3Rpb25hcnkuCiAgICAqLwogICAgcGFyc2VyQ3R4dCA9IHhtbE5ld1BhcnNlckN0eHQoKTsKICAgIGlmIChwYXJzZXJDdHh0ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgInhtbFNjaGVtYVBhcnNlSW5jbHVkZTogIgoJICAgICJhbGxvY2F0aW5nIGEgcGFyc2VyIGNvbnRleHQiLCBOVUxMKTsKCXJldHVybigtMSk7CiAgICB9CSAgIAogICAgCiAgICBpZiAoKGN0eHQtPmRpY3QgIT0gTlVMTCkgJiYgKHBhcnNlckN0eHQtPmRpY3QgIT0gTlVMTCkpIHsKCXhtbERpY3RGcmVlKHBhcnNlckN0eHQtPmRpY3QpOwoJcGFyc2VyQ3R4dC0+ZGljdCA9IGN0eHQtPmRpY3Q7Cgl4bWxEaWN0UmVmZXJlbmNlKHBhcnNlckN0eHQtPmRpY3QpOwogICAgfQogICAgCiAgICBkb2MgPSB4bWxDdHh0UmVhZEZpbGUocGFyc2VyQ3R4dCwgKGNvbnN0IGNoYXIgKikgc2NoZW1hTG9jYXRpb24sIAoJICAgIE5VTEwsIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyk7CiAgICB4bWxGcmVlUGFyc2VyQ3R4dChwYXJzZXJDdHh0KTsKICAgIGlmIChkb2MgPT0gTlVMTCkgewoJLyoKCSogVE9ETzogSXQgaXMgbm90IGFuIGVycm9yIGZvciB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIAoJKiBzY2hlbWFMb2NhdGlvbiBbYXR0cmlidXRlXSB0byBmYWlsIHRvIHJlc29sdmUgaXQgYWxsLCBpbiB3aGljaCAKCSogY2FzZSBubyBjb3JyZXNwb25kaW5nIGluY2x1c2lvbiBpcyBwZXJmb3JtZWQuIAoJKiBTbyBkbyB3ZSBuZWVkIGEgd2FybmluZyByZXBvcnQgaGVyZT8KCSovCgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgCgkgICAgIkZhaWxlZCB0byBsb2FkIHRoZSBkb2N1bWVudCAnJXMnIGZvciBpbmNsdXNpb24iLCBzY2hlbWFMb2NhdGlvbik7CglyZXR1cm4oLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGVuIGV4dHJhY3QgdGhlIHJvb3Qgb2YgdGhlIHNjaGVtYQogICAgICovCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGluY2x1ZGVkIGRvY3VtZW50ICclcycgaGFzIG5vIGRvY3VtZW50ICIKCSAgICAiZWxlbWVudCIsIHNjaGVtYUxvY2F0aW9uKTsJCQoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIENoZWNrIHRoZSBzY2hlbWFzIHRvcCBsZXZlbCBlbGVtZW50CiAgICAgKi8KICAgIGlmICghSVNfU0NIRU1BKHJvb3QsICJzY2hlbWEiKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwKCSAgICAiVGhlIGRvY3VtZW50ICclcycgdG8gYmUgaW5jbHVkZWQgaXMgbm90IGEgc2NoZW1hIGRvY3VtZW50IiwgCgkgICAgc2NoZW1hTG9jYXRpb24pOwoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgCiAgICB0YXJnZXROYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIHJvb3QsICJ0YXJnZXROYW1lc3BhY2UiKTsKICAgIC8qCiAgICAqIDIuMSBTSUkgaGFzIGEgdGFyZ2V0TmFtZXNwYWNlIFthdHRyaWJ1dGVdLCBhbmQgaXRzILdhY3R1YWwgCiAgICAqIHZhbHVltyBpcyBpZGVudGljYWwgdG8gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0YXJnZXROYW1lc3BhY2UgCiAgICAqIFthdHRyaWJ1dGVdIG9mIFNJSZIgKHdoaWNoIG11c3QgaGF2ZSBzdWNoIGFuIFthdHRyaWJ1dGVdKS4KICAgICovCiAgICBpZiAodGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCWlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19JTkNMVURFLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIlRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIHRoZSBpbmNsdWRlZCBzY2hlbWEgIgoJCSInJXMnIGhhcyB0byBiZSBhYnNlbnQsIHNpbmNlIHRoZSBpbmNsdWRpbmcgc2NoZW1hICIKCQkiaGFzIG5vIHRhcmdldCBuYW1lc3BhY2UiLCAKCQlzY2hlbWFMb2NhdGlvbik7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJICAgIHJldHVybiAoLTEpOwoJfSBlbHNlIGlmICgheG1sU3RyRXF1YWwodGFyZ2V0TmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJWE1MX1NDSEVNQVBfU1JDX0lOQ0xVREUsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiVGhlIHRhcmdldCBuYW1lc3BhY2UgJyVzJyBvZiB0aGUgaW5jbHVkZWQgc2NoZW1hICclcycgIgoJCSJkaWZmZXJzIGZyb20gJyVzJyBvZiB0aGUgaW5jbHVkaW5nIHNjaGVtYSIsIAoJCXRhcmdldE5hbWVzcGFjZSwgc2NoZW1hTG9jYXRpb24sIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKCSAgICB4bWxGcmVlRG9jKGRvYyk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9IGVsc2UgaWYgKHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsgICAgIAkKCWlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSA9PSAwKSB7CgkgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19JTkNMVURJTkdfQ09OVkVSVF9OUzsJICAgIAoJfSBlbHNlCgkgICAgd2FzQ29udmVydGluZ05zID0gMTsKICAgIH0KICAgIC8qCiAgICAgKiByZWdpc3RlciB0aGUgaW5jbHVkZQogICAgICovCiAgICBpbmNsdWRlID0gKHhtbFNjaGVtYUluY2x1ZGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSW5jbHVkZSkpOwogICAgaWYgKGluY2x1ZGUgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgaW5jbHVkZWQgc2NoZW1hIiwgTlVMTCk7Cgl4bWxGcmVlRG9jKGRvYyk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgbWVtc2V0KGluY2x1ZGUsIDAsIHNpemVvZih4bWxTY2hlbWFJbmNsdWRlKSk7CiAgICBpbmNsdWRlLT5zY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKICAgIGluY2x1ZGUtPmRvYyA9IGRvYzsKICAgIGluY2x1ZGUtPm5leHQgPSBzY2hlbWEtPmluY2x1ZGVzOwogICAgc2NoZW1hLT5pbmNsdWRlcyA9IGluY2x1ZGU7CgogICAgLyoKICAgICAqIHBhcnNlIHRoZSBkZWNsYXJhdGlvbnMgaW4gdGhlIGluY2x1ZGVkIGZpbGUgbGlrZSBpZiB0aGV5CiAgICAgKiB3ZXJlIGluIHRoZSBvcmlnaW5hbCBmaWxlLgogICAgICovICAgIAogICAgLyoKICAgICogVE9ETzogVGhlIGNvbXBsZXRlIHZhbGlkYXRpb24gb2YgdGhlIDxzY2hlbWE+IGVsZW1lbnQgaXMgbm90IGRvbmUuCiAgICAqLwogICAgLyogICAgCiAgICAqIFRoZSBkZWZhdWx0IHZhbHVlcyAoImJsb2NrRGVmYXVsdCIsICJlbGVtZW50Rm9ybURlZmF1bHQiLCBldGMuKQogICAgKiBhcmUgc2V0IHRvIHRoZSB2YWx1ZXMgb2YgdGhlIGluY2x1ZGVkIHNjaGVtYSBhbmQgcmVzdG9yZWQgYWZ0ZXJ3YXJkcy4KICAgICovICAgIAogICAgc2F2ZUZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIHhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMoY3R4dCwgc2NoZW1hLCByb290KTsKICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCByb290LT5jaGlsZHJlbik7CiAgICBzY2hlbWEtPmZsYWdzID0gc2F2ZUZsYWdzOwogICAgLyoKICAgICogUmVtb3ZlIHRoZSBjb252ZXJ0aW5nIGZsYWcuCiAgICAqLwogICAgaWYgKCh3YXNDb252ZXJ0aW5nTnMgPT0gMCkgJiYgCgkoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0lOQ0xVRElOR19DT05WRVJUX05TKSkKCXNjaGVtYS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfSU5DTFVESU5HX0NPTlZFUlRfTlM7CiAgICByZXR1cm4gKDEpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDaG9pY2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENob2ljZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ2hvaWNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiI2NoJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCwgbm9kZSk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWF4T2NjdXJzIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWluT2NjdXJzIikpKSB7CgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgIE5VTEwsIHR5cGUsIGF0dHIpOwkJICAgIAoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJTlVMTCwgdHlwZSwgYXR0cik7CQkKCX0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogRXh0cmFjdCBhbmQgdmFsaWRhdGUgYXR0cmlidXRlcy4KICAgICovCiAgICB4bWxTY2hlbWFQVmFsQXR0cklEKGN0eHQsIE5VTEwsIE5VTEwsIG5vZGUsIEJBRF9DQVNUICJpZCIpOwogICAgdHlwZS0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUsIDAsIC0xLCAxLCAibm9uTmVnYXRpdmVJbnRlZ2VyIik7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSwgMCwgVU5CT1VOREVELCAxLCAKCSIobm9uTmVnYXRpdmVJbnRlZ2VyIHwgdW5ib3VuZGVkKSIpOwogICAgLyoKICAgICogQW5kIG5vdyBmb3IgdGhlIGNoaWxkcmVuLi4uCiAgICAqLwogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwogICAgY3R4dC0+Y29udGFpbmVyID0gKGNvbnN0IHhtbENoYXIgKikgbmFtZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpKSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CiAgICAgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUVsZW1lbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQW55KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyogVE9ETzogZXJyb3IgY29kZS4gKi8KCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9DSE9JQ0VfQ0hJTEQsCgkgICAgTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkgICAgIihhbm5vdGF0aW9uPywgKGVsZW1lbnQgfCBncm91cCB8IGNob2ljZSB8IHNlcXVlbmNlIHwgYW55KSopIik7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBvbGRjb250YWluZXI7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2VxdWVuY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiNzZXElZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTsKICAgIC8qCiAgICAqIENoZWNrIGZvciBpbGxlZ2FsIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICgoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1pbk9jY3VycyIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIHR5cGUsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIEV4dHJhY3QgYW5kIHZhbGlkYXRlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlLCAwLCAtMSwgMSwgIm5vbk5lZ2F0aXZlSW50ZWdlciIpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUsIDAsIFVOQk9VTkRFRCwgMSwgCgkiKG5vbk5lZ2F0aXZlSW50ZWdlciB8IHVuYm91bmRlZCkiKTsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIGN0eHQtPmNvbnRhaW5lciA9IChjb25zdCB4bWxDaGFyICopIG5hbWU7CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSkgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUFueShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TRVFVRU5DRV9DSElMRCwKCSAgICBOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCSAgICAiKGFubm90YXRpb24/LCAoZWxlbWVudCB8IGdyb3VwIHwgY2hvaWNlIHwgc2VxdWVuY2UgfCBhbnkpKikiKTsKICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgUmVzdHJpY3Rpb24gZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOyAgICAKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIGNvbnN0IHhtbENoYXIgKm9sZGNvbnRhaW5lcjsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgIiNyZXN0ciVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiYmFzZSIpKSkgewoJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCSAgICBOVUxMLCB0eXBlLCBhdHRyKTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpIHsKCSAgICB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsIAoJCU5VTEwsIHR5cGUsIGF0dHIpOwkJCgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0JCiAgICAvKgogICAgKiBFeHRyYWN0IGFuZCB2YWxpZGF0ZSBhdHRyaWJ1dGVzLgogICAgKi8KICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CiAgICAvKgogICAgKiBBdHRyaWJ1dGUgImJhc2UiLgogICAgKi8KICAgIHR5cGUtPmJhc2UgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgImJhc2UiLCAmKHR5cGUtPmJhc2VOcykpOwogICAgaWYgKCh0eXBlLT5iYXNlID09IE5VTEwpICYmIAoJKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSkgewoJLyogVE9ETzogVGhpbmsgYWJvdXQgdGhlIGVycm9yIGNvZGUuICovCgl4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9SRVNUUklDVElPTl9OT05BTUVfTk9SRUYsIAoJICAgIE5VTEwsIHR5cGUsIG5vZGUsICJiYXNlIiwgTlVMTCk7CiAgICB9CiAgICAvKgogICAgKiBBbmQgbm93IGZvciB0aGUgY2hpbGRyZW4uLi4KICAgICovCiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CgkgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCX0KICAgIH0gZWxzZSBpZiAoY3R4dC0+Y3R4dFR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIGlmICh0eXBlLT5iYXNlICE9IE5VTEwpIHsKCQkvKiAKCQkqIHNyYy1yZXN0cmljdGlvbi1iYXNlLW9yLXNpbXBsZVR5cGUKCQkqIEVpdGhlciB0aGUgYmFzZSBbYXR0cmlidXRlXSBvciB0aGUgc2ltcGxlVHlwZSBbY2hpbGRdIG9mIHRoZSAKCQkqIDxyZXN0cmljdGlvbj4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4gCgkJKi8KCQl4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVBfU1JDX1JFU1RSSUNUSU9OX0JBU0VfT1JfU0lNUExFVFlQRSwKCQkgICAgTlVMTCwgTlVMTCwgdHlwZS0+bm9kZSwgY2hpbGQsCgkJICAgICJUaGUgYXR0cmlidXRlICdiYXNlJyBhbmQgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCBhcmUgIgoJCSAgICAibXV0dWFsbHkgZXhjbHVzaXZlIiwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQlzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJICAgIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCQl0eXBlLT5iYXNlVHlwZSA9IHN1YnR5cGU7CgkgICAgfQkgICAgICAgIAoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKGN0eHQtPnBhcmVudEl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CgkgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQoJCXhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0JICAgICAgICAJCiAgICB9CiAgICBpZiAoKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSB7Cgl4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwgbGFzdGZhY2V0ID0gTlVMTDsJCgkJCgkvKgoJKiBBZGQgdGhlIGZhY2V0cyB0byB0aGUgcGFyZW50IHNpbXBsZVR5cGUvY29tcGxleFR5cGUuCgkqLwoJLyoKCSogVE9ETzogRGF0YXR5cGVzOiA0LjEuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb24gb2YgCgkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAoJKiAqU2luZ2xlIEZhY2V0IFZhbHVlKgoJKi8KCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAibWluSW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtYXhJbmNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4RXhjbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInRvdGFsRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImZyYWN0aW9uRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInBhdHRlcm4iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZW51bWVyYXRpb24iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAid2hpdGVTcGFjZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJsZW5ndGgiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4TGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkxlbmd0aCIpKSkgewoJICAgIGZhY2V0ID0geG1sU2NoZW1hUGFyc2VGYWNldChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoZmFjZXQgIT0gTlVMTCkgewoJCWlmIChsYXN0ZmFjZXQgPT0gTlVMTCkKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZhY2V0cyA9IGZhY2V0OwkJCQoJCWVsc2UKCQkgICAgbGFzdGZhY2V0LT5uZXh0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCS8qCgkqIENyZWF0ZSBsaW5rcyBmb3IgZGVyaXZhdGlvbiBhbmQgdmFsaWRhdGlvbi4KCSovCSAgICAKCWlmIChsYXN0ZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbmssIGxhc3RGYWNldExpbmsgPSBOVUxMOwoKCSAgICBmYWNldCA9IGN0eHQtPmN0eHRUeXBlLT5mYWNldHM7CgkgICAgZG8gewkJICAgIAoJCWZhY2V0TGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkJaWYgKGZhY2V0TGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJICAgIHhtbEZyZWUoZmFjZXRMaW5rKTsKCQkgICAgcmV0dXJuIChOVUxMKTsKCQl9CQoJCWZhY2V0TGluay0+ZmFjZXQgPSBmYWNldDsKCQlmYWNldExpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0RmFjZXRMaW5rID09IE5VTEwpIAoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmFjZXRTZXQgPSBmYWNldExpbms7CQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQllbHNlCgkJICAgIGxhc3RGYWNldExpbmstPm5leHQgPSBmYWNldExpbms7CgkJbGFzdEZhY2V0TGluayA9IGZhY2V0TGluazsKCQlmYWNldCA9IGZhY2V0LT5uZXh0OwoJICAgIH0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJfQogICAgfSAgICAKICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewoJICAgIGN0eHQtPmN0eHRUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJLyogVE9ETzogVGhpbmsgYWJvdXQgdGhlIGVycm9yIGNvZGUuICovCglpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQQ29udGVudEVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9VTktOT1dOX1JFU1RSSUNUSU9OX0NISUxELCAKCQlOVUxMLCB0eXBlLCBub2RlLCBjaGlsZCwgTlVMTCwKCQkiYW5ub3RhdGlvbj8sIChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICIKCQkiKChhdHRyaWJ1dGUgfCBhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkiKTsKCX0gZWxzZSBpZiAoY3R4dC0+cGFyZW50SXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpIHsKCSAgICAgeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfVU5LTk9XTl9SRVNUUklDVElPTl9DSElMRCwgCgkJTlVMTCwgdHlwZSwgbm9kZSwgY2hpbGQsIE5VTEwsCgkJIihhbm5vdGF0aW9uPywgKHNpbXBsZVR5cGU/LCAobWluRXhjbHVzaXZlIHwgbWluSW5jbHVzaXZlIHwgIgoJCSJtYXhFeGNsdXNpdmUgfCBtYXhJbmNsdXNpdmUgfCB0b3RhbERpZ2l0cyB8IGZyYWN0aW9uRGlnaXRzIHwgIgoJCSJsZW5ndGggfCBtaW5MZW5ndGggfCBtYXhMZW5ndGggfCBlbnVtZXJhdGlvbiB8IHdoaXRlU3BhY2UgfCAiCgkJInBhdHRlcm4pKik/LCAoKGF0dHJpYnV0ZSB8IGF0dHJpYnV0ZUdyb3VwKSosIGFueUF0dHJpYnV0ZT8pKSIpOwoJfSBlbHNlIHsKCSAgICAvKiBTaW1wbGUgdHlwZSAqLwoJICAgIHhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1VOS05PV05fUkVTVFJJQ1RJT05fQ0hJTEQsIAoJCU5VTEwsIHR5cGUsIG5vZGUsIGNoaWxkLCBOVUxMLAoJCSIoYW5ub3RhdGlvbj8sIChzaW1wbGVUeXBlPywgKG1pbkV4Y2x1c2l2ZSB8IG1pbkluY2x1c2l2ZSB8ICIKCQkibWF4RXhjbHVzaXZlIHwgbWF4SW5jbHVzaXZlIHwgdG90YWxEaWdpdHMgfCBmcmFjdGlvbkRpZ2l0cyB8ICIKCQkibGVuZ3RoIHwgbWluTGVuZ3RoIHwgbWF4TGVuZ3RoIHwgZW51bWVyYXRpb24gfCB3aGl0ZVNwYWNlIHwgIgoJCSJwYXR0ZXJuKSopKSIpOwoJfQogICAgfSAgICAgICAKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgRXh0ZW5zaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiI2V4dCVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwsIG5vZGUpOyAgICAKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIHR5cGUtPmJhc2UgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgImJhc2UiLCAmKHR5cGUtPmJhc2VOcykpOwogICAgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9FWFRFTlNJT05fTk9fQkFTRSwKCSAgICAiPGV4dGVuc2lvbj46IFRoZSBhdHRyaWJ1dGUgXCJiYXNlXCIgaXMgbWlzc2luZy5cbiIsIAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CgogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFsbCIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJncm91cCIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgaWYgKChjdHh0LT5jdHh0VHlwZSAhPSBOVUxMKSAmJgoJKGN0eHQtPmN0eHRUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSkgewoJY2hpbGQgPSB4bWxTY2hlbWFQYXJzZUF0dHJEZWNscyhjdHh0LCBzY2hlbWEsIGNoaWxkLCB0eXBlKTsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewkgICAgCgkgICAgY3R4dC0+Y3R4dFR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gCgkJeG1sU2NoZW1hUGFyc2VBbnlBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9FWFRFTlNJT05fQ0hJTEQsCgkgICAgIjxleHRlbnNpb24+IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLCB0eXBlLT5uYW1lLAoJICAgIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlQ29udGVudCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBvbGRQYXJlbnRJdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjU0MlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CgogICAgeG1sU2NoZW1hUFZhbEF0dHJJRChjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCBCQURfQ0FTVCAiaWQiKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBvbGRQYXJlbnRJdGVtID0gY3R4dC0+cGFyZW50SXRlbTsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgc3VidHlwZSA9IE5VTEw7ICAgIAogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlc3RyaWN0aW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlUmVzdHJpY3Rpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZXh0ZW5zaW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRXh0ZW5zaW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0lNUExFQ09OVEVOVF9DSElMRCwKCSAgICAiPHNpbXBsZUNvbnRlbnQ+IGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IG9sZFBhcmVudEl0ZW07CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBvbGRQYXJlbnRJdGVtOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICIjQ0MlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMLCBub2RlKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7ICAgIAogICAgLyoKICAgICogQ2hlY2sgZm9yIGlsbGVnYWwgYXR0cmlidXRlcy4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCWlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkgICAgaWYgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImlkIikpICYmCgkJKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkpIAoJICAgIHsKCQl4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfTk9UX0FMTE9XRUQsCgkJICAgIE5VTEwsIE5VTEwsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCU5VTEwsIE5VTEwsIGF0dHIpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CQoKICAgIHhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7CgogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZSAnbWl4ZWQnLgogICAgKi8KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBOVUxMLCB0eXBlLCBub2RlLCAibWl4ZWQiLCAwKSkgIHsKCWlmICgoY3R4dC0+Y3R4dFR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgPT0gMCkKCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NSVhFRDsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIG9sZFBhcmVudEl0ZW0gPSBjdHh0LT5wYXJlbnRJdGVtOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IHR5cGU7CiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZXN0cmljdGlvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImV4dGVuc2lvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBDb250ZW50RXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCgkgICAgTlVMTCwgTlVMTCwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHJlc3RyaWN0aW9uIHwgZXh0ZW5zaW9uKSkiKTsKICAgIH0KICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBvbGRQYXJlbnRJdGVtOwogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIENvbXBsZXggVHlwZSBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGNvbnN0IHhtbENoYXIgKmF0dHJWYWx1ZTsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7IC8qIFRoZSByZXBvcnRlZCBkZXNpZ25hdGlvbi4gKi8KICAgIGNoYXIgYnVmWzQwXTsKCgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoKICAgIGlmICh0b3BMZXZlbCkgewoJYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsICJuYW1lIik7CglpZiAoYXR0ciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUE1pc3NpbmdBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX01JU1NJTkcsIAoJCSh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0NULCBOVUxMLCBub2RlLAoJCSJuYW1lIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSBpZiAoeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIAoJICAgICh4bWxDaGFyICoqKSAmeG1sU2NoZW1hRWxlbURlc0NULCBOVUxMLCBhdHRyLCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OQ05BTUUpLCAmbmFtZSkgIT0gMCkgewoJICAgIHJldHVybiAoTlVMTCk7Cgl9CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKHRvcExldmVsID09IDApIHsKCS8qCgkqIFBhcnNlIGFzIGxvY2FsIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uLgoJKi8KICAgICAgICBzbnByaW50ZihidWYsIDM5LCAiI0NUJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgKGNvbnN0IHhtbENoYXIgKilidWYsIE5VTEwsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKCXR5cGUtPm5vZGUgPSBub2RlOwoJdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOwoJLyoKCSogVE9ETzogV2UgbmVlZCB0aGUgdGFyZ2V0IG5hbWVzcGFjZS4KCSovCQogICAgfSBlbHNlIHsJCgkvKgoJKiBQYXJzZSBhcyBnbG9iYWwgY29tcGxleCB0eXBlIGRlZmluaXRpb24uCgkqLwkKCXR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIG5vZGUpOwoJaWYgKHR5cGUgPT0gTlVMTCkKCSAgICByZXR1cm4gKE5VTEwpOwoJdHlwZS0+bm9kZSA9IG5vZGU7Cgl0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsJCgkvKiAKCSogU2V0IGRlZmF1bHRzLgoJKi8KCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfREVGQVVMVDsKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfREVGQVVMVDsKICAgIH0KICAgIHR5cGUtPnRhcmdldE5hbWVzcGFjZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CglpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiaWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgImlkIi4KCQkqLwoJCXhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgdHlwZSwgbm9kZSwKCQkgICAgQkFEX0NBU1QgImlkIik7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibWl4ZWQiKSkgewoJCS8qCgkJKiBBdHRyaWJ1dGUgIm1peGVkIi4KCQkqLwoJCWlmICh4bWxTY2hlbWFQR2V0Qm9vbE5vZGVWYWx1ZShjdHh0LCAmZGVzLCB0eXBlLCAKCQkgICAgKHhtbE5vZGVQdHIpIGF0dHIpKQoJCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOyAJCQoJICAgIH0gZWxzZSBpZiAodG9wTGV2ZWwpIHsJCQoJCS8qCgkJKiBBdHRyaWJ1dGVzIG9mIGdsb2JhbCBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbnMuCgkJKi8KCQlpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5hbWUiKSkgewoJCSAgICAvKiBQYXNzLiAqLwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgImFic3RyYWN0IikpIHsKCQkgICAgLyoKCQkgICAgKiBBdHRyaWJ1dGUgImFic3RyYWN0Ii4KCQkgICAgKi8KCQkgICAgaWYgKHhtbFNjaGVtYVBHZXRCb29sTm9kZVZhbHVlKGN0eHQsICZkZXMsIHR5cGUsIAoJCQkoeG1sTm9kZVB0cikgYXR0cikpCQkgICAgCgkJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1Q7CgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAiZmluYWwiKSkgewoJCSAgICAvKgoJCSAgICAqIEF0dHJpYnV0ZSAiZmluYWwiLgoJCSAgICAqLwoJCSAgICBhdHRyVmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAKCQkJKHhtbE5vZGVQdHIpIGF0dHIpOwoJCSAgICBpZiAoeG1sU2NoZW1hUFZhbEF0dHJCbG9ja0ZpbmFsKGF0dHJWYWx1ZSwgCgkJCSYodHlwZS0+ZmxhZ3MpLCAKCQkJLTEsIAoJCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTiwgCgkJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04sIAoJCQktMSwgLTEsIC0xKSAhPSAwKSAKCQkgICAgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX0lOVkFMSURfVkFMVUUsCgkJCSAgICAmZGVzLCB0eXBlLCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCSAgICBOVUxMLCAKCQkJICAgICIoI2FsbCB8IExpc3Qgb2YgKGV4dGVuc2lvbiB8IHJlc3RyaWN0aW9uKSkiLCAKCQkJICAgIGF0dHJWYWx1ZSwgTlVMTCwgTlVMTCwgTlVMTCk7CgkJICAgIH0KCQl9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJibG9jayIpKSB7CgkJICAgIC8qCgkJICAgICogQXR0cmlidXRlICJibG9jayIuCgkJICAgICovCQkJCgkJICAgIGF0dHJWYWx1ZSA9IHhtbFNjaGVtYUdldE5vZGVDb250ZW50KGN0eHQsIAoJCQkoeG1sTm9kZVB0cikgYXR0cik7CSAgICAKCQkgICAgaWYgKHhtbFNjaGVtYVBWYWxBdHRyQmxvY2tGaW5hbChhdHRyVmFsdWUsICYodHlwZS0+ZmxhZ3MpLCAKCQkJLTEsCgkJCVhNTF9TQ0hFTUFTX1RZUEVfQkxPQ0tfRVhURU5TSU9OLAoJCQlYTUxfU0NIRU1BU19UWVBFX0JMT0NLX1JFU1RSSUNUSU9OLCAKCQkJLTEsIC0xLCAtMSkgIT0gMCkgewoJCQl4bWxTY2hlbWFQU2ltcGxlVHlwZUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfUzRTX0FUVFJfSU5WQUxJRF9WQUxVRSwKCQkJICAgICZkZXMsIHR5cGUsICh4bWxOb2RlUHRyKSBhdHRyLAoJCQkgICAgTlVMTCwgCgkJCSAgICAiKCNhbGwgfCBMaXN0IG9mIChleHRlbnNpb24gfCByZXN0cmljdGlvbikpICIsIAoJCQkgICAgYXR0clZhbHVlLCBOVUxMLCBOVUxMLCBOVUxMKTsKCQkgICAgfQoJCX0gZWxzZSB7CgkJCXhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELCAKCQkJICAgICZkZXMsIHR5cGUsIGF0dHIpOwoJCX0KCSAgICB9IGVsc2UgewkgICAgCgkJeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJICAgICZkZXMsIHR5cGUsIGF0dHIpOwoJICAgIH0KCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYU5zKSkgewoJICAgIHhtbFNjaGVtYVBJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TNFNfQVRUUl9OT1RfQUxMT1dFRCwgCgkJJmRlcywgdHlwZSwgYXR0cik7CQoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9ICAgICAgIAogICAgLyogCiAgICAqIFNldCBhcyBkZWZhdWx0IGZvciBhdHRyaWJ1dGUgd2lsZGNhcmRzLgogICAgKiBUaGlzIHdpbGwgYmUgb25seSBjaGFuZ2VkIGlmIGEgY29tcGxleCB0eXBlCiAgICAqIGluaGVyaXRzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCBmcm9tIGEgYmFzZSB0eXBlLgogICAgKi8KICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKICAgIC8qCiAgICAqIEFuZCBub3cgZm9yIHRoZSBjaGlsZHJlbi4uLgogICAgKi8KICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7ICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZUNvbnRlbnQiKSkgewoJLyogCgkqIDMuNC4zIDogMi4yICAKCSogU3BlY2lmeWluZyBtaXhlZD0ndHJ1ZScgd2hlbiB0aGUgPHNpbXBsZUNvbnRlbnQ+CgkqIGFsdGVybmF0aXZlIGlzIGNob3NlbiBoYXMgbm8gZWZmZWN0CgkqLwoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCSAgICB0eXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOwogICAgICAgIHR5cGUtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhDb250ZW50IikpIHsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CgkvKgoJKiBQYXJzZSBtb2RlbCBncm91cHMuCgkqLwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJLyoKCSogUGFyc2UgYXR0cmlidXRlIGRlY2xzL3JlZnMuCgkqLwogICAgICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CgkvKgoJKiBQYXJzZSBhdHRyaWJ1dGUgd2lsZGNhcmQuCgkqLwoJaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7CSAgICAKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewoJeG1sU2NoZW1hUENvbnRlbnRFcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TNFNfRUxFTV9OT1RfQUxMT1dFRCwgCgkgICAgJmRlcywgdHlwZSwgbm9kZSwgY2hpbGQsCgkgICAgTlVMTCwgIihhbm5vdGF0aW9uPywgKHNpbXBsZUNvbnRlbnQgfCBjb21wbGV4Q29udGVudCB8ICIKCSAgICAiKChncm91cCB8IGFsbCB8IGNob2ljZSB8IHNlcXVlbmNlKT8sICgoYXR0cmlidXRlIHwgIgoJICAgICJhdHRyaWJ1dGVHcm91cCkqLCBhbnlBdHRyaWJ1dGU/KSkpKSIpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChkZXMpOwogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIGEgbm9kZSBzZXQKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZVNjaGVtYSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hUHRyIHNjaGVtYSA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVBhcnNlIG9ubHkgYW5kIGlzIHVzZWQgaWYKICAgICogdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgdGhlIEFQSTsgaS5lLiBub3QKICAgICogYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGlmIChJU19TQ0hFTUEobm9kZSwgInNjaGVtYSIpKSB7Cgl4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwoKICAgICAgICBzY2hlbWEgPSB4bWxTY2hlbWFOZXdTY2hlbWEoY3R4dCk7CiAgICAgICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwoJLyoKCSogRGlzYWJsZSBidWlsZCBvZiBsaXN0IG9mIGl0ZW1zLgoJKi8KCWF0dHIgPSB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCAidGFyZ2V0TmFtZXNwYWNlIik7IAkJCglpZiAoYXR0ciAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFZhbEF0dHJOb2RlKGN0eHQsIE5VTEwsIE5VTEwsIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVVSSSksICZ2YWwpOwoJICAgIC8qCgkgICAgKiBUT0RPOiBTaG91bGQgd2UgcHJvY2VlZCB3aXRoIGFuIGludmFsaWQgdGFyZ2V0IG5hbWVzcGFjZT8KCSAgICAqLwoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCX0gZWxzZSB7CgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBOVUxMOwoJfQoJLyoKCSogQWRkIHRoZSBjdXJyZW50IG5zIG5hbWUgYW5kIGxvY2F0aW9uIHRvIHRoZSBpbXBvcnQgdGFibGU7CgkqIHRoaXMgaXMgbmVlZGVkIHRvIGhhdmUgYSBjb25zaXN0ZW50IG1lY2hhbmlzbSwgcmVnYXJkbGVzcwoJKiBpZiBhbGwgc2NoZW1hdGEgYXJlIGNvbnN0cnVjdGVkIGR5bmFtaWNhbGx5IGZpcmVkIGJ5IHRoZQoJKiBpbnN0YW5jZSBvciBpZiB0aGUgc2NoZW1hIHRvIGJlIHVzZWQgd2FzIHNwZWNpZmllZCB2aWEKCSogdGhlIEFQSS4KCSovCglpbXBvcnQgPSB4bWxTY2hlbWFBZGRJbXBvcnQoY3R4dCwgJihzY2hlbWEtPnNjaGVtYXNJbXBvcnRzKSwKCSAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CglpZiAoaW1wb3J0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCgkJTlVMTCwgTlVMTCwgKHhtbE5vZGVQdHIpIGN0eHQtPmRvYywKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBhcnNlU2NoZW1hLCAiCgkJImZhaWxlZCB0byBhZGQgYW4gaW1wb3J0IGVudHJ5IiwgTlVMTCk7CgkgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwoJICAgIHNjaGVtYSA9IE5VTEw7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCWltcG9ydC0+c2NoZW1hTG9jYXRpb24gPSBjdHh0LT5VUkw7CgkvKgoJKiBOT1RFOiBXZSB3b24ndCBzZXQgdGhlIGRvYyBoZXJlLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBmcmVlZAoJKiBpZiB0aGUgaW1wb3J0IHN0cnVjdCBpcyBmcmVlZC4KCSogaW1wb3J0LT5kb2MgPSBjdHh0LT5kb2M7CgkqLwoKCXhtbFNjaGVtYVBWYWxBdHRySUQoY3R4dCwgTlVMTCwgTlVMTCwgbm9kZSwgQkFEX0NBU1QgImlkIik7Cgl4bWxTY2hlbWFQVmFsQXR0cihjdHh0LCBOVUxMLCBOVUxMLCBub2RlLCAidmVyc2lvbiIsIAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1RPS0VOKSwgJihzY2hlbWEtPnZlcnNpb24pKTsKCgl4bWxTY2hlbWFQYXJzZVNjaGVtYURlZmF1bHRzKGN0eHQsIHNjaGVtYSwgbm9kZSk7CQogICAgICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCBub2RlLT5jaGlsZHJlbik7CiAgICB9IGVsc2UgewogICAgICAgIHhtbERvY1B0ciBkb2M7CgoJZG9jID0gbm9kZS0+ZG9jOwoKICAgICAgICBpZiAoKGRvYyAhPSBOVUxMKSAmJiAoZG9jLT5VUkwgIT0gTlVMTCkpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9UX1NDSEVNQSwKCQkgICAgICAiVGhlIGZpbGUgXCIlc1wiIGlzIG5vdCBhIFhNTCBzY2hlbWEuXG4iLCBkb2MtPlVSTCwgTlVMTCk7Cgl9IGVsc2UgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJCSAgICAgICJUaGUgZmlsZSBpcyBub3QgYSBYTUwgc2NoZW1hLlxuIiwgTlVMTCwgTlVMTCk7Cgl9CglyZXR1cm4oTlVMTCk7CiAgICB9CiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGcmVlKHNjaGVtYSk7CiAgICAgICAgICAgIHNjaGVtYSA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgaWYgKHNjaGVtYSAhPSBOVUxMKQoJc2NoZW1hLT5jb3VudGVyID0gY3R4dC0+Y291bnRlcjsKICAgIGN0eHQtPm5iZXJyb3JzID0gbmJlcnJvcnM7CiNpZmRlZiBERUJVRwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2UoKSBmYWlsZWRcbiIpOwojZW5kaWYKICAgIHJldHVybiAoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpbmcgdXNpbmcgU2NoZW1hcwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVJlYWRpbmcvV3JpdGluZyBTY2hlbWFzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmIDAgLyogV2lsbCBiZSBlbmFibGVkIGlmIGl0IGlzIGNsZWFyIHdoYXQgb3B0aW9ucyBhcmUgbmVlZGVkLiAqLwovKioKICogeG1sU2NoZW1hUGFyc2VyQ3R4dFNldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFQYXJzZXJPcHRpb24KICoKICogU2V0cyB0aGUgb3B0aW9ucyB0byBiZSB1c2VkIGR1cmluZyB0aGUgcGFyc2UuCiAqCiAqIFJldHVybnMgMCBpbiBjYXNlIG9mIHN1Y2Nlc3MsIC0xIGluIGNhc2Ugb2YgYW4KICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZXJDdHh0U2V0T3B0aW9ucyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgIGludCBvcHRpb25zKQoJCQkJCQp7CiAgICBpbnQgaTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBXQVJOSU5HOiBDaGFuZ2UgdGhlIHN0YXJ0IHZhbHVlIGlmIGFkZGluZyB0byB0aGUKICAgICogeG1sU2NoZW1hUGFyc2VPcHRpb24uCiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgcmV0dXJuICgtMSk7ICAgCiAgICAgICAgfQkKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OiBhIHNjaGVtYSBwYXJzZXIgY29udGV4dCAKICoKICogUmV0dXJucyB0aGUgb3B0aW9uIGNvbWJpbmF0aW9uIG9mIHRoZSBwYXJzZXIgY29udGV4dC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VyQ3R4dEdldE9wdGlvbnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQoJCQkJCQp7ICAgIAogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgZWxzZSAKCXJldHVybiAoY3R4dC0+b3B0aW9ucyk7ICAgIAp9Cgogdm9pZCAqY3VySXRlbXM7ICAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgbmJDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwogICAgaW50IHNpemVDdXJJdGVtczsgLyogdXNlZCBmb3IgZHluYW1pYyBhZGRpdGlvbiBvZiBzY2hlbWF0YSAqLwoKI2VuZGlmCgovKioKICogeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dDoKICogQFVSTDogIHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IGZpbGUvcmVzb3VyY2UgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dChjb25zdCBjaGFyICpVUkwpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0LT5VUkwgPSB4bWxEaWN0TG9va3VwKHJldC0+ZGljdCwgKGNvbnN0IHhtbENoYXIgKikgVVJMLCAtMSk7CiAgICByZXQtPmluY2x1ZGVzID0gMDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0OgogKiBAVVJMOiAgdGhlIGxvY2F0aW9uIG9mIHRoZSBzY2hlbWEKICogQGRpY3Q6IHRoZSBkaWN0aW9uYXJ5IHRvIGJlIHVzZWQKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZmlsZS9yZXNvdXJjZSBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3UGFyc2VyQ3R4dFVzZURpY3QoY29uc3QgY2hhciAqVVJMLCB4bWxEaWN0UHRyIGRpY3QpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwogICAgLyoKICAgIGlmIChVUkwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoJKi8KCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZGljdCA9IGRpY3Q7CiAgICB4bWxEaWN0UmVmZXJlbmNlKGRpY3QpOyAgICAKICAgIGlmIChVUkwgIT0gTlVMTCkKCXJldC0+VVJMID0geG1sRGljdExvb2t1cChkaWN0LCAoY29uc3QgeG1sQ2hhciAqKSBVUkwsIC0xKTsKICAgIHJldC0+aW5jbHVkZXMgPSAwOwogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYU5ld01lbVBhcnNlckN0eHQ6CiAqIEBidWZmZXI6ICBhIHBvaW50ZXIgdG8gYSBjaGFyIGFycmF5IGNvbnRhaW5pbmcgdGhlIHNjaGVtYXMKICogQHNpemU6ICB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgbWVtb3J5IGJ1ZmZlciBleHBlY3RlZAogKiB0byBjb250YWluIGFuIFhNTCBTY2hlbWFzIGZpbGUuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0KGNvbnN0IGNoYXIgKmJ1ZmZlciwgaW50IHNpemUpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmICgoYnVmZmVyID09IE5VTEwpIHx8IChzaXplIDw9IDApKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIHJldC0+c2l6ZSA9IHNpemU7CiAgICByZXQtPmRpY3QgPSB4bWxEaWN0Q3JlYXRlKCk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0OgogKiBAZG9jOiAgYSBwcmVwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBkb2N1bWVudC4KICogTkIuIFRoZSBkb2N1bWVudCBtYXkgYmUgbW9kaWZpZWQgZHVyaW5nIHRoZSBwYXJzaW5nIHByb2Nlc3MuCiAqCiAqIFJldHVybnMgdGhlIHBhcnNlciBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cgp4bWxTY2hlbWFOZXdEb2NQYXJzZXJDdHh0KHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcmV0OwoKICAgIGlmIChkb2MgPT0gTlVMTCkKICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShOVUxMLCAiYWxsb2NhdGluZyBzY2hlbWEgcGFyc2VyIGNvbnRleHQiLAoJCQkgIE5VTEwpOwogICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgLyogVGhlIGFwcGxpY2F0aW9uIGhhcyByZXNwb25zaWJpbGl0eSBmb3IgdGhlIGRvY3VtZW50ICovCiAgICByZXQtPnByZXNlcnZlID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChjdHh0LT5kb2MgIT0gTlVMTCAmJiAhY3R4dC0+cHJlc2VydmUpCiAgICAgICAgeG1sRnJlZURvYyhjdHh0LT5kb2MpOwogICAgaWYgKGN0eHQtPmFzc2VtYmxlICE9IE5VTEwpIHsKCXhtbEZyZWUoKHhtbFNjaGVtYVR5cGVQdHIgKikgY3R4dC0+YXNzZW1ibGUtPml0ZW1zKTsKCXhtbEZyZWUoY3R4dC0+YXNzZW1ibGUpOwogICAgfQogICAgaWYgKGN0eHQtPnZjdHh0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWxpZEN0eHQoY3R4dC0+dmN0eHQpOwogICAgfQogICAgeG1sRGljdEZyZWUoY3R4dC0+ZGljdCk7CiAgICB4bWxGcmVlKGN0eHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJCQkJCQkJKgogKgkJCUJ1aWxkaW5nIHRoZSBjb250ZW50IG1vZGVscwkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsOgogKiBAdHlwZTogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBlbGVtZW50IG5hbWUgd2hvc2UgY29udGVudCBpcyBiZWluZyBidWlsdAogKgogKiBHZW5lcmF0ZSB0aGUgYXV0b21hdGEgc2VxdWVuY2UgbmVlZGVkIGZvciB0aGF0IHR5cGUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgdW5leHBlY3RlZCB0eXBlID0gTlVMTCBpbiAlcyBjb250ZW50IG1vZGVsXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWTogeyAgIAoJICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQsIGVuZDsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkOwkgICAgCgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsKCgkgICAgd2lsZCA9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoKCSAgICBpZiAod2lsZCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwsICIKCQkgICAgIm5vIHdpbGRjYXJkIG9uIHhzZDphbnkuXG4iLCBOVUxMLCBOVUxMKTsKCQlyZXR1cm47CgkgICAgfQkgICAgIAoJICAgIAoJICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CgkgICAgZW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkgICAgCgkgICAgaWYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSB7CQkKCQlpZiAod2lsZC0+YW55ID09IDEpIHsKCQkgICAgLyoKCQkgICAgKiBXZSBuZWVkIHRvIGFkZCBib3RoIHRyYW5zaXRpb25zOgoJCSAgICAqCgkJICAgICogMS4gdGhlIHsiKiIsICIqIn0gZm9yIGVsZW1lbnRzIGluIGEgbmFtZXNwYWNlLgoJCSAgICAqLwkJICAgIAoJCSAgICBjdHh0LT5zdGF0ZSA9IAoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBlbmQpOwoJCSAgICAvKgoJCSAgICAqIDIuIHRoZSB7IioifSBmb3IgZWxlbWVudHMgaW4gbm8gbmFtZXNwYWNlLgoJCSAgICAqLwoJCSAgICBjdHh0LT5zdGF0ZSA9IAoJCQl4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBOVUxMLCB0eXBlKTsKCQkgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCgkJfSBlbHNlIGlmICh3aWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIG5zID0gd2lsZC0+bnNTZXQ7CgkJICAgIGRvIHsKCQkJY3R4dC0+c3RhdGUgPSBzdGFydDsKCQkJY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkgICAgY3R4dC0+c3RhdGUsIE5VTEwsIEJBRF9DQVNUICIqIiwgbnMtPnZhbHVlLCB0eXBlKTsKCQkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGRlYWRFbmQ7CgoJCSAgICBkZWFkRW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIGRlYWRFbmQsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLCB0eXBlKTsKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBlbmQpOwoJCX0JCQoJICAgIH0gZWxzZSB7CgkJaW50IGNvdW50ZXI7CgkJeG1sQXV0b21hdGFTdGF0ZVB0ciBob3A7CgkJaW50IG1heE9jY3VycyA9IAoJCSAgICB0eXBlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8gVU5CT1VOREVEIDogdHlwZS0+bWF4T2NjdXJzIC0gMTsKCQlpbnQgbWluT2NjdXJzID0KCQkgICAgdHlwZS0+bWluT2NjdXJzIDwgMSA/IDAgOiB0eXBlLT5taW5PY2N1cnMgLSAxOwoJCQoJCWNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sIG1pbk9jY3VycywgbWF4T2NjdXJzKTsKCQlob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsJCQoJCWlmICh3aWxkLT5hbnkgPT0gMSkgewkJICAgIAoJCSAgICBjdHh0LT5zdGF0ZSA9CgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIEJBRF9DQVNUICIqIiwgdHlwZSk7CgkJICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CgkJICAgIGN0eHQtPnN0YXRlID0gCgkJCXhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCXN0YXJ0LCBOVUxMLCBCQURfQ0FTVCAiKiIsIE5VTEwsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCX0gZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewkJICAgIAoJCSAgICBucyA9IHdpbGQtPm5zU2V0OwoJCSAgICBkbyB7CgkJCWN0eHQtPnN0YXRlID0gCgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkJc3RhcnQsIE5VTEwsIEJBRF9DQVNUICIqIiwgbnMtPnZhbHVlLCB0eXBlKTsKCQkJeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgaG9wKTsKCQkJbnMgPSBucy0+bmV4dDsKCQkgICAgfSB3aGlsZSAobnMgIT0gTlVMTCk7CgoJCX0gZWxzZSBpZiAod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGRlYWRFbmQ7CgoJCSAgICBkZWFkRW5kID0geG1sQXV0b21hdGFOZXdTdGF0ZShjdHh0LT5hbSk7CgkJICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJc3RhcnQsIGRlYWRFbmQsIEJBRF9DQVNUICIqIiwgd2lsZC0+bmVnTnNTZXQtPnZhbHVlLCB0eXBlKTsKCQkgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQlzdGFydCwgTlVMTCwgQkFEX0NBU1QgIioiLCBCQURfQ0FTVCAiKiIsIHR5cGUpOwoJCSAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwoJCX0JCgkJeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIGhvcCwgc3RhcnQsIGNvdW50ZXIpOwoJCXhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwgY291bnRlcik7CgkgICAgfQoJICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewoJCXhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CgkgICAgfQkgICAgCSAgICAJCQkJICAgICAgICAgICAgCgkgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgIGJyZWFrOwoJfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6ewoJCXhtbEF1dG9tYXRhU3RhdGVQdHIgb2xkc3RhdGU7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHBhcnRpY2xlLCBlbGVtRGVjbDsKCgkJLyoKCQkqIElNUE9SVEFOVDogVGhpcyBwdXRzIGVsZW1lbnQgZGVjbGFyYXRpb25zCgkJKiAoYW5kIG5ldmVyIGVsZW1lbnQgZGVjbC4gcmVmZXJlbmNlcykgaW50byB0aGUKCQkqIGF1dG9tYXRvbi4gVGhpcyBpcyBjcnVjaWFsIGFuZCBzaG91bGQgbm90IGJlIGNoYW5nZWQsIAoJCSogc2luY2UgdmFsaWRhdGluZyBmdW5jdGlvbnMgcmVseSBub3cgb24gaXQuCgkJKi8KCQlwYXJ0aWNsZSA9ICh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlOwoJCWlmIChwYXJ0aWNsZS0+cmVmICE9IE5VTEwpIHsKCQkgICAgaWYgKHBhcnRpY2xlLT5yZWZEZWNsID09IE5VTEwpIHsKCQkJLyoKCQkJKiBTa2lwIGNvbnRlbnQgbW9kZWwgY3JlYXRpb24gaWYgdGhlIHJlZmVyZW5jZQoJCQkqIGRpZCBub3QgcmVzb2x2ZSB0byBhIGRlY2xhcmF0aW9uLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBSZWZlcmVuY2VkIGdsb2JhbCBlbGVtZW50IGRlY2xhcmF0aW9uLgoJCQkqLwoJCQllbGVtRGVjbCA9IHBhcnRpY2xlLT5yZWZEZWNsOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBBbm9ueW1vdXMgZWxlbWVudCBkZWNsYXJhdGlvbi4KCQkgICAgKi8KCQkgICAgZWxlbURlY2wgPSBwYXJ0aWNsZTsKCQl9CgkJCiAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkgewogICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0aWNsZS0+bWluT2NjdXJzID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwKCQkJICAgIG9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKCQkJICAgIHBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLCBVTkJPVU5ERUQpOyAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQoJCQkgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uMihjdHh0LT5hbSwKCQkJCWN0eHQtPnN0YXRlLCBOVUxMLCAKCQkJCWVsZW1EZWNsLT5uYW1lLCAKCQkJCWVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJCQkoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wpOwogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwgb2xkc3RhdGUsCgkJCSAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwgTlVMTCwKCQkJCWNvdW50ZXIpOwoKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgIAoJCQljdHh0LT5zdGF0ZSA9CgkJCSAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQkgICAgY3R4dC0+c3RhdGUsIE5VTEwsCgkJCSAgICBlbGVtRGVjbC0+bmFtZSwgCgkJCSAgICBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IGFuIGVsZW0qICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHBhcnRpY2xlLT5tYXhPY2N1cnMgPiAxKSB8fCAocGFydGljbGUtPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCgkJCXBhcnRpY2xlLT5taW5PY2N1cnMgLSAxLAoJCQlwYXJ0aWNsZS0+bWF4T2NjdXJzIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24yKGN0eHQtPmFtLAoJCQljdHh0LT5zdGF0ZSwKCQkJTlVMTCwKCQkJZWxlbURlY2wtPm5hbWUsCgkJCWVsZW1EZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwgb2xkc3RhdGUsCgkJCWNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwKCQkJTlVMTCwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgYW4gZWxlbT8gKi8KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKCQkJICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIAoJCSAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIoY3R4dC0+YW0sCgkJCWN0eHQtPnN0YXRlLAoJCQlOVUxMLAoJCQllbGVtRGVjbC0+bmFtZSwKCQkJZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsKTsKICAgICAgICAgICAgICAgICAgICBpZiAocGFydGljbGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtPyAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAoJCQkgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWYgbWF4IGFuZCBtaW4gb2NjdXJhbmNlcyBhcmUgZGVmYXVsdCAoMSkgdGhlbgogICAgICAgICAgICAgICAgICogc2ltcGx5IGl0ZXJhdGUgb3ZlciB0aGUgc3VidHlwZXMKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKCh0eXBlLT5taW5PY2N1cnMgPT0gMSkgJiYgKHR5cGUtPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1heE9jY3VycyA+PSBVTkJPVU5ERUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluT2NjdXJzIC0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVU5CT1VOREVEKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBjb3VudGVyKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHR5cGUtPm1heE9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAodHlwZS0+bWluT2NjdXJzID4gMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bWluT2NjdXJzIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1heE9jY3VycyAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSk7CgogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0LCBlbmQ7CgogICAgICAgICAgICAgICAgc3RhcnQgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgIGVuZCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzIGFuZCByZW1lcmdlIHRoZSBlbmQgd2l0aCBhbgogICAgICAgICAgICAgICAgICogZXBzaWxvbiB0cmFuc2l0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBzdGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgZW5kKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSBzdWJ0eXBlcy0+bmV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgaG9wOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhPY2N1cnMgPSB0eXBlLT5tYXhPY2N1cnMgPT0gVU5CT1VOREVEID8KICAgICAgICAgICAgICAgICAgICAgICAgVU5CT1VOREVEIDogdHlwZS0+bWF4T2NjdXJzIC0gMTsKICAgICAgICAgICAgICAgICAgICBpbnQgbWluT2NjdXJzID0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bWluT2NjdXJzIDwgMSA/IDAgOiB0eXBlLT5taW5PY2N1cnMgLSAxOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIHVzZSBhIGNvdW50ZXIgdG8ga2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIHRyYW5zdGlvbnMKICAgICAgICAgICAgICAgICAgICAgKiB3aGljaCB3ZW50IHRocm91Z2ggdGhlIGNob2ljZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLCBtaW5PY2N1cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhPY2N1cnMpOwogICAgICAgICAgICAgICAgICAgIGhvcCA9IHhtbEF1dG9tYXRhTmV3U3RhdGUoY3R4dC0+YW0pOwoKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGhvcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCBob3AsIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCBob3AsIGVuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgc3RhcnQsIGVuZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IGVuZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOnsKICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwgcGFydGljbGU7CiAgICAgICAgICAgICAgICBpbnQgbGF4OwoKICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgaWYgKHBhcnRpY2xlID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBzdGFydCA9IGN0eHQtPnN0YXRlOwogICAgICAgICAgICAgICAgd2hpbGUgKHBhcnRpY2xlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwoJCSAgICAvKgoJCSAgICAgKiBDaGFuZ2VkIHRvIHB1dCB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBhbmQKCQkgICAgICogbmV2ZXIgdGhlIGVsZW1lbnQgZGVjbC4gcmVmZXJlbmNlIGludG8gdGhlCgkJICAgICAqIGF1dG9tYXRvbi4gVGhpcyBmaXhlcyBidWcgMTM5ODk3IGFuZCBidWcgMTY3NzU0LgoJCSAgICAgKi8KCQkgICAgaWYgKHBhcnRpY2xlLT5yZWYgIT0gTlVMTCkgewoJCQlpZiAocGFydGljbGUtPnJlZkRlY2wgPT0gTlVMTCkgewoJCQkgICAgLyoKCQkJICAgICogVE9ETzogTm90ZSB0aGF0IHdlIGJyZWFrIG9uIG1pc3NpbmcKCQkJICAgICogc3ViLWNvbXBvbmVudHMuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCX0gZWxzZQoJCQkgICAgZWxlbURlY2wgPSBwYXJ0aWNsZS0+cmVmRGVjbDsKCQkgICAgfSBlbHNlCgkJCWVsZW1EZWNsID0gcGFydGljbGU7ICAgICAgICAgICAgICAgICAgICAJCSAgCgkJICAgIC8qCgkJICAgICogTk9URTogVGhlIHttYXggb2NjdXJzfSBvZiBhbGwgdGhlIHBhcnRpY2xlcyBpbiB0aGUgCgkJICAgICoge3BhcnRpY2xlc30gb2YgdGhlIGdyb3VwIG11c3QgYmUgMCBvciAxOyB0aGlzIGlzCgkJICAgICogYWxyZWFkeSBlbnN1cmVkIGR1cmluZyB0aGUgcGFyc2Ugb2YgdGhlIGNvbnRlbnQgb2YKCQkgICAgKiA8YWxsPi4KCQkgICAgKi8gICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICgocGFydGljbGUtPm1pbk9jY3VycyA9PSAxKSAmJgoJCQkocGFydGljbGUtPm1heE9jY3VycyA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld09uY2VUcmFuczIoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgCgkJCQkJCWVsZW1EZWNsLT5uYW1lLCAKCQkJCQkJZWxlbURlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkJCQkJMSwgMSwgZWxlbURlY2wpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHBhcnRpY2xlLT5taW5PY2N1cnMgPT0gMCkgJiYKCQkJKHBhcnRpY2xlLT5tYXhPY2N1cnMgPT0gMSkpIHsKCQkJCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRUcmFuczIoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIAoJCQkJCQkgZWxlbURlY2wtPm5hbWUsCgkJCQkJCSBlbGVtRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtRGVjbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBhcnRpY2xlID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHBhcnRpY2xlLT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGF4ID0gdHlwZS0+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+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpKSB7CglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIHR5cGUtPnN1YnR5cGVzLCAKCSAgICB2YWxUeXBlKSk7CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZVR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZ2l2ZW4gdHlwZSBvcgogKiBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZUFuY2VzdG9yOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3Rvcih4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCgovKioKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiBAY3VyOiB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGxpc3QKICogQGxhc3RVc2U6IHRoZSB0b3Agb2YgdGhlIGF0dHJpYnV0ZSB1c2UgbGlzdAogKgogKiBCdWlsZHMgdGhlIGF0dHJpYnV0ZSB1c2VzIGxpc3Qgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogVGhpcyBvbmUgaXMgc3VwcG9zZWQgdG8gYmUgY2FsbGVkIGJ5IAogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24gb25seS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgY3VyLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKnVzZXMsCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciAqbGFzdFVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciB0bXA7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCWlmIChjdXItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgLyogCgkgICAgICogVzNDOiAiMiBUaGUge2F0dHJpYnV0ZSB1c2VzfSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwcyC3cmVzb2x2ZWS3IAoJICAgICAqIHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVlt3Mgb2YgdGhlIHJlZiBbYXR0cmlidXRlXSBvZiB0aGUgCgkgICAgICogPGF0dHJpYnV0ZUdyb3VwPiBbY2hpbGRyZW5dLCBpZiBhbnkuIgoJICAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVVzZXNPd25lZChjdHh0LCAKCQkoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBjdXIpLT5hdHRyaWJ1dGVzLCB1c2VzLCAKCQlsYXN0VXNlKSA9PSAtMSkgewoJCXJldHVybiAoLTEpOwkgICAgCgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKiBXM0M6ICIxIFRoZSBzZXQgb2YgYXR0cmlidXRlIHVzZXMgY29ycmVzcG9uZGluZyB0byB0aGUgCgkgICAgICogPGF0dHJpYnV0ZT4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8JICAgIAkgICAgCgkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIpIAoJCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlTGluaykpOwoJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImJ1aWxkaW5nIGF0dHJpYnV0ZSB1c2VzIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIHRtcC0+YXR0ciA9IGN1cjsKCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJICAgIGlmICgqdXNlcyA9PSBOVUxMKQoJCSp1c2VzID0gdG1wOwkJICAgIAoJICAgIGVsc2UgCgkJKCpsYXN0VXNlKS0+bmV4dCA9IHRtcDsKCSAgICAqbGFzdFVzZSA9IHRtcDsJICAgIAoJfQkKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0JCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZGVzdDogIHRoZSBkZXN0aW5hdGlvbiB3aWxkY2FyZAogKiBAc291cmNlOiB0aGUgc291cmNlIHdpbGRjYXJkCiAqCiAqIENsb25lcyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHNvdXJjZQogKiBhbmQgYXNzaWduZXMgdGhlbSB0byBkZXN0LgogKiBSZXR1cm5zIC0xIG9uIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpkZXN0LAoJCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHNvdXJjZSkJCQkJICAgIAp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgdG1wLCBsYXN0OwoKICAgIGlmICgoc291cmNlID09IE5VTEwpIHx8ICgqZGVzdCA9PSBOVUxMKSkKCXJldHVybigtMSk7ICAgIAogICAgKCpkZXN0KS0+YW55ID0gc291cmNlLT5hbnk7CiAgICBjdXIgPSBzb3VyY2UtPm5zU2V0OwogICAgbGFzdCA9IE5VTEw7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXRtcCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKHRtcCA9PSBOVUxMKQoJICAgIHJldHVybigtMSk7Cgl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCWlmIChsYXN0ID09IE5VTEwpCgkgICAgKCpkZXN0KS0+bnNTZXQgPSB0bXA7CgllbHNlIAoJICAgIGxhc3QtPm5leHQgPSB0bXA7CglsYXN0ID0gdG1wOwoJY3VyID0gY3VyLT5uZXh0OwogICAgfSAgICAKICAgIGlmICgoKmRlc3QpLT5uZWdOc1NldCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoKCpkZXN0KS0+bmVnTnNTZXQpOwkgICAKICAgIGlmIChzb3VyY2UtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSgqZGVzdCktPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CglpZiAoKCpkZXN0KS0+bmVnTnNTZXQgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJKCpkZXN0KS0+bmVnTnNTZXQtPnZhbHVlID0gc291cmNlLT5uZWdOc1NldC0+dmFsdWU7CSAgICAKICAgIH0gZWxzZQoJKCpkZXN0KS0+bmVnTnNTZXQgPSBOVUxMOwogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hVW5pb25XaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBVbmlvbnMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiB0aGUgZ2l2ZW4gd2lsZGNhcmRzLgogKiBAY29tcGxldGVXaWxkIHdpbGwgaG9sZCB0aGUgcmVzdWx0aW5nIHVuaW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVW5pb25XaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgdG1wOwoKICAgIC8qCiAgICAqIDEgSWYgTzEgYW5kIE8yIGFyZSB0aGUgc2FtZSB2YWx1ZSwgdGhlbiB0aGF0IHZhbHVlIG11c3QgYmUgdGhlIAogICAgKiB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+YW55ID09IGN1cldpbGQtPmFueSkgJiYKCSgoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bnNTZXQgPT0gTlVMTCkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5lZ05zU2V0ID09IE5VTEwpKSkgewoJCglpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgfHwKCSAgICAoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJICAgIAoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQlpbnQgZm91bmQgPSAwOwoJCQoJCS8qIAoJCSogQ2hlY2sgZXF1YWxpdHkgb2Ygc2V0cy4gCgkJKi8KCQljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJCSAgICBmb3VuZCA9IDA7CgkJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCQkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQkgICAgZm91bmQgPSAxOwoJCQkgICAgYnJlYWs7CgkJCX0KCQkJY3VyQiA9IGN1ckItPm5leHQ7CgkJICAgIH0KCQkgICAgaWYgKCFmb3VuZCkKCQkJYnJlYWs7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQl9CgkJaWYgKGZvdW5kKQoJCSAgICByZXR1cm4oMCk7CgkgICAgfSBlbHNlCgkJcmV0dXJuKDApOwoJfQogICAgfQkgICAgICAgIAogICAgLyoKICAgICogMiBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYW55LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZQogICAgKi8KICAgIGlmIChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpIHsJCglpZiAoY29tcGxldGVXaWxkLT5hbnkgPT0gMCkgewoJICAgIGNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCQl4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgKiAzIElmIGJvdGggTzEgYW5kIE8yIGFyZSBzZXRzIG9mIChuYW1lc3BhY2UgbmFtZXMgb3Igt2Fic2VudLcpLCAKICAgICogdGhlbiB0aGUgdW5pb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CQkKCWludCBmb3VuZDsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc3RhcnQ7CgkKCWN1ciA9IGN1cldpbGQtPm5zU2V0OwoJc3RhcnQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBzdGFydDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAodG1wID09IE5VTEwpIAoJCSAgICByZXR1cm4gKC0xKTsKCQl0bXAtPnZhbHVlID0gY3VyLT52YWx1ZTsKCQl0bXAtPm5leHQgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwkJICAgIAkJICAgIAoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSB0bXA7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyoKICAgICogNCBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IHZhbHVlcyAobmFtZXNwYWNlIG5hbWVzIAogICAgKiBvciC3YWJzZW50tyksIHRoZW4gYSBwYWlyIG9mIG5vdCBhbmQgt2Fic2VudLcgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSkgewoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoKCXJldHVybigwKTsKICAgIH0KICAgIC8qIAogICAgICogNS4KICAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJgoJKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB8fAoJKChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoKCWludCBuc0ZvdW5kLCBhYnNlbnRGb3VuZCA9IDA7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uZWdOc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7CgkgICAgY3VyQiA9IGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQ7Cgl9Cgluc0ZvdW5kID0gMDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIAoJCWFic2VudEZvdW5kID0gMTsKCSAgICBlbHNlIGlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKQoJCW5zRm91bmQgPSAxOwoJICAgIGlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKQoJCWJyZWFrOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgoJaWYgKG5zRm91bmQgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyBib3RoIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgYW5kILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLyAgICAKCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9IGVsc2UgaWYgKG5zRm91bmQgJiYgKCFhYnNlbnRGb3VuZCkpIHsKCSAgICAvKiAKCSAgICAqIDUuMiBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgdGhlIG5lZ2F0ZWQgbmFtZXNwYWNlIG5hbWUgCgkgICAgKiBidXQgbm90ILdhYnNlbnS3LCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QgCgkgICAgKiBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQkgICAgcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiBhYnNlbnRGb3VuZCkgewoJICAgIC8qCgkgICAgKiA1LjMgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3IGJ1dCBub3QgdGhlIG5lZ2F0ZWQgCgkgICAgKiBuYW1lc3BhY2UgbmFtZSwgdGhlbiB0aGUgdW5pb24gaXMgbm90IGV4cHJlc3NpYmxlLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIAoJCVhNTF9TQ0hFTUFQX1VOSU9OX05PVF9FWFBSRVNTSUJMRSwKCQkiVGhlIHVuaW9uIG9mIHRoZSB3aWxjYXJkIGlzIG5vdCBleHByZXNzaWJsZS5cbiIsCgkJTlVMTCwgTlVMTCk7CQoJICAgIHJldHVybihYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUpOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjQgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKiAKICAgICAqIDYuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7Cgl9CQoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCS8qCgkJKiA2LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSAKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQkJCglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IAoJICAgICogYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICgwKTsKCn0KCi8qKgogKiB4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBJbnRlcnNlY3RzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyBpbnRlcnNlY3Rpb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgcHJldiwgIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZSAKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCQoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCSAgICAKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCQkKCQkvKiAKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuIAoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsJCSAgICAKCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwkgICAgCglyZXR1cm4oMCk7CiAgICB9CSAgICAgICAgICAgIAogICAgLyoKICAgICogMyBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSB2YWx1ZSAoYSBuYW1lc3BhY2UgCiAgICAqIG5hbWUgb3Igt2Fic2VudLcpIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciAKICAgICogt2Fic2VudLcpLCB0aGVuIHRoYXQgc2V0LCBtaW51cyB0aGUgbmVnYXRlZCB2YWx1ZSBpZiBpdCB3YXMgaW4gCiAgICAqIHRoZSBzZXQsIG1pbnVzILdhYnNlbnS3IGlmIGl0IHdhcyBpbiB0aGUgc2V0LCBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7Cgljb25zdCB4bWxDaGFyICpuZWc7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpIHsKCSAgICBuZWcgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIG5lZyA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCS8qCgkqIFJlbW92ZSBhYnNlbnQgYW5kIG5lZ2F0ZWQuCgkqLwoJcHJldiA9IE5VTEw7CgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCWlmIChwcmV2ID09IE5VTEwpIAoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UgCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCWlmIChuZWcgIT0gTlVMTCkgewoJICAgIHByZXYgPSBOVUxMOwoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gbmVnKSB7CgkJICAgIGlmIChwcmV2ID09IE5VTEwpIAoJCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCSAgICBlbHNlIAoJCQlwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCSAgICB4bWxGcmVlKGN1cik7CgkJICAgIGJyZWFrOwoJCX0KCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9CgoJcmV0dXJuKDApOwogICAgfQkgICAgICAgIAogICAgLyoKICAgICogNCBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3KSwgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsJCQoJaW50IGZvdW5kOwoJCgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJcHJldiA9IE5VTEw7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZSAKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl0bXAgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWN1ciA9IHRtcDsJCQoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyogNSBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IG5hbWVzcGFjZSBuYW1lcywgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBpcyBub3QgZXhwcmVzc2libGUKICAgICovCSAgICAKICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkpIHsKCgl4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSwKCSAgICAiVGhlIGludGVyc2VjdGlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGUuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwkKCXJldHVybihYTUxfU0NIRU1BUF9JTlRFUlNFQ1RJT05fTk9UX0VYUFJFU1NJQkxFKTsKICAgIH0JCSAgICAKICAgIC8qIAogICAgKiA2IElmIHRoZSBvbmUgaXMgYSBuZWdhdGlvbiBvZiBhIG5hbWVzcGFjZSBuYW1lIGFuZCB0aGUgb3RoZXIgCiAgICAqIGlzIGEgbmVnYXRpb24gb2Ygt2Fic2VudLcsIHRoZW4gdGhlIG9uZSB3aGljaCBpcyB0aGUgbmVnYXRpb24gCiAgICAqIG9mIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSkgewkKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gIGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsgCiAgICB9CiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHdpbGRBOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEB3aWxkQjogdGhlIHNlY29uZCB3aWxkY2FyZCAKICoKICogUmV0dXJucyAxIGlmIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludCBvZiBAd2lsZEEgaXMgYW4gaW50ZW5zaW9uYWwgCiAqIHN1YnNldCBvZiBAd2lsZEIsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRBLAoJCQkJICAgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZEIpCnsgICAgCgogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBXaWxkY2FyZCBTdWJzZXQgCiAgICAqLwogICAgLyoKICAgICogMSBzdXBlciBtdXN0IGJlIGFueS4gCiAgICAqLwogICAgaWYgKHdpbGRCLT5hbnkpCglyZXR1cm4gKDEpOwogICAgLyoKICAgICogMi4xIHN1YiBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3Igt2Fic2VudLcuCiAgICAqIDIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIHRoZSBzYW1lIHZhbHVlLgogICAgKi8KICAgIGlmICgod2lsZEEtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEItPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkod2lsZEEtPm5lZ05zU2V0LT52YWx1ZSA9PSB3aWxkQS0+bmVnTnNTZXQtPnZhbHVlKSkKCXJldHVybiAoMSk7ICAgIAogICAgLyogCiAgICAqIDMuMSBzdWIgbXVzdCBiZSBhIHNldCB3aG9zZSBtZW1iZXJzIGFyZSBlaXRoZXIgbmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3LiAKICAgICovCiAgICBpZiAod2lsZEEtPm5zU2V0ICE9IE5VTEwpIHsKCS8qCgkqIDMuMi4xIHN1cGVyIG11c3QgYmUgdGhlIHNhbWUgc2V0IG9yIGEgc3VwZXJzZXQgdGhlcmVvZi4gCgkqLwoJaWYgKHdpbGRCLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckI7CgkgICAgaW50IGZvdW5kID0gMDsKCSAgICAKCSAgICBjdXIgPSB3aWxkQS0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWN1ckIgPSB3aWxkQi0+bnNTZXQ7CgkJd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCQlmb3VuZCA9IDE7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIGN1ckIgPSBjdXJCLT5uZXh0OwoJCX0KCQlpZiAoIWZvdW5kKQoJCSAgICByZXR1cm4gKDApOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9CgkgICAgaWYgKGZvdW5kKQoJCXJldHVybiAoMSk7IAoJfSBlbHNlIGlmICh3aWxkQi0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoJICAgIC8qCgkgICAgKiAzLjIuMiBzdXBlciBtdXN0IGJlIGEgcGFpciBvZiBub3QgYW5kIGEgbmFtZXNwYWNlIG5hbWUgb3IgCgkgICAgKiC3YWJzZW50tyBhbmQgdGhhdCB2YWx1ZSBtdXN0IG5vdCBiZSBpbiBzdWIncyBzZXQuIAoJICAgICovCgkgICAgY3VyID0gd2lsZEEtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewkJCgkJaWYgKGN1ci0+dmFsdWUgPT0gd2lsZEItPm5lZ05zU2V0LT52YWx1ZSkKCQkgICAgcmV0dXJuICgwKTsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfSAgCgkgICAgcmV0dXJuICgxKTsKCX0KICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAYXR0cnM6IHRoZSBhdHRyaWJ1dGUgbGlzdCAKICogQGNvbXBsZXRlV2lsZDogdGhlIHJlc3VsdGluZyBjb21wbGV0ZSB3aWxkY2FyZAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkJICAgIAoJCQkJICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHJzLAoJCQkJICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgKmNvbXBsZXRlV2lsZCkJCQkJCnsgICAgICAgIAogICAgd2hpbGUgKGF0dHJzICE9IE5VTEwpIHsKCWlmIChhdHRycy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBncm91cDsKCgkgICAgZ3JvdXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGF0dHJzOwoJICAgIC8qCgkgICAgKiBIYW5kbGUgYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZXMuCgkgICAgKi8KCSAgICBpZiAoZ3JvdXAtPnJlZiAhPSBOVUxMKSB7CgkJaWYgKGdyb3VwLT5yZWZJdGVtID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBUT0RPOiBTaG91bGQgd2UgcmFpc2UgYSB3YXJuaW5nIGhlcmU/CgkJICAgICovCgkJICAgIC8qCgkJICAgICogVGhlIHJlZmVyZW5jZWQgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24gY291bGQgbm90CgkJICAgICogYmUgcmVzb2x2ZWQgYmVmb3JlaGFuZCwgc28gc2tpcC4KCQkgICAgKi8KCQkgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlCgkJICAgIGdyb3VwID0gZ3JvdXAtPnJlZkl0ZW07CgkgICAgfQkgICAgCgkgICAgLyoKCSAgICAqIEZvciBldmVyeSBhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiwgYW4gaW50ZXJzZWN0ZWQgd2lsZGNhcmQgCgkgICAgKiB3aWxsIGJlIGNyZWF0ZWQgKGFzc3VtZWQgdGhhdCBhIHdpbGRjYXJkIGV4aXN0cyBvbiB0aGUgCgkgICAgKiBwYXJ0aWN1bGFyIGF0dHIuIGdyLiBkZWYuIG9yIG9uIGFueSBjb250YWluZWQgYXR0ci4gZ3IuIGRlZiAKCSAgICAqIGF0IGFsbCkuCgkgICAgKiBUaGUgZmxhZyBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCBlbnN1cmVzCgkgICAgKiB0aGF0IHRoZSBpbnRlcnNlY3Rpb24gd2lsbCBiZSBwZXJmb3JtZWQgb25seSBvbmNlLgoJICAgICovCgkgICAgaWYgKChncm91cC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRCkgPT0gMCkgewoJCWlmIChncm91cC0+YXR0cmlidXRlcyAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTY2hlbWFCdWlsZENvbXBsZXRlQXR0cmlidXRlV2lsZGNhcmQoY3R4dCwgCgkJCWdyb3VwLT5hdHRyaWJ1dGVzLCAmZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkJcmV0dXJuICgtMSk7CgkJfQoJCWdyb3VwLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfV0lMRENBUkRfQlVJTERFRDsKCSAgICB9CQkKCSAgICBpZiAoZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsJCQoJCWlmICgqY29tcGxldGVXaWxkID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBDb3B5IHRoZSBmaXJzdCBlbmNvdW50ZXJlZCB3aWxkY2FyZCBhcyBjb250ZXh0LCBleGNlcHQgZm9yIHRoZSBhbm5vdGF0aW9uLgoJCSAgICAqLwoJCSAgICAqY29tcGxldGVXaWxkID0geG1sU2NoZW1hQWRkV2lsZGNhcmQoY3R4dCk7CgkJICAgICgqY29tcGxldGVXaWxkKS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOwkgICAKCQkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsIAoJCQljb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPnByb2Nlc3NDb250ZW50cyA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzOwoJCSAgICAvKgoJCSAgICAqIEFsdGhvdWdoIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCBtaWdodCBub3QgY29ycmVzcG9uZCB0byBhbnkKCQkgICAgKiBub2RlIGluIHRoZSBzY2hlbWEsIHdlIHdpbGwgc2F2ZSB0aGlzIGNvbnRleHQgbm9kZS4KCQkgICAgKiBUT0RPOiBIbW0sIGlzIHRoaXMgc2FuZT8KCQkgICAgKi8KCQkgICAgKCpjb21wbGV0ZVdpbGQpLT5ub2RlID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5ub2RlOyAgCgkJICAgIAoJCX0gZWxzZSBpZiAoeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKGN0eHQsICpjb21wbGV0ZVdpbGQsIGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkKCpjb21wbGV0ZVdpbGQpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCSAgICB9Cgl9CglhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgfQogICAJCSAgICAgICAgICAgICAgICAgCiAgICByZXR1cm4gKDApOyAgIAp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJCSAgICAgaW50ICpmaXhlZCwKCQkJCSAgICAgY29uc3QgeG1sQ2hhciAqKnZhbHVlLAoJCQkJICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKewogICAgKmZpeGVkID0gMDsKICAgICp2YWx1ZSA9IE5VTEw7CiAgICBpZiAodmFsICE9IDApIAoJKnZhbCA9IE5VTEw7CgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlID09IE5VTEwpCglpdGVtID0gaXRlbS0+cmVmRGVjbDsKCiAgICBpZiAoaXRlbSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJKnZhbHVlID0gaXRlbS0+ZGVmVmFsdWU7CglpZiAodmFsICE9IDApCgkgICAgKnZhbCA9IGl0ZW0tPmRlZlZhbDsKCWlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpCgkgICAgKmZpeGVkID0gMTsKCXJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKDApOwp9Ci8qKgogKiB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROczoKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDEpOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigxKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYgCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsJCgkKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIAogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBjdXIsIGJhc2UsIHRtcCwgaWQgPSBOVUxMLCBwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIAoJbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW55VHlwZTsKICAgIGludCBiYXNlSXNBbnlUeXBlID0gMDsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CiAgICBpbnQgZXJyID0gMDsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKiAKICAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIHdpdGggY29tcGxleCBjb250ZW50IFNjaGVtYSBDb21wb25lbnQuCiAgICAgKgogICAgICogQXR0cmlidXRlIHVzZXMuCiAgICAgKiBUT0RPOiBBZGQgY2hlY2tzIGZvciBhYnNlbnQgcmVmZXJlbmNlZCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGFuZAogICAgICogc2ltcGxlIHR5cGVzLgogICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJCSAgICAgICJhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJ1aWxkZWQuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkJICAgICAgImNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUuXG4iLAoJCSAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlVHlwZSA9PSBhbnlUeXBlKQoJYmFzZUlzQW55VHlwZSA9IDE7CiAgICAvKgogICAgICogSW5oZXJpdCB0aGUgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZS4KICAgICAqLwogICAgLyoKICAgICAqIE5PVEU6IEl0IGlzIGFsbG93ZWQgdG8gImV4dGVuZCIgdGhlIGFueVR5cGUgY29tcGxleCB0eXBlLgogICAgICovCiAgICBpZiAoIWJhc2VJc0FueVR5cGUpIHsKCWlmIChiYXNlVHlwZSAhPSBOVUxMKSB7CgkgICAgZm9yIChjdXIgPSBiYXNlVHlwZS0+YXR0cmlidXRlVXNlczsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyKSAKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCSJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyBvZiBjb21wbGV4VHlwZSIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdG1wOwoJCX0gZWxzZSAKCQkgICAgbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJbGFzdEJhc2VVc2UgPSB0bXA7IAoJICAgIH0KCX0KICAgIH0KICAgIGlmICgodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkoKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8IAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSkgewoJLyogCgkqIHR5cGUgLS0+ICg8c2ltcGxlQ29udGVudD58PGNvbXBsZXhDb250ZW50PikgCgkqICAgICAgICAtLT4gKDxyZXN0cmljdGlvbj58PGV4dGVuc2lvbj4pIC0tPiBhdHRyaWJ1dGVzCgkqLyAKCWF0dHJzID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT5hdHRyaWJ1dGVzOwogICAgfSBlbHNlIHsKCS8qIFNob3J0IGhhbmQgZm9ybSBvZiB0aGUgY29tcGxleFR5cGUuICovCglhdHRycyA9IHR5cGUtPmF0dHJpYnV0ZXM7CiAgICB9CiAgICAvKgogICAgKiBIYW5kbGUgYXR0cmlidXRlIHdpbGRjYXJkcy4KICAgICovCQogICAgZXJyID0geG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJYXR0cnMsICZ0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCk7ICAgIAogICAgLyoKICAgICogTk9URTogRHVyaW5nIHRoZSBwYXJzZSB0aW1lLCB0aGUgd2lsZGNhcmQgaXMgY3JlYXRlZCBvbiB0aGUgY29tcGxleFR5cGUKICAgICogZGlyZWN0bHksIGlmIGVuY291bnRlcmVkIGluIGEgPHJlc3RyaWN0aW9uPiBvciA8ZXh0ZW5zaW9uPiBlbGVtZW50LgogICAgKi8KICAgIGlmIChlcnIgPT0gLTEpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAiZmFpbGVkIHRvIGJ1aWxkIGFuIGludGVyc2VjdGVkIGF0dHJpYnV0ZSB3aWxkY2FyZC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmIAoJKChiYXNlSXNBbnlUeXBlKSB8fAoJICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgCSAgICAKCSAgKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgkgICAgICAKCSAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkpKSB7CSAgICAKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFVuaW9uIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCB3aXRoIHRoZSBiYXNlIHdpbGRjYXJkLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKGN0eHQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCXJldHVybiAoLTEpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogSnVzdCBpbmhlcml0IHRoZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBOT1RFOiBUaGlzIGlzIHRoZSBvbmx5IGNhc2Ugd2hlcmUgYW4gYXR0cmlidXRlIAogICAgICAgICAgICAqIHdpbGRjYXJkIGlzIHNoYXJlZC4KICAgICAgICAgICAgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQpCgkJdHlwZS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEOwoJICAgIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJfQogICAgfQogICAgCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qIAoJICAgICogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpIAkgICAgCgkgICAgKiA0LjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGhhdmUgb25lLiAKCSAgICAqLwoJICAgIGlmIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkgewkgIAoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAoJCSAgICAiVGhlIHR5cGUgaGFzIGFuIGF0dHJpYnV0ZSB3aWxkY2FyZCwgIgoJCSAgICAiYnV0IHRoZSBiYXNlIHR5cGUgJXMgZG9lcyBub3QgaGF2ZSBvbmUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuICgxKTsKCSAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQoCgkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gMCkgewoJCS8qIDQuMiAqLwoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl80XzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIgCgkJICAgICJzdWJzZXQgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCSAgICAKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICAvKiA0LjMgVW5sZXNzIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3dXItdHlwZSAKCSAgICAqIGRlZmluaXRpb263LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIAoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9IG11c3QgYmUgaWRlbnRpY2FsIHRvIG9yIAoJICAgICogc3Ryb25nZXIgdGhhbiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUgCgkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlciAKCSAgICAqIHRoYW4gbGF4IGlzIHN0cm9uZ2VyIHRoYW4gc2tpcC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0gYW55VHlwZSkgJiYgCgkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cykpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8zLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCSAgICAiVGhlICdwcm9jZXNzIGNvbnRlbnRzJyBvZiB0aGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIHdlYWtlciB0aGFuICIKCQkgICAgInRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSAlcyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikKCQlyZXR1cm4gKDEpOwoJICAgIH0KCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJLyoKCSogRGVyaXZhdGlvbiBWYWxpZCAoRXh0ZW5zaW9uKQoJKiBBdCB0aGlzIHBvaW50IHRoZSB0eXBlIGFuZCB0aGUgYmFzZSBoYXZlIGJvdGgsIGVpdGhlcgoJKiBubyB3aWxkY2FyZCBvciBhIHdpbGRjYXJkLgoJKi8KCWlmICgoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkgICAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkpIHsKCSAgICAvKiAxLjMgKi8KCSAgICBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCgKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfQ1RfRVhURU5EU18xXzMsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAkJCgkJICAgICJUaGUgYXR0cmlidXRlIHdpbGRjYXJkIGlzIG5vdCBhIHZhbGlkICIgCgkJICAgICJzdXBlcnNldCBvZiB0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkKCQlyZXR1cm4gKDEpOwkJCgkgICAgfQoJfQkJCiAgICB9CQoKICAgIC8qCiAgICAgKiBHYXRoZXIgYXR0cmlidXRlIHVzZXMgZGVmaW5lZCBieSB0aGlzIHR5cGUuCiAgICAgKi8KICAgIGlmIChhdHRycyAhPSBOVUxMKSB7CglpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgYXR0cnMsIAoJICAgICZ1c2VzLCAmbGFzdFVzZSkgPT0gLTEpIHsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCA0LgogICAgICogIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCiAgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4iCiAgICAgKgogICAgICogRm9yICJleHRlbnNpb24iIHRoaXMgaXMgZG9uZSBmdXJ0aGVyIGRvd24uCiAgICAgKi8KICAgIGlmICgodXNlcyAhPSBOVUxMKSAmJiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgljdXIgPSB1c2VzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgdG1wID0gY3VyLT5uZXh0OwoJICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJICAgICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoY3VyLT5hdHRyICksIAoJCSAgICB4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkodG1wLT5hdHRyKSkpKSB7CgoJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsIAoJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkJCgkJCSJEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSAlcyBzcGVjaWZpZWQiLAoJCQl4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHIsIAoJCQkgICAgeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0ciksIAoJCQkgICAgeG1sU2NoZW1hR2V0QXR0ck5hbWUodG1wLT5hdHRyKSkKCQkgICAgKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAgCQkgICAgCgkJICAgIGJyZWFrOwoJCX0KCQl0bXAgPSB0bXAtPm5leHQ7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KICAgIH0JCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CQoJLyoKCSAqIERlcml2ZSBieSByZXN0cmljdGlvbi4KCSAqLwoJaWYgKGJhc2VJc0FueVR5cGUpIHsKCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdXNlczsKCX0gZWxzZSB7CgkgICAgaW50IGZvdW5kOwoJICAgIGNvbnN0IHhtbENoYXIgKmJFZmZWYWx1ZTsKCSAgICBpbnQgZWZmRml4ZWQ7CgoJICAgIGN1ciA9IHVzZXM7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJZm91bmQgPSAwOwoJCWJhc2UgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoJCXdoaWxlIChiYXNlICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZShiYXNlLT5hdHRyKSkgJiYKCQkJeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0cikpKSB7CgkJCQoJCQlmb3VuZCA9IDE7CQkJCgkJCQoJCQlpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMKSAmJgoJCQkgICAgKGJhc2UtPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMi4xLjEKCQkJICAgICovCQoJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCgkJCQkiVGhlICdvcHRpb25hbCcgdXNlIGlzIGluY29uc2lzdGVudCB3aXRoIGEgbWF0Y2hpbmcgIgoJCQkJIidyZXF1aXJlZCcgdXNlIG9mIHRoZSBiYXNlIHR5cGUiLCBOVUxMKTsJCQkJCgkJCX0gZWxzZSBpZiAoKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAzIAoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMywgCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCQkJIkEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSBmb3IgdGhlICdyZXF1aXJlZCcgIgoJCQkJImF0dHJpYnV0ZSB1c2UgJXMgb2YgdGhlIGJhc2UgdHlwZSBpcyBtaXNzaW5nIiwKCQkJCXhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgCgkJCQl4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoYmFzZS0+YXR0ciksIAoJCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUoYmFzZS0+YXR0cikpKTsJCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkJfSBlbHNlIHsKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zIFtEZWZpbml0aW9uOl0gIExldCB0aGUgZWZmZWN0aXZlIHZhbHVlIAoJCQkgICAgKiBjb25zdHJhaW50IG9mIGFuIGF0dHJpYnV0ZSB1c2UgYmUgaXRzIHt2YWx1ZSAKCQkJICAgICogY29uc3RyYWludH0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSBpdHMge2F0dHJpYnV0ZSAKCQkJICAgICogZGVjbGFyYXRpb259J3Mge3ZhbHVlIGNvbnN0cmFpbnR9IC4gCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGJhc2UtPmF0dHIsICZlZmZGaXhlZCwgCgkJCQkmYkVmZlZhbHVlLCAwKTsJCQkgICAJCQkJCQkJICAgIAoJCQkgICAgLyoKCQkJICAgICogMi4xLjMgLi4uIG9uZSBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZQoJCQkgICAgKgoJCQkgICAgKiAyLjEuMy4xIEIncyC3ZWZmZWN0aXZlIHZhbHVlIGNvbnN0cmFpbnS3IGlzIAoJCQkgICAgKiC3YWJzZW50tyBvciBkZWZhdWx0LgoJCQkgICAgKi8KCQkJICAgIGlmICgoYkVmZlZhbHVlICE9IE5VTEwpICYmCgkJCQkoZWZmRml4ZWQgPT0gMSkpIHsKCQkJCWNvbnN0IHhtbENoYXIgKnJFZmZWYWx1ZSA9IE5VTEw7CgoJCQkJeG1sU2NoZW1hR2V0RWZmZWN0aXZlVmFsdWVDb25zdHJhaW50KGJhc2UtPmF0dHIsICZlZmZGaXhlZCwgCgkJCQkgICAgJnJFZmZWYWx1ZSwgMCk7CQoJCQkJLyoKCQkJCSogMi4xLjMuMiBSJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcyAKCQkJCSogZml4ZWQgd2l0aCB0aGUgc2FtZSBzdHJpbmcgYXMgQidzLgoJCQkJKi8KCQkJCWlmICgoZWZmRml4ZWQgPT0gMCkgfHwKCQkJCSAgICAoISB4bWxTdHJFcXVhbChyRWZmVmFsdWUsIGJFZmZWYWx1ZSkpKSB7CgkJCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8zLCAKCQkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkKCQkJCQkiVGhlIGVmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJCQkJImF0dHJpYnV0ZSB1c2UgaXMgaW5jb25zaXN0ZW50IHdpdGggIgoJCQkJCSJpdHMgY29ycmVzcG9uZGVudCBvZiB0aGUgYmFzZSB0eXBlIiwKCQkJCQlOVUxMKTsJCQkJCSAgICAKCQkJCX0KCQkJICAgIH0KCQkJICAgIC8qCgkJCSAgICAqIFRPRE86IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMS4yICh7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCkKCQkJICAgICovCgkJCSAgICAvKgoJCQkgICAgKiBPdmVycmlkZSB0aGUgYXR0cmlidXRlIHVzZS4KCQkJICAgICovCgkJCSAgICBiYXNlLT5hdHRyID0gY3VyLT5hdHRyOwoJCQl9CgkJCQkJCQkJCgkJCWJyZWFrOwoJCSAgICB9CQkJCQoJCSAgICBiYXNlID0gYmFzZS0+bmV4dDsKCQl9CgkJCgkJaWYgKCFmb3VuZCkgewoJCSAgICBpZiAoY3VyLT5hdHRyLT5vY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgewoJCQkvKgoJCQkqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMgoJCQkqLwoJCQlpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpICYmCgkJCSAgICB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwKCQkJCWN1ci0+YXR0ci0+dGFyZ2V0TmFtZXNwYWNlKSkKCQkJICAgIGZvdW5kID0gMTsKCgkJCWlmICghZm91bmQpIHsKCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMiwgCgkJCQlOVUxMLCB0eXBlLCBOVUxMLCBjdXItPmF0dHIsCQkKCQkJCSJOZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkJIm5vciBhIG1hdGNoaW5nIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGUgZG9lcyBleGlzdCIsCgkJCQlOVUxMKTsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIAoJCQkgICAgKiBBZGQgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqCgkJCSAgICAqIE5vdGUgdGhhdCB0aGlzIG1heSBsZWFkIHRvIGZ1bm55IGRlcml2YXRpb24gZXJyb3IgcmVwb3J0cywgaWYKCQkJICAgICogbXVsdGlwbGUgZXF1YWwgYXR0cmlidXRlIHVzZXMgZXhpc3Q7IGJ1dCB0aGlzIGlzIG5vdAoJCQkgICAgKiBhbGxvd2VkIGFueXdheSwgYW5kIGl0IHdpbGwgYmUgcmVwb3J0ZWQgYmVmb3JlaGFuZC4KCQkJICAgICovCgkJCSAgICB0bXAgPSBjdXI7CgkJCSAgICBpZiAocHJldiAhPSBOVUxMKQoJCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkJICAgIGVsc2UgCgkJCQl1c2VzID0gY3VyLT5uZXh0OwoJCQkgICAgY3VyID0gY3VyLT5uZXh0OyAgICAJCQkKCQkJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJCSAgICB9IGVsc2UgCgkJCQlsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQkJICAgIGxhc3RCYXNlVXNlID0gdG1wOwkJCgkJCSAgICAKCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJICAgIH0KCQl9CQkgICAgCSAgICAKCQlwcmV2ID0gY3VyOwkKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodXNlcyk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsgCgkvKgoJICogVGhlIHNwZWMgYWxsb3dzIG9ubHkgYXBwZW5kaW5nLCBhbmQgbm90IG90aGVyIGtpbmRzIG9mIGV4dGVuc2lvbnMuCgkgKgoJICogVGhpcyBlbnN1cmVzOiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgOiAxLjIgCgkgKi8KCWlmICh1c2VzICE9IE5VTEwpIHsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CgkgICAgfSBlbHNlIAoJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdXNlczsKCX0KICAgIH0gZWxzZSB7CgkvKiAKCSogRGVyaXZlIGltcGxpY2l0ZWx5IGZyb20gdGhlIHVyLXR5cGUuCgkqLwoJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CiAgICB9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuCgkgICAgKgoJICAgICogTm90ZSB0aGF0IHRoaXMgd2FzIGFscmVhZHkgZG9uZSBmb3IgInJlc3RyaWN0aW9uIiBhbmQgdHlwZXMgZGVyaXZlZCBmcm9tCgkgICAgKiB0aGUgdXItdHlwZS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCQkoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciApLCAKCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0cikpKSkgewoKCQkJeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwgCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCB0bXAtPmF0dHIsCQkKCQkJICAgICJEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSBzcGVjaWZpZWQiLCBOVUxMKTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgdG1wID0gdG1wLT5uZXh0OwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIDUuIFR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCgkgICAgKiBub3QgaGF2ZSB7dHlwZSBkZWZpbml0aW9ufXMgd2hpY2ggYXJlIG9yIGFyZSBkZXJpdmVkIGZyb20gSUQuCgkgICAgKi8KCSAgICBpZiAoKGN1ci0+YXR0ci0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkJKHhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZShjdHh0LCAoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyLCBYTUxfU0NIRU1BU19JRCkpKSB7CgkJaWYgKGlkICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF81LCAKCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAoJCQkiVGhlcmUgbXVzdCBub3QgZXhpc3QgbW9yZSB0aGFuIG9uZSBhdHRyaWJ1dGUgdXNlLCAiCgkJCSJkZWNsYXJlZCBvZiB0eXBlICdJRCcgb3IgZGVyaXZlZCBmcm9tIGl0IiwgCgkJCU5VTEwpOwoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQl9IAoJCWlkID0gY3VyOwoJICAgIH0KCSAgICAvKgoJICAgICogUmVtb3ZlICJwcm9oaWJpdGVkIiBhdHRyaWJ1dGUgdXNlcy4gVGhlIHJlYXNvbiB0aGlzIGlzIGRvbmUgYXQgdGhpcyBsYXRlIAoJICAgICogc3RhZ2UgaXMgdG8gYmUgYWJsZSB0byBjYXRjaCBkdWJsaWNhdGUgYXR0cmlidXRlIHVzZXMuIFNvIHdlIGhhZCB0byBrZWVwCgkgICAgKiBwcm9oaWJpdGVkIHVzZXMgaW4gdGhlIGxpc3QgYXMgd2VsbC4KCSAgICAqLwoJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJdG1wID0gY3VyOwoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIHR5cGUtPmF0dHJpYnV0ZVVzZXMgPSBjdXItPm5leHQ7CgkJZWxzZQoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCWN1ciA9IGN1ci0+bmV4dDsKCQl4bWxGcmVlKHRtcCk7CgkgICAgfSBlbHNlIHsKCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9ICAgIAogICAgfQogICAgLyoJCiAgICAgKiBUT0RPOiBUaGlzIGNoZWNrIHNob3VsZCBiZSByZW1vdmVkIGlmIHdlIGFyZSAxMDAlIHN1cmUgb2YKICAgICAqIHRoZSBiYXNlIHR5cGUgYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBiZWluZyBidWlsdC4KICAgICAqLwogICAgaWYgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoIWJhc2VJc0FueVR5cGUpICYmCgkoYmFzZVR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpICYmCgkoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBiYXNlVHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAiYXR0cmlidXRlIHVzZXMgbm90IGJ1aWxkZWQgb24gYmFzZSB0eXBlICclcycuXG4iLAoJICAgIGJhc2VUeXBlLT5uYW1lLCBOVUxMKTsKICAgIH0gICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnM6CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hCiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVmaW5pdGlvbgogKiBAZmluYWw6IHRoZSBmaW5hbAogKgogKiBFdmFsdWF0ZXMgaWYgYSB0eXBlIGRlZmluaXRpb24gY29udGFpbnMgdGhlIGdpdmVuICJmaW5hbCIuCiAqIFRoaXMgZG9lcyB0YWtlICJmaW5hbERlZmF1bHQiIGludG8gYWNjb3VudCBhcyB3ZWxsLgogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgZG9lcyBjb250YWludCB0aGUgZ2l2ZW4gImZpbmFsIiwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgaW50IGZpbmFsKQp7CiAgICBpbnQgdGZpbmFsID0gZmluYWwsIHRmbGFncyA9IHR5cGUtPmZsYWdzOwoKICAgIGlmICh0eXBlID09IE5VTEwpCglyZXR1cm4gKDApOyAgICAKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfREVGQVVMVCkgewoJc3dpdGNoIChmaW5hbCkgewoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1JFU1RSSUNUSU9OOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT046CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT047CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1Q6CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9MSVNUOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX1VOSU9OOwoJCWJyZWFrOwoJfQoJdGZsYWdzID0gc2NoZW1hLT5mbGFnczsKICAgIH0KICAgIGlmICh0ZmxhZ3MgJiB0ZmluYWwpIAoJcmV0dXJuICgxKTsKICAgIGVsc2UKCXJldHVybiAoMCk7CiAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzOgogKiBAdHlwZTogIHRoZSBVbmlvbiBTaW1wbGUgVHlwZQogKgogKiBSZXR1cm5zIGEgbGlzdCBvZiBtZW1iZXIgdHlwZXMgb2YgQHR5cGUgaWYgZXhpc3RpbmcsIAogKiByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVMaW5rUHRyCnhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgd2hpbGUgKHR5cGUgIT0gTlVMTCkgewoJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpCgkgICAgcmV0dXJuICh0eXBlLT5tZW1iZXJUeXBlcyk7CgllbHNlCgkgICAgdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgaXRlbSB0eXBlIGRlZmluaXRpb24gb2YgdGhlIGxpc3Qgc2ltcGxlIHR5cGUuCiAqLyAKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApCglyZXR1cm4gKE5VTEwpOwogICAgLyoKICAgICogTm90ZTogSW4gbGlieG1sMiwgdGhlIGJ1aWx0LWluIHR5cGVzIGRvIG5vdCByZWZsZWN0IAogICAgKiB0aGUgZGF0YXR5cGUgaGllcmFyY2h5ICh5ZXQ/KSAtIHdlIGhhdmUgdG8gdHJlYXQgdGhlbQogICAgKiBpbiBhIHNwZWNpYWwgd2F5LgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgCglyZXR1cm4gKHhtbFNjaGVtYUdldEJ1aWx0SW5MaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUpKTsKICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkKCS8qIDEgSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlIHR5cGUgCgkqIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIAoJKiBpdGVtVHlwZSBbYXR0cmlidXRlXSBvZiA8bGlzdD4sIGlmIHByZXNlbnQsIG90aGVyd2lzZSAKCSogdGhlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gCgkqIGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDxsaXN0Pi4KCSovCglyZXR1cm4gKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyk7CiAgICBlbHNlIHsKCS8qIDIgSWYgdGhlIDxyZXN0cmljdGlvbj4gb3B0aW9uIGlzIGNob3NlbiwgdGhlbiB0aGUgCgkqIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkqLyAgICAKCXJldHVybiAoeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlLT5iYXNlVHlwZSkpOwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0s6CiAqIEB0eXBlOiAgdGhlIGRlcml2ZWQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAYmFzZVR5cGU6ICB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHdoZXRlciBAdHlwZSBjYW4gYmUgdmFsaWRseSAKICogZGVyaXZlZCBmcm9tIEBiYXNlVHlwZS4KICoKICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIGFuIHBvc2l0aXZlIGVycm9yIGNvZGUgb3RoZXJ3aXNlLgogKi8gCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyh4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUsCgkJCQkgICAgIGludCBzdWJzZXQpCnsgICAKICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpCiAgICAqCiAgICAqCiAgICAqIDEgVGhleSBhcmUgdGhlIHNhbWUgdHlwZSBkZWZpbml0aW9uLgogICAgKiBUT0RPOiBUaGUgaWRlbnR5IGNoZWNrIG1pZ2h0IGhhdmUgdG8gYmUgbW9yZSBjb21wbGV4IHRoYW4gdGhpcy4KICAgICovCiAgICBpZiAodHlwZSA9PSBiYXNlVHlwZSkKCXJldHVybiAoMCk7ICAgIAogICAgLyogCiAgICAqIDIuMSByZXN0cmljdGlvbiBpcyBub3QgaW4gdGhlIHN1YnNldCwgb3IgaW4gdGhlIHtmaW5hbH0KICAgICogb2YgaXRzIG93biB7YmFzZSB0eXBlIGRlZmluaXRpb259OwogICAgKi8KICAgIGlmICgoc3Vic2V0ICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikgfHwKCSh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhzY2hlbWEsIAoJICAgIHR5cGUtPmJhc2VUeXBlLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkpIHsKCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8xKTsgCiAgICB9CiAgICAvKiAyLjIgKi8KICAgIGlmICh0eXBlLT5iYXNlVHlwZSA9PSBiYXNlVHlwZSkgewoJLyoKCSogMi4yLjEgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgQi4KCSovCglyZXR1cm4gKDApOwogICAgfSAgIAogICAgLyogCiAgICAqIDIuMi4yIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIG5vdCB0aGUgt3VyLXR5cGUgZGVmaW5pdGlvbrcgCiAgICAqIGFuZCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBCIGdpdmVuIHRoZSBzdWJzZXQsIGFzIGRlZmluZWQgYnkgdGhpcyAKICAgICogY29uc3RyYWludC4gICAgCiAgICAqLwogICAgaWYgKCh0eXBlLT5iYXNlVHlwZSAhPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKSkgJiYKCSh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIGJhc2VUeXBlLCBzdWJzZXQpID09IDApKSB7CglyZXR1cm4gKDApOwkJCiAgICB9IAogICAgLyogCiAgICAqIDIuMi4zIEQncyB7dmFyaWV0eX0gaXMgbGlzdCBvciB1bmlvbiBhbmQgQiBpcyB0aGUgt3NpbXBsZSB1ci10eXBlIAogICAgKiBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB8fAoJKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSkgJiYKCShiYXNlVHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkpIHsKCXJldHVybiAoMCk7CiAgICB9ICAgIAogICAgLyogCiAgICAqIDIuMi40IEIncyB7dmFyaWV0eX0gaXMgdW5pb24gYW5kIEQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIGluIEIncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBzdWJzZXQsIGFzIAogICAgKiBkZWZpbmVkIGJ5IHRoaXMgY29uc3RyYWludC4KICAgICoKICAgICogTk9URTogVGhpcyBzZWVtcyBub3QgdG8gaW52b2x2ZSBidWlsdC1pbiB0eXBlcywgc2luY2UgdGhlcmUgaXMgbm8KICAgICogYnVpbHQtaW4gVW5pb24gU2ltcGxlIFR5cGUuCiAgICAqLwogICAgaWYgKGJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgY3VyOwoKCWN1ciA9IGJhc2VUeXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHNjaGVtYSwgdHlwZSwgCgkJY3VyLT50eXBlLCBzdWJzZXQpID09IDApCgkJcmV0dXJuICgwKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQogICAgfQogICAgCiAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9ERVJJVkVEX09LXzJfMik7Cn0KCgovKioKICogeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIHN0LXByb3BzLWNvcnJlY3QuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgcHJvcGVydGllcyBhcmUgY29ycmVjdCwKICogaWYgbm90LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlLCBhbnlTaW1wbGVUeXBlLAoJYW55VHlwZTsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgLyogU1RBVEU6IGVycm9yIGZ1bmNzIGNvbnZlcnRlZC4gKi8KICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICoKICAgICogTk9URTogVGhpcyBpcyBzb21laG93IHJlZHVuZGFudCwgc2luY2Ugd2UgYWN0dWFsbHkgYnVpbHQgYSBzaW1wbGUgdHlwZQogICAgKiB0byBoYXZlIGFsbCB0aGUgbmVlZGVkIGluZm9ybWF0aW9uOyB0aGlzIGFjdHMgYXMgYW4gc2VsZiB0ZXN0LgogICAgKi8KICAgIGFueVNpbXBsZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKICAgIGFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIC8qIAogICAgKiBUT0RPOiAxIFRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG11c3QgYmUgYXMgCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBEYXRhdHlwZSBkZWZpbml0aW9uLCBtb2R1bG8gdGhlIAogICAgKiBpbXBhY3Qgb2YgTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuCiAgICAqLwogICAgLyogQmFzZSB0eXBlOiBJZiB0aGUgZGF0YXR5cGUgaGFzIGJlZW4gt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcgCiAgICAqIHRoZW4gdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gY29tcG9uZW50IGZyb20gd2hpY2ggaXQgaXMgt2Rlcml2ZWS3LCAKICAgICogb3RoZXJ3aXNlIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGZvciBhbnlTaW1wbGVUeXBlICinNC4xLjYpLiAKICAgICovCiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiTm8gYmFzZSB0eXBlIGV4aXN0ZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoKGJhc2VUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpICYmCgkoKGJhc2VUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgfHwKCSAoYmFzZVR5cGUgPT0gYW55VHlwZSkpKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJUaGUgYmFzZSB0eXBlICVzIGlzIG5vdCBhIHNpbXBsZSB0eXBlIiwgCgkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCQoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgaWYgKChiYXNlVHlwZSAhPSBhbnlTaW1wbGVUeXBlKSAmJgoJKHR5cGUtPnN1YnR5cGVzLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIkEgdHlwZSwgZGVyaXZlZCBieSBsaXN0IG9yIHVuaW9uLCBtdXN0IGhhdmUiCgkgICAgInRoZSBzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uIGFzIGJhc2UgdHlwZSwgbm90ICVzIiwKCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CglGUkVFX0FORF9OVUxMKHN0cikKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIC8qIAogICAgKiBWYXJpZXR5OiBPbmUgb2Yge2F0b21pYywgbGlzdCwgdW5pb259LiAKICAgICovCiAgICBpZiAoKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmCgkoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSAmJgoJKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlIHZhcmlldHkgaXMgYWJzZW50IiwgTlVMTCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKiBUT0RPOiBGaW5pc2ggdGhpcy4gSG1tLCBpcyB0aGlzIGZpbmlzaGVkPyAqLwoKICAgIC8qCiAgICAqIDIgQWxsIHNpbXBsZSB0eXBlIGRlZmluaXRpb25zIG11c3QgYmUgZGVyaXZlZCB1bHRpbWF0ZWx5IGZyb20gdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbiAoc2+3IGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS4gVGhhdCBpcywgaXQgCiAgICAqIG11c3QgYmUgcG9zc2libGUgdG8gcmVhY2ggYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUgb3IgdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbrcgYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCiAgICAqLyAgICAKICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB3aGlsZSAoKGJhc2VUeXBlICE9IE5VTEwpICYmIChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CglpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgY3R4dCwgIE5VTEwpOwoJaWYgKGJhc2VUeXBlID09IGFueVNpbXBsZVR5cGUpCgkgICAgYnJlYWs7CgllbHNlIGlmIChiYXNlVHlwZSA9PSB0eXBlKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMik7Cgl9CSAgIAoJYmFzZVR5cGUgPSBiYXNlVHlwZS0+YmFzZVR5cGU7CiAgICB9ICAgCiAgICAvKgogICAgKiAzIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgYmFzZVR5cGUsIAoJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzMsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIlRoZSAnZmluYWwnIG9mIGl0cyBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAiCgkgICAgIidyZXN0cmljdGlvbiciLAoJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQkKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8zKTsKICAgIH0gICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBAdHlwZSAoc2ltcGxlVHlwZSkgaXMgZGVyaXZlZCAKICogdmFsaWRseSBieSByZXN0cmljdGlvbi4KICoKICogUmV0dXJucyAtMSBvbiBpbnRlcm5hbCBlcnJvcnMsIDAgaWYgdGhlIHR5cGUgaXMgdmFsaWRseSBkZXJpdmVkLCAKICogYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAKICAgIHhtbENoYXIgKnN0ciA9IE5VTEw7CgogICAgLyogU1RBVEU6IGVycm9yIGZ1bmNzIGNvbnZlcnRlZC4gKi8KCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogVGhlIGdpdmVuICIKCSAgICAidHlwZSAnJXMnIGlzIG5vdCBhIHVzZXItZGVyaXZlZCBzaW1wbGVUeXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpIHsKCXhtbFNjaGVtYVR5cGVQdHIgcHJpbWl0aXZlOwoJLyogCgkqIDEuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIGFuIGF0b21pYyBzaW1wbGUgCgkqIHR5cGUgZGVmaW5pdGlvbiBvciBhIGJ1aWx0LWluIHByaW1pdGl2ZSBkYXRhdHlwZS4KCSovCQoJaWYgKCh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgYmFzZSB0eXBlICVzIGlzIG5vdCBhbiBhdG9taWMgc2ltcGxlIHR5cGUiLAoJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xKTsKCX0KCS8qIDEuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIAoJKiByZXN0cmljdGlvbi4KCSovCgkvKiBPUFRJTUlaRSBUT0RPIDogVGhpcyBpcyBhbHJlYWR5IGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tTdFByb3BzQ29ycmVjdCAqLwoJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgZmluYWwgb2YgaXRzIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yKTsKCX0KCQoJLyogCgkqIDEuMy4xIERGIG11c3QgYmUgYW4gYWxsb3dlZCBjb25zdHJhaW5pbmcgZmFjZXQgZm9yIHRoZSB7cHJpbWl0aXZlCgkqIHR5cGUgZGVmaW5pdGlvbn0sIGFzIHNwZWNpZmllZCBpbiB0aGUgYXBwcm9wcmlhdGUgc3Vic2VjdGlvbiBvZiAzLjIgCgkqIFByaW1pdGl2ZSBkYXRhdHlwZXMuCgkqLwoJaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkgICAgaW50IG9rID0gMTsKCSAgICAKCSAgICBwcmltaXRpdmUgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5cGUpOwoJICAgIGlmIChwcmltaXRpdmUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkgICAgWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246IGZhaWxlZCAiCgkJICAgICJ0byBnZXQgcHJpbWl0aXZlIHR5cGUgb2YgdHlwZSAnJXMnLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQkgICAgCgkgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkgICAgZG8gewoJCWlmICh4bWxTY2hlbWFJc0J1aWx0SW5UeXBlRmFjZXQocHJpbWl0aXZlLCBmYWNldC0+dHlwZSkgPT0gMCkgewoJCSAgICBvayA9IDA7CgkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSwKCQkJTlVMTCwgdHlwZSwgcHJpbWl0aXZlLCBmYWNldCk7CQkgICAgCQkgICAgCQkgICAgCgkJfQoJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CSAgICAKCSAgICBpZiAob2sgPT0gMCkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEpOwkgICAgCgl9CgkvKgoJKiBUT0RPOiAxLjMuMiAoZmFjZXQgZGVyaXZhdGlvbikKCSovCiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKCXhtbFNjaGVtYVR5cGVQdHIgaXRlbVR5cGUgPSBOVUxMOwoKCWl0ZW1UeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKTsKCWlmIChpdGVtVHlwZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiAiCgkJImZhaWxlZCB0byBldmFsdWF0ZSB0aGUgaXRlbSB0eXBlIG9mIHR5cGUgJyVzJy5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiAyLjEgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIGF0b21pYyBvciAKCSogdW5pb24gKGluIHdoaWNoIGNhc2UgYWxsIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IAoJKiBtdXN0IGJlIGF0b21pYykuCgkqLwoJaWYgKCgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYgIAoJICAgICgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSkgewkgICAgCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCSJUaGUgaXRlbSB0eXBlICVzIG11c3QgaGF2ZSBhIHZhcmlldHkgb2YgYXRvbWljIG9yIHVuaW9uIiwKCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCSAgICAKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCX0gZWxzZSBpZiAoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7CgkgICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCSAgICBtZW1iZXIgPSBpdGVtVHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKChtZW1iZXItPnR5cGUtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJCSJUaGUgaXRlbSB0eXBlIGlzIGEgdW5pb24gdHlwZSwgYnV0IHRoZSAiCgkJCSJtZW1iZXIgdHlwZSAlcyBvZiB0aGlzIGl0ZW0gdHlwZSBpcyBub3QgYXRvbWljIiwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAgCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJfQoJCglpZiAodHlwZS0+YmFzZVR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48bGlzdCAuLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4xIAoJICAgICogMi4zLjEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSAgICAqIGNvbnRhaW4gbGlzdC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIAoJCWl0ZW1UeXBlLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBpdGVtIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAnbGlzdCciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBvbmx5IGNvbnRhaW4gdGhlIHdoaXRlU3BhY2UKCSAgICAqIGZhY2V0IGNvbXBvbmVudC4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzIsCgkJCSAgICBOVUxMLCB0eXBlLCBmYWNldCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yKTsKCQkgICAgfQoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJICAgIH0KCSAgICAvKgoJICAgICogVE9ETzogRGF0YXR5cGVzIHN0YXRlczogCgkgICAgKiBBILdsaXN0tyBkYXRhdHlwZSBjYW4gYmUgt2Rlcml2ZWS3IGZyb20gYW4gt2F0b21pY7cgZGF0YXR5cGUgCgkgICAgKiB3aG9zZSC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlIChzdWNoIGFzIHN0cmluZyBvciBhbnlVUkkpb3IgCgkgICAgKiBhILd1bmlvbrcgZGF0YXR5cGUgYW55IG9mIHdob3NlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30ncyAKCSAgICAqILdsZXhpY2FsIHNwYWNltyBhbGxvd3Mgc3BhY2UuCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIFRoaXMgaXMgdGhlIGNhc2UgaWYgd2UgaGF2ZTogPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uIC4uLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4yIAoJICAgICogMi4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgbGlzdC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkJICAgICJUaGUgYmFzZSB0eXBlICVzIG11c3QgYmUgYSBsaXN0IHR5cGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90CgkgICAgKiBjb250YWluIHJlc3RyaWN0aW9uLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkJICAgICJUaGUgZmluYWwgb2YgdGhlIGJhc2UgdHlwZSAlcyBtdXN0IG5vdCBjb250YWluICdyZXN0cmljdGlvbiciLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4yLjMgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgCgkgICAgKiBmcm9tIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259J3Mge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBnaXZlbgoJICAgICogdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJICAgICovCgkgICAgewoJCXhtbFNjaGVtYVR5cGVQdHIgYmFzZUl0ZW1UeXBlOwoKCQliYXNlSXRlbVR5cGUgPSB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUtPmJhc2VUeXBlKTsKCQlpZiAoYmFzZUl0ZW1UeXBlID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQlYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCQkieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogIgoJCQkiTGlzdCBzaW1wbGUgdHlwZSAnJXMnOiBGYWlsZWQgdG8gIgoJCQkiZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSBvZiBpdHMgYmFzZSB0eXBlICclcycuXG4iLAoJCQl0eXBlLT5uYW1lLCB0eXBlLT5iYXNlVHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlpZiAoKGl0ZW1UeXBlICE9IGJhc2VJdGVtVHlwZSkgJiYKCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soY3R4dC0+c2NoZW1hLCBpdGVtVHlwZSwKCQkgICAgYmFzZUl0ZW1UeXBlLCAwKSAhPSAwKSkgewoJCSAgICB4bWxDaGFyICpzdHJCSVQgPSBOVUxMLCAqc3RyQlQgPSBOVUxMOwoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMywKCQkJTlVMTCwgdHlwZSwgTlVMTCwJCgkJCSJUaGUgaXRlbSB0eXBlICVzIGlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUgIgoJCQkiaXRlbSB0eXBlICVzIG9mIHRoZSBiYXNlIHR5cGUgJXMiLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGl0ZW1UeXBlLCBOVUxMLCAxKSwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyQklULCBOVUxMLCBiYXNlSXRlbVR5cGUsIE5VTEwsIDEpLAoJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJCVCwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJJVCkKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCVCkJCSAgICAKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzMpOwoJCX0KCSAgICB9CgkgICAgCgkgICAgaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkJaW50IG9rID0gMTsKCQkvKiAKCQkqIDIuMy4yLjQgT25seSBsZW5ndGgsIG1pbkxlbmd0aCwgbWF4TGVuZ3RoLCB3aGl0ZVNwYWNlLCBwYXR0ZXJuIAoJCSogYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIGFsbG93ZWQgYW1vbmcgdGhlIHtmYWNldHN9LgoJCSovCgkJZmFjZXQgPSB0eXBlLT5mYWNldHM7CgkJZG8gewoJCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJCQkgICAgLyoKCQkJICAgICogVE9ETzogMi41LjEuMiBMaXN0IGRhdGF0eXBlcwoJCQkgICAgKiBUaGUgdmFsdWUgb2Ygt3doaXRlU3BhY2W3IGlzIGZpeGVkIHRvIHRoZSB2YWx1ZSBjb2xsYXBzZS4gCgkJCSAgICAqLwoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCQkgICAgYnJlYWs7CgkJCWRlZmF1bHQ6IHsKCQkJICAgIHhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfNCwKCQkJCU5VTEwsIHR5cGUsIGZhY2V0KTsKCQkJICAgIC8qCgkJCSAgICAqIFdlIGNvdWxkIHJldHVybiwgYnV0IGl0J3MgbmljZXIgdG8gcmVwb3J0IGFsbCAKCQkJICAgICogaW52YWxpZCBmYWNldHMuCgkJCSAgICAqLwoJCQkgICAgb2sgPSAwOwkJCSAgICAKCQkJfQoJCSAgICB9CQkgICAgCgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80KTsKCQkvKgoJCSogVE9ETzogMi4zLjIuNSBGb3IgZWFjaCBmYWNldCBpbiB0aGUge2ZhY2V0c30gKGNhbGwgdGhpcyBERiksIGlmIHRoZXJlCgkJKiBpcyBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgaW4gdGhlIHtmYWNldHN9IG9mIHRoZSB7YmFzZSB0eXBlIAoJCSogZGVmaW5pdGlvbn0gKGNhbGwgdGhpcyBCRiksdGhlbiB0aGUgREYncyB7dmFsdWV9IG11c3QgYmUgYSB2YWxpZCAKCQkqIHJlc3RyaWN0aW9uIG9mIEJGJ3Mge3ZhbHVlfSBhcyBkZWZpbmVkIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KCQkqLwoJICAgIH0JICAgIAoJICAgIAoKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCS8qCgkqIDMuMSBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGFsbCBoYXZlIHt2YXJpZXR5fSBvZiAKCSogYXRvbWljIG9yIGxpc3QuCgkqLwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgaWYgKCgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmIAoJCSgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJICAgICJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbmVpdGhlciBhbiBhdG9taWMsIG5vciBhIGxpc3QgdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfMSk7CgkgICAgfQoJICAgIG1lbWJlciA9IG1lbWJlci0+bmV4dDsKCX0KCS8qCgkqIDMuMy4xIElmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3c2ltcGxlIHVyLXR5cGUgCgkqIGRlZmluaXRpb263IAoJKi8KCWlmICh0eXBlLT5iYXNlVHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKSkgewoJICAgIC8qCgkgICAgKiAzLjMuMS4xIEFsbCBvZiB0aGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGhhdmUgYSAKCSAgICAqIHtmaW5hbH0gd2hpY2ggZG9lcyBub3QgY29udGFpbiB1bmlvbi4KCSAgICAqLwoJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCWlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIG1lbWJlci0+dHlwZSwgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT04pKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIlRoZSBmaW5hbCBvZiBtZW1iZXIgdHlwZSAlcyBjb250YWlucyAndW5pb24nIiwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCQkgICAKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBiZSBlbXB0eS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsIAoJCSAgICAiTm8gZmFjZXRzIGFsbG93ZWQiLCBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzFfMik7CgkgICAgfQoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogMy4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgdW5pb24uCgkgICAgKi8KCSAgICBpZiAoKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgPT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGJhc2UgdHlwZSAlcyBpcyBub3QgYSB1bmlvbiB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLCAKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGZpbmFsIG9mIGl0cyBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzIpOwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuMyBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIsIG11c3QgYmUgdmFsaWRseSAKCSAgICAqIGRlcml2ZWQgZnJvbSB0aGUgY29ycmVzcG9uZGluZyB0eXBlIGRlZmluaXRpb25zIGluIHRoZSB7YmFzZSAKCSAgICAqIHR5cGUgZGVmaW5pdGlvbn0ncyB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IGdpdmVuIHRoZSBlbXB0eSBzZXQsIAoJICAgICogYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLgoJICAgICovCgkgICAgewoJCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGJhc2VNZW1iZXI7CgoJCS8qCgkJKiBPUFRJTUlaRTogaWYgdGhlIHR5cGUgaXMgcmVzdHJpY3RpbmcsIGl0IGhhcyBubyBsb2NhbCBkZWZpbmVkIAoJCSogbWVtYmVyIHR5cGVzIGFuZCBpbmhlcml0cyB0aGUgbWVtYmVyIHR5cGVzIG9mIHRoZSBiYXNlIHR5cGU7IAoJCSogdGh1cyBhIGNoZWNrIGZvciBlcXVhbGl0eSBjYW4gYmUgc2tpcHBlZC4KCQkqLwoJCS8qCgkJKiBFdmVuIHdvcnNlOiBJIGNhbm5vdCBzZWUgYSBzY2VuYXJpbyB3aGVyZSBhIHJlc3RyaWN0aW5nCgkJKiB1bmlvbiBzaW1wbGUgdHlwZSBjYW4gaGF2ZSBvdGhlciBtZW1iZXIgdHlwZXMgYXMgdGhlIG1lbWJlciAKCQkqIHR5cGVzIG9mIGl0J3MgYmFzZSB0eXBlLiBUaGlzIGNoZWNrIHNlZW1zIG5vdCBuZWNlc3Nhcnkgd2l0aAoJCSogcmVzcGVjdCB0byB0aGUgZGVyaXZhdGlvbiBwcm9jZXNzIGluIGxpYnhtbDIuCgkJKiBCdXQgbmVjZXNzYXJ5IGlmIGNvbnN0cnVjdGluZyB0eXBlcyB3aXRoIGFuIEFQSS4KCQkqLwoJCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKSB7CgkJICAgIG1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJCSAgICBiYXNlTWVtYmVyID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZS0+YmFzZVR5cGUpOwoJCSAgICBpZiAoKG1lbWJlciA9PSBOVUxMKSAmJiAoYmFzZU1lbWJlciAhPSBOVUxMKSkgewkJICAgCgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiAiCgkJCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbiAiCgkJCSAgICAiKDMuMy4yLjMpLCB1bmlvbiBzaW1wbGUgdHlwZSAnJXMnLCB1bmVxdWFsIG51bWJlciAiCgkJCSAgICAib2YgbWVtYmVyIHR5cGVzIGluIHRoZSBiYXNlIHR5cGVcbiIsCgkJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQkgICAgfQkJCgkJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCQlpZiAoYmFzZU1lbWJlciA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogIgoJCQkJInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb24gIgoJCQkJIigzLjMuMi4zKSwgdW5pb24gc2ltcGxlIHR5cGUgJyVzJywgdW5lcXVhbCBudW1iZXIgIgoJCQkJIm9mIG1lbWJlciB0eXBlcyBpbiB0aGUgYmFzZSB0eXBlLlxuIiwKCQkJCXR5cGUtPm5hbWUsIE5VTEwpOwoJCQl9CgkJCWlmICgobWVtYmVyLT50eXBlICE9IGJhc2VNZW1iZXItPnR5cGUpICYmCgkJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhjdHh0LT5zY2hlbWEsIAoJCQkgICAgbWVtYmVyLT50eXBlLCBiYXNlTWVtYmVyLT50eXBlLCAwKSAhPSAwKSkgewoJCQkgICAgeG1sQ2hhciAqc3RyQk1UID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzMsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkJIlRoZSBtZW1iZXIgdHlwZSAlcyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gaXRzICIKCQkJCSJjb3JyZXNwb25kaW5nIG1lbWJlciB0eXBlICVzIG9mIHRoZSBiYXNlIHR5cGUgJXMiLAoJCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBtZW1iZXItPnR5cGUsIE5VTEwsIDEpLAoJCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyQk1ULCBOVUxMLCBiYXNlTWVtYmVyLT50eXBlLCBOVUxMLCAxKSwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJULCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJNVCkKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyQlQpCgkJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMyk7CgkJCX0JCQoJCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkJCWJhc2VNZW1iZXIgPSBiYXNlTWVtYmVyLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuNCBPbmx5IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIAoJICAgICogYWxsb3dlZCBhbW9uZyB0aGUge2ZhY2V0c30uCgkgICAgKi8JICAgIAoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJCQl4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQsCgkJCQlOVUxMLCB0eXBlLCBmYWNldCk7CQkJCgkJCW9rID0gMDsJCQkgICAgCgkJICAgIH0JCSAgICAKCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQpOwoJCSAgICAKCSAgICB9CgkgICAgLyoKCSAgICAqIFRPRE86IDMuMy4yLjUgKGZhY2V0IGRlcml2YXRpb24pCgkgICAgKi8KCX0KICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgY3JjLXNpbXBsZS10eXBlIGNvbnN0cmFpbnRzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgIAogICAgLyoKICAgICogTk9URTogc3JjLXNpbXBsZS10eXBlIDItNCBhcmUgcmVkdW5kYW50LCBzaW5jZSB0aGUgY2hlY2tzCiAgICAqIHdlcmUgYXJlIGRvbmUgZm9yIHRoZSBjb3JyZXNwb25kaW5nIDxyZXN0cmljdGlvbj4sIDxsaXN0PiBhbmQgPHVuaW9uPgogICAgKiBlbGVtZW50cywgYnV0IFczQyB3YW50cyBhIDxzaW1wbGVUeXBlPiBlcnJvciBhcyB3ZWxsLCBzbyBpdCBnZXRzIG9uZS4KICAgICogTWFieSB0aGlzIGNhbiBiZSBza2lwcGVkIGluIHRoZSBmdXR1cmUsIGlmIHdlIGdldCBzdXJlIGl0J3Mgbm90IG5lZWRlZC4KICAgICovCiAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlLCAiCgkJIm5vIHN1YnR5cGUgb24gc2ltcGxlIHR5cGUgJyVzJy5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qIAogICAgKiBzcmMtc2ltcGxlLXR5cGUuMSBUaGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCBpZiBhbnksCiAgICAqIG11c3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9ucyBzZXQgb3V0IGluIENvbnN0cmFpbnRzIG9uIFNpbXBsZSBUeXBlIAogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy4xNC42KS4gICAgCiAgICAqLwogICAgaWYgKCh4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KGN0eHQsIHR5cGUpICE9IDApIHx8CgkoeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyhjdHh0LCB0eXBlKSAhPSAwKSkgewoJLyoKCSogVE9ETzogUmVtb3ZlZCB0aGlzLCBzaW5jZSBpdCBnb3QgYW5ub3lpbmcgdG8gZ2V0IGFuCgkqIGV4dHJhIGVycm9yIHJlcG9ydCwgaWYgYW55dGhpbmcgZmFpbGVkIHVudGlsIG5vdy4KCSogRW5hYmxlIHRoaXMgaWYgbmVlZGVkLgoJKi8KCS8qCgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgIlNpbXBsZSB0eXBlICclcycgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY29uc3RyYWludHMgIgoJICAgICJvbiBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucy5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkqLwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMSk7CiAgICB9CgogICAgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewoJLyoKCSogc3JjLXNpbXBsZS10eXBlLjIgSWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCAKCSogZWl0aGVyIGl0IG11c3QgaGF2ZSBhIGJhc2UgW2F0dHJpYnV0ZV0gb3IgYSA8c2ltcGxlVHlwZT4gYW1vbmcgaXRzIAoJKiBbY2hpbGRyZW5dLCBidXQgbm90IGJvdGguCgkqLwkKCS8qCgkqIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8yCgkqIE5PVEU6IFRoaXMgd2FzIHJlbW92ZWQsIHNpbmNlIHRoaXMgd2lsbCBiZSBhbHJlYWR5IGhhbmRsZWQKCSogaW4gdGhlIHBhcnNlIGZ1bmN0aW9uIGZvciA8cmVzdHJpY3Rpb24+LiAKCSovCQogICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewoJLyogc3JjLXNpbXBsZS10eXBlLjMgSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIGVpdGhlciBpdCBtdXN0IGhhdmUgCgkqIGFuIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyBbY2hpbGRyZW5dLCAKCSogYnV0IG5vdCBib3RoLgoJKiBOT1RFOiBiYXNlVHlwZSBpcyBzZXQgdG8gdGhlIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRvbiwKCSogaWYgZXhpc3RlbnQsIGF0IHBhcnNlIHRpbWUuIFRoaXMgaXMgYSBoYWNrIGFuZCBub3QgbmljZS4KCSovCgkvKgoJKiBUT0RPOiBSZW1vdmUgdGhpcywgYW5kIGFkZCB0aGUgY2hlY2sgdG8gdGhlIHBhcnNlIGZ1bmN0aW9uIG9mIDxsaXN0Pi4KCSovCglpZiAoKCh0eXBlLT5zdWJ0eXBlcy0+YmFzZSA9PSBOVUxMKSAmJiAKCSAgICAgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpKSB8fAkgICAgICAKCSAgICAoKHR5cGUtPnN1YnR5cGVzLT5iYXNlICE9IE5VTEwpICYmCgkgICAgICh0eXBlLT5zdWJ0eXBlcy0+YmFzZVR5cGUgIT0gTlVMTCkpKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMywKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJFaXRoZXIgdGhlIGF0dHJpYnV0ZSAnaXRlbVR5cGUnIG9yIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJtdXN0IGJlIHByZXNlbnQgb24gdGhlIDxsaXN0PiBjaGlsZCAiLCBOVUxMKTsJICAgIAoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzMpOwoJfQogICAgCgogICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfVU5JT04pIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcjsKCXhtbFNjaGVtYVR5cGVQdHIgYW5jZXN0b3IsIGFueVNpbXBsZVR5cGU7CgoJYW55U2ltcGxlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoKCS8qIHNyYy1zaW1wbGUtdHlwZS40IENpcmN1bGFyIHVuaW9uIHR5cGUgZGVmaW5pdGlvbiBpcyBkaXNhbGxvd2VkLiBUaGF0IGlzLCBpZiAKCSogdGhlIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVyZSBtdXN0IG5vdCBiZSBhbnkgZW50cmllcyAKCSogaW4gdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIGF0IGFueSBkZXB0aCB3aGljaCByZXNvbHZlIHRvIHRoZSAKCSogY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPi4KCSovCQoJbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7Cgl3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCSAgICBhbmNlc3RvciA9IG1lbWJlci0+dHlwZTsKCSAgICB3aGlsZSAoKGFuY2VzdG9yICE9IE5VTEwpICYmIChhbmNlc3Rvci0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CgkJaWYgKGFuY2VzdG9yLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGFuY2VzdG9yLCBjdHh0LCAgTlVMTCk7CgkJaWYgKGFuY2VzdG9yID09IGFueVNpbXBsZVR5cGUpCgkJICAgIGJyZWFrOwoJCWVsc2UgaWYgKGFuY2VzdG9yID09IHR5cGUpIHsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzQsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgZGVmaW5pdGlvbiBpcyBjaXJjdWxhciIsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCQl9IGVsc2UgaWYgKGFuY2VzdG9yLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJICAgIC8qCgkJICAgICogVE9ETywgRklYTUU6IEFsdGhvdWdoIGEgbGlzdCBzaW1wbGUgdHlwZSBtdXN0IG5vdCBoYXZlIGEgdW5pb24gU1QKCQkgICAgKiB0eXBlIGFzIGl0ZW0gdHlwZSwgd2hpY2ggaW4gdHVybiBoYXMgYSBsaXN0IFNUIGFzIG1lbWJlciAKCQkgICAgKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGlzIGhlcmUgYXMgd2VsbCwgc2luY2UgdGhpcyBjaGVjayAKCQkgICAgKiB3YXMgbm90IHlldCBwZXJmb3JtZWQuCgkJICAgICovCgoJCX0KCQlhbmNlc3RvciA9IGFuY2VzdG9yLT5iYXNlVHlwZTsKCSAgICB9ICAgCgkgICAgbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJfQogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIE5vdCB5ZXQgdXNlZCBjb2RlIGZvciBDVCBzY2hlbWEgdmFsaWRhdGlvbiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ1ZDU2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgIGludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0OwogICAgLyoKICAgICogMy4xNC40IFNpbXBsZSBUeXBlIERlZmluaXRpb24gVmFsaWRhdGlvbiBSdWxlcwogICAgKiBWYWxpZGF0aW9uIFJ1bGU6IFN0cmluZyBWYWxpZAogICAgKi8KICAgIC8qCiAgICAqIDEgSXQgaXMgc2NoZW1hLXZhbGlkIHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCAKICAgICogYnkgRGF0YXR5cGUgVmFsaWQgaW4gW1hNTCBTY2hlbWFzOiBEYXRhdHlwZXNdLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUsIHZhbHVlLCAKCWZpcmVFcnJvcnMsIDEsIDEsIDEpOwogICAgcmV0dXJuIChyZXQpOwogICAgLyoKICAgICogMi4xIElmIFRoZSBkZWZpbml0aW9uIGlzIEVOVElUWSBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVFkgZ2l2ZW4gCiAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgdGhlbgogICAgKiB0aGUgc3RyaW5nIG11c3QgYmUgYSC3ZGVjbGFyZWQgZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMiBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVElFUyBvciBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBFTlRJVElFUyAKICAgICogZ2l2ZW4gdGhlIGVtcHR5IHNldCwgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpLCAKICAgICogdGhlbiBldmVyeSB3aGl0ZXNwYWNlLWRlbGltaXRlZCBzdWJzdHJpbmcgb2YgdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkIAogICAgKiBlbnRpdHkgbmFtZbcuCiAgICAqLwogICAgLyoKICAgICogMi4zIG90aGVyd2lzZSBubyBmdXJ0aGVyIGNvbmRpdGlvbiBhcHBsaWVzLgogICAgKi8KCiAgICByZXR1cm4gKDApOwp9CiNlbmRpZgoKCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICBpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKICAgICAgICB2Y3R4dC0+cGN0eHQgPXhtbFNjaGVtYU5ld1BhcnNlckN0eHRVc2VEaWN0KCIqIiwgdmN0eHQtPnNjaGVtYS0+ZGljdCk7CgkvKiB2Y3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7ICovCglpZiAodmN0eHQtPnBjdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCBOVUxMLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0LCAiCgkJImZhaWxlZCB0byBjcmVhdGUgYSB0ZW1wLiBwYXJzZXIgY29udGV4dC5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh2Y3R4dC0+cGN0eHQsIHZjdHh0LT5lcnJvciwgdmN0eHQtPndhcm5pbmcsIE5VTEwpOwkKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICBpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJY3R4dC0+dmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCwgIgoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qIFRPRE86IFBhc3MgdXNlciBkYXRhLiAqLwoJeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoY3R4dC0+dmN0eHQsIGN0eHQtPmVycm9yLCBjdHh0LT53YXJuaW5nLCBOVUxMKTsJCiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEB2YWx1ZTogdGhlIGRlZmF1bHQgdmFsdWUKICogQHZhbDogdGhlIHByZWNvbXB1dGVkIHZhbHVlIHRvIGJlIHJldHVybmVkCiAqIEBub2RlOiBhbiBvcHRpb25hbCBub2RlICh0aGUgaG9sZGVyIG9mIHRoZSB2YWx1ZSkKICoKICogQ2hlY2tzIHRoZSAiY29zLXZhbGlkLWRlZmF1bHQiIGNvbnN0cmFpbnRzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQsCgkJCSAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkgICAgICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICAgICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgCiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKgogICAgKiBjb3MtdmFsaWQtZGVmYXVsdDoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkKICAgICogRm9yIGEgc3RyaW5nIHRvIGJlIGEgdmFsaWQgZGVmYXVsdCB3aXRoIHJlc3BlY3QgdG8gYSB0eXBlIAogICAgKiBkZWZpbml0aW9uIHRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgaGFzIHRvIHdvcmsgd2l0aG91dCBhIGdpdmVuIG5vZGUgKHRoZSBob2xkZXIgb2YgdGhlCiAgICAqIHZhbHVlKSwgc2luY2UgaXQgc2hvdWxkIHdvcmsgb24gdGhlIGNvbXBvbmVudCwgaS5lLiBhbiB1bmRlcmx5aW5nCiAgICAqIERPTSBtdXN0IG5vdCBiZSBtYW5kYXRvcnkuCiAgICAqLyAgICAgCiAgICBpZiAoKHBjdHh0ID09IE5VTEwpIHx8ICh2Y3R4dCA9PSBOVUxMKSkgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgbm9kZSwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0LCAiCgkgICAgImJhZCBhcmd1bWVudHM6IHRoZSBwYXJzZXIgYW5kL29yIHZhbGlkYXRpb24gY29udGV4dCBpcyAiCgkgICAgIm1pc3NpbmcuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CQogICAgfSAgICAgICAKICAgIGlmIElTX0NPTVBMRVhfVFlQRSh0eXBlKSB7CgkvKgoJKiBDb21wbGV4IHR5cGUuCgkqCgkqIDIuMSBpdHMge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gb3IgbWl4ZWQuCgkqLwoJLyogCgkqIFRPRE86IEFkanVzdCB0aGlzIHdoZW4gdGhlIGNvbnRlbnQgdHlwZSB3aWxsIGJlIGNvbXB1dGVkIAoJKiBjb3JyZWN0bHkuIAoJKi8KCWlmICgodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgJiYKCSAgICAodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSAmJgoJICAgICh0eXBlLT5jb250ZW50VHlwZSAhPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpKSB7CgkgICAgeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIocGN0eHQsIAoJCVhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCXR5cGUsIE5VTEwsIE5VTEwsCgkJIklmIHRoZSB0eXBlIG9mIGEgY29uc3RyYWludCB2YWx1ZSBpcyBjb21wbGV4LCBpdHMgY29udGVudCAiCgkJInR5cGUgbXVzdCBiZSBtaXhlZCBvciBhIHNpbXBsZSB0eXBlIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4oWE1MX1NDSEVNQVBfQ09TX1ZBTElEX0RFRkFVTFRfMl8xKTsKCX0KCWlmICh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHsKCSAgICAvKgoJICAgICogMi4yLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIG1peGVkLCB0aGVuIHRoZSB7Y29udGVudCB0eXBlfSdzIAoJICAgICogcGFydGljbGUgbXVzdCBiZSC3ZW1wdGlhYmxltyBhcyBkZWZpbmVkIGJ5IFBhcnRpY2xlIEVtcHRpYWJsZSAKCSAgICAqICinMy45LjYpLgoJICAgICovCgkgICAgCgkgICAgLyoKCSAgICAqIFVSR0VOVCBUT0RPOiBJbXBsZW1lbnQgdGhpcy4KCSAgICAqLwoJICAgIHJldHVybiAoMCk7Cgl9CiAgICB9CQogICAgLyoKICAgICogMSBJZiB0aGUgdHlwZSBkZWZpbml0aW9uIGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgc3RyaW5nIAogICAgKiBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKICAgICogVmFsaWQgKKczLjE0LjQpLgogICAgKgogICAgKiBBTkQKICAgICoKICAgICogMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCiAgICAqIHN0cmluZyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKICAgICogYXMgZGVmaW5lZCBieSBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLgogICAgKi8gICAgCiAgICB2Y3R4dC0+bm9kZSA9IG5vZGU7CiAgICB2Y3R4dC0+Y3VyID0gTlVMTDsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCB0eXBlLCB2YWx1ZSwgMSwgMSwgMSwgMCk7CiAgICAvKiByZXQgPSB4bWxTY2hlbWFDaGVja0NWQ1NpbXBsZVR5cGUodmN0eHQsIGVsZW1EZWNsLT52YWx1ZSwgdHlwZURlZiwgMCk7ICovICAgCiAgICBpZiAocmV0IDwgMCkgewoJeG1sU2NoZW1hUEVycihwY3R4dCwgbm9kZSwKCS8qIE5PVE5JQ0U6IGVycm9yIGNvZGU6IFRoaXMgZnVuY3Rpb24gd2lsbCBiZSB1c2VkIGR1cmluZwoJKiBzY2hlbWEgY29uc3RydWN0aW9uIGFuZCB4c2k6dHlwZSB2YWxpZGF0aW9uLgoJKi8KCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJIndoaWxlIHZhbGlkYXRpbmcgYSB2YWx1ZSBjb25zdGFpbnQgdmFsdWUuXG4iLAoJTlVMTCwgTlVMTCk7CgogICAgfSAgICAgCSAgICAKICAgIHJldHVybiAocmV0KTsKfQoKI2lmIDAgLyogTm90IHlldCB1c2VkIGNvZGUgZm9yIENUIHNjaGVtYSB2YWxpZGF0aW9uICovCi8qKgogKiB4bWxTY2hlbWFHZXRTVENvbnRlbnRPZkNUOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICoKICogUmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBmb3IgdGhlIGNvbnRlbnQgb2YKICogdGhlIGNvbXBsZXggdHlwZS4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFNUQ29udGVudE9mQ1QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb3JpZyA9IHR5cGUsIGFueVR5cGU7CgogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgd2hpbGUgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlICE9IGFueVR5cGUpICYmIAoJKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKSB7CglpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKQoJICAgIHJldHVybih0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJTlVMTCwgb3JpZywgTlVMTCwKCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0U1RDb250ZW50VHlwZU9mQ1QsICIKCSJubyBzaW1wbGUgdHlwZSBmb3IgdGhlIGNvbnRlbnQgb2YgY29tcGxleCB0eXBlICclcycgY291bGQgYmUgIgoJImNvbXB1dGVkIiwgb3JpZy0+bmFtZSk7CiAgICByZXR1cm4gKE5VTEwpOwp9CgoKCgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKgogKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikKICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLCBhIHBvc2l0aXZlCiAqIGVycm9yIGNvZGUgaWYgbm90IGFuZCAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cmVkLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU0NURXh0ZW5kcyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwogICAgLyogCiAgICAqIDEgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiwgCiAgICAqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHMsICIKCSAgICAidGhlIGNvbXBsZXggdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgaWYgKGJhc2UtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCS8qCgkqIDEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSogY29udGFpbiBleHRlbnNpb24uCgkqLwoJaWYgKGJhc2UtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9FWFRFTlNJT04pIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xLAoJCU5VTEwsIHR5cGUsIE5VTEwsCgkJIlRoZSAnZmluYWwnIG9mIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbiAiCgkJImNvbnRhaW5zIGV4dGVuc2lvbiIsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8xKTsKCX0KCS8qCgkqIDEuMiBJdHMge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IGJlIGEgc3Vic2V0IG9mIHRoZSB7YXR0cmlidXRlIHVzZXN9IAoJKiBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmLCB0aGF0IGlzLCBmb3IgZXZlcnkgYXR0cmlidXRlIAoJKiB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0sIHRoZXJlIAoJKiBtdXN0IGJlIGFuIGF0dHJpYnV0ZSB1c2UgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGNvbXBsZXggCgkqIHR5cGUgZGVmaW5pdGlvbiBpdHNlbGYgd2hvc2Uge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIHRoZSBzYW1lIAoJKiB7bmFtZX0sIHt0YXJnZXQgbmFtZXNwYWNlfSBhbmQge3R5cGUgZGVmaW5pdGlvbn0gYXMgaXRzIGF0dHJpYnV0ZSAKCSogZGVjbGFyYXRpb24KCSoKCSogTk9URTogVGhpcyB3aWxsIGJlIGFscmVhZHkgc2F0aXNmaWVkIGJ5IHRoZSB3YXkgdGhlIGF0dHJpYnV0ZSB1c2VzCgkqIGFyZSBleHRlbmRlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgdGhpcyBjaGVjawoJKiBpcyBub3QgbmVlZGVkLgoJKi8KCgkvKgoJKiAxLjMgSWYgaXQgaGFzIGFuIHthdHRyaWJ1dGUgd2lsZGNhcmR9LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gCgkqIG11c3QgYWxzbyBoYXZlIG9uZSwgYW5kIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgCgkqIHdpbGRjYXJkfSdzIHtuYW1lc3BhY2UgY29uc3RyYWludH0gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUgY29tcGxleCAKCSogdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9LCAKCSogYXMgZGVmaW5lZCBieSBXaWxkY2FyZCBTdWJzZXQgKKczLjEwLjYpLgoJKgoJKiBUaGlzIGlzIGFscmVhZHkgY2hlY2tlZCBpbiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb247IHRodXMgCgkqIHRoaXMgY2hlY2sgaXMgbm90IG5lZWRlZC4KCSovCgkKCS8qCgkqIDEuNCBPbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqCgkqIDEuNC4xIFRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBhbmQgdGhlIAoJKiB7Y29udGVudCB0eXBlfSBvZiB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24gaXRzZWxmIG11c3QgYmUgdGhlIHNhbWUgCgkqIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KCSovCgoKCQogICAgfSBlbHNlIHsKCS8qCgkqIDIgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAKCSogdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJLyoKCSogMi4xIFRoZSB7Y29udGVudCB0eXBlfSBtdXN0IGJlIHRoZSBzYW1lIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkqLwoJLyoKCSogMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gCgkqIGV4dGVuc2lvbgoJKi8KICAgIH0KCn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNDVCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgY29udGVudDsKICAgIGludCBPSyA9IDA7CgogICAgLyoKICAgICogVE9ETzogQWRqdXN0IHRoZSBlcnJvciBjb2RlcyBoZXJlLCBhcyBJIHVzZWQKICAgICogWE1MX1NDSEVNQVBfU1JDX0NUXzEgb25seSB5ZXQuCiAgICAqLwogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAogICAgKiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSwogICAgKi8KICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgIGlmIChiYXNlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIE5VTEwsIHR5cGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja1NSQ0NULCAnJXMnLCBubyBiYXNlIHR5cGUiLCAKCSAgICB0eXBlLT5uYW1lKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgCiAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewoJaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCSAgICBpZiBJU19DT01QTEVYX1RZUEUoYmFzZSkgewoJCS8qCgkJKiAxIElmIHRoZSA8Y29tcGxleENvbnRlbnQ+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlIHR5cGUgZGVmaW5pdGlvbgoJCSogt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gCgkJKiBtdXN0IGJlIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb247CgkJKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIGJhc2UgdHlwZSBpcyBub3QgYSBjb21wbGV4IHR5cGUiLCBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgewoKCSAgICBpZiBJU19TSU1QTEVfVFlQRShiYXNlKSB7CgkJaWYgKHR5cGUtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pIHsKCQkgICAgLyogCgkJICAgICogMi4xLjMgb25seSBpZiB0aGUgPGV4dGVuc2lvbj4gYWx0ZXJuYXRpdmUgaXMgYWxzbyAKCQkgICAgKiBjaG9zZW4sIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCQkgICAgKi8KCQkgICAgLyogVE9ETzogQ2hhbmdlIGVycm9yIGNvZGUgdG8gLi4uX1NSQ19DVF8yXzFfMy4gKi8KCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90IHJlc3RyaWN0ICIKCQkJImFuIG90aGVyIHNpbXBsZSB0eXBlIiwKCQkJTlVMTCk7CgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCX0KCQlPSyA9IDE7CgoJICAgIH0gZWxzZSB7IC8qIGlmIElTX1NJTVBMRV9UWVBFKGJhc2UpICovCgkJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkJICAgIC8qCgkJICAgICogMi4xLjIgb25seSBpZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBhbHNvIAoJCSAgICAqIGNob3NlbiwgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfSAKCQkgICAgKiBpcyBtaXhlZCBhbmQgYSBwYXJ0aWNsZSBlbXB0eWFibGUuCgkJICAgICovCQoJCSAgICAvKgoJCSAgICAqIEZJWE1FIFRPRE86IENoZWNrIGZvciAqZW1waWFibGUgcGFydGljbGUqIGlzIG1pc3NpbmcuIAoJCSAgICAqLwoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYgCgkJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT04pID09IDApIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90ICIKCQkJICAgICJleHRlbmQgYW4gb3RoZXIgY29tcGxleCB0eXBlIHdoaWNoIGhhcyBhICIKCQkJICAgICJjb250ZW50IHR5cGUgb2Y6ICdtaXhlZCcgYW5kIGVtcHRpYWJsZSBwYXJ0aWNsZSIsCgkJCSAgICBOVUxMKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBOT1RFOiBUaGlzIHdpbGwgYmUgZmlyZWQgYXMgd2VsbCwgaWYgdGhlIGJhc2UgdHlwZQoJCSAgICAqIGlzIConYW55VHlwZScqLgoJCSAgICAqIE5PVEU6IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyB3aWxsIGJlIHRoZSAKCQkgICAgKiA8cmVzdHJpY3Rpb24+IGl0ZW0uCgkJICAgICovCgkJICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgewoJCQkvKiBZZXMsIHRoaXMgaXMgcGFyYW5vaWQgcHJvZ3JhbW1pbmcuICovCgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkgICAgIiclcycsIDxzaW1wbGVDb250ZW50PiBoYXMgbm8gPHJlc3RyaWN0aW9uPiIsIAoJCQkgICAgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogMi4yIElmIGNsYXVzZSAyLjEuMiBhYm92ZSBpcyBzYXRpc2ZpZWQsIHRoZW4gdGhlcmUgCgkJICAgICogbXVzdCBiZSBhIDxzaW1wbGVUeXBlPiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiAKCQkgICAgKiA8cmVzdHJpY3Rpb24+LgoJCSAgICAqLwogICAgCQkgICAgaWYgKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+dHlwZSAhPQoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSB7CgkJCS8qIFRPRE86IENoYW5nZSBlcnJvciBjb2RlIHRvIC4uLl9TUkNfQ1RfMl8yLiAqLwoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSA8c2ltcGxlVHlwZT4gaXMgZXhwZWN0ZWQgYW1vbmcgdGhlIGNoaWxkcmVuICIKCQkJICAgICJvZiA8cmVzdHJpY3Rpb24+IiwgTlVMTCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCSAgICB9IAoJCSAgICBPSyA9IDE7CgkJfSBlbHNlIHsgLyogaWYgKGJhc2UtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSovCgkJICAgIC8qCgkJICAgICogMi4xLjEgYSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbiB3aG9zZSB7Y29udGVudCB0eXBlfSBpcyBhIAoJCSAgICAqIHNpbXBsZSB0eXBlIGRlZmluaXRpb247CgkJICAgICovCgkJICAgIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90ICIKCQkJICAgICJiZSBkZXJpdmVkIGZyb20gdGhlIGNvbXBsZXggdHlwZSAnJXMnIiwgCgkJCSAgICBiYXNlLT5uYW1lKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0KCQkgICAgY29udGVudCA9IGJhc2UtPmNvbnRlbnRUeXBlRGVmOwoJCSAgICBpZiAoY29udGVudCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsIAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgIgoJCQkgICAgIiclcycsIGJhc2UgdHlwZSBoYXMgbm8gY29udGVudCB0eXBlIiwgCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgaWYgKGNvbnRlbnQtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiQSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW5ub3QgIgoJCQkgICAgImJlIGRlcml2ZWQgZnJvbSB0aGUgY29tcGxleCB0eXBlICclcyciLCAKCQkJICAgIGJhc2UtPm5hbWUpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQkgICAgfQoJCX0KCSAgICB9IAoJfSAJICAgIAkKICAgIH0KICAgIC8qCiAgICAqIFRPRE86IDMgVGhlIGNvcnJlc3BvbmRpbmcgY29tcGxleCB0eXBlIGRlZmluaXRpb24gY29tcG9uZW50IG11c3QgCiAgICAqIHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBDb21wbGV4IFR5cGUgCiAgICAqIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudHMgKKczLjQuNik7CiAgICAqCiAgICAqIFRPRE86IDQgSWYgY2xhdXNlIDIuMi4xIG9yIGNsYXVzZSAyLjIuMiBpbiB0aGUgY29ycmVzcG9uZGVuY2Ugc3BlY2lmaWNhdGlvbiAKICAgICogYWJvdmUgZm9yIHthdHRyaWJ1dGUgd2lsZGNhcmR9IGlzIHNhdGlzZmllZCwgdGhlIGludGVuc2lvbmFsIAogICAgKiBpbnRlcnNlY3Rpb24gbXVzdCBiZSBleHByZXNzaWJsZSwgYXMgZGVmaW5lZCBpbiBBdHRyaWJ1dGUgV2lsZGNhcmQgCiAgICAqIEludGVyc2VjdGlvbiAopzMuMTAuNikuCiAgICAqLwoKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFHcm91cERlZkZpeHVwOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hR3JvdXBEZWZGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIGdyb3VwLAoJCSAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgZ3JvdXAtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgaWYgKChncm91cC0+cmVmICE9IE5VTEwpICYmIChncm91cC0+c3VidHlwZXMgPT0gTlVMTCkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgZ3JvdXBEZWY7CgkvKgoJKiBSZXNvbHZlIHRoZSByZWZlcmVuY2UuCgkqLwoJZ3JvdXBEZWYgPSB4bWxTY2hlbWFHZXRHcm91cChjdHh0LT5zY2hlbWEsIGdyb3VwLT5yZWYsCgkgICAgZ3JvdXAtPnJlZk5zKTsKCWlmIChncm91cERlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCAKCQlOVUxMLCBncm91cCwgTlVMTCwKCQkicmVmIiwgZ3JvdXAtPnJlZiwgZ3JvdXAtPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfR1JPVVAsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCWdyb3VwLT5zdWJ0eXBlcyA9IGdyb3VwRGVmOwogICAgfQkJCn0KCiNpZiAwIC8qIEVuYWJsZSB3aGVuIHRoZSBjb250ZW50IHR5cGUgd2lsbCBiZSBjb21wdXRlZC4gKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDb21wdXRlQ29udGVudFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgcmVzID0gTlVMTDsKCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkgICAgInRoZSBjb21wbGV4IHR5cGUgJyVzJyBoYXMgbm8gYmFzZSB0eXBlIiwgdHlwZS0+bmFtZSk7CglyZXR1cm4gKC0xKTsKICAgIH0gICAKICAgIGlmIChJU19BTllUWVBFKGJhc2UpIHx8ICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSAKCSAgICBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSkgewoJeG1sU2NoZW1hVHlwZVB0ciBzdGFydDsKCS8qCgkqIEVmZmVjdGl2ZSAnbWl4ZWQnLgoJKi8KCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCgkgICAgIHR5cGUtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwoJLyoKCSogRWZmZWN0aXZlIGNvbnRlbnQuCgkqLwoJaWYgKElTX0FOWVRZUEUoYmFzZSkpIAoJICAgIHN0YXJ0ID0gdHlwZTsKCWVsc2UKCSAgICBzdGFydCA9IHR5cGUtPnN1YnR5cGVzOwoJIAogICAgfSBlbHNlIHsgLyogaWYgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCAqLwoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlQ29udGVudEl0ZW07CgoJLyoKCSogQ29tcGxleCB0eXBlIHdpdGggc2ltcGxlIGNvbnRlbnQuCgkqLwoJaWYgSVNfQ09NUExFWF9UWVBFKGJhc2UpIHsKCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CQoJCS8qCgkJKiBTdW1tYXJ5OiBhIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbiAqcmVzdHJpY3QqCgkJKiBhIGNvbXBsZXggdHlwZSB3aXRoIHRoZSBmb2xsb3dpbmcgY29udGVudCB0eXBlOgoJCSogMS4gJ21peGVkJyBhbmQgYW4gZW1wdGlhYmxlIHBhcnRpY2xlCgkJKiAyLiBzaW1wbGUgdHlwZQoJCSovCgkJaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgewoJCSAgICAvKgoJCSAgICAqIDIgaWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSBiYXNlIHR5cGUgaXMgbWl4ZWQgYW5kIGEgCgkJICAgICogcGFydGljbGUgd2hpY2ggaXMgt2VtcHRpYWJsZbcsIAoJCSAgICAqIFsuLi5dIAoJCSAgICAqIHRoZW4gc3RhcnRpbmcgZnJvbSB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiAKCQkgICAgKiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gCgkJICAgICogb2YgPHJlc3RyaWN0aW9uPiAoKip3aGljaCBtdXN0IGJlIHByZXNlbnQqKikKCQkgICAgKgoJCSAgICAqIEZJWE1FIFRPRE86IEhhbmRsZSAiZW1wdGlhYmxlIHBhcnRpY2xlIi4KCQkgICAgKi8KCQkgICAgcmVzID0gdHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzOwoJCSAgICBpZiAocmVzID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkgICAgIkNUICclcycgKHJlc3RyaWN0aW5nKTogPHNpbXBsZUNvbnRlbnQ+IGhhcyBubyAiCgkJCSAgICAiPHJlc3RyaWN0aW9uPiIsCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCgkJICAgIHJlcy0+c3VidHlwZXM7CgkJICAgIGlmIChyZXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSAgICAiQ1QgJyVzJyAocmVzdHJpY3RpbmcpOiA8cmVzdHJpY3Rpb24+IGhhcyBubyAiCgkJCSAgICAibWFuZGF0b3J5IDxzaW1wbGVUeXBlPiIsCgkJCSAgICB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBiYXNlQ29udGVudEl0ZW0gPSBiYXNlLT5jb250ZW50VHlwZURlZjsKCQkgICAgaWYgKGJhc2VDb250ZW50SXRlbSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJICAgICJDVCAnJXMnIChyZXN0cmljdGluZyksIHRoZSBiYXNlIHR5cGUgaGFzIG5vICIKCQkJICAgICJjb250ZW50IHR5cGUiLCB0eXBlLT5uYW1lKTsKCQkJcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgaWYgSVNfU0lNUExFX1RZUEUoYmFzZUNvbnRlbnRJdGVtKSB7CgkJCS8qCgkJCSogMSBJZiB0aGUgYmFzZSB0eXBlIGlzIGEgY29tcGxleCB0eXBlIHdob3NlIG93biAKCQkgICAgCSoge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBhbmQgdGhlIDxyZXN0cmljdGlvbj4gCgkJCSogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuCgkJCSovCgkJCS8qIHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcyB3aWxsIGJlIHRoZSByZXN0cmljdGlvbiBpdGVtLiovCgkJCXJlcyA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlczsKCQkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCQkiQ1QgJyVzJyAocmVzdHJpY3RpbmcpOiA8c2ltcGxlVHlwZT4gaGFzIG5vICIKCQkJCSI8cmVzdHJpY3Rpb24+IiwgdHlwZS0+bmFtZSk7CgkJCSAgICByZXR1cm4gKC0xKTsKCQkJfQoJCQkvKgoJCQkqIDEuMSB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSAKCQkJKiA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPHJlc3RyaWN0aW9uPmlmIAoJCQkqIHRoZXJlIGlzIG9uZTsKCQkJKi8KCQkJcmVzID0gcmVzLT5zdWJ0eXBlczsKCQkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJCSAgICAvKgoJCQkgICAgKiAxLjIgb3RoZXJ3aXNlIHRoZSB7Y29udGVudCB0eXBlfSAKCQkJICAgICogb2YgdGhlIGJhc2UgdHlwZSAuCgkJCSAgICAqLwoJCQkgICAgcmVzID0gYmFzZUNvbnRlbnRJdGVtOwoJCQl9CgkJICAgIH0KCQl9CgkJLyoKCQkqIFNQRUNJQUwgVE9ETzogSWYgKnJlc3RyaWN0aW5nKiB0aGUgc3BlYyB3YW50cyB1cyB0byAKCQkqIGNyZWF0ZSBhbiAqYWRkaXRpb25hbCogc2ltcGxlIHR5cGUgd2hpY2ggcmVzdHJpY3RzIHRoZSAKCQkqIGxvY2F0ZWQgc2ltcGxlIHR5cGU7IHdlIHdvbid0IGRvIHRoaXMgeWV0LCBhbmQgbG9vayBob3cgCgkJKiBmYXIgd2UgZ2V0IHdpdGggaXQuCgkJKi8KCSAgICB9IGVsc2UgeyAvKiBpZiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OICovCgkJLyoKCQkqIFN1bW1hcnk6IGEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2FuICpleHRlbmQqCgkJKiBvbmx5IGEgY29tcGxleCBiYXNlIHdpdGggYSBzaW1wbGUgdHlwZSBhcyBjb250ZW50LgoJCSovCQkKCQkvKgoJCSogMyBJZiB0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgCgkJKiB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gaXMgYSBjb21wbGV4IHR5cGUgCgkJKiBkZWZpbml0aW9uICh3aG9zZSBvd24ge2NvbnRlbnQgdHlwZX0gKm11c3QgYmUqIGEgc2ltcGxlIAoJCSogdHlwZSBkZWZpbml0aW9uLCBzZWUgYmVsb3cpIGFuZCB0aGUgKjxleHRlbnNpb24+KiAKCQkqIGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhhdCAKCQkqIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uOwoJCSovCgkJcmVzID0gYmFzZS0+Y29udGVudFR5cGVEZWY7CgkJaWYgKHJlcyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJIkNUICclcycgKGV4dGVuZGluZyksIHRoZSBiYXNlIHR5cGUgaGFzIG5vIGNvbnRlbnQgIgoJCQkidHlwZSIsIHR5cGUtPm5hbWUpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CQkKCQlpZiAoISBJU19TSU1QTEVfVFlQRShyZXMpKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJIkNUICclcycgKGV4dGVuZGluZyksIHRoZSBjb250ZW50IHR5cGUgb2YgdGhlICIKCQkJImJhc2UgaXMgbm90IGEgc2ltcGxlIHR5cGUiLCB0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkgICAgfQkgICAgCQoJfSBlbHNlIC8qIGlmIElTX0NPTVBMRVhfVFlQRShiYXNlKSAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkgICAgLyoKCSAgICAqIDQgb3RoZXJ3aXNlICh0aGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlIAoJICAgICogt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gaXMgYSBzaW1wbGUgdHlwZSAKCSAgICAqIGRlZmluaXRpb24gYW5kIHRoZSA8ZXh0ZW5zaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4pLCAKCSAgICAqIHRoZW4gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJICAgICovCgkgICAgcmVzID0gYmFzZTsKCX0JCgl0eXBlLT5jb250ZW50VHlwZURlZiA9IHJlczsKCWlmIChyZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkiJyVzJywgdGhlIGNvbnRlbnQgdHlwZSBjb3VsZCBub3QgYmUgZGV0ZXJtaW5lZCIsIAoJCXR5cGUtPm5hbWUpOwoJICAgIHJldHVybiAoLTEpOwoJfQoKICAgIH0KICAgIAp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaXh1cDoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZpeGVzIHRoZSBjb250ZW50IG1vZGVsIG9mIHRoZSB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGU7CgogICAgaWYgKGl0ZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICAvKgogICAgKiBEbyBub3QgYWxsb3cgdGhlIGZvbGxvd2luZyB0eXBlcyB0byBiZSB0eXBlZml4ZWQsIHByaW9yIHRvCiAgICAqIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5jdHh0VHlwZSA9PSBOVUxMKSB7Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDoKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOgkgICAgCgkJcmV0dXJuOwoJICAgIGRlZmF1bHQ6CgkgICAgICAgIGJyZWFrOwoJfQogICAgfQogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gaXRlbS0+bmFtZTsKICAgIGlmIChpdGVtLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewogICAgICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVDp7CQkgICAgCgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkJCWlmIChpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsCgkJCQlOVUxMKTsKCQkJfQogICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOyAqLwoJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOnsKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlID0gTlVMTDsKCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5mbGFncyB8PSAKCQkJWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTjsKCQkgICAgaWYgKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpCgkJCWJhc2UgPSBpdGVtLT5iYXNlVHlwZTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpdGVtLT5iYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+YmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCQkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsIAoJCQkJTlVMTCwgTlVMTCwgCgkJCQkoeG1sTm9kZVB0cikgeG1sU2NoZW1hR2V0UHJvcE5vZGUoaXRlbS0+bm9kZSwgImJhc2UiKSwKCQkJCSJiYXNlIiwgaXRlbS0+YmFzZSwgaXRlbS0+YmFzZU5zLAoJCQkJWE1MX1NDSEVNQV9UWVBFX0JBU0lDLCAidHlwZSBkZWZpbml0aW9uIik7CQkJICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IAoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQkJCQogICAgICAgICAgICAgICAgICAgIH0JCgkJICAgIGN0eHQtPmN0eHRUeXBlLT5iYXNlVHlwZSA9IGJhc2U7CgkJICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJCQkvKgoJCQkqIENvbXBsZXhUeXBlIHJlc3RyaWN0aW9uLgoJCQkqLwkJCQoJCQkvKgoJCQkqIENvbnRlbnQgdHlwZS4KCQkJKi8KCQkJaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpCgkJCSAgICAvKiAxLjEuMSAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJCWVsc2UgaWYgKChpdGVtLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCQkJICAgICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9BTEwpCgkJCSAgICB8fCAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQoJCQkgICAgLyogMS4xLjIgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpCgkJCSAgICAmJiAoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpKQoJCQkgICAgLyogMS4xLjMgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIHsKCQkJICAgIC8qIDEuMiBhbmQgMi5YIGFyZSBhcHBsaWVkIGF0IHRoZSBvdGhlciBsYXllciAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPQoJCQkJWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCQl9CgkJICAgIH0gZWxzZSB7CQoJCQkvKgoJCQkqIFNpbXBsZVR5cGUgcmVzdHJpY3Rpb24uCgkJCSovCgkJCS8qIFRPRE86IE5vdGhpbmc/ICovCgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOnsKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hQ29udGVudFR5cGUgZXhwbGljaXRDb250ZW50VHlwZTsKCQkgICAgCgkJICAgIC8qCgkJICAgICogQW4gZXh0ZW5zaW9uIGRvZXMgZXhpc3Qgb24gYSBjb21wbGV4VHlwZSBvbmx5LgoJCSAgICAqLwoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmxhZ3MgfD0gCgkJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OOwoJCSAgICBpZiAoaXRlbS0+cmVjdXJzZSkgewoJCQkvKiBUT0RPOiBUaGUgd29yZCAicmVjdXJzaXZlIiBzaG91bGQgYmUgY2hhbmdlZCB0byAiY2lyY3VsYXIiIGhlcmUuICovCgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLAoJCQkgICAgTlVMTCwgaXRlbSwgaXRlbS0+bm9kZSwJCgkJCSAgICAiVGhpcyBpdGVtIGlzIGNpcmN1bGFyIiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKCQkgICAgfQoJCSAgICBpZiAoaXRlbS0+YmFzZSAhPSBOVUxMKSB7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW0tPmJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmJhc2VOcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCAKCQkJCU5VTEwsIGl0ZW0sIGl0ZW0tPm5vZGUsCgkJCQkiYmFzZSIsIGl0ZW0tPmJhc2UsIGl0ZW0tPmJhc2VOcywKCQkJCVhNTF9TQ0hFTUFfVFlQRV9CQVNJQywgInR5cGUgZGVmaW5pdGlvbiIpOwkJCQkgICAKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICBpdGVtLT5yZWN1cnNlID0gMTsKCQkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlLCBjdHh0LCBOVUxMKTsKCQkJICAgIGl0ZW0tPnJlY3Vyc2UgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCS8qCgkJCSogVGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIAoJCQkqIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXQoJCQkqLwoJCQljdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoJCQkvKgoJCQkqIFRPRE86IFRoaXMgb25lIGlzIHN0aWxsIG5lZWRlZCBmb3IgY29tcHV0YXRpb24gb2YKCQkJKiB0aGUgY29udGVudCBtb2RlbCBieSB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwuCgkJCSogVHJ5IHRvIGdldCByaWQgb2YgaXQuCgkJCSovCgkJCWl0ZW0tPmJhc2VUeXBlID0gYmFzZTsJCQkKICAgICAgICAgICAgICAgICAgICB9CgkJICAgIGlmICgoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCQkJKGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CSAgICAKCQkgICAgCgkJICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQkvKiAxLjEuMSAqLwoJCQlleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCSAgICBlbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpICYmCgkJCSgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0FMTCkKCQkJfHwgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCVhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkpKQoJCQkvKiAxLjEuMiAqLwoJCQlleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCSAgICBlbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0NIT0lDRSkKCQkJJiYgKGl0ZW0tPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCQkJLyogMS4xLjMgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgaWYgKGJhc2UgIT0gTlVMTCkgewoJCQkvKiBJdCB3aWxsIGJlIHJlcG9ydGVkIGxhdGVyLCBpZiB0aGUgYmFzZSBpcyBtaXNzaW5nLiAqLwkJCSAgICAKCQkJaWYgKGV4cGxpY2l0Q29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJCSAgICAvKiAyLjEgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gYmFzZS0+Y29udGVudFR5cGU7CgkJCX0gZWxzZSBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCQkgICAgLyogMi4yIGltYml0YWJsZSAhICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0gZWxzZSB7CgkJCSAgICAvKiAyLjMgaW1iaXRhYmxlIHBhcmVpbCAhICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0KCQkgICAgfQkJICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOnsKCQkgICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBpdGVtOwoJCSAgICAvKgoJCSAgICAqIFN0YXJ0IHdpdGggYW4gZW1wdHkgY29udGVudC10eXBlIHR5cGUuCgkJICAgICovCgkJICAgIGlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCgkJICAgIGlmICgoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkgfHwgCgkJCSgoaXRlbS0+c3VidHlwZXMtPnR5cGUgIT0gCgkJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkgJiYgCgkJCShpdGVtLT5zdWJ0eXBlcy0+dHlwZSAhPSAKCQkJWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkpKSB7CgkJCS8qIAoJCQkqIFRoaXMgY2FzZSBpcyB1bmRlcnN0b29kIGFzIHNob3J0aGFuZCBmb3IgY29tcGxleCAKCQkJKiBjb250ZW50IHJlc3RyaWN0aW5nIHRoZSB1ci10eXBlIGRlZmluaXRpb24sIGFuZCAKCQkJKiB0aGUgZGV0YWlscyBvZiB0aGUgbWFwcGluZ3Mgc2hvdWxkIGJlIG1vZGlmaWVkIGFzIAoJCQkqIG5lY2Vzc2FyeS4KCQkJKi8JCQkKCQkJaXRlbS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCQkJaXRlbS0+ZmxhZ3MgfD0gCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwoJCQkvKgoJCQkqIEFzc3VtZSB0aGF0IHdlIGluaGVyaXQgdGhlIGNvbnRlbnQtdHlwZSB0eXBlIAoJCQkqIGZyb20gJ2FueVR5cGUnLCB3aGljaCBpcyAnbWl4ZWQnIGFuZCBhIHBhcnRpY2xlCgkJCSogZW1wdGlhYmxlLgoJCQkqLwoJCQlpdGVtLT5jb250ZW50VHlwZSA9IGl0ZW0tPmJhc2VUeXBlLT5jb250ZW50VHlwZTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIEZpeHVwIHRoZSBzdWIgY29tcG9uZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJCQkoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09CgkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewkJCSAgICAKCQkJeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQkgICAgfQkKCQkgICAgaWYgKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkgewoJCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsJCQkKCQkgICAgfSBlbHNlIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CgkJCS8qCgkJCSogVXNlIHRoZSBjb250ZW50LXR5cGUgdHlwZSBvZiB0aGUgbW9kZWwgZ3JvdXBzCgkJCSogZGVmaW5lZCwgaWYgJ21peGVkJyBpcyBub3Qgc2V0LiBJZiAnbWl4ZWQnIGlzIHNldAoJCQkqIGl0IHdpbGwgZXhwYW5kIHRoZSBjb250ZW50LXR5cGUgYnkgYWxsb3dpbmcgY2hhcmFjdGVyCgkJCSogY29udGVudCB0byBhcHBlYXIuCgkJCSovCgkJCWl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJICAgIGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKCQkgICAgfQoKCQkgICAgLyoKCQkgICAgKiBTb21lIG9wdGltaXphdGlvbiBmb3IgdmFsaWRhdGlvbjoKCQkgICAgKiBJZiB0aGVyZSBhcmUgbm8gZmFjZXRzIGJlc2lkZSB0aGUgIndoaXRlc3BhY2UiIGZhY2V0LAoJCSAgICAqIHRoZW4gYSB2YWx1ZSBuZWVkcyBub3QgdG8gY2hlY2tlZCBhZ2FpbnN0IGFnYWluc3QgYQoJCSAgICAqIGZhY2V0LCB0aHVzIG5vIGNvbXB1dGVkIHZhbHVlIGlzIG5lZWRlZC4KCQkgICAgKiBUT0RPIFVSR0VOVDogVGhpcyBpcyBqdXN0IGEgd29ya2Fyb3VuZCwgd2UgbmVlZCB0bwoJCSAgICAqIGludHJvZHVjZSB0aGUgY29ycmVjdCB1c2FnZSBvZiBjb250ZW50VHlwZSB0byBzdG9yZSB0aGUKCQkgICAgKiBmYWNldHMgaW4hCgkJICAgICovCgkJICAgIGlmICgoaXRlbS0+YmFzZVR5cGUgIT0gTlVMTCkgJiYKCQkgICAgICAgIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJgoJCQkgWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUUpKQoJCQlpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZBQ0VUU05FRURWQUxVRTsKCQkgICAgZWxzZSB7CgkJCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBjdXI7CgoJCQlmb3IgKGN1ciA9IGl0ZW0tPmZhY2V0U2V0OyBjdXIgIT0gTlVMTDsKCQkJICAgIGN1ciA9IGN1ci0+bmV4dCkgewoJCQkgICAgaWYgKGN1ci0+ZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJCQlpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZBQ0VUU05FRURWQUxVRTsKCQkJCWJyZWFrOwoJCQkgICAgfQoJCQl9CgkJICAgIH0JCgoJCSAgICB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oY3R4dCwgaXRlbSk7CgkJICAgIHhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoaXRlbSwgY3R4dCwgaXRlbS0+bmFtZSk7CgkJICAgIGN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDp7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkvKiAKCQkJICogUmVtb3ZlZCBkdWUgdG8gaW1wbGVtZW50YXRpb24gb2YgdGhlIGJ1aWxkIG9mIGF0dHJpYnV0ZSB1c2VzLiAKCQkJICovCgkJCS8qCgkJCWlmIChpdGVtLT5hdHRyaWJ1dGVzID09IE5VTEwpCgkJCSAgICBpdGVtLT5hdHRyaWJ1dGVzID0KCQkJICAgICAgICBpdGVtLT5zdWJ0eXBlcy0+YXR0cmlidXRlczsKCQkJKi8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJCS8qCgkJKiBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnQKCQkqCgkJKi8KCQljdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwkJCgkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWlmIChpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJICAgIGN0eHQtPmN0eHRUeXBlID0gaXRlbTsKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQl9CgkJLyogRml4dXAgYmFzZSB0eXBlICovCQkKCQlpZiAoKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpICYmIAoJCSAgICAoaXRlbS0+YmFzZVR5cGUtPmNvbnRlbnRUeXBlID09CgkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkgewoJCSAgICAvKiBPUFRJTUlaRTogQWN0dWFsbHkgdGhpcyBvbmUgd2lsbCBuZXZlciBieSBoaXQsIHNpbmNlCgkJICAgICogdGhlIGJhc2UgdHlwZSBpcyBhbHJlYWR5IHR5cGUtZml4ZWQgaW4gPHJlc3RyaWN0aW9uPi4KCQkgICAgKi8KCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSBpdGVtOwoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+YmFzZVR5cGUsIGN0eHQsIE5VTEwpOwoJCX0KCQkvKiBCYXNlIHR5cGU6IAoJCSogMiBJZiB0aGUgPGxpc3Q+IG9yIDx1bmlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCAKCQkqIHRoZW4gdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4KCQkqLwoJCWlmIChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewoJCSAgICBpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVDsJCSAgICAKCQl9IGVsc2UgaWYgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9VTklPTikgewoJCSAgICBpdGVtLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT047CgkJfSBlbHNlIGlmIChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHsKCQkgICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0LCBjdXIsIGxhc3QgPSBOVUxMOwoJCSAgICAJCSAgICAJICAgIAkJICAgCgkJICAgIC8qIAoJCSAgICAqIFZhcmlldHkKCQkgICAgKiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlIAoJCSAgICAqIHt2YXJpZXR5fSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KCQkgICAgKi8JCgkJICAgIGlmIChpdGVtLT5iYXNlVHlwZSAhPSBOVUxMKSB7CgkJCWlmIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpCgkJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDOwoJCQllbHNlIGlmIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CgkJCWVsc2UgaWYgKGl0ZW0tPmJhc2VUeXBlLT5mbGFncyAmIAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OOwkJICAgIAkJICAgIAkJICAgCgkJCS8qCgkJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBSZXN0cmljdGlvbiAKCQkJKiAoRmFjZXRzKQoJCQkqIE5PVEU6IFNhdGlzZmFjdGlvbiBvZiAxIGFuZCAyIGFyaXNlIGZyb20gdGhlIGZpeHVwIAoJCQkqIGFwcGxpZWQgYmVmb3JlaGFuZC4KCQkJKgkJCSAgICAKCQkJKiAzIFRoZSB7ZmFjZXRzfSBvZiBSIGFyZSB0aGUgdW5pb24gb2YgUyBhbmQgdGhlIHtmYWNldHN9IAoJCQkqIG9mIEIsIGVsaW1pbmF0aW5nIGR1cGxpY2F0ZXMuIFRvIGVsaW1pbmF0ZSBkdXBsaWNhdGVzLCAKCQkJKiB3aGVuIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBvY2N1cnMgaW4gYm90aCBTIGFuZCB0aGUgCgkJCSoge2ZhY2V0c30gb2YgQiwgdGhlIG9uZSBpbiB0aGUge2ZhY2V0c30gb2YgQiBpcyBub3QgCgkJCSogaW5jbHVkZWQsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBlbnVtZXJhdGlvbiBhbmQgcGF0dGVybiAKCQkJKiBmYWNldHMsIGZvciB3aGljaCBtdWx0aXBsZSBvY2N1cnJlbmNlcyB3aXRoIGRpc3RpbmN0IHZhbHVlcyAKCQkJKiBhcmUgYWxsb3dlZC4KCQkJKi8KCQkJaWYgKGl0ZW0tPmJhc2VUeXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CgkJCSAgICBsYXN0ID0gaXRlbS0+ZmFjZXRTZXQ7CgkJCSAgICBpZiAobGFzdCAhPSBOVUxMKQoJCQkJd2hpbGUgKGxhc3QtPm5leHQgIT0gTlVMTCkKCQkJCSAgICBsYXN0ID0gbGFzdC0+bmV4dDsKCQkJICAgIGN1ciA9IGl0ZW0tPmJhc2VUeXBlLT5mYWNldFNldDsKCQkJICAgIGZvciAoOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CgkJCQkvKiAKCQkJCSogQmFzZSBwYXR0ZXJucyB3b24ndCBiZSBhZGQgaGVyZToKCQkJCSogdGhleSBhcmUgT1JlZCBpbiBhIHR5cGUgYW5kCgkJCQkqIEFORGVkIGluIGRlcml2ZWQgdHlwZXMuIFRoaXMgd2lsbAoJCQkJKiBoYXBwZWQgYXQgdmFsaWRhdGlvbiBsZXZlbCBieQoJCQkJKiB3YWxraW5nIHRoZSBiYXNlIGF4aXMgb2YgdGhlIHR5cGUuCgkJCQkqLwoJCQkJaWYgKGN1ci0+ZmFjZXQtPnR5cGUgPT0gCgkJCQkgICAgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSAKCQkJCSAgICBjb250aW51ZTsKCQkJCWZhY2V0ID0gTlVMTDsKCQkJCWlmICgoaXRlbS0+ZmFjZXRTZXQgIT0gTlVMTCkgJiYKCQkJCSAgICAvKiBSRU1PVkVEOiBhIGNoZWNrIGZvcgoJCQkJICAgICogWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOIHdhcyBhbHJlYWR5CgkJCQkgICAgKiBwZXJmb3JtZWQgYWJvdmUuCgkJCQkKCQkJCSAgICAqIChjdXItPmZhY2V0LT50eXBlICE9IAoJCQkJICAgICogWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSAmJgoJCQkJICAgICovCgkJCQkgIChjdXItPmZhY2V0LT50eXBlICE9IAoJCQkJICBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewkJCQkKCQkJCSAgICBmYWNldCA9IGl0ZW0tPmZhY2V0U2V0OwoJCQkJICAgIGRvIHsKCQkJCQlpZiAoY3VyLT5mYWNldC0+dHlwZSA9PSAKCQkJCQkgICAgZmFjZXQtPmZhY2V0LT50eXBlKSAKCQkJCQkgICAgYnJlYWs7CgkJCQkJZmFjZXQgPSBmYWNldC0+bmV4dDsKCQkJCSAgICB9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQkJCX0KCQkJCWlmIChmYWNldCA9PSBOVUxMKSB7CgkJCQkgICAgZmFjZXQgPSAoeG1sU2NoZW1hRmFjZXRMaW5rUHRyKSAKCQkJCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0TGluaykpOwoJCQkJICAgIGlmIChmYWNldCA9PSBOVUxMKSB7CgkJCQkJeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAKCQkJCQkgICAgImZpeGluZyBzaW1wbGVUeXBlIiwgTlVMTCk7CgkJCQkJcmV0dXJuOwoJCQkJICAgIH0KCQkJCSAgICAvKgoJCQkJICAgICogVGhlIGZhY2V0cyBhcmUgbm90IGNvcGllZCBidXQgcmVmZXJlbmNlZAoJCQkJICAgICogdmlhIHRoZSBmYWNldCBsaW5rLgoJCQkJICAgICovCgkJCQkgICAgZmFjZXQtPmZhY2V0ID0gY3VyLT5mYWNldDsKCQkJCSAgICBmYWNldC0+bmV4dCA9IE5VTEw7CgkJCQkgICAgaWYgKGxhc3QgPT0gTlVMTCkKCQkJCQlpdGVtLT5mYWNldFNldCA9IGZhY2V0OwkJICAgIAoJCQkJICAgIGVsc2UgCgkJCQkJbGFzdC0+bmV4dCA9IGZhY2V0OwoJCQkJICAgIGxhc3QgPSBmYWNldDsJCQkJCgkJCQl9CQkJCSAgICAKCQkJICAgIH0KCQkJfQoJCQkvKgoJCQkqIFNvbWUgb3B0aW1pemF0aW9uIGZvciB2YWxpZGF0aW9uOgoJCQkqIElmIHRoZXJlIGFyZSBubyBmYWNldHMgYmVzaWRlIHRoZSAid2hpdGVzcGFjZSIgZmFjZXQsCgkJCSogdGhlbiBhIHZhbHVlIG5lZWRzIG5vdCB0byBjaGVja2VkIGFnYWluc3QgYWdhaW5zdCBhCgkJCSogZmFjZXQsIHRodXMgbm8gY29tcHV0ZWQgdmFsdWUgaXMgbmVlZGVkLgoJCQkqLwoJCQlpZiAoaXRlbS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUUpCgkJCSAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZBQ0VUU05FRURWQUxVRTsKCQkJZWxzZSB7CgkJCSAgICBmb3IgKGN1ciA9IGl0ZW0tPmZhY2V0U2V0OyBjdXIgIT0gTlVMTDsKCQkJICAgIGN1ciA9IGN1ci0+bmV4dCkgewoJCQkJaWYgKGN1ci0+ZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7CgkJCQkgICAgYnJlYWs7CgkJCQl9CgkJCSAgICB9CgkJCX0KCQkgICAgfQoJCX0JCgkJLyoKCQkqIENoZWNrIGNvbnN0cmFpbnRzLgoJCSovCgkJeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKGN0eHQsIGl0ZW0pOwoJCXhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoaXRlbSwgY3R4dCwgaXRlbS0+bmFtZSk7CgkJY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6ICAgICAgICAgICAgCiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgogICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CiAgICAgICAgICAgICAgICBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQkvKgoJCSogVE9ETzogSGFuZGxpbmcgd2FzIG1vdmVkIHRvIHhtbFNjaGVtYUdyb3VwRGVmRml4dXAuCgkJKi8KCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTElTVDogCgkJeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXAoaXRlbSwgY3R4dCk7CgkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VTklPTjoJCQoJCXhtbFNjaGVtYVBhcnNlVW5pb25SZWZDaGVjayhpdGVtLCBjdHh0KTsKCQlpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0ZBQ0VUOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGOgoJCWJyZWFrOwogICAgICAgIH0KICAgIH0KI2lmZGVmIERFQlVHX1RZUEUKICAgIGlmIChpdGVtLT5ub2RlICE9IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIlR5cGUgb2YgJXMgOiAlczolZCA6IiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+bm9kZS0+ZG9jLT5VUkwsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEdldExpbmVObyhpdGVtLT5ub2RlKSk7CiAgICB9IGVsc2UgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiVHlwZSBvZiAlcyA6IiwgbmFtZSk7CiAgICB9CiAgICBzd2l0Y2ggKGl0ZW0tPmNvbnRlbnRUeXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgInNpbXBsZVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVsZW1lbnRzXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTjoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJ1bmtub3duICEhIVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgImVtcHR5XG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWRcbiIpOwogICAgICAgICAgICBicmVhazsKCS8qIFJlbW92ZWQsIHNpbmNlIG5vdCB1c2VkLiAqLwoJLyoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRF9PUl9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJtaXhlZCBvciBlbGVtc1xuIik7CiAgICAgICAgICAgIGJyZWFrOwoJKi8KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJiYXNpY1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCByZWdpc3RlcmVkICEhIVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQojZW5kaWYKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRmFjZXQ6CiAqIEBmYWNldDogIHRoZSBmYWNldAogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQgb3IgTlVMTAogKiBAbmFtZTogbmFtZSBvZiB0aGUgdHlwZQogKgogKiBDaGVja3MgdGhlIGRlZmF1bHQgdmFsdWVzIHR5cGVzLCBlc3BlY2lhbGx5IGZvciBmYWNldHMgCiAqCiAqIFJldHVybnMgMCBpZiBva2F5IG9yIC0xIGluIGNhZSBvZiBlcnJvcgogKi8KaW50CnhtbFNjaGVtYUNoZWNrRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPSBOVUxMOwogICAgaW50IHJldCA9IDAsIHJldXNlVmFsQ3R4dCA9IDA7CgogICAgaWYgKChmYWNldCA9PSBOVUxMKSB8fCAodHlwZURlY2wgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuKC0xKTsKICAgIC8qIAogICAgKiBUT0RPOiB3aWxsIHRoZSBwYXJzZXIgY29udGV4dCBiZSBnaXZlbiBpZiB1c2VkIGZyb20KICAgICogdGhlIHJlbGF4TkcgbW9kdWxlPwogICAgKi8KCiAgICBpZiAobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9PSBOVUxMKSB7CiAgICAgICAgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9CiAgICAgICAgICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05OSU5URUdFUik7CiAgICB9CiAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjogewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE9rYXkgd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAqIGF0IHRoYXQgcG9pbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CgoJCS8qIDQuMy41LjUgQ29uc3RyYWludHMgb24gZW51bWVyYXRpb24gU2NoZW1hIENvbXBvbmVudHMKCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogZW51bWVyYXRpb24gdmFsaWQgcmVzdHJpY3Rpb24KCQkqIEl0IGlzIGFuILdlcnJvcrcgaWYgYW55IG1lbWJlciBvZiB7dmFsdWV9IGlzIG5vdCBpbiB0aGUgCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uIAoJCSoKCQkqIG1pbkluY2x1c2l2ZSwgbWF4SW5jbHVzaXZlLCBtaW5FeGNsdXNpdmUsIG1heEV4Y2x1c2l2ZToKCQkqIFRoZSB2YWx1ZSC3bXVzdLcgYmUgaW4gdGhlIAoJCSogt3ZhbHVlIHNwYWNltyBvZiB0aGUgt2Jhc2UgdHlwZbcuIAoJCSovCgkJLyoKCQkqIFRoaXMgZnVuY3Rpb24gaXMgaW50ZW5kZWQgdG8gZGVsaXZlciBhIGNvbXBpbGVkIHZhbHVlCgkJKiBvbiB0aGUgZmFjZXQuIEluIFhNTCBTY2hlbWFzIHRoZSB0eXBlIGhvbGRpbmcgYSBmYWNldCwgCgkJKiBjYW5ub3QgYmUgYSBidWlsdC1pbiB0eXBlLiBUaHVzIHRvIGVuc3VyZSB0aGF0IG90aGVyIEFQSQoJCSogY2FsbHMgKHJlbGF4bmcpIGRvIHdvcmssIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGEgYnVpbHQtaW4gCgkJKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlICppcwoJCSogYWxyZWFkeSogdGhlIGJhc2UgdHlwZS4JCQoJCSovCgkJaWYgKHR5cGVEZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCSAgICBiYXNlID0gdHlwZURlY2wtPmJhc2VUeXBlOwoJCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIgoJCQkgICAgInRoZSB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJCSAgICB0eXBlRGVjbC0+bmFtZSwgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CQkKCQl9IGVsc2UKCQkgICAgYmFzZSA9IHR5cGVEZWNsOwoJCS8qCgkJKiBUaGlzIGF2b2lkcyBwZXJzZXZlcmF0aXZlIGNyZWF0aW9uIG9mIHRoZSAKCQkqIHZhbGlkYXRpb24gY29udGV4dCBpZiBhIHBhcnNlciBjb250ZXh0IGlzCgkJKiB1c2VkLgoJCSovCgkJaWYgKGN0eHQgIT0gTlVMTCkgewoJCSAgICByZXVzZVZhbEN0eHQgPSAxOwoJCSAgICBpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJCQlpZiAoeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KGN0eHQpID09IC0xKQoJCQkgICAgcmV0dXJuICgtMSk7CgkJICAgIH0KCQkgICAgdmN0eHQgPSBjdHh0LT52Y3R4dDsKCQl9IGVsc2UgewoJCSAgICB2Y3R4dCA9IHhtbFNjaGVtYU5ld1ZhbGlkQ3R4dChOVUxMKTsKCQkgICAgaWYgKHZjdHh0ID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSAgICAiY3JlYXRpbmcgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQkJICAgIE5VTEwsIE5VTEwpOwoJCQlyZXR1cm4gKC0xKTsJCgkJICAgIH0KCQl9CgkgICAgICAgICAgICAgICAgCgkJdmN0eHQtPm5vZGUgPSBmYWNldC0+bm9kZTsKCQl2Y3R4dC0+Y3VyID0gTlVMTDsKCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCAKCQkqIHNpbmNlIHRoZXkgYXJlIG5vdCBhdmFpbGFibGU6CgkJKiBmYWNldC0+bm9kZSBpcyBqdXN0IHRoZSBub2RlIGhvbGRpbmcgdGhlIGZhY2V0IAoJCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqIAoJCSogb2YgdGhlIGZhY2V0LgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUodmN0eHQsIGJhc2UsIAoJCSAgICBmYWNldC0+dmFsdWUsIDAsIDEsIDEsIDApOwoJCWZhY2V0LT52YWwgPSB2Y3R4dC0+dmFsdWU7CgkJdmN0eHQtPnZhbHVlID0gTlVMTDsJCQogICAgICAgICAgICAgICAgaWYgKHJldCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVCwgCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkgICAgImZhY2V0ICclcycgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSwgCgkJCSAgICB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksIAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgZmFjZXQtPm5vZGUsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCBOVUxMLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgJyVzJyBuYW1lIG9mIHRoZSAiCgkJCSJmYWNldCAnJXMnIGFnYWluc3QgdGhlIGJhc2UgdHlwZSAnJXMnLlxuIiwKCQkJZmFjZXQtPnZhbHVlLCAKCQkJeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQliYXNlLT5uYW1lLCBOVUxMLCBOVUxMKTsgCgkJICAgIHJldCA9IC0xOwoJCX0gICAKCQlpZiAocmV1c2VWYWxDdHh0ID09IDApCgkJICAgIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQodmN0eHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgZmFjZXQtPnJlZ2V4cCA9IHhtbFJlZ2V4cENvbXBpbGUoZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgaWYgKGZhY2V0LT5yZWdleHAgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX1JFR0VYUF9JTlZBTElELAoJCSAgICAiVHlwZSBkZWZpbml0aW9uICclcyc6IFRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJICAgICJmYWNldCAncGF0dGVybicgaXMgbm90IHZhbGlkLlxuIiwKCQkgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6ewogICAgICAgICAgICAgICAgaW50IHRtcDsKCiAgICAgICAgICAgICAgICB0bXAgPQogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlUHJlZGVmaW5lZFR5cGUobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoZmFjZXQtPnZhbCkpOwogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVRfVkFMVUUsCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCQkgICAgImZhY2V0ICclcycgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSwgCgkJCSAgICB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksCgkJCSAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOnsKICAgICAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJwcmVzZXJ2ZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9QUkVTRVJWRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicmVwbGFjZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9SRVBMQUNFOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChmYWNldC0+dmFsdWUsIEJBRF9DQVNUICJjb2xsYXBzZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQtPndoaXRlc3BhY2UgPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9XSElURV9TUEFDRSwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnd2hpdGVTcGFjZScgaXMgbm90IHZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0RlZmF1bHRzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGVEZWNsLT5uYW1lOyAKICAgIC8qCiAgICAqIE5PVEU6IEl0IGlzIGludGVuZGVkIHRvIHVzZSB0aGUgZmFjZXRzIGxpc3QsIGluc3RlYWQKICAgICogb2YgZmFjZXRTZXQuCiAgICAqLwogICAgaWYgKHR5cGVEZWNsLT5mYWNldHMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQgPSB0eXBlRGVjbC0+ZmFjZXRzOwoJCgkvKgoJKiBUZW1wb3JhcmlseSBhc3NpZ24gdGhlICJzY2hlbWEiIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKCSogb2YgdGhlIHBhcnNlciBjb250ZXh0LiBUaGlzIGlzIG5lZWRlZCBmb3IgTk9UQVRJT04gdmFsaWRhdGlvbi4KCSovCglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpCgkJcmV0dXJuOwoJfQoJY3R4dC0+dmN0eHQtPnNjaGVtYSA9IGN0eHQtPnNjaGVtYTsKCgl3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUNoZWNrRmFjZXQoZmFjZXQsIHR5cGVEZWNsLCBjdHh0LCBuYW1lKTsKCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJfQoKCWN0eHQtPnZjdHh0LT5zY2hlbWEgPSBOVUxMOwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmOgogKiBAY3R4dEdyOiB0aGUgc2VhcmNoZWQgbW9kZWwgZ3JvdXAKICogQGxpc3Q6IHRoZSBsaXN0IG9mIG1vZGVsIGdyb3VwcyB0byBiZSBwcm9jZXNzZWQKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiByZWZlcmVuY2UsIG90aGVyd2lzZSBOVUxMLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoeG1sU2NoZW1hVHlwZVB0ciBjdHh0R3JEZWYsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBncikKeyAgICAKICAgIHhtbFNjaGVtYVR5cGVQdHIgY2lyYyA9IE5VTEw7CiAgICBpbnQgbWFya2VkOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIG1vZGVsIGdyb3VwIHJlZmVyZW5jZSB3aGljaAogICAgKiByZWZlcmVuY2VzIHRoZSBjb250ZXh0IG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCiAgICAqLyAgICAgICAgCiAgICB3aGlsZSAoZ3IgIT0gTlVMTCkgewoJaWYgKCgoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB8fAoJICAgICAoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FMTCkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRSkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpKSAmJgoJICAgIChnci0+c3VidHlwZXMgIT0gTlVMTCkpIHsJCSAKCSAgICBtYXJrZWQgPSAwOwoJICAgIGlmICgoZ3ItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSAmJgoJCShnci0+cmVmICE9IE5VTEwpKSB7CgkJaWYgKGdyLT5zdWJ0eXBlcyA9PSBjdHh0R3JEZWYpCgkJICAgIHJldHVybiAoZ3IpOwoJCWVsc2UgaWYgKGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQpIHsKCQkgICAgZ3IgPSBnci0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBNYXJrIHRvIGF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbiBvbgoJCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkgICAgKi8KCQkgICAgZ3ItPnN1YnR5cGVzLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01BUktFRDsKCQkgICAgbWFya2VkID0gMTsKCQl9IAoJCWlmIChnci0+c3VidHlwZXMtPnN1YnR5cGVzICE9IE5VTEwpCgkJICAgIGNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihjdHh0R3JEZWYsIAoJCQlnci0+c3VidHlwZXMtPnN1YnR5cGVzKTsKCQkgICAgLyoKCQkgICAgKiBVbm1hcmsgdGhlIHZpc2l0ZWQgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbi4KCQkqLwoJCWlmIChtYXJrZWQpCgkJICAgIGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCSAgICB9IGVsc2UgewoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihjdHh0R3JEZWYsIAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgZ3ItPnN1YnR5cGVzKTsKCQlpZiAoY2lyYyAhPSBOVUxMKQoJCSAgICByZXR1cm4gKGNpcmMpOwoJICAgIH0KCgl9CglnciA9IGdyLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgdG8gbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoeG1sU2NoZW1hVHlwZVB0ciBtb2RlbEdyRGVmLAoJCQkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsgICAgCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IE1vZGVsIEdyb3VwIENvcnJlY3QKICAgICogMiBDaXJjdWxhciBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIHdpdGhpbiB0aGUge3BhcnRpY2xlc30gCiAgICAqIG9mIGEgZ3JvdXAgdGhlcmUgbXVzdCBub3QgYmUgYXQgYW55IGRlcHRoIGEgcGFydGljbGUgd2hvc2Uge3Rlcm19IAogICAgKiBpcyB0aGUgZ3JvdXAgaXRzZWxmLgogICAgKi8KICAgIC8qCiAgICAqIE5PVEU6ICJnci0+c3VidHlwZXMiIGhvbGRzIHRoZSByZWZlcmVuY2VkIGdyb3VwLgogICAgKi8KICAgIGlmICgobW9kZWxHckRlZi0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfR1JPVVApIHx8IAoJKChtb2RlbEdyRGVmLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSA9PSAwKSB8fAoJKG1vZGVsR3JEZWYtPnN1YnR5cGVzID09IE5VTEwpKQoJcmV0dXJuOwogICAgZWxzZSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKG1vZGVsR3JEZWYsIG1vZGVsR3JEZWYtPnN1YnR5cGVzKTsKCWlmIChjaXJjICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogUmVwb3J0IHRoZSByZWZlcmVuY2VkIGF0dHIgZ3JvdXAgYXMgUU5hbWUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfTUdfUFJPUFNfQ09SUkVDVF8yLAoJCU5VTEwsIE5VTEwsIGNpcmMtPm5vZGUsCgkJIkNpcmN1bGFyIHJlZmVyZW5jZSB0byB0aGUgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiAnJXMnICIKCQkiZGVmaW5lZCIsIG1vZGVsR3JEZWYtPm5hbWUpOwoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLgoJICAgICogVE9ETzogU1BFQzogRG9lcyB0aGUgc3BlYyBkZWZpbmUgaG93IHRvIHByb2Nlc3MgaGVyZT8KCSAgICAqLwoJICAgIGNpcmMtPnN1YnR5cGVzID0gTlVMTDsKCX0KICAgIH0KfQoKCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmOgogKiBAY3R4dEdyOiB0aGUgc2VhcmNoZWQgYXR0cmlidXRlIGdyb3VwCiAqIEBhdHRyOiB0aGUgY3VycmVudCBhdHRyaWJ1dGUgbGlzdCB0byBiZSBwcm9jZXNzZWQKICoKICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBieQogKiB4bWxTY2hlbWFDaGVja1NSQ0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIgb25seS4KICoKICogUmV0dXJucyB0aGUgY2lyY3VsYXIgYXR0cmlidXRlIGdyb3UgcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGN0eHRHciwKCQkJICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cikKeyAgICAKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGNpcmMgPSBOVUxMLCBncjsKICAgIGludCBtYXJrZWQ7CiAgICAvKgogICAgKiBXZSB3aWxsIHNlYXJjaCBmb3IgYW4gYXR0cmlidXRlIGdyb3VwIHJlZmVyZW5jZSB3aGljaAogICAgKiByZWZlcmVuY2VzIHRoZSBjb250ZXh0IGF0dHJpYnV0ZSBncm91cC4KICAgICovICAgIAkKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKCW1hcmtlZCA9IDA7CglpZiAoYXR0ci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApIHsKCSAgICBnciA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgYXR0cjsKCSAgICBpZiAoZ3ItPnJlZkl0ZW0gIT0gTlVMTCkgIHsKCQlpZiAoZ3ItPnJlZkl0ZW0gPT0gY3R4dEdyKQoJCSAgICByZXR1cm4gKGdyKTsKCQllbHNlIGlmIChnci0+cmVmSXRlbS0+ZmxhZ3MgJiAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRCkgewoJCSAgICBhdHRyID0gYXR0ci0+bmV4dDsKCQkgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgLyoKCQkgICAgKiBNYXJrIGFzIHZpc2l0ZWQgdG8gYXZvaWQgaW5maW5pdGUgcmVjdXJzaW9uIG9uCgkJICAgICogY2lyY3VsYXIgcmVmZXJlbmNlcyBub3QgeWV0IGV4YW1pbmVkLgoJCSAgICAqLwoJCSAgICBnci0+cmVmSXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRDsKCQkgICAgbWFya2VkID0gMTsKCQl9CgkgICAgfQoJICAgIGlmIChnci0+YXR0cmlidXRlcyAhPSBOVUxMKQoJCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjQXR0ckdyUmVmKGN0eHRHciwgZ3ItPmF0dHJpYnV0ZXMpOwoJICAgIC8qCgkgICAgKiBVbm1hcmsgdGhlIHZpc2l0ZWQgZ3JvdXAncyBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKG1hcmtlZCkKCQlnci0+cmVmSXRlbS0+ZmxhZ3MgXj0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX01BUktFRDsKCSAgICBpZiAoY2lyYyAhPSBOVUxMKQoJCXJldHVybiAoY2lyYyk7Cgl9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCQkJCQovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNBdHRyaWJ1dGVHcm91cENpcmN1bGFyOgogKiBhdHRyR3I6ICB0aGUgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZQogKgogKiBDaGVja3MgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgb2YgYXR0cmlidXRlIGdyb3Vwcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhcih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyR3IsCgkJCQkJeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCQljb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgLyoKICAgICogU2NoZW1hIFJlcHJlc2VudGF0aW9uIENvbnN0cmFpbnQ6IAogICAgKiBBdHRyaWJ1dGUgR3JvdXAgRGVmaW5pdGlvbiBSZXByZXNlbnRhdGlvbiBPSwogICAgKiAzIENpcmN1bGFyIGdyb3VwIHJlZmVyZW5jZSBpcyBkaXNhbGxvd2VkIG91dHNpZGUgPHJlZGVmaW5lPi4gCiAgICAqIFRoYXQgaXMsIHVubGVzcyB0aGlzIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSdzIHBhcmVudCBpcyAKICAgICogPHJlZGVmaW5lPiwgdGhlbiBhbW9uZyB0aGUgW2NoaWxkcmVuXSwgaWYgYW55LCB0aGVyZSBtdXN0IAogICAgKiBub3QgYmUgYW4gPGF0dHJpYnV0ZUdyb3VwPiB3aXRoIHJlZiBbYXR0cmlidXRlXSB3aGljaCByZXNvbHZlcyAKICAgICogdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4gSW5kaXJlY3QgCiAgICAqIGNpcmN1bGFyaXR5IGlzIGFsc28gcnVsZWQgb3V0LiBUaGF0IGlzLCB3aGVuIFFOYW1lIHJlc29sdXRpb24gCiAgICAqIChTY2hlbWEgRG9jdW1lbnQpICinMy4xNS4zKSBpcyBhcHBsaWVkIHRvIGEgt1FOYW1ltyBhcmlzaW5nIGZyb20gCiAgICAqIGFueSA8YXR0cmlidXRlR3JvdXA+cyB3aXRoIGEgcmVmIFthdHRyaWJ1dGVdIGFtb25nIHRoZSBbY2hpbGRyZW5dLCAKICAgICogaXQgbXVzdCBub3QgYmUgdGhlIGNhc2UgdGhhdCBhILdRTmFtZbcgaXMgZW5jb3VudGVyZWQgYXQgYW55IGRlcHRoIAogICAgKiB3aGljaCByZXNvbHZlcyB0byB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhpcyA8YXR0cmlidXRlR3JvdXA+LgogICAgKi8KICAgIC8qCiAgICAqIE9ubHkgZ2xvYmFsIGNvbXBvbmVudHMgY2FuIGJlIHJlZmVyZW5jZWQuCiAgICAqLwogICAgaWYgKCgoYXR0ckdyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9HTE9CQUwpID09IDApIHx8IAoJKGF0dHJHci0+YXR0cmlidXRlcyA9PSBOVUxMKSkKCXJldHVybjsKICAgIGVsc2UgewoJeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgY2lyYzsKCgljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihhdHRyR3IsIGF0dHJHci0+YXR0cmlidXRlcyk7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19BVFRSSUJVVEVfR1JPVVBfMywKCQlOVUxMLCBOVUxMLCBjaXJjLT5ub2RlLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIGF0dHJpYnV0ZSBncm91cCAnJXMnICIKCQkiZGVmaW5lZCIsIGF0dHJHci0+bmFtZSk7CgkgICAgLyoKCSAgICAqIE5PVEU6IFdlIHdpbGwgY3V0IHRoZSByZWZlcmVuY2UgdG8gYXZvaWQgZnVydGhlcgoJICAgICogY29uZnVzaW9uIG9mIHRoZSBwcm9jZXNzb3IuCgkgICAgKiBCQURTUEVDOiBUaGUgc3BlYyBzaG91bGQgZGVmaW5lIGhvdyB0byBwcm9jZXNzIGluIHRoaXMgY2FzZS4KCSAgICAqLwoJICAgIGNpcmMtPmF0dHJpYnV0ZXMgPSBOVUxMOwoJICAgIGNpcmMtPnJlZkl0ZW0gPSBOVUxMOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXR0ckdycEZpeHVwOgogKiBAYXR0cmdycERlY2w6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckdycEZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHJncnAsCiAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSBhdHRyZ3JwLT5uYW1lOwogICAgaWYgKGF0dHJncnAtPmF0dHJpYnV0ZXMgIT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoYXR0cmdycC0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciByZWY7CgogICAgICAgIHJlZiA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGN0eHQtPnNjaGVtYSwgYXR0cmdycC0+cmVmLCAKCSAgICBhdHRyZ3JwLT5yZWZOcyk7CiAgICAgICAgaWYgKHJlZiA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBhdHRyZ3JwLCBhdHRyZ3JwLT5ub2RlLAoJCSJyZWYiLCBhdHRyZ3JwLT5yZWYsIGF0dHJncnAtPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVAsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJYXR0cmdycC0+cmVmSXRlbSA9IHJlZjsKCS8qCgkqIENoZWNrIGZvciBzZWxmIHJlZmVyZW5jZSEKCSovCiAgICAgICAgeG1sU2NoZW1hQXR0ckdycEZpeHVwKHJlZiwgY3R4dCwgTlVMTCk7CiAgICAgICAgYXR0cmdycC0+YXR0cmlidXRlcyA9IHJlZi0+YXR0cmlidXRlczsKCWF0dHJncnAtPmF0dHJpYnV0ZVdpbGRjYXJkID0gcmVmLT5hdHRyaWJ1dGVXaWxkY2FyZDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJDaGVja1ZhbENvbnN0cjoKICogQGl0ZW06ICBhbiBzY2hlbWEgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZQogKiAKICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBjb25zdHJhaW50cyBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAoJCQkgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKCiAgICAvKgogICAgKiBhLXByb3BzLWNvcnJlY3QKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAqCiAgICAqIDIgaWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKICAgICogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCiAgICAqIHRvIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIFN0cmluZyBWYWxpZCAopzMuMTQuNCkuIAogICAgKi8KCiAgICBpZiAoaXRlbS0+ZGVmVmFsdWUgIT0gTlVMTCkgewoJaW50IHJldDsKCXhtbE5vZGVQdHIgbm9kZTsKCXhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCglpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInZhbHVlIGNvbnN0cmFpbnQiLCBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm47Cgl9CgoJLyoKCSogVE9ETzogVHJ5IHRvIGF2b2lkIGNyZWF0aW5nIGEgbmV3IGNvbnRleHQuCgkqIFRPRE86IFRoaXMgYWxsIGlzIG5vdCB2ZXJ5IHBlcmZvcm1hbnQuCgkqLwoJdHlwZSA9IGl0ZW0tPnN1YnR5cGVzOwoJLyoKCSogRW5zdXJlIHRoZXJlJ3MgdmFsaWRhdGlvbiBjb250ZXh0LgoJKi8KCWlmIChjdHh0LT52Y3R4dCA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyLCAiCgkJICAgICJjcmVhdGluZyBhIG5ldyB2YWxpZGF0aW9uIGNvbnRleHQuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCQlyZXR1cm47CgkgICAgfQoJfQoKCWlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpCgkgICAgbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGl0ZW0tPm5vZGUsIEJBRF9DQVNUICJmaXhlZCIpOwoJZWxzZQoJICAgIG5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChpdGVtLT5ub2RlLCBCQURfQ0FTVCAiZGVmYXVsdCIpOwoJY3R4dC0+dmN0eHQtPm5vZGUgPSBub2RlOwoJY3R4dC0+dmN0eHQtPmN1ciA9IE5VTEw7CgkvKgoJKiBOT1RFOiBUaGlzIGNhbGwgZG9lcyBub3QgY2hlY2sgdGhlIGNvbnRlbnQgbm9kZXMsIAoJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJKiBmYWNldC0+bm9kZSBpcyBqdXN0IHRoZSBub2RlIGhvbGRpbmcgdGhlIGZhY2V0IAoJKiBkZWZpbml0aW9uLCAqbm90KiB0aGUgYXR0cmlidXRlIGhvbGRpbmcgdGhlICp2YWx1ZSogCgkqIG9mIHRoZSBmYWNldC4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LT52Y3R4dCwgdHlwZSwgCgkgICAgaXRlbS0+ZGVmVmFsdWUsIDAsIDEsIDEsIDApOwoJaWYgKHJldCA9PSAwKSB7CgkgICAgLyoKCSAgICAqIFN0b3JlIHRoZSBjb21wdXRlZCB2YWx1ZS4KCSAgICAqLwogICAgCSAgICBpdGVtLT5kZWZWYWwgPSBjdHh0LT52Y3R4dC0+dmFsdWU7CgkgICAgY3R4dC0+dmN0eHQtPnZhbHVlID0gTlVMTDsJCgl9IGVsc2UgaWYgKHJldCA+IDApIHsKCSAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUFNpbXBsZVR5cGVFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFQX0FfUFJPUFNfQ09SUkVDVF8yLCAKCQkgICAgTlVMTCwgTlVMTCwgbm9kZSwgCgkJICAgIHR5cGUsIE5VTEwsIGl0ZW0tPmRlZlZhbHVlLAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9IGVsc2UgaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBdHRyQ2hlY2tWYWxDb25zdHIsICIKCQkiZmFpbGVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJImF0dHJpYnV0ZSBkZWNsL3VzZSBhZ2FpbnN0IHRoZSB0eXBlICclcyciLAoJCXR5cGUtPm5hbWUpOyAJICAgIAoJfQkgICAJCiAgICB9ICAgIAp9CgojaWYgMCAvKiBOb3QgdXNlZCB5ZXQuICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tFbGVtUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWRlY2wpCnsKICAgIC8qCiAgICAqIFRPRE86IDEgVGhlIHZhbHVlcyBvZiB0aGUgcHJvcGVydGllcyBvZiBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIG11c3QgYmUgYXMgCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBUaGUgRWxlbWVudCBEZWNsYXJhdGlvbiBTY2hlbWEgCiAgICAqIENvbXBvbmVudCAopzMuMy4xKSwgbW9kdWxvIHRoZSBpbXBhY3Qgb2YgTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuCiAgICAqLwogICAgLyoKICAgICogMiBJZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsIAogICAgKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUge3R5cGUgCiAgICAqIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLgogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyLgogICAgKi8KICAgIC8qCiAgICAqIDMgSWYgdGhlcmUgaXMgYSBub24tt2Fic2VudLcge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIAogICAgKiB0aGVuIHtzY29wZX0gbXVzdCBiZSBnbG9iYWwuCiAgICAqCiAgICAqIE5PVEU6IFRoaXMgaXMgZG9uZSBpbiB4bWxTY2hlbWFQYXJzZUVsZW1lbnQuCiAgICAqIFRPRE86IE1vdmUgaXQgdG8gdGhpcyBsYXllciBoZXJlLgogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IDQgSWYgdGhlcmUgaXMgYSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgdGhlIHt0eXBlIGRlZmluaXRpb259IAogICAgKiBvZiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCBmcm9tIHRoZSB7dHlwZSAKICAgICogZGVmaW5pdGlvbn0gb2YgdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCBnaXZlbiB0aGUgdmFsdWUgCiAgICAqIG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGV4Y2x1c2lvbnN9IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIAogICAgKiBhZmZpbGlhdGlvbn0sIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChDb21wbGV4KSAopzMuNC42KSAKICAgICogKGlmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBpcyBjb21wbGV4KSBvciBhcyBkZWZpbmVkIGluIAogICAgKiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkgKKczLjE0LjYpIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgCiAgICAqIHNpbXBsZSkuIAogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IDUgSWYgdGhlIHt0eXBlIGRlZmluaXRpb259IG9yIHt0eXBlIGRlZmluaXRpb259J3Mge2NvbnRlbnQgdHlwZX0gCiAgICAqIGlzIG9yIGlzIGRlcml2ZWQgZnJvbSBJRCB0aGVuIHRoZXJlIG11c3Qgbm90IGJlIGEge3ZhbHVlIGNvbnN0cmFpbnR9LgogICAgKiBOb3RlOiBUaGUgdXNlIG9mIElEIGFzIGEgdHlwZSBkZWZpbml0aW9uIGZvciBlbGVtZW50cyBnb2VzIGJleW9uZCAKICAgICogWE1MIDEuMCwgYW5kIHNob3VsZCBiZSBhdm9pZGVkIGlmIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGlzIGRlc2lyZWQKICAgICovCiAgICAvKgogICAgKiBUT0RPOiA2IENpcmN1bGFyIHN1YnN0aXR1dGlvbiBncm91cHMgYXJlIGRpc2FsbG93ZWQuIFRoYXQgaXMsIGl0IG11c3Qgbm90IAogICAgKiBiZSBwb3NzaWJsZSB0byByZXR1cm4gdG8gYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBieSByZXBlYXRlZGx5IGZvbGxvd2luZyAKICAgICogdGhlIHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259IHByb3BlcnR5LgogICAgKi8KfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHI6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGVsZW1lbnQgZGVjbGFyYXRpb24vcGFydGljbGUKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbi4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyKHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbCwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgCiAgICBpZiAoZGVjbC0+dmFsdWUgIT0gTlVMTCkgewoJaW50IHJldDsKCXhtbE5vZGVQdHIgbm9kZSA9IE5VTEw7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJLyoKCSogMiBJZiB0aGVyZSBpcyBhIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlIGNhbm9uaWNhbCBsZXhpY2FsIAoJKiByZXByZXNlbnRhdGlvbiBvZiBpdHMgdmFsdWUgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGUge3R5cGUgCgkqIGRlZmluaXRpb259IGFzIGRlZmluZWQgaW4gRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpICinMy4zLjYpLgoJKi8gICAgCglpZiAoZGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgZGVjbC0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ciwgIgoJCSJ0eXBlIGlzIG1pc3NpbmcuLi4gc2tpcHBpbmcgdmFsaWRhdGlvbiBvZiAiCgkJInRoZSB2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoJLyoKCSogRW5zdXJlIHRoZXJlJ3MgYSB2YWxpZGF0aW9uIGNvbnRleHQuCgkqLwoJaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkKCSAgICByZXR1cm47CgoJdHlwZSA9IGRlY2wtPnN1YnR5cGVzOwoKCWlmIChkZWNsLT5ub2RlICE9IE5VTEwpIHsKCSAgICBpZiAoZGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChkZWNsLT5ub2RlLCBCQURfQ0FTVCAiZml4ZWQiKTsKCSAgICBlbHNlCgkJbm9kZSA9ICh4bWxOb2RlUHRyKSB4bWxIYXNQcm9wKGRlY2wtPm5vZGUsIEJBRF9DQVNUICJkZWZhdWx0Iik7Cgl9CgljdHh0LT52Y3R4dC0+bm9kZSA9IG5vZGU7CgljdHh0LT52Y3R4dC0+Y3VyID0gTlVMTDsKCXJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KGN0eHQsIGN0eHQtPnZjdHh0LCB0eXBlLCBkZWNsLT52YWx1ZSwgCgkgICAgbm9kZSk7CglpZiAocmV0ID09IDApIHsKCSAgICAvKgoJICAgICogQ29uc3VtZSB0aGUgY29tcHV0ZWQgdmFsdWUuCgkgICAgKi8KICAgIAkgICAgZGVjbC0+ZGVmVmFsID0gY3R4dC0+dmN0eHQtPnZhbHVlOwogIAkgICAgY3R4dC0+dmN0eHQtPnZhbHVlID0gTlVMTDsKCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUVsZW1DaGVja1ZhbENvbnN0ciwgIgoJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgdGhlICIKCQkiZWxlbWVudCBkZWNsYXJhdGlvbiAnJXMnIiwKCQlkZWNsLT5uYW1lKTsgCSAgICAKCX0KICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyRml4dXA6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UuCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIAogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zL3VzZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdHRyRml4dXAoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGl0ZW0sCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsKICAgIC8qIAogICAgKiBUT0RPOiBJZiBpbmNsdWRpbmcgdGhpcyBpcyBkb25lIHR3aWNlICghKSBmb3IgZXZlcnkgYXR0cmlidXRlLgogICAgKiAgICAgICAtPiBIbW0sIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgZG9uZS4KICAgICovCiAgICAvKgogICAgKiBUaGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4gZWxlbWVudCAKICAgICogaW5mb3JtYXRpb24gaXRlbSBpbiB0aGUgW2NoaWxkcmVuXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSBzaW1wbGUgCiAgICAqIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgdHlwZSAKICAgICogW2F0dHJpYnV0ZV0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgt3NpbXBsZSB1ci10eXBlIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfSU5URVJOQUxfUkVTT0xWRUQpCglyZXR1cm47CiAgICBpdGVtLT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEOwogICAgaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGl0ZW0tPnR5cGVOYW1lICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJdHlwZSA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBpdGVtLT50eXBlTmFtZSwKCSAgICBpdGVtLT50eXBlTnMpOwoJaWYgKCh0eXBlID09IE5VTEwpIHx8ICghIElTX1NJTVBMRV9UWVBFKHR5cGUpKSkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJCSJ0eXBlIiwgaXRlbS0+dHlwZU5hbWUsIGl0ZW0tPnR5cGVOcywgCgkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSwgTlVMTCk7Cgl9IGVsc2UKCSAgICBpdGVtLT5zdWJ0eXBlcyA9IHR5cGU7CgkKICAgIH0gZWxzZSBpZiAoaXRlbS0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgZGVjbDsKCgkvKgoJKiBXZSBoYXZlIGFuIGF0dHJpYnV0ZSB1c2UgaGVyZTsgYXNzaWduIHRoZSByZWZlcmVuY2VkIAoJKiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24uCgkqLwoJLyoKCSogVE9ETzogRXZhbHVhdGUsIHdoYXQgZXJyb3JzIGNvdWxkIG9jY3VyIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBub3QKCSogZm91bmQuIEl0IG1pZ2h0IGJlIHBvc3NpYmxlIHRoYXQgdGhlICJ0eXBlZml4dXAiIG1pZ2h0IGNyYXNoIGlmCgkqIG5vIHJlZiBkZWNsYXJhdGlvbiB3YXMgZm91bmQuCgkqLwoJZGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZShjdHh0LT5zY2hlbWEsIGl0ZW0tPnJlZiwgaXRlbS0+cmVmTnMpOwogICAgICAgIGlmIChkZWNsID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCSAgICAJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGl0ZW0sIGl0ZW0tPm5vZGUsCgkJInJlZiIsIGl0ZW0tPnJlZiwgaXRlbS0+cmVmTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJaXRlbS0+cmVmRGVjbCA9IGRlY2w7CiAgICAgICAgeG1sU2NoZW1hQXR0ckZpeHVwKGRlY2wsIGN0eHQsIE5VTEwpOwoJCiAgICAgICAgaXRlbS0+c3VidHlwZXMgPSBkZWNsLT5zdWJ0eXBlczsKCS8qCgkqIEF0dHJpYnV0ZSBVc2UgQ29ycmVjdAoJKiBhdS1wcm9wcy1jb3JyZWN0LjI6IElmIHRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSBoYXMgYSBmaXhlZCAKCSoge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGVuIGlmIHRoZSBhdHRyaWJ1dGUgdXNlIGl0c2VsZiBoYXMgYSAKCSoge3ZhbHVlIGNvbnN0cmFpbnR9LCBpdCBtdXN0IGFsc28gYmUgZml4ZWQgYW5kIGl0cyB2YWx1ZSBtdXN0IG1hdGNoIAoJKiB0aGF0IG9mIHRoZSB7YXR0cmlidXRlIGRlY2xhcmF0aW9ufSdzIHt2YWx1ZSBjb25zdHJhaW50fS4KCSovCglpZiAoKGRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgJiYgCgkgICAgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpKSB7CgkgICAgaWYgKCgoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKSA9PSAwKSB8fAoJCSgheG1sU3RyRXF1YWwoaXRlbS0+ZGVmVmFsdWUsIGRlY2wtPmRlZlZhbHVlKSkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0FVX1BST1BTX0NPUlJFQ1RfMiwgCgkJICAgIE5VTEwsIE5VTEwsIGl0ZW0tPm5vZGUsIAoJCSAgICAiVGhlIHZhbHVlIGNvbnN0cmFpbnQgbXVzdCBiZSBmaXhlZCAiCgkJICAgICJhbmQgbWF0Y2ggdGhlIHJlZmVyZW5jZWQgYXR0cmlidXRlICIKCQkgICAgImRlY2xhcmF0aW9ucydzIHZhbHVlIGNvbnN0cmFpbnQgJyVzJyIsCgkJICAgIGRlY2wtPmRlZlZhbHVlKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIEZVVFVSRTogT25lIHNob3VsZCBjaGFuZ2UgdGhlIHZhbHVlcyBvZiB0aGUgYXR0ci4gdXNlCgkgICAgKiBpZiBldmVyIHZhbGlkYXRpb24gc2hvdWxkIGJlIGF0dGVtcHRlZCBldmVuIGlmIHRoZQoJICAgICogc2NoZW1hIGl0c2VsZiB3YXMgbm90IGZ1bGx5IHZhbGlkLgoJICAgICovCgl9CiAgICB9IGVsc2UgewoJaXRlbS0+c3VidHlwZXMgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsgICAgICAgIAogICAgfQkKfQoKLyoqCiAqIHhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWY6CiAqIEBpZGM6ICB0aGUgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBSZXNvbHZlIGtleVJlZiByZWZlcmVuY2VzIHRvIGtleS91bmlxdWUgSURDcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWYoeG1sU2NoZW1hSURDUHRyIGlkYywKCQkJICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQpCnsgIAogICAgaWYgKGlkYy0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikKICAgICAgICByZXR1cm47CiAgICBpZiAoaWRjLT5yZWYtPm5hbWUgIT0gTlVMTCkgeyAJCglpZGMtPnJlZi0+aXRlbSA9ICh4bWxTY2hlbWFCYXNpY0l0ZW1QdHIpIHhtbEhhc2hMb29rdXAyKAoJICAgIGN0eHQtPnNjaGVtYS0+aWRjRGVmLCAKCSAgICBpZGMtPnJlZi0+bmFtZSwgCgkgICAgaWRjLT5yZWYtPnRhcmdldE5hbWVzcGFjZSk7CiAgICAgICAgaWYgKGlkYy0+cmVmLT5pdGVtID09IE5VTEwpIHsKCSAgICAvKiAKCSAgICAqIFRPRE86IEl0IGlzIGFjdHVhbGx5IG5vdCBhbiBlcnJvciB0byBmYWlsIHRvIHJlc29sdmUuCgkgICAgKi8KCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJTlVMTCwgKHhtbFNjaGVtYVR5cGVQdHIpIGlkYywgaWRjLT5ub2RlLAoJCSJyZWZlciIsIGlkYy0+cmVmLT5uYW1lLCAKCQlpZGMtPnJlZi0+dGFyZ2V0TmFtZXNwYWNlLCAKCQlYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRiwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybjsKCX0gICAgICAgIAogICAgfQp9CgovKioKICogeG1sU2NoZW1hUGFyc2U6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIHBhcnNlIGEgc2NoZW1hIGRlZmluaXRpb24gcmVzb3VyY2UgYW5kIGJ1aWxkIGFuIGludGVybmFsCiAqIFhNTCBTaGVtYSBzdHJ1dHVyZSB3aGljaCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSBpbnN0YW5jZXMuCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVB0cgp4bWxTY2hlbWFQYXJzZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVB0ciByZXQgPSBOVUxMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIGludCBwcmVzZXJ2ZSA9IDA7CgogICAgLyoKICAgICogVGhpcyBvbmUgaXMgdXNlZCBpZiB0aGUgc2NoZW1hIHRvIGJlIHBhcnNlZCB3YXMgc3BlY2lmaWVkIHZpYSAKICAgICogdGhlIEFQSTsgaS5lLiBub3QgYXV0b21hdGljYWxseSBieSB0aGUgdmFsaWRhdGVkIGluc3RhbmNlIGRvY3VtZW50LgogICAgKi8KCiAgICB4bWxTY2hlbWFJbml0VHlwZXMoKTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgY3R4dC0+Y291bnRlciA9IDA7CiAgICBjdHh0LT5jb250YWluZXIgPSBOVUxMOwoKICAgIC8qCiAgICAgKiBGaXJzdCBzdGVwIGlzIHRvIHBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBpbnRvIGFuIERPTS9JbmZvc2V0CiAgICAgKi8KICAgIGlmIChjdHh0LT5VUkwgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IHhtbFJlYWRGaWxlKChjb25zdCBjaGFyICopIGN0eHQtPlVSTCwgTlVMTCwgCgkgICAgICAgICAgICAgICAgICBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgICAgIGlmIChkb2MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkJICBYTUxfU0NIRU1BUF9GQUlMRURfTE9BRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBsb2FkICclcycuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPlVSTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChjdHh0LT5idWZmZXIgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IHhtbFJlYWRNZW1vcnkoY3R4dC0+YnVmZmVyLCBjdHh0LT5zaXplLCBOVUxMLCBOVUxMLAoJICAgICAgICAgICAgICAgICAgICBTQ0hFTUFTX1BBUlNFX09QVElPTlMpOwogICAgICAgIGlmIChkb2MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkJICBYTUxfU0NIRU1BUF9GQUlMRURfUEFSU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgcGFyc2UuXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBkb2MtPlVSTCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIpOwogICAgICAgIGN0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiLCAtMSk7CiAgICB9IGVsc2UgaWYgKGN0eHQtPmRvYyAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0gY3R4dC0+ZG9jOwoJcHJlc2VydmUgPSAxOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RISU5HX1RPX1BBUlNFLAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlLlxuIiwKCQkgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBUaGVuIGV4dHJhY3QgdGhlIHJvb3QgYW5kIFNjaGVtYSBwYXJzZSBpdAogICAgICovCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1JPT1QsCgkJICAgICAgIlRoZSBzY2hlbWEgaGFzIG5vIGRvY3VtZW50IGVsZW1lbnQuXG4iLCBOVUxMLCBOVUxMKTsKCWlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBUaGVuIGRvIHRoZSBwYXJzaW5nIGZvciBnb29kCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVBhcnNlU2NoZW1hKGN0eHQsIHJvb3QpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0LT5kb2MgPSBkb2M7CiAgICByZXQtPnByZXNlcnZlID0gcHJlc2VydmU7CiAgICBjdHh0LT5zY2hlbWEgPSByZXQ7CiAgICBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CiAgICBjdHh0LT5wYXJlbnRJdGVtID0gTlVMTDsKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCBhdHRyaWJ1dGVzIGRlY2xhcmF0aW9ucwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF0dHJGaXh1cCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gZml4dXAgYWxsIGF0dHJpYnV0ZXMgZ3JvdXAgZGVjbGFyYXRpb25zCiAgICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0cmdycERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQXR0ckdycEZpeHVwLAogICAgICAgICAgICAgICAgY3R4dCk7CgogICAgLyoKICAgICogUmVzb2x2ZSBpZGVudGl0eS1jb25zdHJhaW50IGtleVJlZnMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5pZGNEZWYsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hUmVzb2x2ZUlEQ0tleVJlZiwgY3R4dCk7CgogICAgLyoKICAgICogQ2hlY2sgYXR0cmlidXRlIGdyb3VwcyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIAoJeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVHcm91cENpcmN1bGFyLCBjdHh0KTsKCiAgICAvKgogICAgKiBUaGVuIGZpeHVwIGFsbCBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4KICAgICovICAgIAogICAgeG1sSGFzaFNjYW4ocmV0LT5ncm91cERlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hR3JvdXBEZWZGaXh1cCwgY3R4dCk7CiAgICAKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVR5cGVGaXh1cCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gZml4IHJlZmVyZW5jZXMgb2YgZWxlbWVudCBkZWNsYXJhdGlvbjsgYXBwbHkgY29uc3RyYWludHMuCiAgICAgKi8gICAgCiAgICB4bWxIYXNoU2NhbkZ1bGwocmV0LT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrLCBjdHh0KTsKCiAgICAgLyoKICAgICogQ2hlY2sgbW9kZWwgZ3JvdXBzIGRlZm5pdGlvbnMgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5ncm91cERlY2wsICh4bWxIYXNoU2Nhbm5lcikgCgl4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGJ1aWxkIHRoZSBjb250ZW50IG1vZGVsIGZvciBhbGwgY29tcGxleCB0eXBlcwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLAogICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCwgY3R4dCk7CgogICAgLyoKICAgICAqIFRoZW4gY2hlY2sgdGhlIGRlZmF1bHRzIHBhcnQgb2YgdGhlIHR5cGUgbGlrZSBmYWNldHMgdmFsdWVzCiAgICAgKi8KICAgIC8qIE9MRDogeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0RlZmF1bHRzLCBjdHh0KTsgKi8KCiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zL3VzZXMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIsIGN0eHQpOwoKICAgIC8qCiAgICAqIFZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIGVsZW1lbnQgZGVjbGFyYXRpb25zLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+ZWxlbURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyLCBjdHh0KTsKCgogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICB4bWxTY2hlbWFGcmVlKHJldCk7CiAgICAgICAgcmV0ID0gTlVMTDsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBjYWxsYmFjawogKiBAd2FybjogIHRoZSB3YXJuaW5nIGNhbGxiYWNrCiAqIEBjdHg6ICBjb250ZXh0dWFsIGRhdGEgZm9yIHRoZSBjYWxsYmFja3MKICoKICogU2V0IHRoZSBjYWxsYmFjayBmdW5jdGlvbnMgdXNlZCB0byBoYW5kbGUgZXJyb3JzIGZvciBhIHZhbGlkYXRpb24gY29udGV4dAogKi8Kdm9pZAp4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4Owp9CgovKioKICogeG1sU2NoZW1hR2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgWE1sLVNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgY2FsbGJhY2sgcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBjYWxsYmFjayByZXN1bHQKICogQGN0eDogY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzIHJlc3VsdAogKgogKiBHZXQgdGhlIGNhbGxiYWNrIGluZm9ybWF0aW9uIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSBwYXJzZXIgY29udGV4dAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZmFpbHVyZSwgMCBvdGhlcndpc2UKICovCmludCAKeG1sU2NoZW1hR2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCQkJCSB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyAqIGVyciwKCQkJCQkJCSB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4oLTEpOwoJaWYgKGVyciAhPSBOVUxMKQoJCSplcnIgPSBjdHh0LT5lcnJvcjsKCWlmICh3YXJuICE9IE5VTEwpCgkJKndhcm4gPSBjdHh0LT53YXJuaW5nOwoJaWYgKGN0eCAhPSBOVUxMKQoJCSpjdHggPSBjdHh0LT51c2VyRGF0YTsKCXJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nOgogKiBAdHlwZTogIHRoZSBmYWNldCB0eXBlCiAqCiAqIENvbnZlcnQgdGhlIHhtbFNjaGVtYVR5cGVUeXBlIHRvIGEgY2hhciBzdHJpbmcuCiAqCiAqIFJldHVybnMgdGhlIGNoYXIgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmYWNldCB0eXBlIGlmIHRoZQogKiAgICAgdHlwZSBpcyBhIGZhY2V0IGFuZCBhbiAiSW50ZXJuYWwgRXJyb3IiIHN0cmluZyBvdGhlcndpc2UuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpCnsKICAgIHN3aXRjaCAodHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJwYXR0ZXJuIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4RXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWElOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4SW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluRXhjbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluSW5jbHVzaXZlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIndoaXRlU3BhY2UiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImVudW1lcmF0aW9uIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWF4TGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAibWluTGVuZ3RoIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJ0b3RhbERpZ2l0cyIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAiZnJhY3Rpb25EaWdpdHMiKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoQkFEX0NBU1QgIkludGVybmFsIEVycm9yIik7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFuYzsKCiAgICAvKiAKICAgICogVGhlIG5vcm1hbGl6YXRpb24gdHlwZSBjYW4gYmUgY2hhbmdlZCBvbmx5IGZvciB0eXBlcyB3aGljaCBhcmUgZGVyaXZlZCAKICAgICogZnJvbSB4c2Q6c3RyaW5nLgogICAgKi8KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykKCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkUpOwoJZWxzZSBpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfTk9STVNUUklORykKCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfRkFDRVRfUkVQTEFDRSk7CgllbHNlIHsKCSAgICAvKgoJICAgICogRm9yIGFsbCC3YXRvbWljtyBkYXRhdHlwZXMgb3RoZXIgdGhhbiBzdHJpbmcgKGFuZCB0eXBlcyC3ZGVyaXZlZLcgCgkgICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvIAoJICAgICogY29sbGFwc2UKCSAgICAqLwoJICAgIHJldHVybihYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSk7Cgl9CQkgICAJICAgIAogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkvKgoJKiBGb3IgbGlzdCB0eXBlcyB0aGUgZmFjZXQgIndoaXRlU3BhY2UiIGlzIGZpeGVkIHRvICJjb2xsYXBzZSIuIAoJKi8KCXJldHVybiAoWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0UpOwogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJcmV0dXJuIChYTUxfU0NIRU1BU19GQUNFVF9VTktOT1dOKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hVHlwZVB0ciBhbnlTVDsKCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBsaW47CgoJLyoKCSogQXRvbWljIHR5cGVzLgoJKi8KCWFueVNUID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CglhbmMgPSB0eXBlLT5iYXNlVHlwZTsKCWRvIHsKCSAgICAvKgoJICAgICogRm9yIGFsbCC3YXRvbWljtyBkYXRhdHlwZXMgb3RoZXIgdGhhbiBzdHJpbmcgKGFuZCB0eXBlcyC3ZGVyaXZlZLcgCgkgICAgKiBieSC3cmVzdHJpY3Rpb263IGZyb20gaXQpIHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIGlzIGZpeGVkIHRvIAoJICAgICogY29sbGFwc2UKCSAgICAqLwoJICAgIGlmICgoYW5jLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYKCQkoYW5jLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpKSB7CgkJCgkJbGluID0gdHlwZS0+ZmFjZXRTZXQ7CgkJZG8gewoJCSAgICBpZiAobGluLT5mYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQkJcmV0dXJuKGxpbi0+ZmFjZXQtPndoaXRlc3BhY2UpOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBsaW4gPSBsaW4tPm5leHQ7CgkJfSB3aGlsZSAobGluICE9IE5VTEwpOwkKCQlicmVhazsKCSAgICB9CgkgICAgYW5jID0gYW5jLT5iYXNlVHlwZTsKCX0gd2hpbGUgKGFuYyAhPSBhbnlTVCk7CglyZXR1cm4gKFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKTsKICAgIH0gIAogICAgcmV0dXJuICgtMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGhvbGRpbmcgdGhlIGZhY2V0cwogKiBAZmFjZXRzOiAgdGhlIGxpc3Qgb2YgZmFjZXRzIHRvIGNoZWNrCiAqIEB2YWx1ZTogIHRoZSBsZXhpY2FsIHJlcHIgb2YgdGhlIHZhbHVlIHRvIHZhbGlkYXRlCiAqIEB2YWw6ICB0aGUgcHJlY29tcHV0ZWQgdmFsdWUKICogQGZpcmVFcnJvcnM6ICBpZiAwLCBvbmx5IGludGVybmFsIGVycm9ycyB3aWxsIGJlIGZpcmVkOwogKgkJIG90aGVyd2lzZSBhbGwgZXJyb3JzIHdpbGwgYmUgZmlyZWQuCiAqCiAqIENoZWNrIGEgdmFsdWUgYWdhaW5zdCBhbGwgZmFjZXQgY29uZGl0aW9ucwogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwKCQkJCXVuc2lnbmVkIGxvbmcgbGVuZ3RoLAoJCQkJaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hVHlwZVB0ciAgYmlUeXBlOyAvKiBUaGUgYnVpbGQtaW4gdHlwZS4gKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbms7CiAgICBpbnQgcmV0RmFjZXQ7CiAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKICAgIHVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCiNpZmRlZiBERUJVR19VTklPTl9WQUxJREFUSU9OCiAgICBwcmludGYoIkZhY2V0cyBvZiB0eXBlOiAnJXMnXG4iLCAoY29uc3QgY2hhciAqKSB0eXBlLT5uYW1lKTsKICAgIHByaW50ZigiICBmaXJlRXJyb3JzOiAlZFxuIiwgZmlyZUVycm9ycyk7CiNlbmRpZgogICAgICAgIAogICAgbm9kZSA9IGN0eHQtPm5vZGU7CiAgICAvKgogICAgKiBOT1RFOiBEbyBub3QganVtcCBhd2F5LCBpZiB0aGUgZmFjZXRTZXQgb2YgdGhlIGdpdmVuIHR5cGUgaXMKICAgICogZW1wdHk6IHVudGlsIG5vdywgInBhdHRlcm4iIGZhY2V0cyBvZiB0aGUgKmJhc2UgdHlwZXMqIG5lZWQgdG8KICAgICogYmUgY2hlY2tlZCBhcyB3ZWxsLgogICAgKi8KICAgIGJpVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgd2hpbGUgKChiaVR5cGUgIT0gTlVMTCkgJiYgKGJpVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKQoJYmlUeXBlID0gYmlUeXBlLT5iYXNlVHlwZTsKICAgIGlmIChiaVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwJCSAgICAKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCSAgICAidGhlIGJhc2UgdHlwZSBheGlzIG9mIHRoZSBnaXZlbiB0eXBlICclcycgZG9lcyBub3QgcmVzb2x2ZSB0byAiCgkgICAgImEgYnVpbHQtaW4gdHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CQoJcmV0dXJuICgtMSk7CiAgICB9ICAgIAogICAgCiAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7Cgl3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgLyoKCSAgICAqIFNraXAgdGhlIHBhdHRlcm4gIndoaXRlU3BhY2UiOiBpdCBpcyB1c2VkIHRvIAoJICAgICogZm9ybWF0IHRoZSBjaGFyYWN0ZXIgY29udGVudCBiZWZvcmVoYW5kLgoJICAgICovCSAgICAKCSAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgoJCSAgICBicmVhazsKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDogCgkJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTGlzdFNpbXBsZVR5cGVGYWNldChmYWNldCwKCQkJICAgIHZhbHVlLCBsZW5ndGgsIDApOwoJCQlsZW4gPSBsZW5ndGg7CgkJICAgIH0gZWxzZQoJCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxlbmd0aEZhY2V0KGJpVHlwZSwgZmFjZXQsCgkJCSAgICB2YWx1ZSwgY3R4dC0+dmFsdWUsICZsZW4pOwoJCSAgICBicmVhazsKCQlkZWZhdWx0OgoJCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXQsIHZhbHVlLCAKCQkJY3R4dC0+dmFsdWUpOwoJICAgIH0KCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldCBvZiB0eXBlICclcycuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQlicmVhazsKCSAgICB9IGVsc2UgaWYgKChyZXQgPiAwKSAmJiAoZmlyZUVycm9ycykpIHsKCQl4bWxTY2hlbWFWRmFjZXRFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgbGVuLAoJCSAgICB0eXBlLCBmYWNldCwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoKCSAgICBmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQ7Cgl9CglpZiAocmV0ID49IDApIHsKCSAgICAvKgoJICAgICogUHJvY2VzcyBlbnVtZXJhdGlvbnMuCgkgICAgKi8KCSAgICByZXRGYWNldCA9IDA7CgkgICAgZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CgkgICAgd2hpbGUgKGZhY2V0TGluayAhPSBOVUxMKSB7CgkJaWYgKGZhY2V0TGluay0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikgewoJCSAgICByZXRGYWNldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmlUeXBlLCBmYWNldExpbmstPmZhY2V0LCAKCQkJdmFsdWUsIGN0eHQtPnZhbHVlKTsJCQoJCSAgICBpZiAocmV0RmFjZXQgPD0gMCkKCQkJYnJlYWs7CgkJfQoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsKCSAgICB9CgkgICAgaWYgKHJldEZhY2V0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRDsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwKCQkJdmFsdWUsIDAsIHR5cGUsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0RmFjZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0IG9mIHR5cGUgJyVzJy5cbiIsCgkJICAgIEJBRF9DQVNUICJlbnVtZXJhdGlvbiIsIE5VTEwpOwoJCSAgICByZXQgPSAtMTsJCQoJICAgIH0JCQoJfQogICAgfQogICAgaWYgKHJldCA+PSAwKSB7CgkvKgoJKiBQcm9jZXNzIHBhdHRlcnMuIFBhdHRlcm4gZmFjZXRzIGFyZSBPUmVkIGF0IHR5cGUgbGV2ZWwgCgkqIGFuZCBBTkRlZCBpZiBkZXJpdmVkLiBXYWxrIHRoZSBiYXNlIHR5cGUgYXhpcy4KCSovCgl0bXBUeXBlID0gdHlwZTsKCWZhY2V0ID0gTlVMTDsKCWRvIHsKCSAgICByZXRGYWNldCA9IDA7CgkgICAgZm9yIChmYWNldExpbmsgPSB0bXBUeXBlLT5mYWNldFNldDsgZmFjZXRMaW5rICE9IE5VTEw7IAoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dCkgewoJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikKCQkgICAgY29udGludWU7CgkJcmV0RmFjZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgCgkJICAgIHZhbHVlLCBjdHh0LT52YWx1ZSk7CgkJaWYgKHJldEZhY2V0ID09IDApIAoJCSAgICBicmVhazsKCQllbHNlIGlmIChyZXRGYWNldCA8IDApIHsKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkJCSJ2YWxpZGF0aW5nICdwYXR0ZXJuJyBmYWNldCAnJXMnIG9mIHR5cGUgJyVzJy5cbiIsCgkJCWZhY2V0TGluay0+ZmFjZXQtPnZhbHVlLCB0bXBUeXBlLT5uYW1lKTsKCQkgICAgcmV0ID0gLTE7CgkJICAgIGJyZWFrOwoJCX0gZWxzZQoJCSAgICAvKiBTYXZlIHRoZSBsYXN0IG5vbi12YWxpZGF0aW5nIGZhY2V0LiAqLwoJCSAgICBmYWNldCA9IGZhY2V0TGluay0+ZmFjZXQ7CgkgICAgfQoJICAgIGlmIChyZXRGYWNldCAhPSAwKQoJCWJyZWFrOwkJICAgIAoJICAgIHRtcFR5cGUgPSB0bXBUeXBlLT5iYXNlVHlwZTsKCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJaWYgKHJldEZhY2V0ID4gMCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19QQVRURVJOX1ZBTElEOwoJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIDAsIHR5cGUsIGZhY2V0LCAKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfQogICAgfQkgICAgCiAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU2ltcGxlIHR5cGUgdmFsaWRhdGlvbgkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJRE9NIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkJICBpbnQgaXNOaWwsCgkJCQkJICBpbnQgdmFsU2ltcGxlQ29udGVudCk7CgpzdGF0aWMgdm9pZCB4bWxTY2hlbWFCZWdpbkVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KTsKc3RhdGljIGludCB4bWxTY2hlbWFFbmRFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCk7CgojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKLyoqCiAqIHhtbFNjaGVtYUdldEZyZXNoRWxlbUluZm86CiAqIEB2Y3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQ3JlYXRlcy9yZXVzZXMgYW5kIGluaXRpYWxpemVzIHRoZSBlbGVtZW50IGluZm8gaXRlbSBmb3IgCiAqIHRoZSBjdXJyZWN0IHRyZWUgZGVwdGguCiAqCiAqIFJldHVybnMgdGhlIGVsZW1lbnQgaW5mbyBpdGVtIG9yIE5VTEwgb24gQVBJIG9yIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFFbGVtSW5mb1B0cgp4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICBpbnQgZGVwdGgpCnsKICAgIHhtbFNjaGVtYUVsZW1JbmZvUHRyIGluZm8gPSBOVUxMOwogICAgCiAgICBpZiAoZGVwdGggPiB2Y3R4dC0+c2l6ZUVsZW1JbmZvcykgewoJeG1sU2NoZW1hVkVycih2Y3R4dCwgTlVMTCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvLCAiCgkgICAgImFuIGluY29uc2lzdGVudCBkZXB0aCBlbmNvdW50ZXJlZC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewkKCXZjdHh0LT5lbGVtSW5mb3MgPSAoeG1sU2NoZW1hRWxlbUluZm9QdHIgKikgCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYUVsZW1JbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgdGhlIGVsZW1lbnQgaW5mbyBhcnJheSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgltZW1zZXQodmN0eHQtPmVsZW1JbmZvcywgMCwgMTAgKiBzaXplb2YoeG1sU2NoZW1hRWxlbUluZm9QdHIpKTsKCXZjdHh0LT5zaXplRWxlbUluZm9zID0gMTA7CiAgICB9IGVsc2UgaWYgKHZjdHh0LT5zaXplRWxlbUluZm9zID09IHZjdHh0LT5kZXB0aCkgewoJaW50IGkgPSB2Y3R4dC0+c2l6ZUVsZW1JbmZvczsKCgl2Y3R4dC0+c2l6ZUVsZW1JbmZvcyAqPSAyOwoJdmN0eHQtPmVsZW1JbmZvcyA9ICh4bWxTY2hlbWFFbGVtSW5mb1B0ciAqKSAKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5lbGVtSW5mb3MsIHZjdHh0LT5zaXplRWxlbUluZm9zICogCgkgICAgc2l6ZW9mKHhtbFNjaGVtYUVsZW1JbmZvUHRyKSk7CglpZiAodmN0eHQtPmVsZW1JbmZvcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJInJlLWFsbG9jYXRpbmcgdGhlIGVsZW1lbnQgaW5mbyBhcnJheSIsIE5VTEwpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CgkvKgoJKiBXZSBuZWVkIHRoZSBuZXcgbWVtb3J5IHRvIGJlIE5VTExlZC4KCSogVE9ETzogVXNlIG1lbXNldCBpbnN0ZWFkPwoJKi8KCWZvciAoOyBpIDwgdmN0eHQtPnNpemVFbGVtSW5mb3M7IGkrKykKCSAgICB2Y3R4dC0+ZWxlbUluZm9zW2ldID0gTlVMTDsKICAgIH0gZWxzZQoJaW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbZGVwdGhdOwoKICAgIGlmIChpbmZvID09IE5VTEwpIHsKCWluZm8gPSAoeG1sU2NoZW1hRWxlbUluZm9QdHIpIAoJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbUluZm8pKTsKCWlmIChpbmZvID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiYWxsb2NhdGluZyBhbiBlbGVtZW50IGluZm8iLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQkKCXZjdHh0LT5lbGVtSW5mb3NbZGVwdGhdID0gaW5mbzsKICAgIH0KICAgIG1lbXNldChpbmZvLCAwLCBzaXplb2YoeG1sU2NoZW1hRWxlbUluZm8pKTsKICAgIGluZm8tPmRlcHRoID0gZGVwdGg7CiAgCiAgICByZXR1cm4gKGluZm8pOwp9CiNlbmRpZiAvKiBFTEVNX0lORk9fRU5BQkxFRCAqLwoKCi8qKgogKiB4bWxTY2hlbWFGcmVlQXR0clN0YXRlczoKICogQHN0YXRlOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZSBzdGF0ZXMKICoKICogRnJlZSB0aGUgZ2l2ZW4gbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBzdGF0ZSkKewogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKICAgIHdoaWxlIChzdGF0ZSAhPSBOVUxMKSB7Cgl0bXAgPSBzdGF0ZTsKCXN0YXRlID0gc3RhdGUtPm5leHQ7CQoJeG1sRnJlZSh0bXApOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAYXR0cnM6ICBhIGxpc3Qgb2YgYXR0cmlidXRlcwogKgogKiBSZWdpc3RlciB0aGUgbGlzdCBvZiBhdHRyaWJ1dGVzIGFzIHRoZSBzZXQgdG8gYmUgdmFsaWRhdGVkIG9uIHRoYXQgZWxlbWVudAogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgb3RoZXJ3aXNlCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sQXR0clB0ciBhdHRycykKewogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCiAgICBjdHh0LT5hdHRyID0gTlVMTDsKICAgIGN0eHQtPmF0dHJUb3AgPSBOVUxMOwogICAgd2hpbGUgKGF0dHJzICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHJzLT5ucyAhPSBOVUxMKSAmJgogICAgICAgICAgICAoeG1sU3RyRXF1YWwoYXR0cnMtPm5zLT5ocmVmLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkpIHsKICAgICAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwoJaWYgKHRtcCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgYXR0cmlidXRlcyIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdG1wLT5hdHRyID0gYXR0cnM7Cgl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOOwoJdG1wLT5uZXh0ID0gTlVMTDsKCXRtcC0+ZGVjbCA9IE5VTEw7CglpZiAoY3R4dC0+YXR0ciA9PSBOVUxMKSAKICAgICAgICAgICAgY3R4dC0+YXR0ciA9IHRtcDsKCWVsc2UKCSAgICBjdHh0LT5hdHRyVG9wLT5uZXh0ID0gdG1wOwoJY3R4dC0+YXR0clRvcCA9IHRtcDsKICAgICAgICBhdHRycyA9IGF0dHJzLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKI2lmIDAgLyogQ3VycmVudGx5IG5vdCB1c2VkICovCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QKICogQG5vZGVsaXN0OiB0aGUgbGlzdCBvZiBub2RlcwogKgogKiBDaGVjayB0aGUgbm9kZSBsaXN0IGlzIG9ubHkgbWFkZSBvZiB0ZXh0IG5vZGVzIGFuZCBlbnRpdGllcyBwb2ludGluZwogKiB0byB0ZXh0IG5vZGVzCiAqCiAqIFJldHVybnMgMSBpZiB0cnVlLCAwIGlmIGZhbHNlIGFuZCAtMSBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdCh4bWxOb2RlUHRyIG5vZGVsaXN0KQp7CiAgICB3aGlsZSAobm9kZWxpc3QgIT0gTlVMTCkgewogICAgICAgIGlmIChub2RlbGlzdC0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSB7CiAgICAgICAgICAgIFRPRE8gICAgICAgICAgICAgICAgLyogaW1wbGVtZW50IHJlY3Vyc2lvbiBpbiB0aGUgZW50aXR5IGNvbnRlbnQgKi8KICAgICAgICB9CiAgICAgICAgaWYgKChub2RlbGlzdC0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX0NPTU1FTlRfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9QSV9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKICAgICAgICAgICAgcmV0dXJuICgwKTsKICAgICAgICB9CiAgICAgICAgbm9kZWxpc3QgPSBub2RlbGlzdC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMSk7Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQb3N0U2NoZW1hQXNzZW1ibGVGaXh1cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIGludCBpLCBuYkl0ZW1zOwogICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLCAqaXRlbXM7CgoKICAgIC8qCiAgICAqIER1cmluZyB0aGUgQXNzZW1ibGUgb2YgdGhlIHNjaGVtYSBjdHh0LT5jdXJJdGVtcyBoYXMKICAgICogYmVlbiBmaWxsZWQgd2l0aCB0aGUgcmVsZXZhbnQgbmV3IGl0ZW1zLiBGaXggdGhvc2UgdXAuCiAgICAqLwogICAgbmJJdGVtcyA9IGN0eHQtPmFzc2VtYmxlLT5uYkl0ZW1zOwogICAgaXRlbXMgPSAoeG1sU2NoZW1hVHlwZVB0ciAqKSBjdHh0LT5hc3NlbWJsZS0+aXRlbXM7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQl4bWxTY2hlbWFBdHRyRml4dXAoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLCBjdHh0LCAKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJeG1sU2NoZW1hQXR0ckdycEZpeHVwKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSwgCgkJICAgIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCXhtbFNjaGVtYUdyb3VwRGVmRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7ICAgICAgICAgICAgCgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIC8qCiAgICAqIENpcmN1bGFyaXR5IGNoZWNrcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJICAgIAoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJCXhtbFNjaGVtYUNoZWNrR3JvdXBEZWZDaXJjdWxhcihpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKCQl4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIoCgkJICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIC8qCiAgICAqIEZpeHVwIGZvciBhbGwgb3RoZXIgaXRlbS4gCiAgICAqIFRPRE86IEhtbSwgbm90IHN1cmUgaWYgc3RhcnRpbmcgZnJvbSBjb21wbGV4L3NpbXBsZSB0eXBlcywKICAgICogYWxsIHN1YnNlcXVlbnQgaXRlbXMgd2lsbCBiZSByZWFjaGVkLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewkgICAgCiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQogICAgLyoKICAgICogQ2hlY2sgZmFjZXQgdmFsdWVzLiBOb3RlIHRoYXQgZmFjZXRzIGFyZQogICAgKiBob2xkIGJ5IHNpbXBsZSB0eXBlIGNvbXBvbmVudHMgb25seSAoYW5kCiAgICAqIGJ5IGNvbXBsZXggdHlwZXMgaW4gdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24pLgogICAgKi8KICAgIC8qIE9MRDogCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJIAoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgICovCiAgICAvKgogICAgKiBCdWlsZCB0aGUgY29udGVudCBtb2RlbCBmb3IgY29tcGxleCB0eXBlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJICAgIAoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CgkJeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0gCiAgICAvKgogICAgKiBWYWxpZGF0ZSB2YWx1ZSBjb250cmFpbnQgdmFsdWVzLgogICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBuYkl0ZW1zOyBpKyspIHsKCWl0ZW0gPSBpdGVtc1tpXTsKCXN3aXRjaCAoaXRlbS0+dHlwZSkgewoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCQl4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIoKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKCQl4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHIoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb246CiAqIEBwY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiB0aGUgZXhpc3Rpbmcgc2NoZW1hCiAqIEBub2RlOiB0aGUgbm9kZSB0aGF0IGZpcmVkIHRoZSBhc3NlbWJsaW5nCiAqIEBuc05hbWU6IHRoZSBuYW1lc3BhY2UgbmFtZSBvZiB0aGUgbmV3IHNjaGVtYQogKiBAbG9jYXRpb246IHRoZSBsb2NhdGlvbiBvZiB0aGUgc2NoZW1hCiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAkJCSAgICAKCQkJICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCSAgICB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpuc05hbWUsCgkJCSAgICBjb25zdCB4bWxDaGFyICpsb2NhdGlvbikKewogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TnMsICpvbGR0bnM7IAogICAgeG1sRG9jUHRyIGRvYywgb2xkZG9jOwogICAgaW50IG9sZGZsYWdzLCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBkb2NFbGVtOwogICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBwY3R4dDsKCiAgICAvKgogICAgKiBUaGlzIHNob3VsZCBiZSB1c2VkOgogICAgKiAxLiBvbiA8aW1wb3J0PihzKQogICAgKiAyLiBpZiByZXF1ZXN0ZWQgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSAKICAgICogMy4gaWYgcmVxdWVzdGVkIHZpYSB0aGUgQVBJCiAgICAqLwogICAgaWYgKCh2Y3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CiAgICAvKgogICAgKiBDcmVhdGUgYSB0ZW1wb3JhcnkgcGFyc2VyIGNvbnRleHQuCiAgICAqLwogICAgaWYgKCh2Y3R4dC0+cGN0eHQgPT0gTlVMTCkgJiYKCSh4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQodmN0eHQpID09IC0xKSkgewoJeG1sU2NoZW1hVkVycih2Y3R4dCwgbm9kZSwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiwgIgoJICAgICJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQuXG4iLCAKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwkJCiAgICB9ICAgICAgICAgICAgCiAgICBwY3R4dCA9IHZjdHh0LT5wY3R4dDsKICAgIC8qCiAgICAqIFNldCB0aGUgY291bnRlciB0byBwcm9kdWNlIHVuaXF1ZSBuYW1lcyBmb3IgYW5vbnltb3VzIGl0ZW1zLgogICAgKi8KICAgIHBjdHh0LT5jb3VudGVyID0gc2NoZW1hLT5jb3VudGVyOyAgICAKICAgIC8qCiAgICAqIEFjcXVpcmUgdGhlIHNjaGVtYSBkb2N1bWVudC4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFBY3F1aXJlU2NoZW1hRG9jKHBjdHh0LCBzY2hlbWEsIG5vZGUsCgluc05hbWUsIGxvY2F0aW9uLCAmZG9jLCAmdGFyZ2V0TnMsIDApOwogICAgaWYgKHJldCAhPSAwKSB7CglpZiAoZG9jICE9IE5VTEwpCgkgICAgeG1sRnJlZURvYyhkb2MpOwogICAgfSBlbHNlIGlmIChkb2MgIT0gTlVMTCkgewoJZG9jRWxlbSA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CgkvKgoJKiBDcmVhdGUgbmV3IGFzc2VtYmxlIGluZm8uCgkqLwoJaWYgKHBjdHh0LT5hc3NlbWJsZSA9PSBOVUxMKSB7CgkgICAgcGN0eHQtPmFzc2VtYmxlID0geG1sU2NoZW1hTmV3QXNzZW1ibGUoKTsKCSAgICBpZiAocGN0eHQtPmFzc2VtYmxlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkgICAgIk1lbW9yeSBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uLCAiCgkJICAgICJhbGxvY2F0aW5nIGFzc2VtYmxlIGluZm8iLCBOVUxMKTsKCQl4bWxGcmVlRG9jKGRvYyk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJLyoKCSogU2F2ZSBhbmQgcmVzZXQgdGhlIGNvbnRleHQgJiBzY2hlbWEuCgkqLwoJb2xkZmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwoJb2xkdG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CglvbGRkb2MgPSBzY2hlbWEtPmRvYzsKCQoJeG1sU2NoZW1hQ2xlYXJTY2hlbWFEZWZhdWx0cyhzY2hlbWEpOwoJc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSB0YXJnZXROczsKCS8qIHNjaGVtYS0+bmJDdXJJdGVtcyA9IDA7ICovCglwY3R4dC0+c2NoZW1hID0gc2NoZW1hOwoJcGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKCXBjdHh0LT5wYXJlbnRJdGVtID0gTlVMTDsKCQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFEZWZhdWx0cyhwY3R4dCwgc2NoZW1hLCBkb2NFbGVtKTsJCQoJeG1sU2NoZW1hUGFyc2VTY2hlbWFUb3BMZXZlbChwY3R4dCwgc2NoZW1hLCBkb2NFbGVtLT5jaGlsZHJlbik7Cgl4bWxTY2hlbWFQb3N0U2NoZW1hQXNzZW1ibGVGaXh1cChwY3R4dCk7CgkvKgoJKiBTZXQgdGhlIGNvdW50ZXIgb2YgaXRlbXMuCgkqLwoJc2NoZW1hLT5jb3VudGVyID0gcGN0eHQtPmNvdW50ZXI7CgkvKgoJKiBGcmVlIHRoZSBsaXN0IG9mIGFzc2VtYmxlZCBjb21wb25lbnRzLgoJKi8KCXBjdHh0LT5hc3NlbWJsZS0+bmJJdGVtcyA9IDA7CgkvKgoJKiBSZXN0b3JlIHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCXNjaGVtYS0+ZmxhZ3MgPSBvbGRmbGFnczsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gb2xkdG5zOwoJc2NoZW1hLT5kb2MgPSBvbGRkb2M7CglyZXQgPSBwY3R4dC0+ZXJyOwogICAgfSAgICAgICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0cjoKICogQHZjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB4c2lBdHRyOiBhbiB4c2kgYXR0cmlidXRlCiAqIEBub05hbWVzcGFjZTogd2hldGhlciBhIHNjaGVtYSB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UgaXMgZXhwdGVjdGVkCiAqCiAqIEV4cGFuZHMgYW4gZXhpc3Rpbmcgc2NoZW1hIGJ5IGFuIGFkZGl0aW9uYWwgc2NoZW1hIHVzaW5nCiAqIHRoZSB4c2k6c2NoZW1hTG9jYXRpb24gb3IgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gYXR0cmlidXRlCiAqIG9mIGFuIGluc3RhbmNlLiBJZiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBpcyB1c2VkLCBAbm9OYW1lc3BhY2UKICogbXVzdCBiZSBzZXQgdG8gMS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgeG1sQXR0clB0ciB4c2lBdHRyLAoJCQkgaW50IG5vTmFtZXNwYWNlKQp7CiAgICB4bWxDaGFyICp2YWx1ZTsKICAgIGNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKICAgIGNvbnN0IHhtbENoYXIgKm5zbmFtZSA9IE5VTEwsICpsb2NhdGlvbjsKICAgIGludCBjb3VudCA9IDA7CiAgICBpbnQgcmV0ID0gMDsKICAgIAogICAgaWYgKHhzaUF0dHIgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJICAgIE5VTEwsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0ciwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIFBhcnNlIHRoZSB2YWx1ZTsgd2Ugd2lsbCBhc3N1bWUgYW4gZXZlbiBudW1iZXIgb2YgdmFsdWVzCiAgICAqIHRvIGJlIGdpdmVuICh0aGlzIGlzIGhvdyBYZXJjZXMgYW5kIFhTViB3b3JrKS4KICAgICovCiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KCh4bWxOb2RlUHRyKSB4c2lBdHRyKTsgICAgCiAgICBjdXIgPSB2YWx1ZTsKICAgIGRvIHsJCglpZiAobm9OYW1lc3BhY2UgIT0gMSkgewoJICAgIC8qCgkgICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBuYW1lLgoJICAgICovCgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICBjb3VudCsrOwoJICAgIG5zbmFtZSA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwkJCgkgICAgY3VyID0gZW5kOwoJfQoJLyoKCSogR2V0IHRoZSBVUkkuCgkqLwoJd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJICAgIGN1cisrOwoJZW5kID0gY3VyOwoJd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkgICAgZW5kKys7CglpZiAoZW5kID09IGN1cikKCSAgICBicmVhazsKCWNvdW50Kys7Cglsb2NhdGlvbiA9IHhtbERpY3RMb29rdXAodmN0eHQtPnNjaGVtYS0+ZGljdCwgY3VyLCBlbmQgLSBjdXIpOwoJY3VyID0gZW5kOwkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbih2Y3R4dCwgdmN0eHQtPnNjaGVtYSwgCgkgICAgeHNpQXR0ci0+cGFyZW50LCBuc25hbWUsIGxvY2F0aW9uKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKHZjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkoeG1sTm9kZVB0cikgeHNpQXR0ciwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyLCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hdGEiLCBOVUxMKTsKCSAgICBpZiAodmFsdWUgIT0gTlVMTCkKCQl4bWxGcmVlKHZhbHVlKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0gd2hpbGUgKCpjdXIgIT0gMCk7CiAgICBpZiAodmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUodmFsdWUpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW06CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogYW4gZWxlbWVudCBub2RlIHBvc3NpYmx5IGhvbGRpbmcgeHNpIGF0dHJpYnV0ZXMKICogQG5vTmFtZXNwYWNlOiB3aGV0aGVyIGEgc2NoZW1hIHdpdGggbm8gdGFyZ2V0IG5hbWVzcGFjZSBpcyBleHB0ZWN0ZWQKICoKICogQXNzZW1ibGVzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZXMKICogb2YgdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIG5ldyBzY2hlbWEgaXMgY29ycmVjdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsICAKCQkJIHhtbE5vZGVQdHIgZWxlbSkKeyAgICAKICAgIGludCByZXQgPSAwLCByZXROcyA9IDA7CiAgICB4bWxBdHRyUHRyIGF0dHI7CgogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJldE5zID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDApOwoJaWYgKHJldE5zID09IC0xKQoJICAgIHJldHVybiAoLTEpOwogICAgfQogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIsIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIodmN0eHQsIGF0dHIsIDEpOwoJaWYgKHJldCA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChyZXROcyAhPSAwKQoJcmV0dXJuIChyZXROcyk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGRldGVjdGVkIChtaWdodCBiZSBOVUxMKQogKiBAdHlwZTogIHRoZSB0eXBlCiAqCiAqIEEgdHJhbnNpdGlvbiBoYXMgYmVlbiBtYWRlIGluIHRoZSBhdXRvbWF0YSBhc3NvY2lhdGVkIHRvIGFuIGVsZW1lbnQKICogY29udGVudCBtb2RlbAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgeG1sTm9kZVB0ciBvbGRub2RlID0gY3R4dC0+bm9kZTsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazogJXMsICVzLCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLT5uYW1lLCBub2RlLT5uYW1lKTsKI2VuZGlmCiAgICAvKgogICAgKiBAdHlwZS0+dHlwZSB3aWxsIGJlIFhNTF9TQ0hFTUFfVFlQRV9BTlkgb3IgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQuCiAgICAqLwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICBjdHh0LT5ub2RlID0gbm9kZTsgICAgCiAgICBjdHh0LT5jdXIgPSBub2RlLT5jaGlsZHJlbjsKCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAogICAgeG1sU2NoZW1hQmVnaW5FbGVtZW50KGN0eHQpOwojZW5kaWYKCiAgICAvKgogICAgKiBBc3NlbWJsZSBuZXcgc2NoZW1hdGEgdXNpbmcgeHNpLgogICAgKi8KICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewoJaW50IHJldDsKCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbShjdHh0LCBjdHh0LT5ub2RlKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYSBieSB4c2kiLCBOVUxMKTsKCSAgICBnb3RvIGxlYXZlOwoJfQoJLyoKCSogTk9URTogV2Ugd29uJ3QgcmVhY3Qgb24gc2NoZW1hIHBhcnNlciBlcnJvcnMgaGVyZS4KCSogVE9ETzogQnV0IGEgd2FybmluZyB3b3VsZCBiZSBuaWNlLgoJKi8KICAgIH0gICAgCiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6IHsKCSAgICAvKgoJICAgICogTk9URTogVGhlIGJ1aWxkIG9mIHRoZSBjb250ZW50IG1vZGVsIAoJICAgICogKHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCkgZW5zdXJlcyB0aGF0IHRoZSBlbGVtZW50IAoJICAgICogZGVjbGFyYXRpb24gKGFuZCBub3QgYSByZWZlcmVuY2UgdG8gaXQpIHdpbGwgYmUgZ2l2ZW4uCgkgICAgKi8KCSAgICBpZiAoKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBjdHh0LT50eXBlKS0+cmVmICE9IE5VTEwpIHsKCQkvKgoJCSogVGhpcyBpcyBwYXJhbm9pZCBjb2RpbmcgOy0pLi4uIGl0IHNob3VsZCBub3QKCQkqIGhhcHBlbiBoZXJlIGFueSBtb3JlLgoJCSovCgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSAgICBub2RlLCBOVUxMLAkJCQkJCQoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2ssICIKCQkgICAgImVsZW1lbnQgZGVjbGFyYXRpb24gJ3JlZmVyZW5jZScgZW5jb3VudGVyZWQsICIKCQkgICAgImJ1dCBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIHdhcyBleHBlY3RlZCIsIAoJCSAgICBOVUxMKTsKCQlnb3RvIGxlYXZlOwoJICAgIH0KCSAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIAoJCSh4bWxTY2hlbWFFbGVtZW50UHRyKSB0eXBlKTsKCSAgICBicmVhazsKCX0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CgkgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZChjdHh0LCB0eXBlKTsKICAgICAgICAgICAgYnJlYWs7CglkZWZhdWx0OiAKCSAgICBicmVhazsKICAgIH0KbGVhdmU6CgojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIHhtbFNjaGVtYUVuZEVsZW1lbnQoY3R4dCk7CiNlbmRpZgogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKfSAgCgpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAKCQkJICBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJICB4bWxTY2hlbWFWYWxQdHIgKnZhbCwKCQkJICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCByZXQ7CiAgICAgICAgCiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgIT0gMCkKCXJldHVybiAocmV0KTsKCiAgICB7Cgl4bWxDaGFyICp1cmkgPSBOVUxMOwoJeG1sQ2hhciAqbG9jYWwgPSBOVUxMOwoJeG1sQ2hhciAqcHJlZml4OwoJCglsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIHhtbE5zUHRyIG5zOwoKCSAgICAvKgoJICAgICogVE9ETzogTWFrZSB0aGlzIHN0cmVhbWFibGUuCgkgICAgKi8KCSAgICBpZiAoKG5vZGUgPT0gTlVMTCkgfHwgKG5vZGUtPmRvYyA9PSBOVUxMKSkgewogICAgCQl4bWxGcmVlKHByZWZpeCk7CgkJeG1sRnJlZShsb2NhbCk7CgkJcmV0dXJuICgzKTsKCSAgICB9CgkgICAgCgkgICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CgkgICAgaWYgKG5zID09IE5VTEwpIHsKCQl4bWxGcmVlKHByZWZpeCk7CgkJeG1sRnJlZShsb2NhbCk7CgkJcmV0dXJuICgxKTsKCSAgICB9Cgl9CQoJaWYgKHByZWZpeCAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbEhhc2hMb29rdXAyKHZjdHh0LT5zY2hlbWEtPm5vdGFEZWNsLCBsb2NhbCwgdXJpKSA9PSBOVUxMKQoJCXJldCA9IDE7Cgl9IGVsc2UgaWYgKHhtbEhhc2hMb29rdXAyKHZjdHh0LT5zY2hlbWEtPm5vdGFEZWNsLCB2YWx1ZSwKCSAgICBOVUxMKSA9PSBOVUxMKQoJICAgIHJldCA9IDE7CgoJaWYgKChyZXQgPT0gMCkgJiYgKHZhbCAhPSBOVUxMKSkgewoJICAgIGlmIChwcmVmaXggIT0gTlVMTCkgewoJCSgqdmFsKSA9IHhtbFNjaGVtYU5ld05PVEFUSU9OVmFsdWUoQkFEX0NBU1QgbG9jYWwsCgkJICAgIEJBRF9DQVNUIHhtbFN0cmR1cCh1cmkpKTsKCQlsb2NhbCA9IE5VTEw7CgkgICAgfSBlbHNlIAoJCSgqdmFsKSA9IHhtbFNjaGVtYU5ld05PVEFUSU9OVmFsdWUoQkFEX0NBU1QgeG1sU3RyZHVwKHZhbHVlKSwKCQlOVUxMKTsKCSAgICBpZiAoKnZhbCA9PSBOVUxMKQoJCXJldCA9IC0xOwoJfQoJaWYgKGxvY2FsICE9IE5VTEwpCgkgICAgeG1sRnJlZShsb2NhbCk7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB2YWx1ZTogdGhlIHZhbHVlIHRvIGJlIHZhbGlkYXRlZAogKiBAZmlyZUVycm9yczogc2hhbGwgZXJyb3JzIGJlIHJlcG9ydGVkPwogKiBAYXBwbHlGYWNldHM6IHNoYWxsIGZhY2V0cyBiZSBhcHBsaWVkPwogKiBAbm9ybWFsaXplOiBzaGFsbCB0aGUgdmFsdWUgYmUgbm9ybWFsaXplZD8KICogQGNoZWNrTm9kZXM6IHNoYWxsIHRoZSBjb250ZW50IG5vZGVzIGJlIGNoZWNrZWQ/CiAqCiAqIFZhbGlkYXRlcyBhIHZhbHVlIGJ5IHRoZSBnaXZlbiB0eXBlICh1c2VyIGRlcml2ZWQgb3IgYnVpbHQtaW4pLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgY29uc3QgeG1sQ2hhciAqdmFsdWUsCQkJCSAKCQkJCSBpbnQgZmlyZUVycm9ycywJCQkJIAoJCQkJIGludCBhcHBseUZhY2V0cywKCQkJCSBpbnQgbm9ybWFsaXplLAoJCQkJIGludCBjaGVja05vZGVzKQp7CiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICBpbnQgcmV0ID0gMDsgIAogICAgeG1sQ2hhciAqbm9ybVZhbHVlID0gTlVMTDsKICAgIGludCB3dHNwOyAgICAgICAKIAogICAgbm9kZSA9IGN0eHQtPm5vZGU7CiAgICAvKiBTYXZlIHRoZSBjdXJyZW50IHdoaXRlc3BhY2Ugbm9ybWFsaXphdGlvbiB0eXBlLiAqLwogICAgd3RzcCA9IGN0eHQtPnZhbHVlV1M7CiAgICAvKgogICAgKiBOb3JtYWxpemUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmIChub3JtYWxpemUgJiYgCgkoY3R4dC0+dmFsdWVXUyAhPSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSkpIHsKCWludCBub3JtID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUodHlwZSk7CgkKCWlmICgobm9ybSAhPSAtMSkgJiYgKG5vcm0gPiBjdHh0LT52YWx1ZVdTKSkgewoJICAgIGlmIChub3JtID09IFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKQoJCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYUNvbGxhcHNlU3RyaW5nKHZhbHVlKTsKCSAgICBlbHNlCgkJbm9ybVZhbHVlID0geG1sU2NoZW1hV2hpdGVTcGFjZVJlcGxhY2UodmFsdWUpOwoJICAgIGN0eHQtPnZhbHVlV1MgPSBub3JtOwoJICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQl2YWx1ZSA9IChjb25zdCB4bWxDaGFyICopIG5vcm1WYWx1ZTsKCX0JCQogICAgfSAgICAKICAgIC8qCiAgICAqIFRoZSBub2RlcyBvZiBhIGNvbnRlbnQgbXVzdCBiZSBjaGVja2VkIG9ubHkgb25jZSwKICAgICogdGhpcyBpcyBub3Qgd29ya2luZyBzaW5jZSBsaXN0IHR5cGVzIHdpbGwgZmlyZSB0aGlzCiAgICAqIG11bHRpcGxlIHRpbWVzLgogICAgKi8KICAgIGlmICgoY2hlY2tOb2RlcyA9PSAxKSAmJiAoY3R4dC0+Y3VyICE9IE5VTEwpKSB7Cgl4bWxOb2RlUHRyIGN1ciA9IGN0eHQtPmN1cjsKCglkbyB7CgkgICAgc3dpdGNoIChjdXItPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9URVhUX05PREU6CgkgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgoJICAgIGNhc2UgWE1MX1BJX05PREU6CgkgICAgY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX1hJTkNMVURFX1NUQVJUOgoJICAgIGNhc2UgWE1MX1hJTkNMVURFX0VORDoKCQlicmVhazsKCSAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CgkgICAgY2FzZSBYTUxfRU5USVRZX05PREU6CgkJLyogVE9ETzogU2NvdXIgdGhlIGVudGl0aWVzIGZvciBpbGxlZ2FsIG5vZGVzLiAqLwoJCVRPRE8gYnJlYWs7CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOiB7CgkgICAgLyogTk9URTogQ2hhbmdlZCB0byBhbiBpbnRlcm5hbCBlcnJvciwgc2luY2UgdGhlIAoJICAgICogZXhpc3RlbmNlIG9mIGFuIGVsZW1lbnQgbm9kZSB3aWxsIGJlIGFscmVhZHkgY2hlY2tlZCBpbgoJICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlIGFuZCBpbgoJICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZS4KCQkqLwoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sICovCgkJICAgIG5vZGUsIHR5cGUsCgkJICAgICJFbGVtZW50ICclcycgZm91bmQgaW4gc2ltcGxlIHR5cGUgY29udGVudCIsIAoJCSAgICBjdXItPm5hbWUpOwoJCXJldHVybiAoWE1MX1NDSEVNQVZfSU5URVJOQUwpOwoJCQkJICAgfQoJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CgkgICAgY2FzZSBYTUxfRE9DVU1FTlRfVFlQRV9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX0ZSQUdfTk9ERToKCSAgICBjYXNlIFhNTF9OT1RBVElPTl9OT0RFOgoJICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9EVERfTk9ERToKCSAgICBjYXNlIFhNTF9FTEVNRU5UX0RFQ0w6CgkgICAgY2FzZSBYTUxfQVRUUklCVVRFX0RFQ0w6CgkgICAgY2FzZSBYTUxfRU5USVRZX0RFQ0w6CgkgICAgY2FzZSBYTUxfTkFNRVNQQUNFX0RFQ0w6CiNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECgkgICAgY2FzZSBYTUxfRE9DQl9ET0NVTUVOVF9OT0RFOiAKI2VuZGlmCQkgICAgCQkgICAgCQkgICAgCgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgIC8qIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElERUxFTSwgKi8KCQkgICAgbm9kZSwgTlVMTCwKCQkgICAgIk5vZGUgb2YgdW5leHBlY3RlZCB0eXBlIGZvdW5kIGluIHNpbXBsZSB0eXBlIGNvbnRlbnQiLAoJCSAgICBOVUxMKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFWX0lOVEVSTkFMKTsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfSB3aGlsZSAoY3VyICE9IE5VTEwpOwogICAgfQoKICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGJhc2UsIGFueVR5cGU7CgoJYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoKCWJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKCXdoaWxlICgoYmFzZSAhPSBOVUxMKSAmJiAKCSAgICAoYmFzZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSAmJgoJICAgIChiYXNlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgJiYKCSAgICAoYmFzZSAhPSBhbnlUeXBlKSkgewoJICAgIGJhc2UgPSBiYXNlLT5iYXNlVHlwZTsKCX0KCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIGJhc2UsIHZhbHVlLCAxLCAwLCAxLCAwKTsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgY29tcGxleCB0eXBlICclcydcbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7Cgl9IGVsc2UgaWYgKChyZXQgPT0gMCkgJiYgKGFwcGx5RmFjZXRzKSAmJiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICAvKiAKCSAgICAqIENoZWNrIGZhY2V0cy4KCSAgICAqLwkgICAgCgkgICAgLyoKCSAgICAqIFRoaXMgaXMgc29tZWhvdyBub3QgbmljZSwgc2luY2UgaWYgYW4gZXJyb3Igb2NjdXJzCgkgICAgKiB0aGUgcmVwb3J0ZWQgdHlwZSB3aWxsIGJlIHRoZSBjb21wbGV4IHR5cGU7IHRoZSBzcGVjCgkgICAgKiB3YW50cyBhIHNpbXBsZSB0eXBlIHRvIGJlIGNyZWF0ZWQgb24gdGhlIGNvbXBsZXggdHlwZQoJICAgICogaWYgaXQgaGFzIGEgc2ltcGxlIGNvbnRlbnQuIEZvciBub3cgd2UgaGF2ZSB0byBsaXZlIHdpdGgKCSAgICAqIGl0LgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBjb21wbGV4IHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJCWlmIChmaXJlRXJyb3JzKSAKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CgkgICAgfQkKCX0JCiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7CgoJaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwoJICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKCX0KCS8qCgkqIFNUUkVBTS1SRUFELUNISUxEUkVOLgoJKi8JICAgIAkJCglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PVEFUSU9OKSAmJgoJICAgIChjdHh0LT5zY2hlbWEgIT0gTlVMTCkpIHsKCSAgICAvKgoJICAgICogTk9UQVRJT05zIG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGhlcmUsIHNpbmNlIHRoZXkgbmVlZAoJICAgICogdG8gbG9va3VwIGluIHRoZSBoYXNodGFibGUgb2YgTk9UQVRJT04gZGVjbGFyYXRpb25zLgoJICAgICovCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVOb3RhdGlvbihjdHh0LCB2YWx1ZSwgJihjdHh0LT52YWx1ZSksIG5vZGUpOyAKCX0gZWxzZQoJICAgIHJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlTm9Ob3JtKHR5cGUsIHZhbHVlLCAmKGN0eHQtPnZhbHVlKSwgbm9kZSk7CglpZiAocmV0ID4gMCkgewkgICAgCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIAoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCSAgICBlbHNlCgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwkgICAgCgkgICAgaWYgKGZpcmVFcnJvcnMpCgkJeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7Cgl9IGVsc2UgaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBidWlsdC1pbiB0eXBlICclcydcbiIsIHR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgoY3R4dC0+dmFsdWUgPT0gTlVMTCkgJiYgCgkgICAgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgJiYKCSAgICAoY3R4dC0+bm9kZUluZm8gIT0gTlVMTCkgJiYKCSAgICAoY3R4dC0+bm9kZUluZm8tPmZsYWdzICYgWE1MX1NDSEVNQV9FTEVNX0lORk9fVkFMVUVfTkVFREVEKSkgewojaWZkZWYgSURDX1ZBTFVFX1NVUFBPUlQKCSAgICB4bWxDaGFyICp2YWxkdXA7CgkgICAgLyoKCSAgICAqIENyZWF0ZSBhIHByZWNvbXB1dGVkIHN0cmluZyB2YWx1ZSBmb3IgInN0cmluZyIgYXMgd2VsbCBpZgoJICAgICogcmVxdWVzdGVkLgoJICAgICovCgkgICAgdmFsZHVwID0geG1sU3RyZHVwKHZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZSA9IHhtbFNjaGVtYU5ld1N0cmluZ1ZhbHVlKFhNTF9TQ0hFTUFTX1NUUklORywKCQlCQURfQ0FTVCB2YWxkdXApOwoJICAgIGlmICgodmFsZHVwICE9IE5VTEwpICYmIChjdHh0LT52YWx1ZSA9PSBOVUxMKSkKCQl4bWxGcmVlKHZhbGR1cCk7CiNlbmRpZgoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpIHsgICAgICAgIAoJLyogMS4yLjEgaWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgCgkqIGEgbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gCgkqLwkKCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHR5cGUtPmJhc2VUeXBlLCB2YWx1ZSwgMCwgMCwgMCwgMCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGF0b21pYyBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmIChyZXQgPiAwKSB7CSAgICAKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkgICAgaWYgKGZpcmVFcnJvcnMpCgkJeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CQoJfSBlbHNlIGlmICgoYXBwbHlGYWNldHMpICYmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSkgewoJICAgIC8qIAoJICAgICogQ2hlY2sgZmFjZXRzLgoJICAgICovCSAgICAJICAgIAkgICAgCgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgMCwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBhdG9taWMgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJCS8qCgkJIERpc2FibGVkLCBzaW5jZSB0aGUgZmFjZXQgdmFsaWRhdGlvbiBhbHJlYWR5IHJlcG9ydHMgZXJyb3JzLgoJCWlmIChmaXJlRXJyb3JzKSAKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBjdHh0LT5jdXIsIHZhbHVlLCB0eXBlKTsKCQkqLwoJICAgIH0JCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKICAgICAgICAKCXhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcDsKCXVuc2lnbmVkIGxvbmcgbGVuID0gMDsKCgkvKiAxLjIuMiBpZiB7dmFyaWV0eX0gaXMgt2xpc3S3IHRoZW4gdGhlIHN0cmluZyBtdXN0IGJlIGEgc2VxdWVuY2UgCgkqIG9mIHdoaXRlIHNwYWNlIHNlcGFyYXRlZCB0b2tlbnMsIGVhY2ggb2Ygd2hpY2ggt21hdGNot2VzIGEgbGl0ZXJhbCAKCSogaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7aXRlbSB0eXBlIGRlZmluaXRpb259IAoJKi8KCQoJaWYgKHZhbHVlID09IE5VTEwpCgkgICAgdmFsdWUgPSBCQURfQ0FTVCAiIjsKCXRtcFR5cGUgPSB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUpOwkKCWN1ciA9IHZhbHVlOwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CgkgICAgbGVuKys7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdG1wVHlwZSwgdG1wLCAwLCAxLCAwLCAwKTsKCSAgICB4bWxGcmVlKHRtcCk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGFuIGl0ZW0gb2YgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsJCgkJYnJlYWs7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCQlicmVhazsKCSAgICB9CQoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7CgkvKiAKCSogQ2hlY2sgZmFjZXRzLgoJKi8KCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykpIHsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCBsZW4sIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgbGlzdCBzaW1wbGUgdHlwZSAnJXMnXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkJLyoKCQkgRGlzYWJsZWQsIHNpbmNlIHRoZSBmYWNldCB2YWxpZGF0aW9uIGFscmVhZHkgcmVwb3J0cyBlcnJvcnMuCgkJaWYgKGZpcmVFcnJvcnMpIAoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIGN0eHQtPmN1ciwgdmFsdWUsIHR5cGUpOwoJCSovCgkgICAgfQkgCSAgIAoJICAgCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXJMaW5rOwoKCS8qCgkqIFRPRE86IEZvciBhbGwgZGF0YXR5cGVzILdkZXJpdmVktyBieSC3dW5pb263ICB3aGl0ZVNwYWNlIGRvZXMgCgkqIG5vdCBhcHBseSBkaXJlY3RseTsgaG93ZXZlciwgdGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utyAKCSogdHlwZXMgaXMgY29udHJvbGxlZCBieSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUgCgkqILdtZW1iZXJUeXBlc7cgYWdhaW5zdCB3aGljaCB0aGUgt3VuaW9utyBpcyBzdWNjZXNzZnVsbHkgdmFsaWRhdGVkLiAKCSoKCSogVGhpcyBtZWFucyB0aGF0IHRoZSB2YWx1ZSBpcyBub3JtYWxpemVkIGJ5IHRoZSBmaXJzdCB2YWxpZGF0aW5nCgkqIG1lbWJlciB0eXBlLCB0aGVuIHRoZSBmYWNldHMgb2YgdGhlIHVuaW9uIHR5cGUgYXJlIGFwcGxpZWQuIFRoaXMKCSogbmVlZHMgY2hhbmdpbmcgb2YgdGhlIHZhbHVlIQoJKi8JCgkKCS8qCgkqIDEuMi4zIGlmIHt2YXJpZXR5fSBpcyC3dW5pb263IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgYSAKCSogbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIGF0IGxlYXN0IG9uZSBtZW1iZXIgb2YgCgkqIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gCgkqLwojaWZkZWYgREVCVUdfVU5JT05fVkFMSURBVElPTgoJcHJpbnRmKCJVbmlvbiBTVCAgICAgOiAnJXMnXG4iLCAoY29uc3QgY2hhciAqKSB0eXBlLT5uYW1lKTsKCXByaW50ZigiICBmaXJlRXJyb3JzIDogJWRcbiIsIGZpcmVFcnJvcnMpOwoJcHJpbnRmKCIgIGFwcGx5RmFjZXRzOiAlZFxuIiwgYXBwbHlGYWNldHMpOwojZW5kaWYKCW1lbWJlckxpbmsgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlKTsKCWlmIChtZW1iZXJMaW5rID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidW5pb24gc2ltcGxlIHR5cGUgJyVzJyBoYXMgbm8gbWVtYmVyIHR5cGVzXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIHJldCA9IC0xOwoJfSAKCWlmIChyZXQgPT0gMCkgewoJICAgIHdoaWxlIChtZW1iZXJMaW5rICE9IE5VTEwpIHsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBtZW1iZXJMaW5rLT50eXBlLCAKCQkgICAgdmFsdWUsIDAsIDEsIDEsIDApOwoJCWlmICgocmV0IDw9IDApIHx8IChyZXQgPT0gMCkpCgkJICAgIGJyZWFrOwkgICAgCgkJbWVtYmVyTGluayA9IG1lbWJlckxpbmstPm5leHQ7CgkgICAgfSAgICAgCgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIG1lbWJlcnMgb2YgdW5pb24gc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCB0eXBlKTsKCSAgICB9Cgl9CgkvKgoJKiBBcHBseSBmYWNldHMgKHBhdHRlcm4sIGVudW1lcmF0aW9uKS4JCgkqLwoJaWYgKChyZXQgPT0gMCkgJiYgKGFwcGx5RmFjZXRzKSAmJiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICBpbnQgbXdzOwoJICAgIC8qCgkgICAgKiBUaGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkgCgkgICAgKiB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBvbiB0aGF0IG9uZSBvZiB0aGUgt21lbWJlclR5cGVztyAKCSAgICAqIGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4gCgkgICAgKi8JCSAgICAKCSAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ0aGUgdmFsdWUgd2FzIGFscmVhZHkgbm9ybWFsaXplZCBmb3IgdGhlIHVuaW9uIHNpbXBsZSAiCgkJICAgICJ0eXBlICclcycuXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9CgkgICAgbXdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUobWVtYmVyTGluay0+dHlwZSk7CgkgICAgaWYgKG13cyA+IGN0eHQtPnZhbHVlV1MpIHsKCQlpZiAobXdzID09IFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKQoJCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkJZWxzZQoJCSAgICBub3JtVmFsdWUgPSB4bWxTY2hlbWFXaGl0ZVNwYWNlUmVwbGFjZSh2YWx1ZSk7CgkJaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKQoJCSAgICB2YWx1ZSA9IChjb25zdCB4bWxDaGFyICopIG5vcm1WYWx1ZTsKCSAgICB9CgoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgdW5pb24gc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8zOwoJCS8qCgkJaWYgKGZpcmVFcnJvcnMpCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkJKi8KCSAgICB9CQoJfQogICAgfSAgICAgICAgICAgCiAgICBjdHh0LT52YWx1ZVdTID0gd3RzcDsKICAgIGlmIChub3JtVmFsdWUgIT0gTlVMTCkKCXhtbEZyZWUobm9ybVZhbHVlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIGVsZW1lbnQgbm9kZSB0byBiZSB2YWxpZGF0ZWQuCiAqCiAqIFZhbGlkYXRlIHRoZSBlbGVtZW50IGFnYWluc3QgYSBzaW1wbGUgdHlwZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSAgICAgaW50IGlzTmlsLAoJCQkJICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOwogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sTm9kZVB0ciBjdXI7CiAgICBpbnQgcmV0ID0gMCwgcmV0dmFsID0gMDsKICAgICAgICAKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsIE5VTEwsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOyAgICAKICAgIH0KCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogCiAgICAqIGN2Yy10eXBlOiAzLjEuMiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgaGF2ZSBubyBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBDaGlsZCBub2RlcyBhcmUgcHJvY2Vzc2VkLgogICAgKi8KICAgIGN1ciA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkvKgoJKiBUT0RPOiBFbnRpdGllcywgd2lsbCB0aGV5IHByb2R1Y2UgZWxlbWVudHMgYXMgd2VsbD8KCSovCglpZiAoY3VyLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzIsCgkJbm9kZSwgdHlwZSwJCQoJCSJObyBlbGVtZW50IGNvbnRlbnQgYWxsb3dlZCIsIE5VTEwpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8yOwoJfQoJY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgCiAgICAvKgogICAgKiBjdmMtdHlwZSAzLjEuMToKICAgICoKICAgICogVGhlIGF0dHJpYnV0ZXMgb2YgbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nIHRob3NlIHdob3NlIG5hbWVzcGFjZSBuYW1lIAogICAgKiBpcyBpZGVudGljYWwgdG8gaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kIHdob3NlIGxvY2FsIAogICAgKiBuYW1lIGlzIG9uZSBvZiB0eXBlLCBuaWwsIHNjaGVtYUxvY2F0aW9uIG9yIG5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24uCiAgICAqLyAgIAogICAgLyoKICAgICogU1RSRUFNOiBBdHRyaWJ1dGUgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB8fAogICAgICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmlsIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbAogICAgICAgICAgICAgIChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIpKSkpIHsKCSAgICB4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfM18xXzEsIGF0dHIpOwoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8xOwogICAgICAgIH0KCWF0dHIgPSBhdHRyLT5uZXh0OwogICAgfQogICAgLyoKICAgICogVGhpcyB3aWxsIHNraXAgdmFsaWRhdGlvbiBpZiB0aGUgdHlwZSBpcyAnYW55U2ltcGxlVHlwZScgYW5kCiAgICAqIGlmIHRoZSB2YWx1ZSB3YXMgYWxyZWFkeSB2YWxpZGF0ZWQgKGUuZy4gZGVmYXVsdCB2YWx1ZXMpLgogICAgKi8KICAgIGlmICgoISBpc05pbCkgJiYgCgkodmFsU2ltcGxlQ29udGVudCA9PSAxKSAmJgoJKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgfHwKCSAodHlwZS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpKSB7Cgl4bWxDaGFyICp2YWx1ZTsKCgl2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KG5vZGUpOwoJLyoKCSogTk9URTogVGhpcyBjYWxsIHdpbGwgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCBzaW5jZQoJKiB0aGlzIHNob3VsZCBiZSBjaGVja2VkIGhlcmUgYWxyZWFkeS4KCSovCglyZXR2YWwgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgCgkgICAgMSwgMSwgMSwgMCk7CglpZiAodmFsdWUgIT0gTlVMTCkKCSAgICB4bWxGcmVlKHZhbHVlKTsKCWlmIChyZXR2YWwgIT0gMCkKCSAgICByZXQgPSByZXR2YWw7CiAgICB9CiAgICBjdHh0LT50eXBlID0gb2xkdHlwZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbFFOYW1lQWNxdWlyZToKICogQHZhbHVlOiB0aGUgbGV4aWNhbCByZXByZXNhbnRhdGlvbiBvZiB0aGUgUU5hbWUgdmFsdWUKICogQG5vZGU6IHRoZSBub2RlIHRvIHNlYXJjaCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uCiAqIEBuc05hbWU6IHRoZSByZXN1bHRpbmcgbmFtZXNwYWNlIG5hbWUgaWYgZm91bmQKICoKICogQ2hlY2tzIHRoYXQgYSB2YWx1ZSBjb25mb3JtcyB0byB0aGUgbGV4aWNhbCBzcGFjZSBvZiB0aGUgdHlwZSBRTmFtZTsKICogaWYgdmFsaWQsIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBuYW1lIGlzIHNlYXJjaGVkIGFuZCByZXR1cmVkIAogKiBhcyBhIGNvcHkgaW4gQG5zTmFtZS4gVGhlIGxvY2FsIG5hbWUgaXMgcmV0dXJuZWQgaW4gQGxvY2FsTmFtZSBhcwogKiBhIGNvcHkuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZCwgMSBpZiBub3QgdmFsaWQgYnkgdHlwZSwgMiBpZiBubyBjb3JyZXNwb25kaW5nIAogKiBuYW1lc3BhY2UgZGVjbGFyYXRpb24gd2FzIGZvdW5kIGluIHNjb3BlOyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIAogKiBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbFFOYW1lQWNxdWlyZShjb25zdCB4bWxDaGFyICp2YWx1ZSwgeG1sTm9kZVB0ciBub2RlLAoJCQl4bWxDaGFyICoqbnNOYW1lLCB4bWxDaGFyICoqbG9jYWxOYW1lKQp7CiAgICBpbnQgcmV0OwogICAgeG1sQ2hhciAqbG9jYWwgPSBOVUxMOwoKICAgIGlmICgobnNOYW1lID09IE5VTEwpIHx8IChsb2NhbE5hbWUgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCglyZXR1cm4gKC0xKTsgIAogICAgKm5zTmFtZSA9IE5VTEw7ICAgCiAgICAqbG9jYWxOYW1lID0gTlVMTDsKICAgIHJldCA9IHhtbFZhbGlkYXRlUU5hbWUodmFsdWUsIDEpOwogICAgaWYgKHJldCA9PSAwKSB7Cgl4bWxDaGFyICpwcmVmaXg7Cgl4bWxOc1B0ciBuczsKCQoJLyoKCSogTk9URTogeG1sU3BsaXRRTmFtZTIgd2lsbCByZXR1cm4gYSBkdXBsaWNhdGVkCgkqIHN0cmluZy4KCSovCglsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCWlmIChsb2NhbCA9PSBOVUxMKQoJICAgIGxvY2FsID0geG1sU3RyZHVwKHZhbHVlKTsKCW5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBwcmVmaXgpOwoJLyoKICAgICAgICAqIEEgbmFtZXNwYWNlIG5lZWQgbm90IHRvIGJlIGZvdW5kIGlmIHRoZSBwcmVmaXggaXMgTlVMTC4KCSovCglpZiAobnMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBJcyBpdCBuZWNlc3NhcnkgdG8gZHVwbGljYXRlIHRoZSBVUkkgaGVyZT8KCSAgICAqLwoJICAgICpuc05hbWUgPSB4bWxTdHJkdXAobnMtPmhyZWYpOwoJfSBlbHNlIGlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIHhtbEZyZWUocHJlZml4KTsgCgkgICAgaWYgKGxvY2FsICE9IE5VTEwpCgkJeG1sRnJlZShsb2NhbCk7CgkgICAgcmV0dXJuICgyKTsKCX0JCQoJKmxvY2FsTmFtZSA9IGxvY2FsOwoJaWYgKHByZWZpeCAhPSBOVUxMKQoJICAgIHhtbEZyZWUocHJlZml4KTsgICAgCiAgICB9IGVsc2UKCXJldHVybiAoMSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFIYXNFbGVtQ29udGVudDogCiAqIEBub2RlOiAgdGhlIG5vZGUKICoKICogU2NvdXJzIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBub2RlIGZvciBlbGVtZW50CiAqIG5vZGVzLgogKgogKiBSZXR1cm5zIDEgaWYgYW4gZWxlbWVudCBub2RlIGlzIGZvdW5kLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbUNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAobm9kZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIG5vZGUgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChub2RlICE9IE5VTEwpIHsKCWlmIChub2RlLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgcmV0dXJuICgxKTsKCW5vZGUgPSBub2RlLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQovKioKICogeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQ6IAogKiBAbm9kZTogIHRoZSBub2RlCiAqCiAqIFNjb3VycyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gbm9kZSBmb3IgZWxlbWVudAogKiBhbmQgY2hhcmFjdGVyIG5vZGVzLgogKgogKiBSZXR1cm5zIDEgaWYgYW4gZWxlbWVudCBvciBjaGFyYWN0ZXIgbm9kZSBpcyBmb3VuZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKG5vZGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7Cglzd2l0Y2ggKG5vZGUtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9FTEVNRU5UX05PREU6CQoJICAgIC8qIAoJICAgICogVE9ETzogQXNrIERhbmllbCBpZiB0aGVzZSBhcmUgYWxsIGNoYXJhY3RlciBub2Rlcy4KCSAgICAqLwoJICAgIGNhc2UgWE1MX1RFWFRfTk9ERToKCSAgICBjYXNlIFhNTF9DREFUQV9TRUNUSU9OX05PREU6CgkgICAgLyoKCSAgICAqIFRPRE86IEhvdyBYTUxfRU5USVRZX05PREVzIGV2YWx1YXRlZD8KCSAgICAqLwoJICAgIGNhc2UgWE1MX0VOVElUWV9SRUZfTk9ERToKCSAgICBjYXNlIFhNTF9FTlRJVFlfTk9ERToKCQlyZXR1cm4gKDEpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9Cglub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAgSWRlbnRpdHktY29uc3RyYWludHMgKElEQykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpZmRlZiBJRENfRU5BQkxFRAoKLyoqCiAqIHhtbFNjaGVtYUF1Z21lbnRJREM6CiAqIEBpZGNEZWY6IHRoZSBJREMgZGVmaW5pdGlvbgogKgogKiBDcmVhdGVzIGFuIGF1Z21lbnRlZCBJREMgZGVmaW5pdGlvbiBpdGVtLgogKgogKiBSZXR1cm5zIHRoZSBpdGVtLCBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF1Z21lbnRJREMoeG1sU2NoZW1hSURDUHRyIGlkY0RlZiwKCQkgICAgeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKCiAgICBhaWRjID0gKHhtbFNjaGVtYUlEQ0F1Z1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENBdWcpKTsKICAgIGlmIChhaWRjID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJICAgICJ4bWxTY2hlbWFBdWdtZW50SURDOiBhbGxvY2F0aW5nIGFuIGF1Z21lbnRlZCBJREMgZGVmaW5pdGlvbiIsCgkgICAgTlVMTCk7CglyZXR1cm47CiAgICB9CiAgICBhaWRjLT5idWJibGVEZXB0aCA9IC0xOwogICAgYWlkYy0+ZGVmID0gaWRjRGVmOwogICAgYWlkYy0+bmV4dCA9IE5VTEw7CiAgICBpZiAodmN0eHQtPmFpZGNzID09IE5VTEwpCgl2Y3R4dC0+YWlkY3MgPSBhaWRjOwogICAgZWxzZSB7CglhaWRjLT5uZXh0ID0gdmN0eHQtPmFpZGNzOwoJdmN0eHQtPmFpZGNzID0gYWlkYzsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ05ld0JpbmRpbmc6CiAqIEBpZGNEZWY6IHRoZSBJREMgZGVmaW5pdGlvbiBvZiB0aGlzIGJpbmRpbmcKICoKICogQ3JlYXRlcyBhIG5ldyBJREMgYmluZGluZy4KICoKICogUmV0dXJucyB0aGUgbmV3IGJpbmRpbmcgaW4gY2FzZSBvZiBzdWNjZWVkZWQsIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyCnhtbFNjaGVtYUlEQ05ld0JpbmRpbmcoeG1sU2NoZW1hSURDUHRyIGlkY0RlZikKewogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cikgeG1sTWFsbG9jKAoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDQmluZGluZykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJICAgICJhbGxvY2F0aW5nIGEgUFNWSSBJREMgYmluZGluZyBpdGVtIiwgTlVMTCk7CglyZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nKSk7CiAgICByZXQtPmRlZmluaXRpb24gPSBpZGNEZWY7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENTdG9yZU5vZGVUYWJsZUl0ZW06CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGl0ZW06IHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtCiAqCiAqIFRoZSB2YWxpZGF0aW9uIGNvbnRleHQgaXMgdXNlZCB0byBzdG9yZSBhbiBJREMgbm9kZSB0YWJsZSBpdGVtcy4KICogVGhleSBhcmUgc3RvcmVkIHRvIGF2b2lkIGNvcHlpbmcgdGhlbSBpZiBJREMgbm9kZS10YWJsZXMgYXJlIG1lcmdlZAogKiB3aXRoIGNvcnJlc3BvbmRpbmcgcGFyZW50IElEQyBub2RlLXRhYmxlcyAoYnViYmxpbmcpLgogKgogKiBSZXR1cm5zIDAgaWYgc3VjY2VlZGVkLCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1N0b3JlTm9kZVRhYmxlSXRlbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsIAoJCQkgICAgICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaXRlbSkKewogICAgLyoKICAgICogQWRkIHRvIGdvYmFsIGxpc3QuCiAgICAqLyAgICAKICAgIGlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewkJCQoJdmN0eHQtPmlkY05vZGVzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJICAgIHhtbE1hbGxvYygyMCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKHZjdHh0LT5pZGNOb2RlcyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgdGhlIElEQyBub2RlIHRhYmxlIGl0ZW0gbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJdmN0eHQtPnNpemVJZGNOb2RlcyA9IDIwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUlkY05vZGVzIDw9IHZjdHh0LT5uYklkY05vZGVzKSB7Cgl2Y3R4dC0+c2l6ZUlkY05vZGVzICo9IDI7Cgl2Y3R4dC0+aWRjTm9kZXMgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+aWRjTm9kZXMsIHZjdHh0LT5zaXplSWRjTm9kZXMgKiAKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHZjdHh0LT5pZGNOb2Rlc1t2Y3R4dC0+bmJJZGNOb2RlcysrXSA9IGl0ZW07CiAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1N0b3JlS2V5OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIGtleQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgYW4gSURDIGtleS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZUtleSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsIAoJCSAgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkpCnsKICAgIC8qCiAgICAqIEFkZCB0byBnb2JhbCBsaXN0LgogICAgKi8gICAgCiAgICBpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJdmN0eHQtPmlkY0tleXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSAKCSAgICB4bWxNYWxsb2MoNDAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiYWxsb2NhdGluZyB0aGUgSURDIGtleSBzdG9yYWdlIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXZjdHh0LT5zaXplSWRjS2V5cyA9IDQwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUlkY0tleXMgPD0gdmN0eHQtPm5iSWRjS2V5cykgewoJdmN0eHQtPnNpemVJZGNLZXlzICo9IDI7Cgl2Y3R4dC0+aWRjS2V5cyA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopIAoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmlkY0tleXMsIHZjdHh0LT5zaXplSWRjS2V5cyAqIAoJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CglpZiAodmN0eHQtPmlkY0tleXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBJREMga2V5IHN0b3JhZ2UgbGlzdCIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQogICAgfQogICAgdmN0eHQtPmlkY0tleXNbdmN0eHQtPm5iSWRjS2V5cysrXSA9IGtleTsKICAgCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbToKICogQGJpbmQ6IHRoZSBJREMgYmluZGluZwogKiBAbnRJdGVtOiB0aGUgbm9kZS10YWJsZSBpdGVtCiAqCiAqIEFwcGVuZHMgdGhlIElEQyBub2RlLXRhYmxlIGl0ZW0gdG8gdGhlIGJpbmRpbmcuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50IAp4bWxTY2hlbWFJRENBcHBlbmROb2RlVGFibGVJdGVtKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQsCgkJCQl4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciBudEl0ZW0pCnsKICAgIGlmIChiaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJYmluZC0+c2l6ZU5vZGVzID0gMTA7CgliaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkgICAgeG1sTWFsbG9jKDEwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0JCiAgICB9IGVsc2UgaWYgKGJpbmQtPnNpemVOb2RlcyA8PSBiaW5kLT5uYk5vZGVzKSB7CgliaW5kLT5zaXplTm9kZXMgKj0gMjsKCWJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCSAgICB4bWxSZWFsbG9jKGJpbmQtPm5vZGVUYWJsZSwgYmluZC0+c2l6ZU5vZGVzICogCgkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSJyZS1hbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0KICAgIH0KICAgIGJpbmQtPm5vZGVUYWJsZVtiaW5kLT5uYk5vZGVzKytdID0gbnRJdGVtOwogICAgcmV0dXJuKDApOyAgIAp9CgovKioKICogeG1sU2NoZW1hSURDQXF1aXJlQmluZGluZzogCiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG1hdGNoZXI6IHRoZSBJREMgbWF0Y2hlcgogKgogKiBMb29rcyB1cCBhbiBQU1ZJIElEQyBiaW5kaW5nLCBmb3IgdGhlIElEQyBkZWZpbml0aW9uIGFuZCAKICogb2YgdGhlIGdpdmVuIG1hdGNoZXIuIElmIG5vbmUgZm91bmQsIGEgbmV3IG9uZSBpcyBjcmVhdGVkCiAqIGFuZCBhZGRlZCB0byB0aGUgSURDIHRhYmxlLgogKgogKiBSZXR1cm5zIGFuIElEQyBiaW5kaW5nIG9yIE5VTEwgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyCnhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmcoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcikKewogICAgeG1sU2NoZW1hRWxlbUluZm9QdHIgaW5mbzsKCiAgICBpbmZvID0gdmN0eHQtPmVsZW1JbmZvc1ttYXRjaGVyLT5kZXB0aF07CgogICAgaWYgKGluZm8tPmlkY1RhYmxlID09IE5VTEwpIHsKCWluZm8tPmlkY1RhYmxlID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhtYXRjaGVyLT5haWRjLT5kZWYpOwoJaWYgKGluZm8tPmlkY1RhYmxlID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCXJldHVybihpbmZvLT5pZGNUYWJsZSk7CiAgICB9IGVsc2UgewoJeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCA9IE5VTEw7CgkKCWJpbmQgPSBpbmZvLT5pZGNUYWJsZTsKCWRvIHsKCSAgICBpZiAoYmluZC0+ZGVmaW5pdGlvbiA9PSBtYXRjaGVyLT5haWRjLT5kZWYpCgkJcmV0dXJuKGJpbmQpOwoJICAgIGlmIChiaW5kLT5uZXh0ID09IE5VTEwpIHsKCQliaW5kLT5uZXh0ID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhtYXRjaGVyLT5haWRjLT5kZWYpOwoJCWlmIChiaW5kLT5uZXh0ID09IE5VTEwpCgkJICAgIHJldHVybiAoTlVMTCk7CgkJcmV0dXJuKGJpbmQtPm5leHQpOwoJICAgIH0KCSAgICBiaW5kID0gYmluZC0+bmV4dDsKCX0gd2hpbGUgKGJpbmQgIT0gTlVMTCk7CQogICAgfQogICAgcmV0dXJuIChOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVLZXk6IAogKiBAa2V5OiB0aGUgSURDIGtleQogKgogKiBGcmVlcyBhbiBJREMga2V5IHRvZ2V0aGVyIHdpdGggaXRzIGNvbXBpbGVkIHZhbHVlLgogKi8Kc3RhdGljIHZvaWQgCnhtbFNjaGVtYUlEQ0ZyZWVLZXkoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciBrZXkpCnsKICAgIGlmIChrZXktPmNvbXBWYWx1ZSAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZVZhbHVlKGtleS0+Y29tcFZhbHVlKTsKICAgIHhtbEZyZWUoa2V5KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nOgogKgogKiBGcmVlcyBhbiBJREMgYmluZGluZy4gTm90ZSB0aGF0IHRoZSBub2RlIHRhYmxlLWl0ZW1zCiAqIGFyZSBub3QgZnJlZWQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlQmluZGluZyh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlICE9IE5VTEwpIHsKCWlmIChiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgaW50IGk7CgkgICAgLyoKCSAgICAqIE5vZGUtdGFibGUgaXRlbXMgZm9yIGtleXJlZnMgYXJlIG5vdCBzdG9yZWQgZ2xvYmFsbHkKCSAgICAqIHRvIHRoZSB2YWxpZGF0aW9uIGNvbnRleHQsIHNpbmNlIHRoZXkgYXJlIG5vdCBidWJibGVkLgoJICAgICogV2UgbmVlZCB0byBmcmVlIHRoZW0gaGVyZS4KCSAgICAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQl4bWxGcmVlKGJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5cyk7CgkJeG1sRnJlZShiaW5kLT5ub2RlVGFibGVbaV0pOwoJICAgIH0KCX0KCXhtbEZyZWUoYmluZC0+bm9kZVRhYmxlKTsKICAgIH0KICAgIHhtbEZyZWUoYmluZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlSURDVGFibGU6CiAqIEBiaW5kOiB0aGUgZmlyc3QgSURDIGJpbmRpbmcgaW4gdGhlIGxpc3QKICoKICogRnJlZXMgYW4gSURDIHRhYmxlLCBpLmUuIGFsbCB0aGUgSURDIGJpbmRpbmdzIGluIHRoZSBsaXN0LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlKHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHByZXY7CgogICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJcHJldiA9IGJpbmQ7CQkgICAgCgliaW5kID0gYmluZC0+bmV4dDsKCXhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nKHByZXYpOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0OgogKiBAbWF0Y2hlcjogdGhlIGZpcnN0IElEQyBtYXRjaGVyIGluIHRoZSBsaXN0CiAqCiAqIEZyZWVzIGEgbGlzdCBvZiBJREMgbWF0Y2hlcnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFJRENGcmVlTWF0Y2hlckxpc3QoeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyKQp7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG5leHQ7CgogICAgd2hpbGUgKG1hdGNoZXIgIT0gTlVMTCkgewoJbmV4dCA9IG1hdGNoZXItPm5leHQ7CglpZiAobWF0Y2hlci0+a2V5U2VxcyAhPSBOVUxMKSB7CgkgICAgaW50IGk7CgkgICAgZm9yIChpID0gMDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspCgkJaWYgKG1hdGNoZXItPmtleVNlcXNbaV0gIT0gTlVMTCkKCQkgICAgeG1sRnJlZShtYXRjaGVyLT5rZXlTZXFzW2ldKTsKCSAgICB4bWxGcmVlKG1hdGNoZXItPmtleVNlcXMpOwoJfQoJeG1sRnJlZShtYXRjaGVyKTsKCW1hdGNoZXIgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWw6CiAqIEB0YTogdGhlIGZpcnN0IHR5cGUKICogQGE6IHRoZSBmaXJzdCB2YWx1ZQogKiBAdGI6IHRoZSBzZWNvbmQgdHlwZQogKiBAYjogdGhlIHNlY29uZCB2YWx1ZQogKgogKiBDb21wYXJlcyB0d28gdmFsdWVzLgogKgogKiBSZXR1cm5zIDEgaWYgdGhleSBhcmUgZXF1YWwsIDAgaWYgbm90IGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0YSwKCQkJeG1sU2NoZW1hVmFsUHRyIGEsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdGIsCgkJCXhtbFNjaGVtYVZhbFB0ciBiKSAKeyAgICAgICAKICAgIC8qIFNhbWUgdXNlciBkZXJpdmVkL2J1aWx0LWluIGRlcml2ZWQvYnVpbHQtaW4gcHJpbWl0aXZlIHR5cGVzLiAqLwogICAgaWYgKHRhID09IHRiKQoJZ290byBjb21wYXJlVmFsdWU7CiAgICAKICAgIC8qCiAgICAqIENvbXBhcmlzb24gd2l0aCBhbnlTaW1wbGVUeXBlcyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgaW1wbGVtZW50aW9uLgogICAgKi8KICAgIGlmICgodGEtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHx8CgkodGItPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKQoJcmV0dXJuKDApOwogICAgCiAgICAvKgogICAgKiA0LjIuMSBlcXVhbCAoZGF0YS10eXBlcykKICAgICoKICAgICogdGhlILd2YWx1ZSBzcGFjZbdzIG9mIGFsbCC3cHJpbWl0aXZltyBkYXRhdHlwZXMgYXJlIGRpc2pvaW50IAogICAgKiAodGhleSBkbyBub3Qgc2hhcmUgYW55IHZhbHVlcykgCiAgICAqLwogICAgaWYgKCh0YS0+YnVpbHRJblR5cGUgIT0gMCkgJiYgKHRiLT5idWlsdEluVHlwZSAhPSAwKSAmJgoJKHRhLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQlVJTFRJTl9QUklNSVRJVkUpICYmIAoJKHRiLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQlVJTFRJTl9QUklNSVRJVkUpKQoJcmV0dXJuKDApOwoKICAgIGlmICgodGEtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHx8CgkodGEtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB8fAoJKHRiLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB8fAoJKHRiLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikpIHsKCVRPRE8KCXJldHVybigwKTsKICAgIH0KICAgIC8qCiAgICAqICgxKSBpZiBhIGRhdGF0eXBlIFQnIGlzILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263IGZyb20gYW4gYXRvbWljIGRhdGF0eXBlCiAgICAqIFQgdGhlbiB0aGUgt3ZhbHVlIHNwYWNltyBvZiBUJyBpcyBhIHN1YnNldCBvZiB0aGUgt3ZhbHVlIHNwYWNltyBvZiBULiAKICAgICovCiAgICAvKgogICAgKiAoMikgaWYgZGF0YXR5cGVzIFQnIGFuZCBUJycgYXJlILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263IGZyb20gYSBjb21tb24gCiAgICAqIGF0b21pYyBhbmNlc3RvciBUIHRoZW4gdGhlILd2YWx1ZSBzcGFjZbdzIG9mIFQnIGFuZCBUJycgbWF5IG92ZXJsYXAuIAogICAgKi8KICAgIAogICAgewoJeG1sU2NoZW1hVHlwZVB0ciBwdGEgPSB0YSwgcHRiID0gdGI7CgoJLyogTm90ZSB0aGF0IHdlIHdpbGwgY29tcGFyZSB0aGUgcHJpbWl0aXZlcyBoZXJlLiAqLwoJd2hpbGUgKChwdGEtPmJ1aWx0SW5UeXBlID09IDApIHx8CgkgICAgICAgKChwdGEtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkgPT0gMCkpCgkgICAgcHRhID0gcHRhLT5iYXNlVHlwZTsJCgl3aGlsZSAoKHB0Yi0+YnVpbHRJblR5cGUgPT0gMCkgfHwKCSAgICAgICAoKHB0Yi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0JVSUxUSU5fUFJJTUlUSVZFKSA9PSAwKSkKCSAgICBwdGIgPSBwdGItPmJhc2VUeXBlOwoJaWYgKHB0YSA9PSBwdGIpCgkgICAgZ290byBjb21wYXJlVmFsdWU7CglyZXR1cm4oMCk7CiAgICB9CmNvbXBhcmVWYWx1ZToKICAgIHsJCiNpZmRlZiBJRENfVkFMVUVfU1VQUE9SVAoJaW50IHJldDsKCWludCBhd3MsIGJ3czsKCglhd3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0YSk7Cglid3MgPSB4bWxTY2hlbWFHZXRXaGl0ZVNwYWNlRmFjZXRWYWx1ZSh0Yik7CgoJcmV0ID0geG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKAoJICAgIGEsICh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSBhd3MsCgkgICAgYiwgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIGJ3cyk7CglpZiAocmV0ID09IDApIAoJICAgIHJldHVybigxKTsKCWVsc2UgaWYgKHJldCA9PSAtMikgewoJICAgIHhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwsICIKCQkiZmFpbGVkIHRvIGNvbXBhcmUgdGhlIHZhbHVlcy5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIHJldHVybigwKTsKI2Vsc2UKCXJldHVybiAoMSk7CiNlbmRpZgogICAgfQp9CgovKioKICogeG1sU2NoZW1hSURDQWRkU3RhdGVPYmplY3Q6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQG1hdGNoZXI6IHRoZSBJREMgbWF0Y2hlcgogKiBAc2VsOiB0aGUgWFBhdGggaW5mb3JtYXRpb24KICogQHBhcmVudDogdGhlIHBhcmVudCAic2VsZWN0b3IiIHN0YXRlIG9iamVjdCBpZiBhbnkKICogQHR5cGU6ICJzZWxlY3RvciIgb3IgImZpZWxkIgogKgogKiBDcmVhdGVzL3JldXNlcyBhbmQgYWN0aXZhdGVzIHN0YXRlIG9iamVjdHMgZm9yIHRoZSBnaXZlbgogKiBYUGF0aCBpbmZvcm1hdGlvbjsgaWYgdGhlIFhQYXRoIGV4cHJlc3Npb24gY29uc2lzdHMgb2YgdW5pb25zLAogKiBtdWx0aXBsZSBzdGF0ZSBvYmplY3RzIGFyZSBjcmVhdGVkIGZvciBldmVyeSB1bmlvbmVkIGV4cHJlc3Npb24uCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyLAoJCQl4bWxTY2hlbWFJRENTZWxlY3RQdHIgc2VsLAoJCQlpbnQgdHlwZSkKewogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgc3RvOwoKICAgIC8qCiAgICAqIFJldXNlIHRoZSBzdGF0ZSBvYmplY3RzIGZyb20gdGhlIHBvb2wuCiAgICAqLwogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlUG9vbCAhPSBOVUxMKSB7CglzdG8gPSB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2w7Cgl2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgPSBzdG8tPm5leHQ7CglzdG8tPm5leHQgPSBOVUxMOwogICAgfSBlbHNlIHsJCgkvKgoJKiBDcmVhdGUgYSBuZXcgc3RhdGUgb2JqZWN0LgoJKi8KCXN0byA9ICh4bWxTY2hlbWFJRENTdGF0ZU9ialB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENTdGF0ZU9iaikpOwoJaWYgKHN0byA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLAoJCSJhbGxvY2F0aW5nIGFuIElEQyBzdGF0ZSBvYmplY3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCW1lbXNldChzdG8sIDAsIHNpemVvZih4bWxTY2hlbWFJRENTdGF0ZU9iaikpOwogICAgfQkKICAgIC8qCiAgICAqIEFkZCB0byBnbG9iYWwgbGlzdC4gCiAgICAqLwkKICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkKCXN0by0+bmV4dCA9IHZjdHh0LT54cGF0aFN0YXRlczsKICAgIHZjdHh0LT54cGF0aFN0YXRlcyA9IHN0bzsKCiAgICAvKgogICAgKiBGcmVlIHRoZSBvbGQgeHBhdGggdmFsaWRhdGlvbiBjb250ZXh0LgogICAgKi8KICAgIGlmIChzdG8tPnhwYXRoQ3R4dCAhPSBOVUxMKQoJeG1sRnJlZVN0cmVhbUN0eHQoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0KTsKCiAgICAvKgogICAgKiBDcmVhdGUgYSBuZXcgWFBhdGggKHBhdHRlcm4pIHZhbGlkYXRpb24gY29udGV4dC4KICAgICovCiAgICBzdG8tPnhwYXRoQ3R4dCA9ICh2b2lkICopIHhtbFBhdHRlcm5HZXRTdHJlYW1DdHh0KAoJKHhtbFBhdHRlcm5QdHIpIHNlbC0+eHBhdGhDb21wKTsKICAgIGlmIChzdG8tPnhwYXRoQ3R4dCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZSwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0LCAiCgkgICAgImZhaWxlZCB0byBjcmVhdGUgdGhlIFhQYXRoIHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0gICAgCiAgICBzdG8tPnR5cGUgPSB0eXBlOwogICAgc3RvLT5kZXB0aCA9IHZjdHh0LT5kZXB0aDsKICAgIHN0by0+bWF0Y2hlciA9IG1hdGNoZXI7CiAgICBzdG8tPnNlbCA9IHNlbDsKICAgIHN0by0+bmJIaXN0b3J5ID0gMDsKICAgIAojaWYgREVCVUdfSURDCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBTVE8gcHVzaCAnJXMnXG4iLAoJc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZVR5cGU6IHRoZSBub2RlVHlwZSBvZiB0aGUgY3VycmVudCBub2RlCiAqCiAqIEV2YWx1YXRlcyBhbGwgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAqCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBJQyAiZmllbGQiIHN0YXRlIG9iamVjdHMgd2hpY2ggcmVzb2x2ZWQgdG8KICogdGhpcyBub2RlLCAwIGlmIG5vbmUgcmVzb2x2ZWQgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIHhtbEVsZW1lbnRUeXBlIG5vZGVUeXBlKQp7CiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciBzdG8sIGhlYWQgPSBOVUxMLCBmaXJzdDsKICAgIGludCByZXMsIHJlc29sdmVkID0gMCwgZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CiAgICAgICAgCiAgICBpZiAodmN0eHQtPnhwYXRoU3RhdGVzID09IE5VTEwpCglyZXR1cm4gKDApOwoKICAgIGlmIChub2RlVHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCglkZXB0aCsrOwojaWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IEVWQUwgb24gJXMsIGRlcHRoICVkLCB0eXBlICVkXG4iLAkgICAgCgkgICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyLCB2Y3R4dC0+bm9kZUluZm8tPm5hbWVzcGFjZU5hbWUsCgkJdmN0eHQtPm5vZGVJbmZvLT5sb2NhbE5hbWUpLCBkZXB0aCwgbm9kZVR5cGUpOwoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9CiNlbmRpZgogICAgLyoKICAgICogUHJvY2VzcyBhbGwgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCiAgICAqLwogICAgZmlyc3QgPSB2Y3R4dC0+eHBhdGhTdGF0ZXM7CiAgICBzdG8gPSBmaXJzdDsKICAgIHdoaWxlIChzdG8gIT0gaGVhZCkgewojaWYgREVCVUdfSURDCglpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19TRUxFQ1RPUikKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBbJyVzJ10gc2VsZWN0b3IgJyVzJ1xuIiwgCgkJc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYtPm5hbWUsIHN0by0+c2VsLT54cGF0aCk7CgllbHNlCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgWyclcyddIGZpZWxkICclcydcbiIsIAoJCXN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5uYW1lLCBzdG8tPnNlbC0+eHBhdGgpOwojZW5kaWYKCiNpZmRlZiBJRENfWFBBVEhfU1VQUE9SVAoJaWYgKG5vZGVUeXBlID09IFhNTF9FTEVNRU5UX05PREUpCgkgICAgcmVzID0geG1sU3RyZWFtUHVzaCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQsCgkJdmN0eHQtPm5vZGVJbmZvLT5sb2NhbE5hbWUsIHZjdHh0LT5ub2RlSW5mby0+bmFtZXNwYWNlTmFtZSk7CgllbHNlCgkgICAgcmVzID0geG1sU3RyZWFtUHVzaEF0dHIoKHhtbFN0cmVhbUN0eHRQdHIpIHN0by0+eHBhdGhDdHh0LAoJCXZjdHh0LT5ub2RlSW5mby0+bG9jYWxOYW1lLCB2Y3R4dC0+bm9kZUluZm8tPm5hbWVzcGFjZU5hbWUpOwoKI2Vsc2UKCXJlcyA9IDA7CiNlbmRpZgkKCWlmIChyZXMgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZSwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUsICIKCQkiZmFpbGVkIHRvIGV2YWx1YXRlIGEgbm9kZS5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CglpZiAocmVzID09IDApCgkgICAgZ290byBuZXh0X3N0bzsKCS8qCgkqIEZ1bGwgbWF0Y2guCgkqLwojaWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICIKCSAgICAiTUFUQ0hcbiIpOwojZW5kaWYKCS8qCgkqIFJlZ2lzdGVyIGEgbWF0Y2ggaW4gdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5LgoJKi8KCWlmIChzdG8tPmhpc3RvcnkgPT0gTlVMTCkgewoJICAgIHN0by0+aGlzdG9yeSA9IChpbnQgKikgeG1sTWFsbG9jKDUgKiBzaXplb2YoaW50KSk7CgkgICAgaWYgKHN0by0+aGlzdG9yeSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkgICAgImFsbG9jYXRpbmcgdGhlIHN0YXRlIG9iamVjdCBoaXN0b3J5IiwgTlVMTCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgc3RvLT5zaXplSGlzdG9yeSA9IDEwOwoJfSBlbHNlIGlmIChzdG8tPnNpemVIaXN0b3J5IDw9IHN0by0+bmJIaXN0b3J5KSB7CgkgICAgc3RvLT5zaXplSGlzdG9yeSAqPSAyOwoJICAgIHN0by0+aGlzdG9yeSA9IChpbnQgKikgeG1sUmVhbGxvYyhzdG8tPmhpc3RvcnksCgkJc3RvLT5zaXplSGlzdG9yeSAqIHNpemVvZihpbnQpKTsKCSAgICBpZiAoc3RvLT5oaXN0b3J5ID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAicmUtYWxsb2NhdGluZyB0aGUgc3RhdGUgb2JqZWN0IGhpc3RvcnkiLCBOVUxMKTsKCQlyZXR1cm4oLTEpOwoJICAgIH0KCX0JCQoJc3RvLT5oaXN0b3J5W3N0by0+bmJIaXN0b3J5KytdID0gZGVwdGg7CgojaWZkZWYgREVCVUdfSURDCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICAgICAgcHVzaCBtYXRjaCAnJWQnXG4iLAoJICAgIHZjdHh0LT5kZXB0aCk7CiNlbmRpZgoKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKSB7CgkgICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbDsKCSAgICAvKgoJICAgICogQWN0aXZhdGUgc3RhdGUgb2JqZWN0cyBmb3IgdGhlIElEQyBmaWVsZHMgb2YKCSAgICAqIHRoZSBJREMgc2VsZWN0b3IuCgkgICAgKi8KI2lmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgICAgIgoJCSJhY3RpdmF0aW5nIGZpZWxkIHN0YXRlc1xuIik7CiNlbmRpZgoJICAgIHNlbCA9IHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLT5maWVsZHM7CgkgICAgd2hpbGUgKHNlbCAhPSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHZjdHh0LCBzdG8tPm1hdGNoZXIsCgkJICAgIHNlbCwgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSA9PSAtMSkKCQkgICAgcmV0dXJuICgtMSk7CgkJc2VsID0gc2VsLT5uZXh0OwoJICAgIH0KCX0gZWxzZSBpZiAoc3RvLT50eXBlID09IFhQQVRIX1NUQVRFX09CSl9UWVBFX0lEQ19GSUVMRCkgewoJICAgIC8qCgkgICAgKiBBbiBJREMga2V5IG5vZGUgd2FzIGZvdW5kLgoJICAgICovCiNpZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkiSURDOiAgICAga2V5IGZvdW5kXG4iKTsKI2VuZGlmCgkgICAgLyoKCSAgICAqIE5vdGlmeSB0aGF0IHRoZSBjaGFyYWN0ZXIgdmFsdWUgb2YgdGhpcyBub2RlIGlzCgkgICAgKiBuZWVkZWQuCgkgICAgKi8KCSAgICBpZiAocmVzb2x2ZWQgPT0gMCkKCQl2Y3R4dC0+bm9kZUluZm8tPmZsYWdzIHw9IFhNTF9TQ0hFTUFfRUxFTV9JTkZPX1ZBTFVFX05FRURFRDsKCSAgICByZXNvbHZlZCsrOwoJfQpuZXh0X3N0bzoKCWlmIChzdG8tPm5leHQgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBFdmFsdWF0ZSBmaWVsZCBzdGF0ZSBvYmplY3RzIGNyZWF0ZWQgb24gdGhpcyBub2RlIGFzIHdlbGwuCgkgICAgKi8KCSAgICBoZWFkID0gZmlyc3Q7CgkgICAgc3RvID0gdmN0eHQtPnhwYXRoU3RhdGVzOwoJfSBlbHNlCgkgICAgc3RvID0gc3RvLT5uZXh0OwogICAgfQogICAgcmV0dXJuIChyZXNvbHZlZCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEB0eXBlOiB0aGUgc2ltcGxlL2NvbXBsZXggdHlwZSBvZiB0aGUgY3VycmVudCBub2RlIGlmIGFueSBhdCBhbGwKICogQGNvbXBWYWx1ZTogdGhlIHByZWNvbXBpbGVkIHZhbHVlCiAqCiAqIFByb2Nlc3NlcyBhbmQgcG9wcyB0aGUgaGlzdG9yeSBpdGVtcyBvZiB0aGUgSURDIHN0YXRlIG9iamVjdHMuCiAqIElEQyBrZXktc2VxdWVuY2VzIGFyZSB2YWxpZGF0ZWQvY3JlYXRlZCBvbiBJREMgYmluZGluZ3MuCiAqIAogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICBpbnQgZGVwdGgpCnsKICAgIHhtbFNjaGVtYUlEQ1N0YXRlT2JqUHRyIHN0bywgbmV4dHN0bzsKICAgIGludCByZXMsIG1hdGNoRGVwdGg7CiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSA9IE5VTEw7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUgPSB2Y3R4dC0+bm9kZUluZm8tPnR5cGVEZWY7CgogICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIHN0byA9IHZjdHh0LT54cGF0aFN0YXRlczsKCiNpZiBERUJVR19JREMKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgCgkgICAgIklEQzogQkFDSyBvbiAlcywgZGVwdGggJWRcbiIsCgkgICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyLCB2Y3R4dC0+bm9kZUluZm8tPm5hbWVzcGFjZU5hbWUsCgkJdmN0eHQtPm5vZGVJbmZvLT5sb2NhbE5hbWUpLCB2Y3R4dC0+ZGVwdGgpOwoJRlJFRV9BTkRfTlVMTChzdHIpCiAgICB9CiNlbmRpZiAgICAKICAgIC8qCiAgICAqIEV2YWx1YXRlIHRoZSBzdGF0ZSBvYmplY3RzLgogICAgKi8KICAgIHdoaWxlIChzdG8gIT0gTlVMTCkgewojaWZkZWYgSURDX1hQQVRIX1NVUFBPUlQKCXhtbFN0cmVhbVBvcCgoeG1sU3RyZWFtQ3R4dFB0cikgc3RvLT54cGF0aEN0eHQpOwoJI2lmIERFQlVHX0lEQwoJICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiSURDOiAgIHN0cmVhbSBwb3AgJyVzJ1xuIiwKCQlzdG8tPnNlbC0+eHBhdGgpOwoJI2VuZGlmCiNlbmRpZgoJaWYgKHN0by0+bmJIaXN0b3J5ID09IDApCgkgICAgZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoKCW1hdGNoRGVwdGggPSBzdG8tPmhpc3Rvcnlbc3RvLT5uYkhpc3RvcnkgLTFdOwoKCS8qCgkqIE9ubHkgbWF0Y2hlcyBhdCB0aGUgY3VycmVudCBkZXB0aCBhcmUgb2YgaW50ZXJlc3QuCgkqLwoJaWYgKG1hdGNoRGVwdGggIT0gZGVwdGgpIHsKCSAgICBzdG8gPSBzdG8tPm5leHQ7CgkgICAgY29udGludWU7Cgl9CgkKCWlmIChzdG8tPnR5cGUgPT0gWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX0ZJRUxEKSB7CgkgICAgaWYgKCEgSVNfU0lNUExFX1RZUEUodHlwZSkpIHsKCQkvKgoJCSogTm90IHF1YWxpZmllZCBpZiB0aGUgZmllbGQgcmVzb2x2ZXMgdG8gYSBub2RlIG9mIG5vbgoJCSogc2ltcGxlIHR5cGUuCgkJKi8JCgkJeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0lEQywKCQkgICAgdmN0eHQtPm5vZGUsIAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYsCgkJICAgICJUaGUgZmllbGQgJyVzJyBkb2VzIGV2YWx1YXRlIHRvIGEgbm9kZSBvZiAiCgkJICAgICJub24tc2ltcGxlIHR5cGUiLCBzdG8tPnNlbC0+eHBhdGgpOwoJCQoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0KCSAgICBpZiAoKGtleSA9PSBOVUxMKSAmJiAodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSA9PSBOVUxMKSkgewoJCS8qCgkJKiBGYWlsZWQgdG8gcHJvdmlkZSB0aGUgbm9ybWFsaXplZCB2YWx1ZTsgbWFieQoJCSogdGhlIHZhbHVlIHdhcyBpbnZhbGlkLgoJCSovIAoJCXhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJICAgIHZjdHh0LT5ub2RlSW5mby0+bm9kZSwKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLAoJCSAgICAiV2FybmluZzogTm8gcHJlY29tcHV0ZWQgdmFsdWUgYXZhaWxhYmxlLCB0aGUgdmFsdWUgIgoJCSAgICAid2FzIGVpdGhlciBpbnZhbGlkIG9yIHNvbWV0aGluZyBzdHJhbmdlIGhhcHBlbmQiLCBOVUxMKTsKCQkvKgoJCXhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlSW5mby0+bm9kZSwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnksICIKCQkgICAgImNvbXB1dGVkIHZhbHVlIG5vdCBhdmFpbGFibGUuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCQkqLwoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyID0gc3RvLT5tYXRjaGVyOwoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmtleVNlcTsKCQlpbnQgcG9zLCBpZHg7CgkJCgkJLyoKCQkqIFRoZSBrZXkgd2lsbCBiZSBhbmNob3JlZCBvbiB0aGUgbWF0Y2hlcidzIGxpc3Qgb2YKCQkqIGtleS1zZXF1ZW5jZXMuIFRoZSBwb3NpdGlvbiBpbiB0aGlzIGxpc3QgaXMgZGV0ZXJtaW5lZAoJCSogYnkgdGhlIHRhcmdldCBub2RlJ3MgZGVwdGggcmVsYXRpdmUgdG8gdGhlIG1hdGNoZXIncwoJCSogZGVwdGggb2YgY3JlYXRpb24gKGkuZS4gdGhlIGRlcHRoIG9mIHRoZSBzY29wZSBlbGVtZW50KS4KCQkqLwkJICAgIAoJCXBvcyA9IHN0by0+ZGVwdGggLSBtYXRjaGVyLT5kZXB0aDsKCQlpZHggPSBzdG8tPnNlbC0+aW5kZXg7CgkJCgkJLyoKCQkqIENyZWF0ZS9ncm93IHRoZSBhcnJheSBvZiBrZXktc2VxdWVuY2VzLgoJCSovCgkJaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCSAgICBpZiAocG9zID4gOSkgCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzID0gcG9zICogMjsKCQkgICAgZWxzZQoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyA9IDEwOwoJCSAgICBtYXRjaGVyLT5rZXlTZXFzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiopIAoJCQl4bWxNYWxsb2MobWF0Y2hlci0+c2l6ZUtleVNlcXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSk7CQkJCgkJICAgIGlmIChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHsJCQoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBrZXktc2VxdWVuY2VzIiwKCQkJICAgIE5VTEwpOwoJCQlyZXR1cm4oLTEpOwoJCSAgICB9CgkJICAgIG1lbXNldChtYXRjaGVyLT5rZXlTZXFzLCAwLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQl9IGVsc2UgaWYgKHBvcyA+PSBtYXRjaGVyLT5zaXplS2V5U2VxcykgewkKCQkgICAgaW50IGkgPSBtYXRjaGVyLT5zaXplS2V5U2VxczsKCQkgICAgCgkJICAgIG1hdGNoZXItPnNpemVLZXlTZXFzICo9IDI7CgkJICAgIG1hdGNoZXItPmtleVNlcXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKikKCQkJeG1sUmVhbGxvYyhtYXRjaGVyLT5rZXlTZXFzLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQkgICAgaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAicmVhbGxvY2F0aW5nIGFuIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogVGhlIGFycmF5IG5lZWRzIHRvIGJlIE5VTExlZC4KCQkgICAgKiBUT0RPOiBVc2UgbWVtc2V0PwoJCSAgICAqLwoJCSAgICBmb3IgKDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspIAoJCQltYXRjaGVyLT5rZXlTZXFzW2ldID0gTlVMTDsJCQkKCQl9CgkJCgkJLyoKCQkqIEdldC9jcmVhdGUgdGhlIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9IG1hdGNoZXItPmtleVNlcXNbcG9zXTsJCSAgICAKCQlpZiAoa2V5U2VxID09IE5VTEwpIHsJCgkJICAgIGdvdG8gY3JlYXRlX3NlcXVlbmNlOwoJCX0gZWxzZSB7CgkJICAgIGlmIChrZXlTZXFbaWR4XSAhPSBOVUxMKSB7CgkJCS8qCgkJCSogY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQ6CgkJCSogMyBGb3IgZWFjaCBub2RlIGluIHRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbGwKCQkJKiBvZiB0aGUge2ZpZWxkc30sIHdpdGggdGhhdCBub2RlIGFzIHRoZSBjb250ZXh0CgkJCSogbm9kZSwgZXZhbHVhdGUgdG8gZWl0aGVyIGFuIGVtcHR5IG5vZGUtc2V0IG9yCgkJCSogYSBub2RlLXNldCB3aXRoIGV4YWN0bHkgb25lIG1lbWJlciwgd2hpY2ggbXVzdAoJCQkqIGhhdmUgYSBzaW1wbGUgdHlwZS4KCQkJKiAKCQkJKiBUaGUga2V5IHdhcyBhbHJlYWR5IHNldDsgcmVwb3J0IGFuIGVycm9yLgoJCQkqLwoJCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKHZjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJCSAgICB2Y3R4dC0+bm9kZSwgKHhtbFNjaGVtYVR5cGVQdHIpIG1hdGNoZXItPmFpZGMtPmRlZiwKCQkJICAgICJUaGUgZmllbGQgJyVzJyBldmFsdWF0ZXMgdG8gYSBub2RlLXNldCAiCgkJCSAgICAid2l0aCBtb3JlIHRoYW4gb25lIG1lbWJlciIsIHN0by0+c2VsLT54cGF0aCk7CgkJCXN0by0+bmJIaXN0b3J5LS07CgkJCWdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCQkgICAgfSBlbHNlIHsKCQkJZ290byBjcmVhdGVfa2V5OwoJCSAgICB9CgkJfQoJCQpjcmVhdGVfc2VxdWVuY2U6CgkJLyoKCQkqIENyZWF0ZSBhIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopIHhtbE1hbGxvYygKCQkgICAgbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkcyAqIAoJCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJCWlmIChrZXlTZXEgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkiYWxsb2NhdGluZyBhbiBJREMga2V5LXNlcXVlbmNlIiwgTlVMTCk7CgkJICAgIHJldHVybigtMSk7CQkJCgkJfQkKCQltZW1zZXQoa2V5U2VxLCAwLCBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzICogCgkJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CgkJbWF0Y2hlci0+a2V5U2Vxc1twb3NdID0ga2V5U2VxOwpjcmVhdGVfa2V5OgoJCS8qCgkJKiBDcmVhdGVkIGEga2V5IG9uY2UgcGVyIG5vZGUgb25seS4KCQkqLyAgCgkJaWYgKGtleSA9PSBOVUxMKSB7CgkJICAgIGtleSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSB4bWxNYWxsb2MoCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5KSk7CgkJICAgIGlmIChrZXkgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhIElEQyBrZXkiLCBOVUxMKTsKCQkJeG1sRnJlZShrZXlTZXEpOwoJCQltYXRjaGVyLT5rZXlTZXFzW3Bvc10gPSBOVUxMOwoJCQlyZXR1cm4oLTEpOwkJCQoJCSAgICB9CgkJICAgIC8qCgkJICAgICogQ29uc3VtZSB0aGUgY29tcGlsZWQgdmFsdWUuCgkJICAgICovCgkJICAgIGtleS0+dHlwZSA9IHR5cGU7CgkJICAgIGtleS0+Y29tcFZhbHVlID0gdmN0eHQtPm5vZGVJbmZvLT52YWx1ZTsKCQkgICAgdmN0eHQtPm5vZGVJbmZvLT52YWx1ZSA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogU3RvcmUgdGhlIGtleSBpbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hSURDU3RvcmVLZXkodmN0eHQsIGtleSkgPT0gLTEpIHsKCQkJeG1sU2NoZW1hSURDRnJlZUtleShrZXkpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0KCQlrZXlTZXFbaWR4XSA9IGtleTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpIHsKCQkKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxID0gTlVMTDsKCSAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOwoJICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG50SXRlbTsKCSAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7CgkgICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKCSAgICBpbnQgcG9zLCBpLCBqLCBuYktleXM7CgkgICAgLyoKCSAgICAqIEhlcmUgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIHNjZW5hcmlvOgoJICAgICogQW4gSURDICdzZWxlY3Rvcicgc3RhdGUgb2JqZWN0IHJlc29sdmVkIHRvIGEgdGFyZ2V0IG5vZGUsCgkgICAgKiBkdXJpbmcgdGhlIHRpbWUgdGhpcyB0YXJnZXQgbm9kZSB3YXMgaW4gdGhlIAoJICAgICogYW5jZXN0b3Itb3Itc2VsZiBheGlzLCB0aGUgJ2ZpZWxkJyBzdGF0ZSBvYmplY3QocykgbG9va2VkIAoJICAgICogb3V0IGZvciBtYXRjaGluZyBub2RlcyB0byBjcmVhdGUgYSBrZXktc2VxdWVuY2UgZm9yIHRoaXMgCgkgICAgKiB0YXJnZXQgbm9kZS4gTm93IHdlIGFyZSBiYWNrIHRvIHRoaXMgdGFyZ2V0IG5vZGUgYW5kIG5lZWQKCSAgICAqIHRvIHB1dCB0aGUga2V5LXNlcXVlbmNlLCB0b2dldGhlciB3aXRoIHRoZSB0YXJnZXQgbm9kZSAKCSAgICAqIGl0c2VsZiwgaW50byB0aGUgbm9kZS10YWJsZSBvZiB0aGUgY29ycmVzcG9uZGluZyBJREMgCgkgICAgKiBiaW5kaW5nLgoJICAgICovCgkgICAgbWF0Y2hlciA9IHN0by0+bWF0Y2hlcjsKCSAgICBpZGMgPSBtYXRjaGVyLT5haWRjLT5kZWY7CgkgICAgbmJLZXlzID0gaWRjLT5uYkZpZWxkczsKCSAgICBwb3MgPSBkZXB0aCAtIG1hdGNoZXItPmRlcHRoOwkJCgkgICAgLyoKCSAgICAqIENoZWNrIGlmIHRoZSBtYXRjaGVyIGhhcyBhbnkga2V5LXNlcXVlbmNlcyBhdCBhbGwsIHBsdXMKCSAgICAqIGlmIGl0IGhhcyBhIGtleS1zZXF1ZW5jZSBmb3IgdGhlIGN1cnJlbnQgdGFyZ2V0IG5vZGUuCgkgICAgKi8JCQoJICAgIGlmICgobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB8fAoJCShtYXRjaGVyLT5zaXplS2V5U2VxcyA8PSBwb3MpKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBrZXlTZXEgPSAmKG1hdGNoZXItPmtleVNlcXNbcG9zXSk7CQkKCSAgICBpZiAoKmtleVNlcSA9PSBOVUxMKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBmb3IgKGkgPSAwOyBpIDwgbmJLZXlzOyBpKyspIHsKCQlpZiAoKCprZXlTZXEpW2ldID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBOb3QgcXVhbGlmaWVkLCBpZiBub3QgYWxsIGZpZWxkcyBkaWQgcmVzb2x2ZS4KCQkgICAgKi8KCQkgICAgaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkgewoJCQkvKgoJCQkqIEFsbCBmaWVsZHMgb2YgYSAia2V5IiBJREMgbXVzdCByZXNvbHZlLgoJCQkqLwoJCQlnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQkgICAgfQkJICAgIAoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEFsbCBmaWVsZHMgZGlkIHJlc29sdmUuCgkgICAgKi8KCSAgICAKCSAgICAvKgoJICAgICogNC4xIElmIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBjYXRlZ29yeX0gaXMgdW5pcXVlKC9rZXkpLAoJICAgICogdGhlbiBubyB0d28gbWVtYmVycyBvZiB0aGUgt3F1YWxpZmllZCBub2RlIHNldLcgaGF2ZQoJICAgICogt2tleS1zZXF1ZW5jZXO3IHdob3NlIG1lbWJlcnMgYXJlIHBhaXJ3aXNlIGVxdWFsLCBhcwoJICAgICogZGVmaW5lZCBieSBFcXVhbCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCgkgICAgKgoJICAgICogR2V0IHRoZSBJREMgYmluZGluZyBmcm9tIHRoZSBtYXRjaGVyIGFuZCBjaGVjayBmb3IKCSAgICAqIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2VzLgoJICAgICovCgkgICAgYmluZCA9IHhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmcodmN0eHQsIG1hdGNoZXIpOwoJICAgIGlmICgoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSAmJiAKCQkoYmluZC0+bmJOb2RlcyAhPSAwKSkgewoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgY2tleSwgYmtleSwgKmJrZXlTZXE7CgkJCgkJaSA9IDA7CgkJcmVzID0gMDsKCQkvKgoJCSogQ29tcGFyZSB0aGUga2V5LXNlcXVlbmNlcywga2V5IGJ5IGtleS4KCQkqLwoJCWRvIHsKCQkgICAgYmtleVNlcSA9IGJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5czsJCSAgICAKCQkgICAgZm9yIChqID0gMDsgaiA8IG5iS2V5czsgaisrKSB7CgkJCWNrZXkgPSAoKmtleVNlcSlbal07CgkJCWJrZXkgPSBia2V5U2VxW2pdOwkJCQkJCQkKCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwodmN0eHQsIGNrZXktPnR5cGUsCgkJCSAgICBja2V5LT5jb21wVmFsdWUsIGJrZXktPnR5cGUsIGJrZXktPmNvbXBWYWx1ZSk7CgkJCWlmIChyZXMgPT0gLTEpIHsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9IGVsc2UgaWYgKHJlcyA9PSAwKQoJCQkgICAgYnJlYWs7CgkJICAgIH0KCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCS8qCgkJCSogRHVwbGljYXRlIGZvdW5kLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBpKys7CgkJfSB3aGlsZSAoaSA8IGJpbmQtPm5iTm9kZXMpOwoJCWlmIChpICE9IGJpbmQtPm5iTm9kZXMpIHsKCQkgICAgLyogICAKCQkgICAgKiBUT0RPOiBUcnkgdG8gcmVwb3J0IHRoZSBrZXktc2VxdWVuY2UuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLAoJCQl2Y3R4dC0+bm9kZSwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGlkYywKCQkJIkR1cGxpY2F0ZSBrZXktc2VxdWVuY2UgZm91bmQiLCBOVUxMKTsKCQkgICAgCgkJICAgIGdvdG8gc2VsZWN0b3JfbGVhdmU7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogQWRkIGEgbm9kZS10YWJsZSBpdGVtIHRvIHRoZSBJREMgYmluZGluZy4KCSAgICAqLwoJICAgIG50SXRlbSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikgeG1sTWFsbG9jKAoJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZSkpOwoJICAgIGlmIChudEl0ZW0gPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIElEQyBub2RlLXRhYmxlIGl0ZW0iLCBOVUxMKTsKCQl4bWxGcmVlKCprZXlTZXEpOwoJCSprZXlTZXEgPSBOVUxMOwoJCXJldHVybigtMSk7CgkgICAgfQkKCSAgICBtZW1zZXQobnRJdGVtLCAwLCBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGUpKTsJCQoJICAgIAoJICAgIC8qIAoJICAgICogU3RvcmUgdGhlIG5vZGUtdGFibGUgaXRlbSBvbiBnbG9iYWwgbGlzdC4KCSAgICAqLwoJICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCQlpZiAoeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtKHZjdHh0LCBudEl0ZW0pID09IC0xKSB7CgkJICAgIHhtbEZyZWUobnRJdGVtKTsKCQkgICAgeG1sRnJlZSgqa2V5U2VxKTsKCQkgICAgKmtleVNlcSA9IE5VTEw7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEluaXQgdGhlIG5vZGUtdGFibGUgaXRlbS4gQ29uc3VtZSB0aGUga2V5LXNlcXVlbmNlLgoJICAgICovCgkgICAgbnRJdGVtLT5ub2RlID0gdmN0eHQtPm5vZGU7CgkgICAgbnRJdGVtLT5rZXlzID0gKmtleVNlcTsKCSAgICAqa2V5U2VxID0gTlVMTDsKCSAgICBpZiAoeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbShiaW5kLCBudEl0ZW0pID09IC0xKSB7CQkgICAgCgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJCSAgICAvKiAKCQkgICAgKiBGcmVlIHRoZSBpdGVtLCBzaW5jZSBrZXlyZWYgaXRlbXMgd29uJ3QgYmUKCQkgICAgKiBwdXQgb24gYSBnbG9iYWwgbGlzdC4KCQkgICAgKi8KCQkgICAgeG1sRnJlZShudEl0ZW0tPmtleXMpOwoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJfQoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICAKCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwpzZWxlY3Rvcl9rZXlfZXJyb3I6CgkgICAgLyoKCSAgICAqIDQuMi4xIChLRVkpIFRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbmQgdGhlIAoJICAgICogt3F1YWxpZmllZCBub2RlIHNldLcgYXJlIGVxdWFsLCB0aGF0IGlzLCBldmVyeSAKCSAgICAqIG1lbWJlciBvZiB0aGUgt3RhcmdldCBub2RlIHNldLcgaXMgYWxzbyBhIG1lbWJlcgoJICAgICogb2YgdGhlILdxdWFsaWZpZWQgbm9kZSBzZXS3IGFuZCB2aWNlIHZlcnNhLgoJICAgICovCgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX0lEQywKCQl2Y3R4dC0+bm9kZSwgCgkJKHhtbFNjaGVtYVR5cGVQdHIpIGlkYywKCQkiQWxsICdrZXknIGZpZWxkcyBtdXN0IGV2YWx1YXRlIHRvIGEgbm9kZSIsCgkJTlVMTCk7CnNlbGVjdG9yX2xlYXZlOgoJICAgIC8qCgkgICAgKiBGcmVlIHRoZSBrZXktc2VxdWVuY2UgaWYgbm90IGFkZGVkIHRvIHRoZSBJREMgdGFibGUuCgkgICAgKi8KCSAgICBpZiAoKGtleVNlcSAhPSBOVUxMKSAmJiAoKmtleVNlcSAhPSBOVUxMKSkgewoJCXhtbEZyZWUoKmtleVNlcSk7CgkJKmtleVNlcSA9IE5VTEw7CgkgICAgfQoJfSAvKiBpZiBzZWxlY3RvciAqLwoJCglzdG8tPm5iSGlzdG9yeS0tOwoKZGVyZWdpc3Rlcl9jaGVjazoKCS8qCgkqIERlcmVnaXN0ZXIgc3RhdGUgb2JqZWN0cyBpZiB0aGV5IHJlYWNoIHRoZSBkZXB0aCBvZiBjcmVhdGlvbi4KCSovCglpZiAoKHN0by0+bmJIaXN0b3J5ID09IDApICYmIChzdG8tPmRlcHRoID09IGRlcHRoKSkgewojaWYgREVCVUdfSURDCgkgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgU1RPIHBvcCAnJXMnXG4iLAoJCXN0by0+c2VsLT54cGF0aCk7CiNlbmRpZgoJICAgIGlmICh2Y3R4dC0+eHBhdGhTdGF0ZXMgIT0gc3RvKSB7CgkJeG1sU2NoZW1hVkVycih2Y3R4dCwgdmN0eHQtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnksICIKCQkgICAgIlRoZSBzdGF0ZSBvYmplY3QgdG8gYmUgcmVtb3ZlZCBpcyBub3QgdGhlIGZpcnN0ICIKCQkgICAgImluIHRoZSBsaXN0LlxuIiwKCQkgICAgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIG5leHRzdG8gPSBzdG8tPm5leHQ7CgkgICAgLyoKCSAgICAqIFVubGluayBmcm9tIHRoZSBsaXN0IG9mIGFjdGl2ZSBYUGF0aCBzdGF0ZSBvYmplY3RzLgoJICAgICovCgkgICAgdmN0eHQtPnhwYXRoU3RhdGVzID0gc3RvLT5uZXh0OwoJICAgIHN0by0+bmV4dCA9IHZjdHh0LT54cGF0aFN0YXRlUG9vbDsKCSAgICAvKgoJICAgICogTGluayBpdCB0byB0aGUgcG9vbCBvZiByZXVzYWJsZSBzdGF0ZSBvYmplY3RzLgoJICAgICovCgkgICAgdmN0eHQtPnhwYXRoU3RhdGVQb29sID0gc3RvOwkgICAgCgkgICAgc3RvID0gbmV4dHN0bzsKCX0gZWxzZQoJICAgIHN0byA9IHN0by0+bmV4dDsKICAgIH0gLyogd2hpbGUgKHN0byAhPSBOVUxMKSAqLwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW1EZWNsOiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvbgogKgogKiBDcmVhdGVzIGhlbHBlciBvYmplY3RzIHRvIGV2YWx1YXRlIElEQyBzZWxlY3RvcnMvZmllbGRzCiAqIHN1Y2Nlc3NpdmVseS4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlciwgbGFzdCA9IE5VTEw7CiAgICB4bWxTY2hlbWFJRENQdHIgaWRjLCByZWZJZGM7CiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKICAgICAgICAKICAgIGlkYyA9ICh4bWxTY2hlbWFJRENQdHIpIGVsZW1EZWNsLT5pZGNzOwogICAgaWYgKGlkYyA9PSBOVUxMKQoJcmV0dXJuICgwKTsKICAgIAojaWYgREVCVUdfSURDCiAgICB7Cgl4bWxDaGFyICpzdHIgPSBOVUxMOwoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsIAoJICAgICJJREM6IFJFR0lTVEVSIG9uICVzLCBkZXB0aCAlZFxuIiwKCSAgICAoY2hhciAqKSB4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHIsIHZjdHh0LT5ub2RlSW5mby0+bmFtZXNwYWNlTmFtZSwKCQl2Y3R4dC0+bm9kZUluZm8tPmxvY2FsTmFtZSksIHZjdHh0LT5kZXB0aCk7CglGUkVFX0FORF9OVUxMKHN0cikKICAgIH0KI2VuZGlmCiAgICBpZiAodmN0eHQtPm5vZGVJbmZvLT5pZGNNYXRjaGVycyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZSwKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6ICIKCSAgICAiVGhlIGNoYWluIG9mIElEQyBtYXRjaGVycyBpcyBleHBlY3RlZCB0byBiZSBlbXB0eS5cbiIsCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGRvIHsKCWlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCSAgICAvKgoJICAgICogU2luY2UgSURDcyBidWJibGVzIGFyZSBleHBlbnNpdmUgd2UgbmVlZCB0byBrbm93IHRoZQoJICAgICogZGVwdGggYXQgd2hpY2ggdGhlIGJ1YmJsZXMgc2hvdWxkIHN0b3A7IHRoaXMgd2lsbCBiZQoJICAgICogdGhlIGRlcHRoIG9mIHRoZSB0b3AtbW9zdCBrZXlyZWYgSURDLiBJZiBubyBrZXlyZWYKCSAgICAqIHJlZmVyZW5jZXMgYSBrZXkvdW5pcXVlIElEQywgdGhlIGJ1YmJsZURlcHRoIHdpbGwKCSAgICAqIGJlIC0xLCBpbmRpY2F0aW5nIHRoYXQgbm8gYnViYmxlcyBhcmUgbmVlZGVkLgoJICAgICovCgkgICAgcmVmSWRjID0gKHhtbFNjaGVtYUlEQ1B0cikgaWRjLT5yZWYtPml0ZW07CgkgICAgaWYgKHJlZklkYyAhPSBOVUxMKSB7CgkJLyoKCQkqIExvb2t1cCB0aGUgYXVnbWVudGVkIElEQy4KCQkqLwoJCWFpZGMgPSB2Y3R4dC0+YWlkY3M7CgkJd2hpbGUgKGFpZGMgIT0gTlVMTCkgewoJCSAgICBpZiAoYWlkYy0+ZGVmID09IHJlZklkYykKCQkJYnJlYWs7CgkJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJCX0KCQlpZiAoYWlkYyA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlLAoJCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzOiAiCgkJCSJDb3VsZCBub3QgZmluZCBhbiBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIGFuIElEQyAiCgkJCSJkZWZpbml0aW9uLlxuIiwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJCWlmICgoYWlkYy0+YnViYmxlRGVwdGggPT0gLTEpIHx8CgkJICAgICh2Y3R4dC0+ZGVwdGggPCBhaWRjLT5idWJibGVEZXB0aCkpCgkJICAgIGFpZGMtPmJ1YmJsZURlcHRoID0gdmN0eHQtPmRlcHRoOwoJICAgIH0KCX0KCS8qCgkqIExvb2t1cCB0aGUgYXVnbWVudGVkIElEQyBpdGVtIGZvciB0aGUgSURDIGRlZmluaXRpb24uCgkqLwoJYWlkYyA9IHZjdHh0LT5haWRjczsKCXdoaWxlIChhaWRjICE9IE5VTEwpIHsKCSAgICBpZiAoYWlkYy0+ZGVmID09IGlkYykKCQlicmVhazsKCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0KCWlmIChhaWRjID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZSwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6ICIKCQkiQ291bGQgbm90IGZpbmQgYW4gYXVnbWVudGVkIElEQyBpdGVtIGZvciBhbiBJREMgZGVmaW5pdGlvbi5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiBDcmVhdGUgYW4gSURDIG1hdGNoZXIgZm9yIGV2ZXJ5IElEQyBkZWZpbml0aW9uLgoJKi8KCW1hdGNoZXIgPSAoeG1sU2NoZW1hSURDTWF0Y2hlclB0cikgCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFJRENNYXRjaGVyKSk7CglpZiAobWF0Y2hlciA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgYW4gSURDIG1hdGNoZXIiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCW1lbXNldChtYXRjaGVyLCAwLCBzaXplb2YoeG1sU2NoZW1hSURDTWF0Y2hlcikpOwoJaWYgKGxhc3QgPT0gTlVMTCkKCSAgICB2Y3R4dC0+bm9kZUluZm8tPmlkY01hdGNoZXJzID0gbWF0Y2hlcjsKCWVsc2UKCSAgICBsYXN0LT5uZXh0ID0gbWF0Y2hlcjsKCWxhc3QgPSBtYXRjaGVyOwoKCW1hdGNoZXItPnR5cGUgPSBJRENfTUFUQ0hFUjsKCW1hdGNoZXItPmRlcHRoID0gdmN0eHQtPmRlcHRoOwkKCW1hdGNoZXItPmFpZGMgPSBhaWRjOwojaWYgREVCVUdfSURDCQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJJREM6ICAgcmVnaXN0ZXIgbWF0Y2hlclxuIik7CiNlbmRpZiAKCS8qCgkqIEluaXQgdGhlIGF1dG9tYXRvbiBzdGF0ZSBvYmplY3QuIAoJKi8KCWlmICh4bWxTY2hlbWFJRENBZGRTdGF0ZU9iamVjdCh2Y3R4dCwgbWF0Y2hlciwgCgkgICAgaWRjLT5zZWxlY3RvciwgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKCglpZGMgPSBpZGMtPm5leHQ7CiAgICB9IHdoaWxlIChpZGMgIT0gTlVMTCk7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlczogCiAqIEBkZXB0aDogdGhlIGN1cnJlbnQgdHJlZSBkZXB0aAogKgogKiBNZXJnZXMgSURDIGJpbmRpbmdzIG9mIGFuIGVsZW1lbnQgYXQgQGRlcHRoIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgSURDIAogKiBiaW5kaW5ncyBvZiBpdHMgcGFyZW50IGVsZW1lbnQuIElmIGEgZHVwbGljYXRlIG5vdGUtdGFibGUgZW50cnkgaXMgZm91bmQsIAogKiBib3RoLCB0aGUgcGFyZW50IG5vZGUtdGFibGUgZW50cnkgYW5kIGNoaWxkIGVudHJ5IGFyZSBkaXNjYXJkZWQgZnJvbSB0aGUgCiAqIG5vZGUtdGFibGUgb2YgdGhlIHBhcmVudC4KICoKICogUmV0dXJucyAwIGlmIE9LIGFuZCAtMSBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1YmJsZUlEQ05vZGVUYWJsZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOyAvKiBJREMgYmluZGluZ3Mgb2YgdGhlIGN1cnJlbnQgbm9kZS4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyICpwYXJUYWJsZSwgcGFyQmluZCA9IE5VTEwsIGxhc3RQYXJCaW5kID0gTlVMTDsgLyogcGFyZW50IElEQyBiaW5kaW5ncy4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG5vZGUsIHBhck5vZGUgPSBOVUxMOyAvKiBub2RlLXRhYmxlIGVudHJpZXMuICovCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIGtleSwgcGFyS2V5OyAvKiBrZXlzIG9mIGluIGEga2V5LXNlcXVlbmNlLiAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7CiAgICBpbnQgaSwgaiwgaywgcmV0ID0gMCwgb2xkTnVtLCBuZXdEdXBscyA9IDA7CiAgICBpbnQgZHVwbFRvcDsKCiAgICAvKgogICAgKiBUaGUgbm9kZSB0YWJsZSBoYXMgdGhlIGZvbGxvd2luZyBzZWN0aW9uczoKICAgICoKICAgICogIE8gLS0+IG9sZCBub2RlLXRhYmxlIGVudHJpZXMgKGZpcnN0KQogICAgKiAgTyAKICAgICogICsgLS0+IG5ldyBub2RlLXRhYmxlIGVudHJpZXMKICAgICogICsgCiAgICAqICAlIC0tPiBuZXcgZHVwbGljYXRlIG5vZGUtdGFibGUgZW50cmllcyAgICAKICAgICogICUgCiAgICAqICAjIC0tPiBvbGQgZHVwbGljYXRlIG5vZGUtdGFibGUgZW50cmllcyAgICAKICAgICogICMgKGxhc3QpCiAgICAqCiAgICAqLwogICAgYmluZCA9IHZjdHh0LT5ub2RlSW5mby0+aWRjVGFibGU7ICAgICAgICAKICAgIGlmIChiaW5kID09IE5VTEwpIHsKCS8qIEZpbmUsIG5vIHRhYmxlLCBubyBidWJibGVzLiAqLwoJcmV0dXJuICgwKTsKICAgIH0KICAgIAogICAgcGFyVGFibGUgPSAmKHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoIC0xXS0+aWRjVGFibGUpOwogICAgLyoKICAgICogV2FsayBhbGwgYmluZGluZ3M7IGNyZWF0ZSBuZXcgb3IgYWRkIHRvIGV4aXN0aW5nIGJpbmRpbmdzLgogICAgKiBSZW1vdmUgZHVwbGljYXRlIGtleS1zZXF1ZW5jZXMuCiAgICAqLwpzdGFydF9iaW5kaW5nOgogICAgd2hpbGUgKGJpbmQgIT0gTlVMTCkgewoJLyoKCSogU2tpcCBrZXlyZWYgSURDcy4KCSovCglpZiAoYmluZC0+ZGVmaW5pdGlvbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIGJpbmQgPSBiaW5kLT5uZXh0OwoJICAgIGNvbnRpbnVlOwoJfQoJLyoKCSogQ2hlY2sgaWYgdGhlIGtleS91bmlxdWUgSURDIHRhYmxlIG5lZWRzIHRvIGJlIGJ1YmJsZWQuCgkqLwoJYWlkYyA9IHZjdHh0LT5haWRjczsKCWRvIHsKCSAgICBpZiAoYWlkYy0+ZGVmID09IGJpbmQtPmRlZmluaXRpb24pIHsKCQlpZiAoYWlkYy0+YnViYmxlRGVwdGggPj0gdmN0eHQtPmRlcHRoKSB7CgkJICAgIGJpbmQgPSBiaW5kLT5uZXh0OwoJCSAgICBnb3RvIHN0YXJ0X2JpbmRpbmc7CgkJfQoJCWJyZWFrOwoJICAgIH0KCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7CgoJaWYgKHBhclRhYmxlICE9IE5VTEwpCgkgICAgcGFyQmluZCA9ICpwYXJUYWJsZTsKCXdoaWxlIChwYXJCaW5kICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogU2VhcmNoIGEgbWF0Y2hpbmcgcGFyZW50IGJpbmRpbmcgZm9yIHRoZQoJICAgICogSURDIGRlZmluaXRpb24uCgkgICAgKi8KCSAgICBpZiAocGFyQmluZC0+ZGVmaW5pdGlvbiA9PSBiaW5kLT5kZWZpbml0aW9uKSB7CgoJCS8qCgkJKiBDb21wYXJlIGV2ZXJ5IG5vZGUtdGFibGUgZW50cnkgb2YgdGhlIGNoaWxkIG5vZGUsIAoJCSogaS5lLiB0aGUga2V5LXNlcXVlbmNlIHdpdGhpbiwgLi4uCgkJKi8KCQlvbGROdW0gPSBwYXJCaW5kLT5uYk5vZGVzOyAvKiBTa2lwIG5ld2x5IGFkZGVkIGl0ZW1zLiAqLwoJCWR1cGxUb3AgPSBvbGROdW0gKyBwYXJCaW5kLT5uYkR1cGxzOwoKCQlmb3IgKGkgPSAwOyBpIDwgYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJICAgIG5vZGUgPSBiaW5kLT5ub2RlVGFibGVbaV07CgkJICAgIGlmIChub2RlID09IE5VTEwpCgkJCWNvbnRpbnVlOwoJCSAgICAvKgoJCSAgICAqIC4uLndpdGggZXZlcnkga2V5LXNlcXVlbmNlIG9mIHRoZSBwYXJlbnQgbm9kZSwgYWxyZWFkeQoJCSAgICAqIGV2YWx1YXRlZCB0byBiZSBhIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2UuCgkJICAgICovCgkJICAgIGlmIChwYXJCaW5kLT5uYkR1cGxzICE9IDApIHsKCQkJaiA9IGJpbmQtPm5iTm9kZXMgKyBuZXdEdXBsczsgCgkJCXdoaWxlIChqIDwgZHVwbFRvcCkgewoJCQkgICAgcGFyTm9kZSA9IHBhckJpbmQtPm5vZGVUYWJsZVtqXTsKCQkJICAgIGZvciAoayA9IDA7IGsgPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaysrKSB7CgkJCQlrZXkgPSBub2RlLT5rZXlzW2tdOwoJCQkJcGFyS2V5ID0gcGFyTm9kZS0+a2V5c1trXTsKCQkJCXJldCA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKHZjdHh0LCBrZXktPnR5cGUsIAoJCQkJICAgIGtleS0+Y29tcFZhbHVlLAoJCQkJICAgIHBhcktleS0+dHlwZSwgcGFyS2V5LT5jb21wVmFsdWUpOwoJCQkJaWYgKHJldCA9PSAtMSkgewoJCQkJICAgIC8qIFRPRE86IEludGVybmFsIGVycm9yICovCgkJCQkgICAgcmV0dXJuKC0xKTsKCQkJCX0gZWxzZSBpZiAocmV0ID09IDApCgkJCQkgICAgYnJlYWs7CgoJCQkgICAgfQoJCQkgICAgaWYgKHJldCA9PSAxKQoJCQkJLyogRHVwbGljYXRlIGZvdW5kLiAqLwoJCQkJYnJlYWs7CgkJCSAgICBqKys7CgkJCX0KCQkJaWYgKGogIT0gZHVwbFRvcCkgewoJCQkgICAgLyogRHVwbGljYXRlIGZvdW5kLiAqLwoJCQkgICAgY29udGludWU7CgkJCX0KCQkgICAgfQkJICAgIAoJCSAgICAvKgoJCSAgICAqIC4uLiBhbmQgd2l0aCBldmVyeSBrZXktc2VxdWVuY2Ugb2YgdGhlIHBhcmVudCBub2RlLgoJCSAgICAqLwkJICAgIAkJICAgIAoJCSAgICBqID0gMDsKCQkgICAgd2hpbGUgKGogPCBvbGROdW0pIHsKCQkJcGFyTm9kZSA9IHBhckJpbmQtPm5vZGVUYWJsZVtqXTsKCQkJLyoKCQkJKiBDb21wYXJlIGtleSBieSBrZXkuIAoJCQkqLwoJCQlmb3IgKGsgPSAwOyBrIDwgcGFyQmluZC0+ZGVmaW5pdGlvbi0+bmJGaWVsZHM7IGsrKykgewoJCQkgICAga2V5ID0gbm9kZS0+a2V5c1trXTsKCQkJICAgIHBhcktleSA9IHBhck5vZGUtPmtleXNba107CQkJCgoJCQkgICAgcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwodmN0eHQsIGtleS0+dHlwZSwgCgkJCQlrZXktPmNvbXBWYWx1ZSwKCQkJCXBhcktleS0+dHlwZSwgcGFyS2V5LT5jb21wVmFsdWUpOwoJCQkgICAgaWYgKHJldCA9PSAtMSkgewoJCQkJLyogVE9ETzogSW50ZXJuYWwgZXJyb3IgKi8KCQkJICAgIH0gZWxzZSBpZiAocmV0ID09IDApCgkJCQlicmVhazsKCgkJCX0KCQkJaWYgKHJldCA9PSAxKQoJCQkgICAgLyoKCQkJICAgICogVGhlIGtleS1zZXF1ZW5jZXMgYXJlIGVxdWFsLgoJCQkgICAgKi8KCQkJICAgIGJyZWFrOwoJCQlqKys7CgkJICAgIH0KCQkgICAgaWYgKGogIT0gb2xkTnVtKSB7CgkJCS8qCgkJCSogSGFuZGxlIGR1cGxpY2F0ZXMuCgkJCSovCgkJCW5ld0R1cGxzKys7CgkJCW9sZE51bS0tOwoJCQlwYXJCaW5kLT5uYk5vZGVzLS07CgkJCS8qCgkJCSogTW92ZSBsYXN0IG9sZCBpdGVtIHRvIHBvcyBvZiBkdXBsaWNhdGUuCgkJCSovCgkJCXBhckJpbmQtPm5vZGVUYWJsZVtqXSA9IAoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW29sZE51bV07CgkJCQoJCQlpZiAocGFyQmluZC0+bmJOb2RlcyAhPSBvbGROdW0pIHsKCQkJICAgIC8qCgkJCSAgICAqIElmIG5ldyBpdGVtcyBleGlzdCwgbW92ZSBsYXN0IG5ldyBpdGVtIHRvIAoJCQkgICAgKiBsYXN0IG9mIG9sZCBpdGVtcy4KCQkJICAgICovCgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGVbb2xkTnVtXSA9IAoJCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdOwoJCQl9CgkJCS8qCgkJCSogTW92ZSBkdXBsaWNhdGUgdG8gbGFzdCBwb3Mgb2YgbmV3L29sZCBpdGVtcy4KCQkJKi8KCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdID0gcGFyTm9kZTsJCQkKCQkJCgkJICAgIH0gZWxzZSB7CgkJCS8qCgkJCSogQWRkIHRoZSBub2RlLXRhYmxlIGVudHJ5IChub2RlIGFuZCBrZXktc2VxdWVuY2UpIG9mIAoJCQkqIHRoZSBjaGlsZCBub2RlIHRvIHRoZSBub2RlIHRhYmxlIG9mIHRoZSBwYXJlbnQgbm9kZS4KCQkJKi8KCQkJaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CQkJCgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkJCQl4bWxNYWxsb2MoMSAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJCQkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkJICAgICJhbGxvY2F0aW5nIElEQyBsaXN0IG9mIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCQkJCXJldHVybigtMSk7CgkJCSAgICB9CgkJCSAgICBwYXJCaW5kLT5zaXplTm9kZXMgPSAxOwoJCQl9IGVsc2UgaWYgKGR1cGxUb3AgPj0gcGFyQmluZC0+c2l6ZU5vZGVzKSB7CgkJCSAgICBwYXJCaW5kLT5zaXplTm9kZXMrKzsKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQkJCXhtbFJlYWxsb2MocGFyQmluZC0+bm9kZVRhYmxlLCBwYXJCaW5kLT5zaXplTm9kZXMgKiAKCQkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJCQkgICAgaWYgKHBhckJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkJICAgICJyZS1hbGxvY2F0aW5nIElEQyBsaXN0IG9mIG5vZGUtdGFibGUgaXRlbXMiLCBOVUxMKTsKCQkJCXJldHVybigtMSk7CgkJCSAgICB9CgkJCX0KCQkJCgkJCS8qCgkJCSogTW92ZSBmaXJzdCBvbGQgZHVwbGljYXRlIHRvIGxhc3QgcG9zaXRpb24KCQkJKiBvZiBvbGQgZHVwbGljYXRlcyArMS4KCQkJKi8KCQkJaWYgKHBhckJpbmQtPm5iRHVwbHMgIT0gMCkgewoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW2R1cGxUb3BdID0KCQkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzICsgbmV3RHVwbHNdOwoJCQl9CgkJCS8qCgkJCSogTW92ZSBmaXJzdCBuZXcgZHVwbGljYXRlIHRvIGxhc3QgcG9zaXRpb24gb2YKCQkJKiBuZXcgZHVwbGljYXRlcyArMS4KCQkJKi8KCQkJaWYgKG5ld0R1cGxzICE9IDApIHsKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzICsgbmV3RHVwbHNdID0KCQkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXTsKCQkJfQoJCQkvKgoJCQkqIEFwcGVuZCB0aGUgbmV3IG5vZGUtdGFibGUgZW50cnkgdG8gdGhlICduZXcgbm9kZS10YWJsZQoJCQkqIGVudHJpZXMnIHNlY3Rpb24uCgkJCSovCgkJCXBhckJpbmQtPm5vZGVUYWJsZVtwYXJCaW5kLT5uYk5vZGVzXSA9IG5vZGU7CgkJCXBhckJpbmQtPm5iTm9kZXMrKzsKCQkJZHVwbFRvcCsrOwoJCSAgICB9CgkJfQoJCXBhckJpbmQtPm5iRHVwbHMgKz0gbmV3RHVwbHM7CgkJYnJlYWs7CgkgICAgfQoJICAgIGlmIChwYXJCaW5kLT5uZXh0ID09IE5VTEwpCgkJbGFzdFBhckJpbmQgPSBwYXJCaW5kOwoJICAgIHBhckJpbmQgPSBwYXJCaW5kLT5uZXh0OwoJfQoJaWYgKHBhckJpbmQgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBObyBiaW5kaW5nIGZvciB0aGUgSURDIHdhcyBmb3VuZDogY3JlYXRlIGEgbmV3IG9uZSBhbmQKCSAgICAqIGNvcHkgYWxsIG5vZGUtdGFibGVzLgoJICAgICovCgkgICAgcGFyQmluZCA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcoYmluZC0+ZGVmaW5pdGlvbik7CgkgICAgaWYgKHBhckJpbmQgPT0gTlVMTCkKCQlyZXR1cm4oLTEpOwoKCSAgICBwYXJCaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkJeG1sTWFsbG9jKGJpbmQtPm5iTm9kZXMgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCXhtbFNjaGVtYUlEQ0ZyZWVCaW5kaW5nKHBhckJpbmQpOwoJCXJldHVybigtMSk7CgkgICAgfQoJICAgIHBhckJpbmQtPnNpemVOb2RlcyA9IGJpbmQtPm5iTm9kZXM7CgkgICAgcGFyQmluZC0+bmJOb2RlcyA9IGJpbmQtPm5iTm9kZXM7CgkgICAgbWVtY3B5KHBhckJpbmQtPm5vZGVUYWJsZSwgYmluZC0+bm9kZVRhYmxlLAoJCWJpbmQtPm5iTm9kZXMgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCSAgICBpZiAoKnBhclRhYmxlID09IE5VTEwpCgkJKnBhclRhYmxlID0gcGFyQmluZDsKCSAgICBlbHNlCgkJbGFzdFBhckJpbmQtPm5leHQgPSBwYXJCaW5kOwoJfQoJYmluZCA9IGJpbmQtPm5leHQ7CiAgICB9ICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZjoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbURlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqCiAqIENoZWNrIHRoZSBjdmMtaWRjLWtleXJlZiBjb25zdHJhaW50cy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWYoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciByZWZiaW5kLCBiaW5kOwoKICAgIHJlZmJpbmQgPSB2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlOwogICAgLyoKICAgICogRmluZCBhIGtleXJlZi4KICAgICovCiAgICB3aGlsZSAocmVmYmluZCAhPSBOVUxMKSB7CglpZiAocmVmYmluZC0+ZGVmaW5pdGlvbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIGludCBpLCBqLCBrLCByZXM7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqcmVmS2V5cywgKmtleXM7CgkgICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciByZWZLZXksIGtleTsKCgkgICAgLyoKCSAgICAqIEZpbmQgdGhlIHJlZmVycmVkIGtleS91bmlxdWUuCgkgICAgKi8KCSAgICBiaW5kID0gdmN0eHQtPm5vZGVJbmZvLT5pZGNUYWJsZTsKCSAgICBkbyB7CgkJaWYgKCh4bWxTY2hlbWFJRENQdHIpIHJlZmJpbmQtPmRlZmluaXRpb24tPnJlZi0+aXRlbSA9PSAKCQkgICAgYmluZC0+ZGVmaW5pdGlvbikKCQkgICAgYnJlYWs7CgkJYmluZCA9IGJpbmQtPm5leHQ7CgkgICAgfSB3aGlsZSAoYmluZCAhPSBOVUxMKTsKCgkgICAgLyoKCSAgICAqIFNlYXJjaCBmb3IgYSBtYXRjaGluZyBrZXktc2VxdWVuY2VzLgoJICAgICovCgkgICAgZm9yIChpID0gMDsgaSA8IHJlZmJpbmQtPm5iTm9kZXM7IGkrKykgewoJCXJlcyA9IDA7CgkJaWYgKGJpbmQgIT0gTlVMTCkgewkJICAgIAoJCSAgICByZWZLZXlzID0gcmVmYmluZC0+bm9kZVRhYmxlW2ldLT5rZXlzOwoJCSAgICBmb3IgKGogPSAwOyBqIDwgYmluZC0+bmJOb2RlczsgaisrKSB7CgkJCWtleXMgPSBiaW5kLT5ub2RlVGFibGVbal0tPmtleXM7CgkJCWZvciAoayA9IDA7IGsgPCBiaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaysrKSB7CgkJCSAgICByZWZLZXkgPSByZWZLZXlzW2tdOwoJCQkgICAga2V5ID0ga2V5c1trXTsKCQkJICAgIHJlcyA9IHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsKHZjdHh0LAoJCQkJa2V5LT50eXBlLCBrZXktPmNvbXBWYWx1ZSwKCQkJCXJlZktleS0+dHlwZSwgcmVmS2V5LT5jb21wVmFsdWUpOwoJCQkgICAgaWYgKHJlcyA9PSAwKQoJCQkJYnJlYWs7CgkJCSAgICBlbHNlIGlmIChyZXMgPT0gLTEpIHsKCQkJCXJldHVybiAoLTEpOwoJCQkgICAgfQoJCQl9CgkJCWlmIChyZXMgPT0gMSkgewoJCQkgICAgLyoKCQkJICAgICogTWF0Y2ggZm91bmQuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCX0KCQkgICAgfQoJCX0KCQlpZiAocmVzID09IDApIHsKCQkgICAgLyogVE9ETzogUmVwb3J0IHRoZSBrZXktc2VxdWVuY2UuICovCgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJCXJlZmJpbmQtPm5vZGVUYWJsZVtpXS0+bm9kZSwgCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSByZWZiaW5kLT5kZWZpbml0aW9uLAoJCQkiTm8gbWF0Y2hpbmcga2V5LXNlcXVlbmNlIGZvdW5kIiwgTlVMTCk7CgkJfQoJICAgIH0KCX0KCXJlZmJpbmQgPSByZWZiaW5kLT5uZXh0OwogICAgfQogICAgcmV0dXJuICgwKTsKfQojZW5kaWYgLyogSURDX0VOQUJMRUQgKi8KCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAovKioKICogeG1sU2NoZW1hQmVnaW5FbGVtZW50OgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEp1c3QgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCB0byBzaW11bGF0ZSBzdHJlYW1pbmcgdmFsaWRhdGlvbgogKiBhIGJpdC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUJlZ2luRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHZjdHh0LT5kZXB0aCsrOwogICAgdmN0eHQtPm5vZGVJbmZvID0geG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyh2Y3R4dCwgdmN0eHQtPmRlcHRoKTsKICAgIHZjdHh0LT5ub2RlSW5mby0+bm9kZSA9IHZjdHh0LT5ub2RlOwogICAgdmN0eHQtPm5vZGVJbmZvLT5sb2NhbE5hbWUgPSB2Y3R4dC0+bm9kZS0+bmFtZTsKICAgIGlmICh2Y3R4dC0+bm9kZS0+bnMgIT0gTlVMTCkKCXZjdHh0LT5ub2RlSW5mby0+bmFtZXNwYWNlTmFtZSA9IHZjdHh0LT5ub2RlLT5ucy0+aHJlZjsKICAgIGVsc2UgCgl2Y3R4dC0+bm9kZUluZm8tPm5hbWVzcGFjZU5hbWUgPSBOVUxMOyAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUVuZEVsZW1lbnQ6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogSnVzdCBhIHRlbXBvcmFyeSB3b3JrYXJvdW5kIHRvIHNpbXVsYXRlIHN0cmVhbWluZyB2YWxpZGF0aW9uCiAqIGEgYml0LgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFFbmRFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgaWYgKHZjdHh0LT5kZXB0aCA8IDApIHsKCS8qIFRPRE86IHJhaXNlIGVycm9yPyAqLwoJdmN0eHQtPmRlcHRoLS07CglyZXR1cm4gKDApOwogICAgfQojaWZkZWYgSURDX0VOQUJMRUQKICAgIC8qCiAgICAqIEV2YWx1YXRlIHRoZSBoaXN0b3J5IG9mIGNoYW5nZXMgb2YgYWN0aXZlIHN0YXRlIG9iamVjdHMuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkodmN0eHQsIHZjdHh0LT5kZXB0aCkgPT0gLTEpCglyZXR1cm4gKC0xKTsKCiAgICBpZiAodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSk7Cgl2Y3R4dC0+bm9kZUluZm8tPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIC8qCiAgICAqIFRPRE86IDYgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIGVhY2ggb2YgCiAgICAqIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uc30gYXMgcGVyIElkZW50aXR5LWNvbnN0cmFpbnQgCiAgICAqIFNhdGlzZmllZCAopzMuMTEuNCkuCiAgICAqLwogICAgLyoKICAgICogVmFsaWRhdGUgSURDIGtleXJlZnMuCiAgICAqLwogICAgeG1sU2NoZW1hQ2hlY2tDVkNJRENLZXlSZWYodmN0eHQpOwojZW5kaWYKICAgIAogICAgLyoKICAgICogTWVyZ2UvZnJlZSB0aGUgSURDIHRhYmxlLgogICAgKi8KICAgIGlmICh2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlICE9IE5VTEwpIHsKI2lmZGVmIElEQ19FTkFCTEVECiNpZmRlZiBERUJVR19JREMKCXhtbFNjaGVtYURlYnVnRHVtcElEQ1RhYmxlKHN0ZG91dCwKCSAgICB2Y3R4dC0+bm9kZUluZm8tPm5hbWVzcGFjZU5hbWUsCgkgICAgdmN0eHQtPm5vZGVJbmZvLT5sb2NhbE5hbWUsCgkgICAgdmN0eHQtPm5vZGVJbmZvLT5pZGNUYWJsZSk7CiNlbmRpZgoJaWYgKHZjdHh0LT5kZXB0aCA+IDApIHsKCSAgICAvKgoJICAgICogTWVyZ2UgdGhlIElEQyBub2RlIHRhYmxlIHdpdGggdGhlIHRhYmxlIG9mIHRoZSBwYXJlbnQgbm9kZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYUJ1YmJsZUlEQ05vZGVUYWJsZXModmN0eHQpOwkgICAgCgl9CgkvKgoJKiBUT0RPOiBEb24ndCBmcmVlIHRoZSBQU1ZJIElEQyB0YWJsZXMgaWYgdGhleSBhcmUKCSogcmVxdWVzdGVkIGZvciB0aGUgUFNWSS4KCSovCgl4bWxTY2hlbWFJRENGcmVlSURDVGFibGUodmN0eHQtPm5vZGVJbmZvLT5pZGNUYWJsZSk7CiNlbmRpZgoJdmN0eHQtPm5vZGVJbmZvLT5pZGNUYWJsZSA9IE5VTEw7CiAgICB9CgogICAgLyoKICAgICogQ2xlYW51cCBJREMgbWF0Y2hlcnMuCiAgICAqLwojaWZkZWYgSURDX0VOQUJMRUQKICAgIGlmICh2Y3R4dC0+bm9kZUluZm8tPmlkY01hdGNoZXJzICE9IE5VTEwpIHsJCgl4bWxTY2hlbWFJRENGcmVlTWF0Y2hlckxpc3QodmN0eHQtPm5vZGVJbmZvLT5pZGNNYXRjaGVycyk7Cgl2Y3R4dC0+bm9kZUluZm8tPmlkY01hdGNoZXJzID0gTlVMTDsKICAgIH0KI2VuZGlmCgogICAgLyoKICAgICogU2tpcCBmdXJ0aGVyIHByb2Nlc3NpbmcgaWYgd2UgYXJlIG9uIHRoZSB2YWxpZGF0aW9uIHJvb3QuCiAgICAqLwogICAgaWYgKHZjdHh0LT5kZXB0aCA9PSAwKSB7Cgl2Y3R4dC0+ZGVwdGgtLTsKCXJldHVybiAoMCk7CiAgICB9CgogICAgLyoKICAgICogUmVzZXQgdGhlIGJ1YmJsZURlcHRoIGlmIG5lZWRlZC4KICAgICovCiNpZmRlZiBJRENfRU5BQkxFRAogICAgaWYgKHZjdHh0LT5haWRjcyAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFJRENBdWdQdHIgYWlkYyA9IHZjdHh0LT5haWRjczsKCWRvIHsKCSAgICBpZiAoYWlkYy0+YnViYmxlRGVwdGggPT0gdmN0eHQtPmRlcHRoKSB7CgkJLyoKCQkqIEEgYnViYmxlRGVwdGggb2YgYSBrZXkvdW5pcXVlIElEQyBtYXRjaGVzIHRoZSBjdXJyZW50CgkJKiBkZXB0aCwgdGhpcyBtZWFucyB0aGF0IHdlIGFyZSBsZWF2aW5nIHRoZSBzY29wZSBvZiB0aGUKCQkqIHRvcC1tb3N0IGtleXJlZiBJREMuCgkJKi8KCQlhaWRjLT5idWJibGVEZXB0aCA9IC0xOwoJICAgIH0KCSAgICBhaWRjID0gYWlkYy0+bmV4dDsKCX0gd2hpbGUgKGFpZGMgIT0gTlVMTCk7CiAgICB9CiNlbmRpZgogICAgdmN0eHQtPmRlcHRoLS07CiAgICAvKgogICAgKiBDbGVhciB0aGUgY3VycmVudCBlbGVtSW5mby4KICAgICovCiAgICBpZiAodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSAhPSBOVUxMKSB7Cgl4bWxTY2hlbWFGcmVlVmFsdWUodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSk7Cgl2Y3R4dC0+bm9kZUluZm8tPnZhbHVlID0gTlVMTDsKICAgIH0KICAgIHZjdHh0LT5ub2RlSW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKICAgIHZjdHh0LT5ub2RlID0gdmN0eHQtPm5vZGVJbmZvLT5ub2RlOwoKICAgIHJldHVybiAoMCk7Cn0KCiNlbmRpZiAvKiBFTEVNX0lORk9fRU5BQkxFRCAqLwoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IHR5cGUuCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChFbGVtZW50KQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2wpCnsKICAgIHhtbE5vZGVQdHIgZWxlbTsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hVHlwZVB0ciBhY3R1YWxUeXBlID0gTlVMTDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIHhtbENoYXIgKmF0dHJWYWx1ZTsgCiAgICBpbnQgbmlsbGVkID0gMCwgZWxlbUhhc0NvbnRlbnQgPSAtMTsKCiAgICAvKiAKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbCwgCiAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZSBhbmQgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LgogICAgKiBOb3RlIHRoYXQgQGVsZW1EZWNsIHdpbGwgYmUgdGhlIGRlY2xhcmF0aW9uIGFuZCBuZXZlciB0aGUKICAgICogcmVmZXJlbmNlIHRvIGEgZGVjbGFyYXRpb24uCiAgICAqLwoKICAgIGlmIChjdHh0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJICAgICJiYWQgYXJndW1lbnRzLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICBlbGVtID0gY3R4dC0+bm9kZTsgICAKCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAxCiAgICAqLwogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzEsIAoJICAgIGVsZW0sIE5VTEwsCgkgICAgIk5vIG1hdGNoaW5nIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIsIE5VTEwpOwoJLyogCgkqIEV2YWx1YXRlIElEQ3MgZXZlbiBpZiBhbiBlcnJvciBvY2N1cmVkLgoJKi8KI2lmZGVmIElEQ19FTkFCTEVECglpZiAoeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZShjdHh0LCBYTUxfRUxFTUVOVF9OT0RFKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMgogICAgKi8KICAgIGlmIChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKSB7Cgl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF8yLAoJICAgIGVsZW0sIE5VTEwsIAoJICAgICJUaGUgZWxlbWVudCBkZWNsYXJhdGlvbiBpcyBhYnN0cmFjdCIsIE5VTEwpOwoJLyogCgkqIEV2YWx1YXRlIElEQ3MgZXZlbiBpZiBhbiBlcnJvciBvY2N1cmVkLgoJKi8KI2lmZGVmIElEQ19FTkFCTEVECglpZiAoeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZShjdHh0LCBYTUxfRUxFTUVOVF9OT0RFKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgIAogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMwogICAgKiBIYW5kbGUgJ3hzaTpuaWwnLgogICAgKi8KICAgIAogICAgYXR0ciA9IHhtbEhhc05zUHJvcChlbGVtLCBCQURfQ0FTVCAibmlsIiwgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CglhdHRyVmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgYXR0cik7CQoJY3R4dC0+bm9kZSA9ICh4bWxOb2RlUHRyKSBhdHRyOwoJY3R4dC0+Y3VyID0gYXR0ci0+Y2hpbGRyZW47CQoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQk9PTEVBTiksCgkgICAgQkFEX0NBU1QgYXR0clZhbHVlLCAxLCAxLCAxLCAxKTsKCWN0eHQtPm5vZGUgPSBlbGVtOwoJY3R4dC0+dHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbDsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkoeG1sTm9kZVB0cikgYXR0ciwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSJ2YWxpZGF0aW5nIHRoZSBhdHRyaWJ1dGUgJ3hzaTpuaWwnIiwgTlVMTCk7CgkgICAgaWYgKGF0dHJWYWx1ZSAhPSBOVUxMKQoJCXhtbEZyZWUoYXR0clZhbHVlKTsKCSAgICByZXR1cm4gKC0xKTsKCX0gCglpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpID09IDApIHsKCSAgICAvKiAKCSAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDMuMSAKCSAgICAqLwoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzEsIAoJCWVsZW0sIE5VTEwsCgkJIlRoZSBlbGVtZW50IGlzIG5vdCAnbmlsbGFibGUnIiwgTlVMTCk7CQoJfSBlbHNlIHsJCSAgICAKCSAgICBpZiAoeG1sU3RyRXF1YWwoQkFEX0NBU1QgYXR0clZhbHVlLCBCQURfQ0FTVCAidHJ1ZSIpIHx8CgkJeG1sU3RyRXF1YWwoQkFEX0NBU1QgYXR0clZhbHVlLCBCQURfQ0FTVCAiMSIpKSB7CQkKCQlyZXQgPSAwOwoJCS8qIAoJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjEgCgkJKi8KCQllbGVtSGFzQ29udGVudCA9IHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pOwoJCWlmIChlbGVtSGFzQ29udGVudCA9PSAxKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzEsIAoJCQkvKiBYTUxfU0NIRU1BU19FUlJfTk9URU1QVFksICovCgkJCWVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJIlRoZSAnbmlsbGVkJyBlbGVtZW50IG11c3QgaGF2ZSBubyBjaGFyYWN0ZXIgb3IgIgoJCQkiZWxlbWVudCBjb250ZW50IiwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzE7CgkJfQoJCS8qIAoJCSogY3ZjLWVsdCAoMy4zLjQpIDogMy4yLjIgCgkJKi8KCQlpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCgkJICAgIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yLCAKCQkJLyogWE1MX1NDSEVNQVNfRVJSX0hBVkVERUZBVUxULCAqLwoJCQllbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSJUaGVyZSBpcyBhIGZpeGVkIHZhbHVlIGNvbnN0cmFpbnQgZGVmaW5lZCBmb3IgIgoJCQkidGhlICduaWxsZWQnIGVsZW1lbnQiLCBOVUxMKTsJCSAgICAKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMjsKCQl9CgkJaWYgKHJldCA9PSAwKQoJCSAgICBuaWxsZWQgPSAxOwkJCgkgICAgfQoJfQoJaWYgKGF0dHJWYWx1ZSAhPSBOVUxMKQoJICAgIHhtbEZyZWUoYXR0clZhbHVlKTsKICAgIH0KICAgIAoKICAgIGFjdHVhbFR5cGUgPSBlbGVtRGVjbC0+c3VidHlwZXM7CiAgICAvKiAKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNCAKICAgICogSGFuZGxlICd4c2k6dHlwZScuCiAgICAqLwogICAgCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJ0eXBlIiwgIHhtbFNjaGVtYUluc3RhbmNlTnMpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewkKCXhtbENoYXIgKm5zTmFtZSA9IE5VTEwsICpsb2NhbCA9IE5VTEw7CgkKCS8qCgkqIFRPRE86IFdlIHNob3VsZCByZXBvcnQgYSAqd2FybmluZyogdGhhdCB0aGUgdHlwZSB3YXMgb3ZlcnJpZGVuCgkqIGJ5IHRoZSBpbnN0YW5jZS4KCSovCgkKCS8qIAoJKiBjdmMtZWx0ICgzLjMuNCkgOiA0LjEgCgkqLwoJYXR0clZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoKHhtbE5vZGVQdHIpIGF0dHIpOwoJcmV0ID0geG1sU2NoZW1hVmFsUU5hbWVBY3F1aXJlKGF0dHJWYWx1ZSwgYXR0ci0+cGFyZW50LAkKCSAgICAmbnNOYW1lLCAmbG9jYWwpOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJInZhbGlkYXRpbmcgdGhlIGF0dHJpYnV0ZSAneHNpOnR5cGUnIiwgTlVMTCk7OwoJICAgIEZSRUVfQU5EX05VTEwoYXR0clZhbHVlKQoJCUZSRUVfQU5EX05VTEwobnNOYW1lKQoJCUZSRUVfQU5EX05VTEwobG9jYWwpCgkJcmV0dXJuICgtMSk7Cgl9IGVsc2UgaWYgKHJldCA9PSAxKSB7CgkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJKHhtbE5vZGVQdHIpIGF0dHIsIGF0dHJWYWx1ZSwgCgkJeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpKTsKCX0gZWxzZSBpZiAocmV0ID09IDIpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSksCgkJIlRoZSBRTmFtZSB2YWx1ZSAnJXMnIGhhcyBubyAiCgkJImNvcnJlc3BvbmRpbmcgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIGluIHNjb3BlIiwgCgkJYXR0clZhbHVlKTsJICAgIAkgICAgCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA0LjIgCgkgICAgKi8KCSAgICBhY3R1YWxUeXBlID0geG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGxvY2FsLCBuc05hbWUpOwoJICAgIGlmIChhY3R1YWxUeXBlID09IE5VTEwpIHsJICAKCQl4bWxDaGFyICpzdHJBID0gTlVMTDsKCQkKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNF8yLAoJCSAgICAoeG1sTm9kZVB0cikgYXR0ciwgCgkJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkgICAgIlRoZSB2YWx1ZSAlcyBkb2VzIG5vdCByZXNvbHZlIHRvIGEgdHlwZSAiCgkJICAgICJkZWZpbml0aW9uIiwgCgkJICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIG5zTmFtZSwgbG9jYWwpKTsKCQlGUkVFX0FORF9OVUxMKHN0ckEpOyAgICAKCSAgICB9IGVsc2UgewkJCgkJLyoKCQkqIFVSR0VOVCBUT0RPOiBjdmMtZWx0ICgzLjMuNCkgOiA0LjMgKFR5cGUgRGVyaXZhdGlvbiBPSykKCQkqLwkJCgkgICAgfQoJfQoJRlJFRV9BTkRfTlVMTChhdHRyVmFsdWUpCglGUkVFX0FORF9OVUxMKG5zTmFtZSkKCUZSRUVfQU5EX05VTEwobG9jYWwpCiAgICB9CQkKICAgIC8qIFRPRE86IENoYW5nZSB0aGUgaGFuZGxpbmcgb2YgbWlzc2luZyB0eXBlcyBhY2NvcmRpbmcgdG8KICAgICogdGhlIHNwZWMuCiAgICAqLwogICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewogICAgCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCiAgICAJICAgIFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEsCiAgICAJICAgIGVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwgCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIsIE5VTEwpOwoJLyogCgkqIEV2YWx1YXRlIElEQ3MgZXZlbiBpZiBhbiBlcnJvciBvY2N1cmVkLgoJKi8KI2lmZGVmIElEQ19FTkFCTEVECglpZiAoeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZShjdHh0LCBYTUxfRUxFTUVOVF9OT0RFKSA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKI2VuZGlmCiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8xKTsKICAgIH0KICAgIAogICAgLyoKICAgICogUmVtZW1iZXIgdGhlIGFjdHVhbC10eXBlIGRlZmluaXRpb24uCiAgICAqLwojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIGN0eHQtPm5vZGVJbmZvLT50eXBlRGVmID0gYWN0dWFsVHlwZTsKI2VuZGlmCiAgICAKICAgIC8qCiAgICAqIFRPRE86IFNpbmNlIHRoaXMgc2hvdWxkIGJlIGFscmVhZHkgY2hlY2tlZCBieSB0aGUgY29udGVudCBtb2RlbCBhdXRvbWF0b24sCiAgICAqIGFuZCB3ZSB3YW50IHRvIGdldCByaWQgb2YgdGhlIFhNTF9TQ0hFTUFTX0VSUi4uLiB0eXBlcywgdGhlIGVycm9yIGNvZGUKICAgICogaGFzIGJlZW4gY2hhbmdlZCB0byBYTUxfU0NIRU1BVl9JTlRFUk5BTC4KICAgICovCiAgICAvKgogICAgaWYgKGNoaWxkID09IE5VTEwpIHsKICAgICAgICBpZiAoZGVjbC0+bWluT2NjdXJzID4gMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywgCgkJIkVsZW1lbnQgJXM6IG1pc3NpbmcgY2hpbGQgJXNcbiIsCgkJbm9kZS0+bmFtZSwgZGVjbC0+bmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0gCiAgICAqLwogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBtYXRjaGVzCiAgICAgKiBUT0RPLCBGSVhNRTogQ2FuIHRoaXMgc3RpbGwgaGFwcGVuIGhlcmU/IElzbid0IHRoaXMgYWxyZWFkeSBjaGVja2VkCiAgICAgKiBieSB0aGUgY29udGVudCBtb2RlbCBhdXRvbWF0b24/ICAgICAgICAgCiAgICBpZiAoIXhtbFN0ckVxdWFsKGNoaWxkLT5uYW1lLCBkZWNsLT5uYW1lKSkgewogICAgICAgIHhtbFNjaGVtYVZFcnIzKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICBYTUxfU0NIRU1BU19FUlJfV1JPTkdFTEVNLCAKCSAgICAiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlcyBmb3VuZCAlc1xuIiwKCSAgICBub2RlLT5uYW1lLCBkZWNsLT5uYW1lLCBjaGlsZC0+bmFtZSk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgKi8gICAgCiAgICBpZiAoZWxlbUhhc0NvbnRlbnQgPT0gLTEpCgllbGVtSGFzQ29udGVudCA9IHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pOwoKICAgIC8qCiAgICAqIElEQzogUmVnaXN0ZXIgaWRlbnRpdHktY29uc3RyYWludCBYUGF0aCBtYXRjaGVycy4KICAgICovCiNpZmRlZiBJRENfRU5BQkxFRAogICAgaWYgKGVsZW1EZWNsLT5pZGNzICE9IE5VTEwpCgl4bWxTY2hlbWFJRENSZWdpc3Rlck1hdGNoZXJzKGN0eHQsIGVsZW1EZWNsKTsKICAgIC8qIAogICAgKiBFdmFsdWF0ZSBJRENzLgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsIFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJcmV0dXJuICgtMSk7CiNlbmRpZgogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNSAKICAgICogVGhlIGFwcHJvcHJpYXRlIGNhc2UgYW1vbmcgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgLyoKICAgICogY3ZjLWVsdCAoMy4zLjQpIDogNS4xIAogICAgKiBJZiB0aGUgZGVjbGFyYXRpb24gaGFzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCAKICAgICogdGhlIGl0ZW0gaGFzIG5laXRoZXIgZWxlbWVudCBub3IgY2hhcmFjdGVyIFtjaGlsZHJlbl0gYW5kIAogICAgKiBjbGF1c2UgMy4yIGhhcyBub3QgYXBwbGllZCwgdGhlbiBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CiAgICAqLwogICAgaWYgKChlbGVtSGFzQ29udGVudCA9PSAwKSAmJiAobmlsbGVkID09IDApICYmIChlbGVtRGVjbC0+dmFsdWUgIT0gTlVMTCkpIHsKCS8qCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDUuMS4xIAoJKiBJZiB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGlzIGEgt2xvY2FsIHR5cGUgZGVmaW5pdGlvbrcKCSogdGhlbiB0aGUgY2Fub25pY2FsIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fQoJKiB2YWx1ZSBtdXN0IGJlIGEgdmFsaWQgZGVmYXVsdCBmb3IgdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBhcyAKCSogZGVmaW5lZCBpbiBFbGVtZW50IERlZmF1bHQgVmFsaWQgKEltbWVkaWF0ZSkgKKczLjMuNikuIAoJKi8KCS8qIAoJKiBOT1RFOiAnbG9jYWwnIGFib3ZlIG1lYW5zIHR5cGVzIGFxdWlyZWQgYnkgeHNpOnR5cGUuCgkqLwoJcmV0ID0gMDsKCWlmIChhY3R1YWxUeXBlICE9IGVsZW1EZWNsLT5zdWJ0eXBlcykgewoJICAgIHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dChjdHh0KTsKCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdChjdHh0LT5wY3R4dCwgY3R4dCwgYWN0dWFsVHlwZSwgCgkJZWxlbURlY2wtPnZhbHVlLCBOVUxMKTsJICAgIAoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSAgICBlbGVtLCBhY3R1YWxUeXBlLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkgICAgInZhbGlkYXRpbmcgYSBkZWZhdWx0IHZhbHVlIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJfQoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjIgCgkqIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gd2l0aCB0aGUgY2Fub25pY2FsIGxleGljYWwgCgkqIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUgdXNlZCBhcyBpdHMgCgkqILdub3JtYWxpemVkIHZhbHVltyBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IHRvIHRoZSAKCSogt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIGRlZmluZWQgYnkgRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKQoJKiAopzMuMy40KS4KCSovCgkvKgogICAgICAgICogRGlzYWJsZSB2YWxpZGF0aW9uIG9mIHRoZSBzaW1wbGUgY29udGVudCwgaWYgaXQgd2FzIGFscmVhZHkKCSogZG9uZSBhYm92ZS4KCSovCglpZiAocmV0ID09IDApIHsKCSAgICBpZiAoYWN0dWFsVHlwZSAhPSBlbGVtRGVjbC0+c3VidHlwZXMpCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlKGN0eHQsIGFjdHVhbFR5cGUsIDAsIDApOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgMCwgMSk7CgkgICAgY3R4dC0+bm9kZSA9IGVsZW07CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJICAgIGVsZW0sIGFjdHVhbFR5cGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSAgICAidmFsaWRhdGluZyBhZ2FpbnN0IHRoZSB0eXBlIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBQU1ZJOiBDcmVhdGUgYSB0ZXh0IG5vZGUgb24gdGhlIGluc3RhbmNlIGVsZW1lbnQuCgkgICAgKi8KCSAgICBpZiAoY3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSB7CgkJeG1sTm9kZVB0ciB0ZXh0Q2hpbGQ7CgkJCgkJdGV4dENoaWxkID0geG1sTmV3VGV4dChlbGVtRGVjbC0+dmFsdWUpOwoJCWlmICh0ZXh0Q2hpbGQgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJCWVsZW0sIGFjdHVhbFR5cGUsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCQkiY291bGQgbm90IGNyZWF0ZSBhIGRlZmF1bHQgdGV4dCBub2RlIGZvciB0aGUgaW5zdGFuY2UiLCAKCQkJTlVMTCk7CgkJfSBlbHNlCgkJICAgIHhtbEFkZENoaWxkKGVsZW0sIHRleHRDaGlsZCk7CSAgICAKCSAgICB9Cgl9CgogICAgfSBlbHNlIHsJCgkvKgoJKiA1LjIuMSBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCgkqIHRvIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgCgkqIFZhbGlkIChUeXBlKSAopzMuMy40KS4KCSovCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgbmlsbGVkLCAxKTsKCS8qCgkqIENvbnN1bWUgdGhlIGNvbXB1dGVkIHZhbHVlIGZvciBJRENzLCBlY3QuIE5vdGUgdGhhdCBkZWZhdWx0CgkqIHZhbHVlcyBhcmUgbm90IHN1cHBvcnRlZCB5ZXQuCgkqLwojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKCWlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkgICAgY3R4dC0+bm9kZUluZm8tPnZhbHVlID0gY3R4dC0+dmFsdWU7CgkgICAgY3R4dC0+dmFsdWUgPSBOVUxMOwoJfQojZW5kaWYKCWN0eHQtPm5vZGUgPSBlbGVtOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQllbGVtLCBhY3R1YWxUeXBlLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSJjYWxsaW5nIHZhbGlkYXRpb24gYnkgdHlwZSIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogNS4yLjIgSWYgdGhlcmUgaXMgYSBmaXhlZCB7dmFsdWUgY29uc3RyYWludH0gYW5kIGNsYXVzZSAzLjIgaGFzIAoJKiBub3QgYXBwbGllZCwgYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKi8KCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYgKG5pbGxlZCA9PSAwKSkgewoJICAgIC8qCgkgICAgKiA1LjIuMi4xIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBoYXZlIG5vIGVsZW1lbnQgCgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCgkgICAgKgoJICAgICogVE9ETyBSRURVTkRBTlQ6IElmIHRoZSBhY3R1YWwgdHlwZSBleGlzdHMsIHRoZSBhYm92ZSBjYWxsICB0byAKCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSB3aWxsIGFscmVhZHkgY2hlY2sgZm9yIGVsZW1lbnQgCgkgICAgKiBub2Rlcy4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFIYXNFbGVtQ29udGVudChlbGVtKSkgewoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfNV8yXzJfMSwgCgkJICAgIGVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkgICAgIkVsZW1lbnRzIGluIHRoZSBjb250ZW50IGFyZSBub3QgYWxsb3dlZCBpZiBpdCBpcyAiCgkJICAgICJjb25zdHJhaW5lZCBieSBhIGZpeGVkIHZhbHVlIiwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQkvKgoJCSogNS4yLjIuMiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgCgkJKiBiZSB0cnVlOgoJCSovCgkJCgkJaWYgKGFjdHVhbFR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgewoJCSAgICB4bWxDaGFyICp2YWx1ZTsKCQkgICAgLyoKCQkgICAgKiA1LjIuMi4yLjEgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSC3YWN0dWFsIHR5cGUgCgkJICAgICogZGVmaW5pdGlvbrcgaXMgbWl4ZWQsIHRoZW4gdGhlICppbml0aWFsIHZhbHVlKiBvZiB0aGUgCgkJICAgICogaXRlbSBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiAKCQkgICAgKiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgoJCSAgICAqCgkJICAgICogLi4uIHRoZSAqaW5pdGlhbCB2YWx1ZSogb2YgYW4gZWxlbWVudCBpbmZvcm1hdGlvbiAKCQkgICAgKiBpdGVtIGlzIHRoZSBzdHJpbmcgY29tcG9zZWQgb2YsIGluIG9yZGVyLCB0aGUgCgkJICAgICogW2NoYXJhY3RlciBjb2RlXSBvZiBlYWNoIGNoYXJhY3RlciBpbmZvcm1hdGlvbiBpdGVtIGluIAoJCSAgICAqIHRoZSBbY2hpbGRyZW5dIG9mIHRoYXQgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtLgoJCSAgICAqLwoJCSAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgZWxlbS0+Y2hpbGRyZW4sIDEpOwoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgZWxlbURlY2wtPnZhbHVlKSkgewoJCQkvKiAKCQkJKiBUT0RPOiBSZXBvcnQgaW52YWxpZCAmIGV4cGVjdGVkIHZhbHVlcyBhcyB3ZWxsLgoJCQkqIFRPRE86IEltcGxlbWVudCB0aGUgY2Fub25pY2FsIHN0dWZmLgoJCQkqLwoJCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8yXzEsIAoJCQkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSBkb2VzIG5vdCBtYXRjaCB0aGUgY29ub25pY2FsICIKCQkJICAgICJsZXhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaXhlZCBjb25zdHJhaW50IiwgCgkJCSAgICBOVUxMKTsKCQkgICAgfQoJCSAgICBpZiAodmFsdWUgIT0gTlVMTCkKCQkJeG1sRnJlZSh2YWx1ZSk7CgkJfSBlbHNlIGlmICgoYWN0dWFsVHlwZS0+Y29udGVudFR5cGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpIHx8IAoJCSAgICAoYWN0dWFsVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDKSkgewoJCSAgICB4bWxDaGFyICp2YWx1ZTsKCgkJICAgIC8qCgkJICAgICogNS4yLjIuMi4yIElmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgt2FjdHVhbCB0eXBlIAoJCSAgICAqIGRlZmluaXRpb263IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgdGhlbiB0aGUgCgkJICAgICogKmFjdHVhbCB2YWx1ZSogb2YgdGhlIGl0ZW0gbXVzdCBtYXRjaCB0aGUgY2Fub25pY2FsIAoJCSAgICAqIGxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZS4KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBUT0RPOiAqYWN0dWFsIHZhbHVlKiBpcyB0aGUgbm9ybWFsaXplZCB2YWx1ZSwgaW1wbC4gdGhpcy4KCQkgICAgKiBUT0RPOiBSZXBvcnQgaW52YWxpZCAmIGV4cGVjdGVkIHZhbHVlcyBhcyB3ZWxsLgoJCSAgICAqIFRPRE86IEltcGxlbWVudCB0aGUgY2Fub25pY2FsIHN0dWZmLgoJCSAgICAqIAoJCSAgICAqLwoJCSAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgZWxlbS0+Y2hpbGRyZW4sIDEpOwoJCSAgICBpZiAoISB4bWxTdHJFcXVhbChCQURfQ0FTVCB2YWx1ZSwgZWxlbURlY2wtPnZhbHVlKSkgewoJCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8yXzIsIAoJCQkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCQkgICAgIlRoZSBub3JtYWxpemVkIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBjYW5vbmljYWwgIgoJCQkgICAgImxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpeGVkIGNvbnN0cmFpbnQiLCAKCQkJICAgIE5VTEwpOwoJCSAgICB9CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsKCQkgICAgCgkJfQoJCS8qCgkJKiBUT0RPOiBXaGF0IGlmIHRoZSBjb250ZW50IHR5cGUgaXMgbm90ICdtaXhlZCcgb3Igc2ltcGxlPwoJCSovCgoJICAgIH0KCSAgICAKCX0KICAgIH0KICAgIC8qCiAgICAqIFRPRE86IDcgSWYgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyB0aGUgt3ZhbGlkYXRpb24gcm9vdLcsIGl0IG11c3QgYmUgCiAgICAqILd2YWxpZLcgcGVyIFZhbGlkYXRpb24gUm9vdCBWYWxpZCAoSUQvSURSRUYpICinMy4zLjQpLgogICAgKi8KICAgICAgICAgICAgICAgCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBSZXByZXNlbnRzIHRoZSByZWN1cnNpdmUgcG9ydGlvbiBvZiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkLiAKICogTm90IGludGVuZGVkIHRvIGJlIHVzZWQgYnkgb3RoZXIgZnVuY3Rpb25zLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwgCgkJCQkJICAgeG1sTm9kZVB0ciBub2RlKQp7ICAgICAgICAKICAgIGNvbnN0IHhtbENoYXIgKnVyaTsKICAgIGludCByZXQgPSAwOwogICAgeG1sTm9kZVB0ciBjaGlsZDsKCiAgICBpZiAoY3R4dC0+eHNpQXNzZW1ibGUpIHsJCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJRWxlbShjdHh0LCBjdHh0LT5ub2RlKTsKCWlmIChyZXQgPT0gLTEpIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCWN0eHQtPm5vZGUsIE5VTEwsIAkKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudCwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYSBieSB4c2kiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9ICAgIAogICAgaWYgKHdpbGQtPnByb2Nlc3NDb250ZW50cyAhPSBYTUxfU0NIRU1BU19BTllfU0tJUCkgewoJeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gTlVMTDsKCglpZiAobm9kZS0+bnMgIT0gTlVMTCkKCSAgICBkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKCSAgICBub2RlLT5uYW1lLCBub2RlLT5ucy0+aHJlZiwgTlVMTCk7CgllbHNlIAoJICAgIGRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLCBub2RlLT5uYW1lLAoJICAgIE5VTEwsIE5VTEwpOwoJaWYgKGRlY2wgIT0gTlVMTCkgewkJICAgIAoJICAgIGN0eHQtPm5vZGUgPSBub2RlOwkKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIGRlY2wpOwoJICAgIGlmIChyZXQgPCAwKSB7CQkKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQW55SW50ZXJuYWwsICIKCQkgICAgInZhbGlkYXRpbmcgYW4gZWxlbWVudCBpbiB0aGUgY29udGV4dCBvZiBhIHdpbGRjYXJkLiIsCgkJICAgIE5VTEwsIE5VTEwpOwoJICAgIH0KCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UgaWYgKHdpbGQtPnByb2Nlc3NDb250ZW50cyA9PSBYTUxfU0NIRU1BU19BTllfU1RSSUNUKSB7CgkgICAgLyogVE9ETzogQ2hhbmdlIHRvIHByb3BlciBlcnJvciBjb2RlLiAqLwoJICAgIHhtbFNjaGVtYVZXaWxkY2FyZEVycihjdHh0LCBYTUxfU0NIRU1BVl9DVkNfRUxUXzEsCgkJbm9kZSwgd2lsZCwgIk5vIG1hdGNoaW5nIGdsb2JhbCBkZWNsYXJhdGlvbiBhdmFpbGFibGUiKTsKCSAgICAvKiAKCSAgICAqIEV2YWx1YXRlIElEQ3MgZXZlbiBpZiBhIHZhbGlkYXRpb24gZXJyb3Igb2NjdXJlZC4KCSAgICAqLwojaWZkZWYgSURDX0VOQUJMRUQKCSAgICBpZiAoeG1sU2NoZW1hWFBhdGhFdmFsdWF0ZShjdHh0LFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJCXJldHVybigtMSk7CiNlbmRpZgoJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKCX0KCS8qIAoJKiBFdmFsdWF0ZSBJRENzOyB3ZSBuZWVkIHRvIGtub3cgaWYgYW4gSURDIGZpZWxkIHJlc29sdmVzIHRvCgkqIHN1Y2ggYSBub2RlLiBUaGlzIG5vZGUgaGFzIG5vIHR5cGUgZGVmaW5pdGlvbiBhbmQgd2lsbAoJKiBkZWZpbml0ZWx5IHJlc3VsdCBpbiBhbiBJREMgdmFsaWRhdGlvbiBlcnJvciBpZiBhbiBJREMgZmllbGQKCSogcmVzb2x2ZXMuCgkqLwojaWZkZWYgSURDX0VOQUJMRUQKCWlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsIFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJICAgIHJldHVybigtMSk7CiNlbmRpZgogICAgfQogICAgaWYgKG5vZGUtPmNoaWxkcmVuICE9IE5VTEwpIHsJICAgCgljaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwoJZG8gewoJICAgIGlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkJaWYgKGNoaWxkLT5ucyAhPSBOVUxMKQoJCSAgICB1cmkgPSBjaGlsZC0+bnMtPmhyZWY7CgkJZWxzZQoJCSAgICB1cmkgPSBOVUxMOwoJCWlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh3aWxkLCB1cmkpID09IDApIHsKCQkgICAgLyogVE9ETzogZXJyb3IgY29kZS4gKi8KCQkgICAgeG1sU2NoZW1hVldpbGRjYXJkRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwKCQkJY2hpbGQsIHdpbGQsIAoJCQkiVGhlIG5hbWVzcGFjZSBvZiB0aGUgZWxlbWVudCBpcyBub3QgYWxsb3dlZCIpOwoJCSAgICByZXR1cm4gKGN0eHQtPmVycik7ICAKCQl9CiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAoJCWN0eHQtPm5vZGUgPSBjaGlsZDsKCQl4bWxTY2hlbWFCZWdpbkVsZW1lbnQoY3R4dCk7CiNlbmRpZgoJCS8qCgkJKiBSZWN1cnNlIG92ZXIgdGhlIGNoaWxkcmVuLgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsKGN0eHQsIAoJCSAgICB3aWxkLCBjaGlsZCk7CgkJaWYgKHJldCA9PSAtMSkKCQkgICAgcmV0dXJuICgtMSk7CiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAoJCWlmICh4bWxTY2hlbWFFbmRFbGVtZW50KGN0eHQpID09IC0xKQoJCSAgICByZXR1cm4gKC0xKTsKI2VuZGlmCgkJaWYgKHJldCAhPSAwKQoJCSAgICByZXR1cm4gKHJldCk7CQkKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gd2hpbGUgIChjaGlsZCAhPSBOVUxMKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRDb250QnlXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgICAgIAogICAgaWYgKCh0eXBlID09IE5VTEwpIHx8ICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9BTlkpIHx8CgkoY3R4dC0+bm9kZSA9PSBOVUxMKSkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBjdHh0LT5ub2RlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldHVybih4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoY3R4dCwgCgkgICAgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIGN0eHQtPm5vZGUpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQW55VHlwZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY3VycmVudCBlbGVtZW50CiAqCiAqIFRoaXMgb25lIHZhbGlkYXRlcyB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IG9mIHRoZSB0eXBlCiAqICdhbnlUeXBlJy4gVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIG9mICdhbnlUeXBlJyBpcyAibGF4IiwgCiAqIHRodXMgZWxlbWVudHMgaW4gdGhlIHN1YnRyZWUgd2lsbCBiZSB2YWxpZGF0ZWQsIGlmIGEgY29ycmVzcG9uZGluZwogKiBkZWNsYXJhdGlvbiBpbiB0aGUgc2NoZW1hIGV4aXN0cy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGFuZCBpdHMgc3VidHJlZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOwogICAgeG1sTm9kZVB0ciB0b3AsIGN1cjsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZGVjbDsKICAgIGludCBza2lwQ29udGVudCwgcmV0OwoKICAgIGlmICgodHlwZSA9PSBOVUxMKSB8fCAoY3R4dC0+bm9kZSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwoKICAgIGlmIChjdHh0LT5ub2RlLT5jaGlsZHJlbiA9PSBOVUxMKSAKCXJldHVybiAoMCk7CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICB0b3AgPSBjdHh0LT5ub2RlOyAgICAgICAgCiAgICAvKgogICAgKiBTVFJFQU06IENoaWxkIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgY3VyID0gY3R4dC0+bm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCXNraXBDb250ZW50ID0gMDsKCWlmIChjdXItPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJICAgIC8qCgkgICAgKiBUaGUgcHJvY2VzcyBjb250ZW50cyBvZiB0aGUgd2lsZGNhcmQgaXMgImxheCIsIHRodXMKCSAgICAqIHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIGVsZW1lbnQgaWYgYSBkZWNsYXJhdGlvbgoJICAgICogZXhpc3RzLgoJICAgICovCQkKCSAgICBpZiAoY3VyLT5ucyAhPSBOVUxMKQoJCWRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAoJCSAgICBjdXItPm5hbWUsIGN1ci0+bnMtPmhyZWYsIE5VTEwpOwoJICAgIGVsc2UgCgkJZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsIGN1ci0+bmFtZSwgTlVMTCwgTlVMTCk7CSAgICAKCSAgICBpZiAoZGVjbCAhPSBOVUxMKSB7CQkgICAgCgkJY3R4dC0+bm9kZSA9IGN1cjsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIGRlY2wpOwoJCWN0eHQtPm5vZGUgPSB0b3A7CgkJaWYgKHJldCA8IDApIHsJCQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN1ciwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBbnlUeXBlQ29udGVudCwgIgoJCQkidmFsaWRhdGluZyBhbiBlbGVtZW50IGluIHRoZSBjb250ZXh0IG9mIGEgd2lsZGNhcmQuIiwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIHJldHVybiAocmV0KTsKCQl9IGVsc2UgaWYgKHJldCA+IDApCgkJICAgIHJldHVybiAocmV0KTsKCQlza2lwQ29udGVudCA9IDE7CgkgICAgfQoJfSAgIAoJLyoKCSogQnJvd3NlIHRoZSBmdWxsIHN1YnRyZWUsIGRlZXAgZmlyc3QuCgkqLwogICAgICAgIGlmICgoc2tpcENvbnRlbnQgPT0gMCkgJiYgKGN1ci0+Y2hpbGRyZW4gIT0gTlVMTCkpIHsKCSAgICAvKiBkZWVwIGZpcnN0ICovCgkgICAgY3VyID0gY3VyLT5jaGlsZHJlbjsKCX0gZWxzZSBpZiAoKGN1ciAhPSB0b3ApICYmIChjdXItPm5leHQgIT0gTlVMTCkpIHsKCSAgICAvKiB0aGVuIHNpYmxpbmdzICovCgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfSBlbHNlIGlmIChjdXIgIT0gdG9wKSB7CgkgICAgLyogZ28gdXAgdG8gcGFyZW50cy0+bmV4dCBpZiBuZWVkZWQgKi8KCSAgICB3aGlsZSAoY3VyICE9IHRvcCkgewoJICAgICAgICBpZiAoY3VyLT5wYXJlbnQgIT0gTlVMTCkKCQkgICAgY3VyID0gY3VyLT5wYXJlbnQ7CgkJaWYgKChjdXIgIT0gdG9wKSAmJiAoY3VyLT5uZXh0ICE9IE5VTEwpKSB7CgkJICAgIGN1ciA9IGN1ci0+bmV4dDsKCQkgICAgYnJlYWs7CgkJfQoJCWlmIChjdXItPnBhcmVudCA9PSBOVUxMKSB7CgkJICAgIGN1ciA9IE5VTEw7CgkJICAgIGJyZWFrOwoJCX0KCSAgICB9CgkgICAgLyogZXhpdCBjb25kaXRpb24gKi8KCSAgICBpZiAoY3VyID09IHRvcCkgCgkgICAgICAgIGN1ciA9IE5VTEw7Cgl9IGVsc2UKCSAgICBicmVhazsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGV4cGVjdGVkIHRvIGJlIGEgY29tcGxleCB0eXBlIHR5cGUKICogeG1sc2NoZW1hLTEuaHRtbCNjdmMtY29tcGxleC10eXBlCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChDb21wbGV4IFR5cGUpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqIE5vdGUgb24gcmVwb3J0ZWQgZXJyb3JzOiBBbHRob3VnaCBpdCBtaWdodCBiZSBuaWNlIHRvIHJlcG9ydAogKiB0aGUgbmFtZSBvZiB0aGUgc2ltcGxlL2NvbXBsZXggdHlwZSwgdXNlZCB0byB2YWxpZGF0ZSB0aGUgY29udGVudAogKiBvZiBhIG5vZGUsIGl0IGlzIHF1aXRlIHVubmVjZXNzYXJ5OiBmb3IgZ2xvYmFsIGRlZmluZWQgdHlwZXMKICogdGhlIGxvY2FsIG5hbWUgb2YgdGhlIGVsZW1lbnQgaXMgZXF1YWwgdG8gdGhlIE5DTmFtZSBvZiB0aGUgdHlwZSwKICogZm9yIGxvY2FsIGRlZmluZWQgdHlwZXMgaXQgbWFrZXMgbm8gc2Vuc2UgdG8gb3V0cHV0IHRoZSBpbnRlcm5hbAogKiBjb21wdXRlZCBuYW1lIG9mIHRoZSB0eXBlLiBUT0RPOiBJbnN0ZWFkLCBvbmUgc2hvdWxkIGF0dGFjaCB0aGUgCiAqIHN0cnVjdCBvZiB0aGUgdHlwZSBpbnZvbHZlZCB0byB0aGUgZXJyb3IgaGFuZGxlciAtIHRoaXMgYWxsb3dzCiAqIHRoZSByZXBvcnQgb2YgYW55IGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYnkgdGhlIHVzZXIuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJICAgICAgaW50IHZhbFNpbXBsZUNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb2xkdHlwZTsgICAgCiAgICB4bWxOb2RlUHRyIGVsZW0sIGNoaWxkOwogICAgaW50IHJldCA9IDA7CiAgICBjb25zdCB4bWxDaGFyICpuc1VyaTsgICAgCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cnMgPSBOVUxMLCBhdHRyVG9wID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpKQoJcmV0dXJuICgtMSk7CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIGVsZW0gPSBjdHh0LT5ub2RlOwoKICAgIC8qCiAgICAqIFZlcmlmeSB0aGUgYXR0cmlidXRlcwogICAgKi8KICAgIC8qCiAgICAqIFRPRE86IFRoaXMgImF0dHJUb3AiIHRoaW5nIGlzIG5vdCBuZWVkZWQgYW55IG1vcmUuCiAgICAqLyAgCiAgICAvKiBOT1RFOiByZW1vdmVkLCBzaW5jZSBhIGNoZWNrIGZvciBhYnN0cmFjdCBpcwogICAgKiBkb25lIGluIHRoZSBjdmMtdHlwZSBjb25zdHJhaW50LgogICAgKgogICAgKgogICAgKiBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0FCU1RSQUNUKSB7CiAgICAqCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKICAgICoJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMSwKICAgICoJICAgIGVsZW0sIHR5cGUsIAogICAgKgkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzdHJhY3QiKTsKICAgICoJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzEpOwogICAgKn0KICAgICovCiAgICAKICAgIGF0dHJzID0gY3R4dC0+YXR0cjsgICAgCiAgICBhdHRyVG9wID0gY3R4dC0+YXR0clRvcDsgICAKICAgIC8qCiAgICAqIFNUUkVBTTogQXR0cmlidXRlIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKGN0eHQsIGVsZW0tPnByb3BlcnRpZXMpOyAgICAgCiAgICB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgZWxlbSwgdHlwZSk7CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyhjdHh0LT5hdHRyKTsKICAgIGN0eHQtPmF0dHIgPSBhdHRyczsgICAgCiAgICBjdHh0LT5hdHRyVG9wID0gYXR0clRvcDsgICAgCgogICAgLyoKICAgICogVE9ETzogVGhpcyBvbmUgY3JlYXRlcyBhIHJlZ2V4cCBldmVuIGlmIG5vIGNvbnRlbnQKICAgICogbW9kZWwgd2FzIGRlZmluZWQuIFNvbWVob3cgLT5jb250TW9kZWwgaXMgYWx3YXlzIG5vdCBOVUxMCiAgICAqIGZvciBjb21wbGV4IHR5cGVzLCBldmVuIGlmIHRoZXkgYXJlIGVtcHR5LgogICAgKiBUT0RPOiBDaGVjayBpZiB0aGUgb2JvdmUgc3RpbGwgb2NjdXJzLgogICAgKi8gICAgICAgICAgICAgIAogICAgc3dpdGNoICh0eXBlLT5jb250ZW50VHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk6IHsKCSAgICAvKgoJICAgICogMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgZW1wdHksIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gCgkgICAgKiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgb3IgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0uCgkgICAgKi8KCSAgICAvKgoJICAgICogVE9ETzogSXMgdGhlIGVudGl0eSBzdHVmZiBjb3JyZWN0PwoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50KGVsZW0pID09IDEpIHsJICAgIAkgICAgCgkJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMSwKCQkgICAgZWxlbSwgdHlwZSwgCgkJICAgICJDaGFyYWN0ZXIgb3IgZWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJICAgICJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZW1wdHkiKTsKICAgICAgICAgICAgfQkgCiAgICAgICAgICAgIGJyZWFrOwoJfQoJY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CgkgICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJiAKCQkodHlwZS0+YmFzZVR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSB7CgkJLyoKCQkqIFRoZSB0eXBlIGhhcyAnYW55VHlwZScgYXMgaXRzIGJhc2UgYW5kIG5vIGNvbnRlbnQgbW9kZWwKCQkqIGlzIGRlZmluZWQgLT4gdXNlICdhbnlUeXBlJyBhcyB0aGUgdHlwZSB0byB2YWxpZGF0ZQoJCSogYWdhaW5zdC4KCQkqLwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZShjdHh0LCB0eXBlLT5iYXNlVHlwZSk7CgkJLyogVE9ETzogSGFuZGxlIC0xLiAqLwoJCWJyZWFrOwoJICAgIH0KCSAgICAvKiBObyBicmVhayBvbiBwdXJwb3NlLiAqLwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOgogICAgICAgIHsKCSAgICB4bWxSZWdFeGVjQ3R4dFB0ciBvbGRyZWdleHAgPSBOVUxMOwoJICAgIHhtbENoYXIgKnZhbHVlc1sxMF07CgkgICAgaW50IHRlcm1pbmFsLCBuYnZhbCA9IDEwLCBuYm5lZzsKCSAgICAKCSAgICAvKgoJICAgICogQ29udGVudCBtb2RlbCBjaGVjayBpbml0aWFsaXphdGlvbi4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkgewkJCQkJCgkJb2xkcmVnZXhwID0gY3R4dC0+cmVnZXhwOwoJCWN0eHQtPnJlZ2V4cCA9IHhtbFJlZ05ld0V4ZWNDdHh0KHR5cGUtPmNvbnRNb2RlbCwKCQkgICAgKHhtbFJlZ0V4ZWNDYWxsYmFja3MpCgkJICAgIHhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2ssIGN0eHQpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIj09PT0+ICVzXG4iLCBlbGVtLT5uYW1lKTsKI2VuZGlmCgkgICAgfQoJICAgIC8qCgkgICAgKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkgICAgKi8KCSAgICBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOwoJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CQkKCQlpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJCSAgICBpZiAoY2hpbGQtPm5zICE9IE5VTEwpCgkJCW5zVXJpID0gY2hpbGQtPm5zLT5ocmVmOwoJCSAgICBlbHNlCgkJCW5zVXJpID0gTlVMTDsKCQkgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcyKGN0eHQtPnJlZ2V4cCwKCQkJY2hpbGQtPm5hbWUsIG5zVXJpLCBjaGlsZCk7CgkJICAgIGlmIChjdHh0LT5lcnIgPT0gWE1MX1NDSEVNQVZfSU5URVJOQUwpCgkJCXJldHVybiAoLTEpOwoJCSAgICAvKgoJCSAgICAqIFVSR0VOVCBUT0RPOiBDb3VsZCB3ZSBhbmNob3IgYW4gZXJyb3IgcmVwb3J0CgkJICAgICogaGVyZSB0byBub3RpZnkgb2YgaW52YWxpZCBlbGVtZW50cz8KCQkgICAgKiBUT0RPOiBQZXJoYXBzIGl0IHdvdWxkIGJlIGJldHRlciB0byByZXBvcnQgCgkJICAgICogb25seSB0aGUgZmlyc3QgZXJyb25lb3VzIGVsZW1lbnQgYW5kIHRoZW4gYnJlYWsuCgkJICAgICovCiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCSAgICBpZiAocmV0IDwgMCkKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlcyBFcnJvclxuIiwgY2hpbGQtPm5hbWUpOwoJCSAgICBlbHNlCgkJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkiICAtLT4gJXNcbiIsIGNoaWxkLT5uYW1lKTsKI2VuZGlmCgkJICAgIGlmIChyZXQgPCAwKSB7CgkJCXhtbFJlZ0V4ZWNFcnJJbmZvKGN0eHQtPnJlZ2V4cCwgTlVMTCwgJm5idmFsLCAmbmJuZWcsCgkJCSAgICAmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJCQl4bWxTY2hlbWFWQ29tcGxleFR5cGVFbGVtRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfRUxFTUVOVF9DT05URU5ULAoJCQkgICAgY2hpbGQsIE5VTEwvKiB0eXBlICovLCAKCQkJICAgICJUaGlzIGVsZW1lbnQgaXMgbm90IGV4cGVjdGVkIiwKCQkJICAgIG5idmFsLCBuYm5lZywgdmFsdWVzKTsKCQkJcmV0ID0gMTsKCQkJLyoKCQkJKiBOb3RlIHRoYXQgdGhpcyB3aWxsIHNraXAgZnVydGhlciB2YWxpZGF0aW9uIG9mIHRoZQoJCQkqIGNvbnRlbnQuCgkJCSovCgkJCWJyZWFrOwoJCSAgICB9CgkJfSBlbHNlIGlmICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSAmJiAKCQkgICAgLyogCgkJICAgICogVE9ETzogQXNrIERhbmllbCBpZiB0aGlzIGFyZSBhbGwgY2hhcmFjdGVyIG5vZGVzLgoJCSAgICAqLwoJCSAgICAoKChjaGlsZC0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoIUlTX0JMQU5LX05PREUoY2hpbGQpKSkgfHwKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CQkgICAgCQkgICAgCgkJICAgICAoY2hpbGQtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgfHwJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkpIHsJCSAgICAKCQkgICAgLyogCgkJICAgICogMi4zIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIAoJCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gW2NoaWxkcmVuXSBvdGhlciB0aGFuIHRob3NlIHdob3NlIFtjaGFyYWN0ZXIgCgkJICAgICogY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgCgkJICAgICogRWRpdGlvbildLgoJCSAgICAqLwkJCQoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8zLAoJCQllbGVtLCB0eXBlLCAKCQkJIkNoYXJhY3RlciBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCAiCgkJCSJiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgaXMgZWxlbWVudC1vbmx5Iik7CgkJICAgIHJldCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwkJICAgIAoJICAgIH0gICAgCgkgICAgLyoKCSAgICAqIENvbnRlbnQgbW9kZWwgY2hlY2sgZmluYWxpemF0aW9uLgoJICAgICovCiAgICAgICAJICAgIGlmICh0eXBlLT5jb250TW9kZWwgIT0gTlVMTCkgewoJCWlmIChyZXQgPT0gMCkgewoJCSAgICB4bWxSZWdFeGVjTmV4dFZhbHVlcyhjdHh0LT5yZWdleHAsICZuYnZhbCwgJm5ibmVnLAoJCQkmdmFsdWVzWzBdLCAmdGVybWluYWwpOwoJCSAgICBpZiAobmJ2YWwgKyBuYm5lZyAhPSAwKSB7CgkJCS8qCgkJCSogSWYgYSBuZXh0IHZhbHVlIHN0aWxsIGV4aXN0cywgSSBkb2VzIG5vdCBoYXZlIHRvCgkJCSogbWVhbiB0aGF0IHRoZXJlJ3MgYW4gZWxlbWVudCBtaXNzaW5nLCBzaW5jZSBpdAoJCQkqIG1pZ2h0IGJlIGFuIG9wdGlvbmFsIGVsZW1lbnQuIFNvIGRvdWJsZSBjaGVjayBpdC4KCQkJKi8KCQkJcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLAoJCQkgICAgTlVMTCwgTlVMTCk7CgkJCWlmIChyZXQgPD0gMCkgewoJCQkgICAgcmV0ID0gMTsKICAgIAkJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFbGVtRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCQllbGVtLCB0eXBlLCAiTWlzc2luZyBjaGlsZCBlbGVtZW50KHMpIiwKCQkJCW5idmFsLCBuYm5lZywgdmFsdWVzKTsJCQkgICAgCgkJCX0gZWxzZQoJCQkgICAgcmV0ID0gMDsJCQkKI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkgICAgIj09PT0+ICVzIDogJWRcbiIsIGVsZW0tPm5hbWUsIHJldCk7CiNlbmRpZgoJCSAgICB9CQkgICAgCiNpZmRlZiBERUJVR19DT05URU5UCgkJICAgIGlmIChyZXQgPT0gMCkKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSAgICAiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIHN1Y2NlZWRlZFxuIiwKCQkJICAgIGVsZW0tPm5hbWUpOwojZW5kaWYKCQl9CgkJeG1sUmVnRnJlZUV4ZWNDdHh0KGN0eHQtPnJlZ2V4cCk7CgkJY3R4dC0+cmVnZXhwID0gb2xkcmVnZXhwOwoJICAgIH0KCX0KICAgICAgICAgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CgkgICAgLyoKCSAgICAqIElmIHRoZSBzaW1wbGUgY29udGVudCB3YXMgYWxyZWFkeSB2YWxpZGF0ZWQgCgkgICAgKiAoZS5nLiBhIGRlZmF1bHQgdmFsdWUpLCB0aGUgY29udGVudCBuZWVkIG5vdAoJICAgICogdG8gYmUgdmFsaWRhdGVkIGFnYWluLgoJICAgICovCglpZiAodmFsU2ltcGxlQ29udGVudCA9PSAxKSB7CgkgICAgeG1sQ2hhciAqdmFsdWUgPSBOVUxMOwoJICAgIC8qCgkgICAgKiBXZSBoaXQgYSBjb21wbGV4VHlwZSB3aXRoIGEgc2ltcGxlQ29udGVudCByZXNvbHZpbmcKCSAgICAqIHRvIGEgdXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluIHNpbXBsZSB0eXBlLgoJICAgICovCgkgICAgLyogCgkgICAgKiAyLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgCgkgICAgKiB0aGVuIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaGFzIG5vIGVsZW1lbnQgCgkgICAgKiBpbmZvcm1hdGlvbiBpdGVtIFtjaGlsZHJlbl0sIGFuZCB0aGUgt25vcm1hbGl6ZWQgdmFsdWW3IAoJICAgICogb2YgdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBpcyC3dmFsaWS3IHdpdGggcmVzcGVjdCAKCSAgICAqIHRvIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBhcyBkZWZpbmVkIGJ5IFN0cmluZyAKCSAgICAqIFZhbGlkICinMy4xNC40KS4KCSAgICAqLwkgIAoJICAgIC8qCgkgICAgKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkgICAgKi8KCSAgICBjaGlsZCA9IGVsZW0tPmNoaWxkcmVuOwoJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CgkJLyoKCQkqIFRPRE86IENvdWxkIHRoZSBlbnRpdHkgc3R1ZmYgcHJvZHVjZSBlbGVtZW50cwoJCSogYXMgd2VsbD8KCQkqLwogICAgICAgICAgICAgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAKCQkJIkVsZW1lbnQgY29udGVudCBpcyBub3QgYWxsb3dlZCwgYmVjYXVzZSAiCgkJCSJ0aGUgY29udGVudCB0eXBlIGlzIGEgc2ltcGxlIHR5cGUiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJICAgIGJyZWFrOwoJCX0KCQljaGlsZCA9IGNoaWxkLT5uZXh0OwkJICAgIAoJICAgIH0JCgkgICAgY3R4dC0+bm9kZSA9IGVsZW07CgkgICAgY3R4dC0+Y3VyID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyoKCQkqIFZhbGlkYXRlIHRoZSBjaGFyYWN0ZXIgY29udGVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCgkJKi8KCQkvKgoJCSogU1RSRUFNOiBDaGlsZHJlbiBhcmUgcHJvY2Vzc2VkLgoJCSovCgkJaWYgKGVsZW0tPmNoaWxkcmVuID09IE5VTEwpCgkJICAgIHZhbHVlID0gTlVMTDsKCQllbHNlCgkJICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoZWxlbSk7IAoJCS8qCgkJKiBVUkdFTlQgVE9ETzogU2hvdWxkIGZhY2V0cyBmb3IgdGhlIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gYmUgCgkJKiBkaXNhYmxlZCwgaWYgdGhlIGRlcml2YXRpb24gb2YgZmFjZXRzIGZvciBjb21wbGV4IHR5cGVzIAoJCSogaXMgaW1wbGVtZW50ZWQ/CgkJKi8KCQkvKgoJCSogTk9URTogVGhpcyBjYWxsIHdvbid0IGNoZWNrIHRoZSBjb3JyZWN0IHR5cGVzIG9mIHRoZQoJCSogY29udGVudCBub2Rlcywgc2luY2UgdGhpcyBzaG91bGQgYmUgZG9uZSBoZXJlLgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUsIDEsIDEsIDEsIDApOwoJCWlmIChyZXQgPiAwKSB7CQoJCSAgICAvKgoJCSAgICAqIE5PVEU6IEFsdGhvdWdoIGFuIGVycm9yIHdpbGwgYmUgcmVwb3J0ZWQgYnkgCgkJICAgICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsIHRoZSBzcGVjIHdhbnRzCgkJICAgICogYSBzcGVjaWZpYyBjb21wbGV4IHR5cGUgZXJyb3IgdG8gYmUgcmVwb3J0ZWQgCgkJICAgICogYWRkaXRpb25hbGx5LgoJCSAgICAqLwoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnLlxuIiwKCQkJZWxlbS0+bmFtZSwgdHlwZS0+bmFtZSk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQkgICAgCgkgICAgaWYgKHJldCA9PSAwKSB7CgkJLyogCgkJKiBBcHBseSBmYWNldHMgb2YgdGhlIGNvbXBsZXhUeXBlLiBCZSBzdXJlIHRvIHBhc3MgdGhlIAoJCSogYnVpbHQtaW4gdHlwZSB0byB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLgoJCSovCSAgICAKCQkvKiBVUkdFTlQgVE9ETzogSSBkb24ndCBrbm93IHlldCBpZiB0aGUgZmFjZXRzIG9mIHRoZSBzaW1wbGUgdHlwZQoJCSogYXJlIHVzZWQsIG9yIGlmIHRoZSBmYWNldHMsIGRlZmluZWQgYnkgdGhpcyBjb21wbGV4IHR5cGUsCgkJKiBhcmUgdG8gYmUgdXNlZCBvbmx5LiBUaGlzIGhlcmUgYXBwbGllcyBib3RoIGZhY2V0IHNldHMuCgkJKi8JICAgIAoKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIAoJCSAgICB0eXBlLCB2YWx1ZSwgMCwgMSk7CgkJaWYgKHJldCA+IDApIHsKCQkgICAgeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMiwKCQkJZWxlbSwgdHlwZSwgCgkJCSJUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkIik7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgJyVzJzogRXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSAnJXMnOyBmYWlsZWQgdG8gIgoJCQkiYXBwbHkgZmFjZXRzLlxuIiwKCQkJdHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsgCgkJICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCXhtbEZyZWUodmFsdWUpOwoKCX0KCSAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUT0RPIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5pbXBsZW1lbnRlZCBjb250ZW50IHR5cGUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgbGlzdCBvZiB0eXBlIGRlY2xhcmF0aW9ucwogKgogKiBWYWxpZGF0aW9uIFJ1bGU6IEVsZW1lbnQgTG9jYWxseSBWYWxpZCAoVHlwZSkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgICBpbnQgaXNOaWwsCgkJCSAgICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgaW50IHJldDsKCiAgIAogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgTlVMTCwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSwgIgoJICAgICJiYWQgYXJndW1lbnRzIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7ICAgIAogICAgfSAgICAJCiAgICAvKiAKICAgICogVGhpcyBvbmUgaXMgY2FsbGVkIGJ5ICJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uIi4KICAgICogSXQgd2lsbCBmb3J3YXJkIHRvIHRoZSBwcm9wZXIgdmFsaWRhdGlvbiAKICAgICogcHJvY2VkdXJlcyBmb3IgdGhlIGdpdmVuIHR5cGUuCiAgICAqLyAgICAgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKICAgIAkgICAgWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSwKICAgIAkgICAgY3R4dC0+bm9kZSwgTlVMTCwgCiAgICAJICAgICJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIsIE5VTEwpOwogICAgCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSk7CiAgICB9CiAgICAKICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1QpIHsKICAgIAl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAogICAgCSAgICBYTUxfU0NIRU1BVl9DVkNfVFlQRV8yLAogICAgCSAgICBjdHh0LT5ub2RlLCB0eXBlLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzdHJhY3QiLCBOVUxMKTsKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzIpOwogICAgfQoKICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZShjdHh0LCB0eXBlLAoJCXZhbFNpbXBsZUNvbnRlbnQpOwogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlKGN0eHQsIHR5cGUsCgkJaXNOaWwsIHZhbFNpbXBsZUNvbnRlbnQpOwogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgoJICAgIGlmICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllUWVBFKQoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5QW55VHlwZShjdHh0LCB0eXBlKTsKCSAgICBlbHNlCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlKGN0eHQsIHR5cGUsCgkJICAgIGlzTmlsLCB2YWxTaW1wbGVDb250ZW50KTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0ID0gLTE7CgkgICAgYnJlYWs7CiAgICB9CQogICAgaWYgKHJldCA9PSAtMSkKCXJldHVybiAoLTEpOwogICAgZWxzZQoJcmV0dXJuIChyZXQpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQXR0ckxvY2FsbHlWYWxpZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBzdGF0ZSkKewogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpkZWZWYWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciBkZWZWYWw7CiAgICBpbnQgZml4ZWQ7CiAgICBpbnQgcmV0OwoKICAgIGlmIChjdHh0LT5hdHRySW5mby0+dHlwZURlZiA9PSBOVUxMKSB7CglzdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEOwoJcmV0dXJuIChYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEKTsKICAgIH0KICAgIGN0eHQtPm5vZGUgPSBjdHh0LT5hdHRySW5mby0+bm9kZTsKICAgIGN0eHQtPmN1ciA9IGN0eHQtPm5vZGUtPmNoaWxkcmVuOwogICAgdmFsdWUgPSB4bWxOb2RlTGlzdEdldFN0cmluZyhjdHh0LT5ub2RlLT5kb2MsIGN0eHQtPmN1ciwgMSk7CiAgICAKICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgY2FsbCBhbHNvIGNoZWNrcyB0aGUgY29udGVudCBub2RlcyBmb3IgY29ycmVjdCB0eXBlLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIGN0eHQtPmF0dHJJbmZvLT50eXBlRGVmLAoJdmFsdWUsIDEsIDEsIDEsIDEpOwogICAgCSAgICAKICAgIC8qCiAgICAqIEhhbmRsZSAnZml4ZWQnIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKHJldCA+IDApIHsKCXN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsKCS8qCgkqIE5PVEU6IEZpeGVkIHZhbHVlIGNvbnN0cmFpbnRzIHdpbGwgYmUgbm90CgkqIGFwcGxpZWQgaWYgdGhlIHZhbHVlIHdhcyBpbnZhbGlkLCBiZWNhdXNlOiAKCSogMS4gVGhlIHZhbGlkYXRpb24gcHJvY2VzcyBkb2VzIG5vdCByZXR1cm4gYSBwcmVjb21wdXRlZCAKCSogICAgdmFsdWUuCgkqIDIuIEFuIGludmFsaWQgdmFsdWUgaW1wbGllcyBhIHZpb2xhdGlvbiBvZiBhIGZpeGVkIAoJKiAgICB2YWx1ZSBjb25zdHJhaW50LgoJKi8KICAgIH0gZWxzZSBpZiAocmV0ID09IDApIHsKCXN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCWlmICh4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoCgkgICAgKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikgY3R4dC0+YXR0ckluZm8tPmRlY2wsIAoJICAgICZmaXhlZCwgJmRlZlZhbHVlLCAmZGVmVmFsKSAmJiAoZml4ZWQgPT0gMSkpIHsKCgkgICAgaW50IHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoCgkJY3R4dC0+YXR0ckluZm8tPnR5cGVEZWYpOwkgICAKCgkgICAgLyoKCSAgICAqIGN2Yy1hdSA6IEF0dHJpYnV0ZSBMb2NhbGx5IFZhbGlkIChVc2UpCgkgICAgKiBGb3IgYW4gYXR0cmlidXRlIGluZm9ybWF0aW9uIGl0ZW0gdG8gYmW3dmFsaWS3IAoJICAgICogd2l0aCByZXNwZWN0IHRvIGFuIGF0dHJpYnV0ZSB1c2UgaXRzILdub3JtYWxpemVkIAoJICAgICogdmFsdWW3IG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uCgkgICAgKiBvZiB0aGUgYXR0cmlidXRlIHVzZSdzIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSwgaWYgaXQgCgkgICAgKiBpcyBwcmVzZW50IGFuZCBmaXhlZC4KCSAgICAqLwoJICAgIC8qIAoJICAgICogTk9URTogdGhlIHZhbGlkYXRpb24gY29udGV4dCBob2xkcyBpbiBjdHh0LT52YWx1ZSB0aGUKCSAgICAqIHByZWNvbXB1dGVkIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGU7IHdlbGwgZm9yIHNvbWUgdHlwZXMsCgkgICAgKiBmYWxsYmFjayB0byBzdHJpbmcgY29tcGFyaXNvbiBpZiBubyBjb21wdXRlZCB2YWx1ZSAKCSAgICAqIGV4aXN0cy4KCSAgICAqIFRPRE86IFVzZSB0aGUgKm5vcm1hbGl6ZWQqIHZhbHVlIGFuZCB0aGUgKmNhbm9uaWNhbCogZml4ZWQKCSAgICAqIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCQlpZiAoZGVmVmFsID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBwcmltOwoJCSAgICAvKgoJCSAgICAqIE9vcHMsIHRoZSB2YWx1ZSB3YXMgbm90IGNvbXB1dGVkLgoJCSAgICAqLwoJCSAgICBwcmltID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZShjdHh0LT5hdHRySW5mby0+dHlwZURlZik7CgkJICAgIGlmIChwcmltLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpIHsKCQkJeG1sU2NoZW1hVHlwZVB0ciBidWlsdEluOwoJCQkKCQkJYnVpbHRJbiA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlQW5jZXN0b3IoCgkJCSAgICBjdHh0LT5hdHRySW5mby0+dHlwZURlZik7CgkJCWRlZlZhbCA9IHhtbFNjaGVtYU5ld1N0cmluZ1ZhbHVlKAoJCQkgICAgYnVpbHRJbi0+YnVpbHRJblR5cGUsIHZhbHVlKTsJCQkKCQkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGN0eHQtPmF0dHJJbmZvLT5kZWNsKS0+ZGVmVmFsID0KCQkJICAgIGRlZlZhbDsKCQkJdmFsdWUgPSBOVUxMOwoJCSAgICB9IGVsc2UgewoJCQkgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5hdHRySW5mby0+bm9kZSwgCgkJCSAgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0F0dHJMb2NhbGx5VmFsaWQsICIKCQkJICAgICAiY291bGQgbm90IGFxdWlyZSBhIHByZWNvbXB1dGVkIHZhbGUiLAoJCQkgICAgIE5VTEwsIE5VTEwpOwoJCSAgICB9CgkJfQoJCWlmIChkZWZWYWwgIT0gTlVMTCkgewoJCSAgICBpZiAoeG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKGN0eHQtPnZhbHVlLAoJCQkoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MsCgkJCWRlZlZhbCwgKHhtbFNjaGVtYVdoaXRlc3BhY2VWYWx1ZVR5cGUpIHdzKSAhPSAwKQoJCSAgICBzdGF0ZS0+c3RhdGUgPSAKCQkJWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX0ZJWEVEX1ZBTFVFOwoJCX0KCSAgICB9IGVsc2UgaWYgKCEgeG1sU3RyRXF1YWwoZGVmVmFsdWUsIEJBRF9DQVNUIHZhbHVlKSkgewoJCS8qCgkJKiBUT0RPOiBSZW1vdmUgdGhpcyBhbmQgZW5zdXJlIGNvbXB1dGVkIHZhbHVlcyB0byBiZQoJCSogZXhpc3RlbnQuCgkJKi8KCQlzdGF0ZS0+c3RhdGUgPSAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX0ZJWEVEX1ZBTFVFOwoJICAgIH0KCX0KICAgIH0gIAogICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCXhtbEZyZWUodmFsdWUpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgY29tcGxleFR5cGUgaG9sZGluZyB0aGUgYXR0cmlidXRlIHVzZXMKICoKICogVmFsaWRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgYW4gZWxlbWVudC4KICoKICogMS4gRXhpc3RlbnQsIGludmFsaWQgYXR0cmlidXRlcyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvcm0gCiAqICAgICJwcmVmaXg6bG9jYWxOYW1lIi4gCiAqICAgIFJlYXNvbjogcmVhZGFiaWxpdHkgLSBpdCBpcyBlYXNpZXIgdG8gZmluZCB0aGUgYWN0dWFsIFhNTCAKICogICAgcmVwcmVzZW50YXRpb24gb2YgdGhlIGF0dHJpYnV0ZXMgUU5hbWUuCiAqIDIuIE1pc3NpbmcgYXR0cmlidXRlcyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvcm0gCiAqICAgIHsiVVJJIiwgImxvY2FsTmFtZSJ9LgogKiAgICBUaGlzIGlzIG5lY2Vzc2FyeSwgc2luY2UgdGhlIHRoZSBwcmVmaXggbmVlZCBub3QgdG8gYmUgZGVjbGFyZWQKICogICAgYXQgYWxsLCBhbmQgdGh1cyBpcyBub3QgY29tcHV0YWJsZS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5zVVJJOwogICAgaW50IHJldDsKICAgIHhtbEF0dHJQdHIgYXR0cjsgLyogQW4gYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50LiAqLwogICAgY29uc3QgeG1sQ2hhciAqZGVmVmFsdWU7CiAgICB4bWxTY2hlbWFWYWxQdHIgZGVmVmFsOwogICAgaW50IGZpeGVkOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBhdHRyVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyRGVjbDsKICAgIGludCBmb3VuZDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBjdXJTdGF0ZSwgcmVxQXR0clN0YXRlcyA9IE5VTEwsIHJlcUF0dHJTdGF0ZXNUb3AgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGRlZkF0dHJTdGF0ZXMgPSBOVUxMLCBkZWZBdHRyU3RhdGVzVG9wID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZTsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgogICAgaW50IHJlZHVuZGFudCA9IDA7CiNlbmRpZgoKICAgICAgCiAgICAvKgogICAgKiBBbGxvdyBhbGwgYXR0cmlidXRlcyBpZiB0aGUgdHlwZSBpcyBhbnlUeXBlLgogICAgKi8KICAgIGlmICh0eXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpKQoJcmV0dXJuICgwKTsKCiAgICBvbGRub2RlID0gY3R4dC0+bm9kZTsKICAgIGlmICh0eXBlICE9IE5VTEwpCglhdHRyVXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKICAgICAgICBmb3VuZCA9IDA7ICAgIAoJYXR0ckRlY2wgPSBhdHRyVXNlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCglwcmludGYoImF0dHIgdXNlIC0gbmFtZTogJXNcbiIsIHhtbFNjaGVtYUdldEF0dHJOYW1lKGF0dHJEZWNsKSk7CglwcmludGYoImF0dHIgdXNlIC0gdXNlOiAlZFxuIiwgYXR0ckRlY2wtPm9jY3Vycyk7CiNlbmRpZgogICAgICAgIGZvciAoY3VyU3RhdGUgPSBjdHh0LT5hdHRyOyBjdXJTdGF0ZSAhPSBOVUxMOyBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0KSB7CgoJICAgIGlmIChjdXJTdGF0ZS0+ZGVjbCA9PSBhdHRyVXNlLT5hdHRyKSB7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCQlyZWR1bmRhbnQgPSAxOwojZW5kaWYKCSAgICB9CgkgICAgYXR0ciA9IGN1clN0YXRlLT5hdHRyOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJhdHRyIC0gbmFtZTogJXNcbiIsIGF0dHItPm5hbWUpOwoJICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKQoJCXByaW50ZigiYXR0ciAtIG5zOiAlc1xuIiwgYXR0ci0+bnMtPmhyZWYpOwoJICAgIGVsc2UKCQlwcmludGYoImF0dHIgLSBuczogbm9uZVxuIik7CiNlbmRpZgoJICAgIC8qIFRPRE86IENhbiB0aGlzIGV2ZXIgaGFwcGVuPyAqLwogICAgICAgICAgICBpZiAoYXR0ciA9PSBOVUxMKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChhdHRyRGVjbC0+cmVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPnJlZikpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGlmICgoYXR0ckRlY2wtPnJlZk5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIGF0dHJEZWNsLT5yZWZOcykpKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0ckRlY2wtPnJlZk5zICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgYXR0ckRlY2wtPm5hbWUpKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGhhbmRsZSB0aGUgbmFtZXNwYWNlcyBjaGVja3MgaGVyZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoYXR0ci0+bnMgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAgKiBhY2NlcHQgYW4gdW5xdWFsaWZpZWQgYXR0cmlidXRlIG9ubHkgaWYgdGhlIHRhcmdldAoJCSAgICAgKiBuYW1lc3BhY2Ugb2YgdGhlIGRlY2xhcmF0aW9uIGlzIGFic2VudC4KCQkgICAgICovCgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpCgkJCS8qIAoJCQkgKiBUaGlzIGNoZWNrIHdhcyByZW1vdmVkLCBzaW5jZSB0aGUgdGFyZ2V0IG5hbWVzcGFjZQoJCQkgKiB3YXMgZXZhbHVhdGVkIGR1cmluZyBwYXJzaW5nIGFuZCBhbHJlYWR5IHRvb2sKCQkJICogImF0dHJpYnV0ZUZvcm1EZWZhdWx0IiBpbnRvIGFjY291bnQuCgkJCSAqLwoJCSAgICAgICAgLyogKChhdHRyaWJ1dGVzLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfTlNERUZBVUxUKSA9PSAwKSkgKi8KCQkgICAgICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIGlmIChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlID09IE5VTEwpCgkJICAgICAgICBjb250aW51ZTsKCQkgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlLAoJCSAgICAgICAgICAgICAgICAgICAgIGF0dHItPm5zLT5ocmVmKSkKCQkJY29udGludWU7CgkJfQogICAgICAgICAgICB9CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImZvdW5kXG4iKTsKI2VuZGlmCiAgICAgICAgICAgIGZvdW5kID0gMTsJICAgIAoJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRTsKCSAgICAvKgoJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQXR0ckxvY2FsbHlWYWxpZChjdHh0LCBhdHRyRGVjbCwgY3VyU3RhdGUsIGF0dHIpOwoJICAgICovCiAgICAgICAgfQogICAgICAgIGlmICghZm91bmQpIHsKCSAgICBpZiAoYXR0ckRlY2wtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkgewoJCXhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgkJCiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCQlwcmludGYoInJlcXVpcmVkIGF0dHIgbm90IGZvdW5kXG4iKTsKI2VuZGlmCgkJLyoKCQkqIEFkZCBhIG5ldyBkdW1teSBhdHRyaWJ1dGUgc3RhdGUuCgkJKi8JCgkJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAicmVnaXN0ZXJpbmcgcmVxdWlyZWQgYXR0cmlidXRlcyIsIE5VTEwpOwoJCSAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKCQkgICAgZ290byBmYXRhbF9leGl0OwoJCX0gICAgICAgICAgICAKCQl0bXAtPmF0dHIgPSBOVUxMOwoJCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX01JU1NJTkc7CgkJdG1wLT5kZWNsID0gYXR0ckRlY2w7CgkJdG1wLT5uZXh0ID0gTlVMTDsKCQkKCQlpZiAocmVxQXR0clN0YXRlcyA9PSBOVUxMKSB7CgkJICAgIHJlcUF0dHJTdGF0ZXMgPSB0bXA7CgkJICAgIHJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CgkJfSBlbHNlIHsKCQkgICAgcmVxQXR0clN0YXRlc1RvcC0+bmV4dCA9IHRtcDsKCQkgICAgcmVxQXR0clN0YXRlc1RvcCA9IHRtcDsKCQl9CgkgICAgfSBlbHNlIGlmICgoYXR0ckRlY2wtPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCQkgICAgKHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChhdHRyRGVjbCwgCgkJCSZmaXhlZCwgJmRlZlZhbHVlLCAmZGVmVmFsKSkpIHsKCQl4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoJCS8qCgkJKiBIYW5kbGUgbm9uIGV4aXN0ZW50IGRlZmF1bHQvZml4ZWQgYXR0cmlidXRlcy4KCQkqLwkKCQl0bXAgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKSAKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAKCQkJInJlZ2lzdGVyaW5nIHNjaGVtYSBzcGVjaWZpZWQgYXR0cmlidXRlcyIsIE5VTEwpOwoJCSAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKCQkgICAgZ290byBmYXRhbF9leGl0OwoJCX0gICAgICAgICAgICAKCQl0bXAtPmF0dHIgPSBOVUxMOwoJCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0RFRkFVTFQ7CgkJdG1wLT5kZWNsID0gYXR0ckRlY2w7CgkJdG1wLT52YWx1ZSA9IGRlZlZhbHVlOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJCgkJaWYgKGRlZkF0dHJTdGF0ZXMgPT0gTlVMTCkgewoJCSAgICBkZWZBdHRyU3RhdGVzID0gdG1wOwoJCSAgICBkZWZBdHRyU3RhdGVzID0gdG1wOwoJCX0gZWxzZSB7CgkJICAgIGRlZkF0dHJTdGF0ZXMtPm5leHQgPSB0bXA7CgkJICAgIGRlZkF0dHJTdGF0ZXNUb3AgPSB0bXA7CgkJfQkJCQkKCSAgICB9CQkJCgl9CiAgICAgICAgYXR0clVzZSA9IGF0dHJVc2UtPm5leHQ7CiAgICB9CiAgICAvKgogICAgICogQWRkIHJlcXVpcmVkIGF0dHJpYnV0ZXMgdG8gdGhlIGF0dHJpYnV0ZSBzdGF0ZXMgb2YgdGhlIGNvbnRleHQuCiAgICAgKi8KICAgIGlmIChyZXFBdHRyU3RhdGVzICE9IE5VTEwpIHsKCWlmIChjdHh0LT5hdHRyID09IE5VTEwpIHsKCSAgICBjdHh0LT5hdHRyID0gcmVxQXR0clN0YXRlczsKCX0gZWxzZSB7CQkKCSAgICBjdHh0LT5hdHRyVG9wLT5uZXh0ID0gcmVxQXR0clN0YXRlczsKCX0KCWN0eHQtPmF0dHJUb3AgPSByZXFBdHRyU3RhdGVzVG9wOwogICAgfQogICAgLyoKICAgICogUHJvY2VzcyB3aWxkY2FyZHMuCiAgICAqLwogICAgCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpKSB7CQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5zOwkKCXByaW50ZigibWF0Y2hpbmcgd2lsZGNhcmQ6IFslZF0gb2YgY29tcGxleFR5cGU6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+bmFtZSk7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBsYXhcbiIpOwoJZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCSAgICBYTUxfU0NIRU1BU19BTllfU1RSSUNUKQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBzdHJpY3RcbiIpOwoJZWxzZQoJICAgIHByaW50ZigicHJvY2Vzc0NvbnRlbnRzOiBza2lwXG4iKTsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+YW55KQoJICAgIHByaW50ZigidHlwZTogYW55XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkgICAgcHJpbnRmKCJ0eXBlOiBuZWdhdGVkXG4iKTsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKQoJCXByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCSAgICBlbHNlCgkJcHJpbnRmKCJuczogJXNcbiIsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUpOwoJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogc2V0XG4iKTsKCSAgICBucyA9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uc1NldDsKCSAgICB3aGlsZSAobnMgIT0gTlVMTCkgewoJCWlmIChucy0+dmFsdWUgPT0gTlVMTCkKCQkgICAgcHJpbnRmKCJuczogKGFic2VudClcbiIpOwoJCWVsc2UKCQkgICAgcHJpbnRmKCJuczogJXNcbiIsIG5zLT52YWx1ZSk7CgkJbnMgPSBucy0+bmV4dDsKCSAgICB9CSAgICAKCX0gZWxzZQoJICAgIHByaW50ZigiZW1wdHlcbiIpOwoKCiNlbmRpZgkKCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlIChjdXJTdGF0ZSAhPSBOVUxMKSB7CgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pIHsJCQoJCWlmIChjdXJTdGF0ZS0+YXR0ci0+bnMgIT0gTlVMTCkgCgkJICAgIG5zVVJJID0gY3VyU3RhdGUtPmF0dHItPm5zLT5ocmVmOwoJCWVsc2UKCQkgICAgbnNVUkkgPSBOVUxMOwkJCgkJaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQkgICAgbnNVUkkpKSB7CgkJICAgIC8qCgkJICAgICogSGFuZGxlIHByb2Nlc3NDb250ZW50cy4KCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQlYTUxfU0NIRU1BU19BTllfTEFYKSB8fAoJCQkodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkpIHsKCQkJCgkJCWF0dHIgPSBjdXJTdGF0ZS0+YXR0cjsJCQkJCQkKCQkJYXR0ckRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCAKCQkJICAgIGF0dHItPm5hbWUsIG5zVVJJKTsKCQkJY3VyU3RhdGUtPmRlY2wgPSBhdHRyRGVjbDsKCQkJaWYgKGF0dHJEZWNsICE9IE5VTEwpIHsKCQkJICAgIGN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCSAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1ZBTElEQVRFX1ZBTFVFOwoJCQkgICAgLyogVE9ETwoJCQkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKGN0eHQsIGF0dHJEZWNsLCBjdXJTdGF0ZSwgYXR0cik7CgkJCSAgICAqLwoJCQl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCSAgICBYTUxfU0NIRU1BU19BTllfTEFYKSB7CgkJCSAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJCX0gZWxzZQoJCQkgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9XSUxEX05PX0RFQ0w7CgkJICAgIH0gZWxzZQoJCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJfQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwogICAgICAgIH0KICAgIH0gICAgCiAgICAKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpIHsKCWludCB2YWx1ZU5lZWRlZDsKCgkvKgoJKiBWYWxpZGF0ZSB0aGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZS4KCSovCglpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT52YWx1ZSk7CgkgICAgY3R4dC0+dmFsdWUgPSBOVUxMOwoJfQoJY3VyU3RhdGUgPSBjdHh0LT5hdHRyOwoJd2hpbGUgKChjdXJTdGF0ZSAhPSBOVUxMKSAmJiAoY3VyU3RhdGUgIT0gY3R4dC0+YXR0clRvcC0+bmV4dCkpIHsKCSAgICB2YWx1ZU5lZWRlZCA9IDA7CgkgICAgc3dpdGNoIChjdXJTdGF0ZS0+c3RhdGUpIHsKCQljYXNlIFhNTF9TQ0hFTUFTX0FUVFJfVkFMSURBVEVfVkFMVUU6CgoJCSAgICAvKgoJCSAgICAqIENyZWF0ZSBhbiBhdHRyaWJ1dGUgaW5mbyBpZiBuZWVkZWQuCgkJICAgICovCgkJICAgIGlmIChjdHh0LT5hdHRySW5mbyA9PSBOVUxMKSB7CgkJCWN0eHQtPmF0dHJJbmZvID0gKHhtbFNjaGVtYUVsZW1JbmZvUHRyKSAKCQkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbUluZm8pKTsKCQkJaWYgKGN0eHQtPmF0dHJJbmZvID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgCgkJCQkiYWxsb2NhdGluZyBhbiBhdHRyaWJ1dGUgaW5mbyIsIE5VTEwpOwoJCQkgICAgZ290byBmYXRhbF9leGl0OwoJCQl9CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBJbml0IHRoZSBhdHRyaWJ1dGUgaW5mby4KCQkgICAgKi8KCQkgICAgY3R4dC0+YXR0ckluZm8tPmZsYWdzID0gMDsKCQkgICAgY3R4dC0+YXR0ckluZm8tPm5vZGUgPSAoeG1sTm9kZVB0cikgY3VyU3RhdGUtPmF0dHI7CgkJICAgIGN0eHQtPmF0dHJJbmZvLT5kZWNsID0gKHhtbFNjaGVtYVR5cGVQdHIpIGN1clN0YXRlLT5kZWNsOwoJCSAgICBjdHh0LT5hdHRySW5mby0+dmFsdWUgPSBOVUxMOwoJCSAgICBpZiAoY3VyU3RhdGUtPmRlY2wgIT0gTlVMTCkKCQkJY3R4dC0+YXR0ckluZm8tPnR5cGVEZWYgPSBjdXJTdGF0ZS0+ZGVjbC0+c3VidHlwZXM7CgkJICAgIGVsc2UKCQkJY3R4dC0+YXR0ckluZm8tPnR5cGVEZWYgPSBOVUxMOwoJCSAgICBpZiAoY3VyU3RhdGUtPmF0dHItPm5zICE9IE5VTEwpCgkJCWN0eHQtPmF0dHJJbmZvLT5uYW1lc3BhY2VOYW1lID0gCgkJCWN1clN0YXRlLT5hdHRyLT5ucy0+aHJlZjsKCQkgICAgZWxzZQoJCQljdHh0LT5hdHRySW5mby0+bmFtZXNwYWNlTmFtZSA9IE5VTEw7CgkJICAgIGN0eHQtPmF0dHJJbmZvLT5sb2NhbE5hbWUgPSBjdXJTdGF0ZS0+YXR0ci0+bmFtZTsKCQkgICAgCgkJICAgIGN0eHQtPm5vZGVJbmZvID0gY3R4dC0+YXR0ckluZm87CgojaWZkZWYgSURDX0VOQUJMRUQgIAoJCSAgICAvKgoJCSAgICAqIEV2YWx1YXRlIElEQ3MuCgkJICAgICovCgkJICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CgkJCXJldCA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoY3R4dCwKCQkJICAgIFhNTF9BVFRSSUJVVEVfTk9ERSk7CgkJCWlmIChyZXQgPT0gLTEpCgkJCSAgICBnb3RvIGZhdGFsX2V4aXQ7CgkJICAgIH0KCiNlbmRpZgoJCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0F0dHJMb2NhbGx5VmFsaWQoY3R4dCwgY3VyU3RhdGUpOwoJCSAgICBpZiAocmV0ID09IC0xKQoJCQlnb3RvIGZhdGFsX2V4aXQ7CgkJICAgIGlmICgocmV0ICE9IDApICYmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSkgewoJCQl4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwoJCQljdHh0LT52YWx1ZSA9IE5VTEw7CgkJICAgIH0KCQkgICAgLyogTm8gYnJlYWsgb24gcHVycG9zZS4gKi8KCQljYXNlIFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDoKI2lmZGVmIElEQ19FTkFCTEVECgkJICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CgkJCS8qCgkJCSogRXZhbHVhdGUgSURDcy4KCQkJKi8KCQkJaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCQkJICAgIGN0eHQtPmF0dHJJbmZvLT52YWx1ZSA9IGN0eHQtPnZhbHVlOwoJCQkgICAgY3R4dC0+dmFsdWUgPSBOVUxMOwoJCQl9CQkKCQkJaWYgKHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnkoY3R4dCwgY3R4dC0+ZGVwdGggKzEpID09IC0xKQoJCQkgICAgZ290byBmYXRhbF9leGl0OwoJCSAgICB9CgkJICAgIGJyZWFrOwojZW5kaWYKCQlkZWZhdWx0OgoJCSAgICBicmVhazsKCSAgICB9CgkgICAgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dDsKCX0KCgkvKgoJKiBSZXBvcnQgbWlzc2luZyBhbmQgaWxsZWdhbCBhdHRyaWJ1dGVzLgoJKi8KCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlICgoY3VyU3RhdGUgIT0gTlVMTCkgJiYgKGN1clN0YXRlICE9IGN0eHQtPmF0dHJUb3AtPm5leHQpKSB7CgkgICAgaWYgKGN1clN0YXRlLT5zdGF0ZSAhPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQpIHsKCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CgkJaWYgKGN1clN0YXRlLT5kZWNsICE9IE5VTEwpIHsKCQkgICAgaWYgKGN1clN0YXRlLT5kZWNsLT5yZWYgIT0gTlVMTCkKCQkJYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbC0+cmVmRGVjbDsKCQkgICAgZWxzZSAKCQkJYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbDsKCQl9IGVsc2UKCQkgICAgYXR0ckRlY2wgPSBOVUxMOwoJCWlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HKSB7CgkJICAgIHhtbFNjaGVtYVZNaXNzaW5nQXR0ckVycihjdHh0LCBlbGVtLCBhdHRyRGVjbCk7CgkJfSBlbHNlIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gCgkJICAgIFhNTF9TQ0hFTUFTX0FUVFJfVFlQRV9OT1RfUkVTT0xWRUQpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCQlYTUxfU0NIRU1BVl9DVkNfQVRUUklCVVRFXzIsCgkJCSh4bWxOb2RlUHRyKSBhdHRyLAoJCQkoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2wsCgkJCSJUaGUgdHlwZSBkZWZpbml0aW9uIGlzIGFic2VudCIsCgkJCU5VTEwpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IAoJCSAgICBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfRklYRURfVkFMVUUpIHsJCQkKCQkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0FVLCAKCQkJICAgICh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2wsCgkJCSAgICAiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBmaXhlZCB2YWx1ZSAiCgkJCSAgICAiY29uc3RyYWludCIsIE5VTEwpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9OT19ERUNMKSB7CgkJICAgIHhtbFNjaGVtYVZXaWxkY2FyZEVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX1dJTERDQVJELAoJCQkoeG1sTm9kZVB0cikgYXR0ciwKCQkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJCSJObyBnbG9iYWwgYXR0cmlidXRlIGRlY2xhcmF0aW9uIGZvdW5kLCBidXQgIgoJCQkic3RpcHVsYXRlZCBieSB0aGUgc3RyaWN0IHByb2Nlc3NDb250ZW50cyBvZiAiCgkJCSJ0aGUgd2lsZGNhcmQiKTsJCQkKCQl9IGVsc2UgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pIHsKCQkgICAgLyogVE9ETzogInByb2hpYml0ZWQiIHdvbid0IGV2ZXIgYmUgdG91Y2hlZCBoZXJlIS4gCgkJICAgICAgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQpKQoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRPRE86IE9uZSBtaWdodCByZXBvcnQgZGlmZmVyZW50IGVycm9yIG1lc3NhZ2VzIAoJCSAgICAqIGZvciB0aGUgZm9sbG93aW5nIGVycm9ycy4KCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlID09IE5VTEwpIHx8ICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9PSBOVUxMKSkgewoJCQl4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzNfMl8xLCBhdHRyKTsKCQkgICAgfSBlbHNlIHsKCQkJeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMiwgYXR0cik7CgkJICAgIH0KCQl9CgkgICAgfQkKCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwoJfSAgCiAgICB9ICAgIAogICAgCiAgICAvKgogICAgKiBBZGQgbWlzc2luZyBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCiAgICAqLwogICAgaWYgKGRlZkF0dHJTdGF0ZXMgIT0gTlVMTCkgeyAgICAKCWN1clN0YXRlID0gZGVmQXR0clN0YXRlczsKCQoJd2hpbGUgKGN1clN0YXRlICE9IE5VTEwpIHsgCgkgICAgYXR0ckRlY2wgPSBjdXJTdGF0ZS0+ZGVjbDsKCSAgICBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKQoJCWF0dHJEZWNsID0gYXR0ckRlY2wtPnJlZkRlY2w7CgojaWZkZWYgSURDX0VOQUJMRUQgCgkgICAgLyoKCSAgICAqIEV2YWx1YXRlIElEQ3Mgb24gZGVmYXVsdCBhdHRyaWJ1dGVzLgoJICAgICovCgkgICAgaWYgKGN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpIHsKCQkvKgoJCSogQ3JlYXRlIGFuIGF0dHJpYnV0ZSBpbmZvIGlmIG5lZWRlZC4KCQkqLwoJCWlmIChjdHh0LT5hdHRySW5mbyA9PSBOVUxMKSB7CgkJICAgIGN0eHQtPmF0dHJJbmZvID0gKHhtbFNjaGVtYUVsZW1JbmZvUHRyKSAKCQkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFFbGVtSW5mbykpOwoJCSAgICBpZiAoY3R4dC0+YXR0ckluZm8gPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsIAoJCQkgICAgImFsbG9jYXRpbmcgYW4gYXR0cmlidXRlIGluZm8iLCBOVUxMKTsKCQkJZ290byBmYXRhbF9leGl0OwoJCSAgICB9CgkJfQoJCS8qCgkJKiBJbml0IHRoZSBhdHRyaWJ1dGUgaW5mby4KCQkqIFRPRE86IEhtbSwgbWFieSBhIGJpdCBvdmVyc2l6ZWQgdGhpcyBhbGwuCgkJKi8KCQljdHh0LT5hdHRySW5mby0+ZmxhZ3MgPSAwOwkJCgkJY3R4dC0+YXR0ckluZm8tPmRlY2wgPSAoeG1sU2NoZW1hVHlwZVB0cikgYXR0ckRlY2w7CgkJY3R4dC0+YXR0ckluZm8tPm5vZGUgPSBOVUxMOwkJCQkKCQljdHh0LT5hdHRySW5mby0+dHlwZURlZiA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCQljdHh0LT5hdHRySW5mby0+bmFtZXNwYWNlTmFtZSA9IGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2U7CgkJY3R4dC0+YXR0ckluZm8tPmxvY2FsTmFtZSA9IGF0dHJEZWNsLT5uYW1lOwoKCQljdHh0LT5ub2RlSW5mbyA9IGN0eHQtPmF0dHJJbmZvOwoJCQkJCQkJCQkgICAgCgkJcmV0ID0geG1sU2NoZW1hWFBhdGhFdmFsdWF0ZShjdHh0LAoJCSAgICBYTUxfQVRUUklCVVRFX05PREUpOwoJCWlmIChyZXQgPT0gLTEpCgkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCQlpZiAoY3R4dC0+YXR0ckluZm8tPnZhbHVlICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPmF0dHJJbmZvLT52YWx1ZSk7CgkJICAgIGN0eHQtPmF0dHJJbmZvLT52YWx1ZSA9IE5VTEw7CgkJfQoJCWlmIChyZXQgPiAwKSB7CgkJICAgIC8qCgkJICAgICogSURDcyB3aWxsIGNvbnN1bWUgdGhlIHByZWNvbXB1dGVkIGRlZmF1bHQgdmFsdWUsCgkJICAgICogc28gd2UgbmVlZCB0byBjbG9uZSBpdCBzb21laG93LgoJCSAgICAqLwoJCSAgICBjdHh0LT5hdHRySW5mby0+dmFsdWUgPSB4bWxTY2hlbWFDb3B5VmFsdWUoYXR0ckRlY2wtPmRlZlZhbCk7CgkJICAgIC8qIFRPRE86IGVycm9yIG9uIE5VTEwgcmV0dXJuLiAqLwoJCX0KCQkKCQlpZiAoeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeShjdHh0LCBjdHh0LT5kZXB0aCArMSkgPT0gLTEpCgkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCSAgICB9CiNlbmRpZgoKCSAgICBpZiAoY3R4dC0+b3B0aW9ucyAmIFhNTF9TQ0hFTUFfVkFMX1ZDX0lfQ1JFQVRFKSB7CgkJLyoKCQkqIFBTVkk6IEFkZCBhIG5ldyBhdHRyaWJ1dGUgbm9kZSB0byB0aGUgY3VycmVudCBlbGVtZW50LgoJCSovCgkJaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkgewoJCSAgICB4bWxOZXdQcm9wKGVsZW0sIGF0dHJEZWNsLT5uYW1lLCBjdXJTdGF0ZS0+dmFsdWUpOwoJCX0gZWxzZSB7CgkJICAgIHhtbE5zUHRyIG5zOwoJCSAgICAKCQkgICAgbnMgPSB4bWxTZWFyY2hOc0J5SHJlZihlbGVtLT5kb2MsIGVsZW0sIAoJCQlhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlKTsKCQkgICAgaWYgKG5zID09IE5VTEwpIHsKCQkJeG1sQ2hhciBwcmVmaXhbMTJdOwoJCQlpbnQgY291bnRlciA9IDE7CgkJCQoJCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CgkJCS8qCgkJCSogQ3JlYXRlIGEgbmFtZXNwYWNlIGRlY2xhcmF0aW9uIG9uIHRoZSB2YWxpZGF0aW9uIAoJCQkqIHJvb3Qgbm9kZSBpZiBubyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaXMgaW4gc2NvcGUuCgkJCSovCQkgICAgCgkJCXNucHJpbnRmKChjaGFyICopIHByZWZpeCwgc2l6ZW9mKHByZWZpeCksICJwIik7CgkJCS8qCgkJCSogVGhpcyBpcyBzb21laG93IG5vdCBwZXJmb3JtYW50LCBzaW5jZSB0aGUgYW5jZXN0b3IgCgkJCSogYXhpcyBiZXlvbmQgQGVsZW0gd2lsbCBiZSBzZWFyY2hlZCBhcyB3ZWxsLgoJCQkqLwoJCQlucyA9IHhtbFNlYXJjaE5zKGVsZW0tPmRvYywgZWxlbSwgQkFEX0NBU1QgcHJlZml4KTsKCQkJd2hpbGUgKG5zICE9IE5VTEwpIHsKCQkJICAgIGlmIChjb3VudGVyID4gMTAwMCkgewoJCQkJeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgCgkJCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMsICIKCQkJCSAgICAiY291bGQgbm90IGNvbXB1dGUgYSBucyBwcmVmaXggZm9yICIKCQkJCSAgICAiZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGUgJyVzJy5cbiIsCgkJCQkgICAgYXR0ckRlY2wtPm5hbWUsIE5VTEwpOwoJCQkJCgkJCQlicmVhazsKCQkJICAgIH0KCQkJICAgIHNucHJpbnRmKChjaGFyICopIHByZWZpeCwgCgkJCQlzaXplb2YocHJlZml4KSwgInAlZCIsIGNvdW50ZXIrKyk7CgkJCSAgICBucyA9IHhtbFNlYXJjaE5zKGVsZW0tPmRvYywgZWxlbSwgCgkJCQlCQURfQ0FTVCBwcmVmaXgpOwoJCQl9CgkJCWlmIChucyA9PSBOVUxMKSB7CgkJCSAgICBucyA9IHhtbE5ld05zKGN0eHQtPnZhbGlkYXRpb25Sb290LCAKCQkJCWF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UsIEJBRF9DQVNUIHByZWZpeCk7CgkJCSAgICB4bWxOZXdOc1Byb3AoZWxlbSwgbnMsIGF0dHJEZWNsLT5uYW1lLCAKCQkJCWN1clN0YXRlLT52YWx1ZSk7CgkJCX0KCQkgICAgfSBlbHNlIHsKCQkJeG1sTmV3TnNQcm9wKGVsZW0sIG5zLCBhdHRyRGVjbC0+bmFtZSwgCgkJCSAgICBjdXJTdGF0ZS0+dmFsdWUpOwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICBjdXJTdGF0ZSA9IGN1clN0YXRlLT5uZXh0OwoJfQogICAgfQogICAgcmV0ID0gY3R4dC0+ZXJyOwogICAgZ290byBleGl0OwoKZmF0YWxfZXhpdDoKICAgIHJldCA9IC0xOwoKZXhpdDogICAgCgogICAgaWYgKGRlZkF0dHJTdGF0ZXMgIT0gTlVMTCkgCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGRlZkF0dHJTdGF0ZXMpOwoJCQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCiAgICBpZiAocmVkdW5kYW50KQoJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkgICAgInhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlczogcmVkdW5kYW50IGNhbGwgYnkgIgoJICAgICJ0eXBlOiAlc1xuIiwgdHlwZS0+bmFtZSk7CiNlbmRpZgogICAgY3R4dC0+bm9kZUluZm8gPSBjdHh0LT5lbGVtSW5mb3NbY3R4dC0+ZGVwdGhdOwogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKgogKiBWYWxpZGF0ZSBhbiBlbGVtZW50IGluIGEgdHJlZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOyAgICAKICAgIGludCByZXQgPSAwOwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCBhbmQKICAgICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50LgogICAgKi8gIAogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7CgkvKgoJKiBObyBzY2hlbWEgd2FzIHNwZWNpZmllZCBhdCB0aW1lIG9mIGNyZWF0aW9uIG9mIHRoZSB2YWxpZGF0aW9uCgkqIGNvbnRleHQuIFVzZSB4c2k6c2NoZW1hTG9jYXRpb24gYW5kIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uCgkqIG9mIHRoZSBpbnN0YW5jZSB0byBidWlsZCBhIHNjaGVtYS4KCSovCglpZiAoY3R4dC0+cGN0eHQgPT0gTlVMTCkgCgkgICAgY3R4dC0+cGN0eHQgPSB4bWxTY2hlbWFOZXdQYXJzZXJDdHh0KCIqIik7CglpZiAoY3R4dC0+cGN0eHQgPT0gTlVMTCkKCSAgICByZXR1cm4gKC0xKTsKCWN0eHQtPnNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0LT5wY3R4dCk7CglpZiAoY3R4dC0+c2NoZW1hID09IE5VTEwpCgkgICAgcmV0dXJuICgtMSk7CgkvKiBUT0RPOiBhc3NpZ24gdXNlciBkYXRhLiAqLwoJY3R4dC0+cGN0eHQtPmVycm9yID0gY3R4dC0+ZXJyb3I7CgljdHh0LT5wY3R4dC0+d2FybmluZyA9IGN0eHQtPndhcm5pbmc7CQoJY3R4dC0+eHNpQXNzZW1ibGUgPSAxOwogICAgfSBlbHNlCgljdHh0LT54c2lBc3NlbWJsZSA9IDA7CiAgICAvKgogICAgKiBBc3NlbWJsZSBuZXcgc2NoZW1hdGEgdXNpbmcgeHNpLgogICAgKi8KICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwkgICAgCgl9CgkvKgoJKiBOT1RFOiBXZSB3b24ndCByZWFjdCBvbiBzY2hlbWEgcGFyc2VyIGVycm9ycyBoZXJlLgoJKiBUT0RPOiBCdXQgYSB3YXJuaW5nIHdvdWxkIGJlIG5pY2UuCgkqLwogICAgfQogICAgaWYgKHJldCAhPSAtMSkgewkgICAgCglpZiAoY3R4dC0+bm9kZS0+bnMgIT0gTlVMTCkKCSAgICBlbGVtRGVjbCA9IHhtbFNjaGVtYUdldEVsZW0oY3R4dC0+c2NoZW1hLCBjdHh0LT5ub2RlLT5uYW1lLCAKCQljdHh0LT5ub2RlLT5ucy0+aHJlZik7CgllbHNlCgkgICAgZWxlbURlY2wgPSB4bWxTY2hlbWFHZXRFbGVtKGN0eHQtPnNjaGVtYSwgY3R4dC0+bm9kZS0+bmFtZSwgTlVMTCk7CgkKCWlmIChlbGVtRGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfRUxUXzEsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCSAgCgkJIk5vIG1hdGNoaW5nIGdsb2JhbCBkZWNsYXJhdGlvbiBhdmFpbGFibGUiLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzE7Cgl9IGVsc2UgeyAKI2lmZGVmIElEQ19FTkFCTEVECgkgICAgLyoKCSAgICAqIEF1Z21lbnQgdGhlIElEQyBkZWZpbml0aW9ucy4KCSAgICAqLwoJICAgIGlmIChjdHh0LT5zY2hlbWEtPmlkY0RlZiAhPSBOVUxMKSB7CgkJeG1sSGFzaFNjYW4oY3R4dC0+c2NoZW1hLT5pZGNEZWYsIAoJCSAgICAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF1Z21lbnRJREMsIGN0eHQpOwoJICAgIH0KI2VuZGlmCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAoJICAgIGN0eHQtPmRlcHRoID0gLTE7CgkgICAgeG1sU2NoZW1hQmVnaW5FbGVtZW50KGN0eHQpOwojZW5kaWYKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKGN0eHQsIGVsZW1EZWNsKTsgICAgCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAoJICAgIHhtbFNjaGVtYUVuZEVsZW1lbnQoY3R4dCk7CiNlbmRpZgoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgY3R4dC0+bm9kZSwgTlVMTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQsICIKCQkgICAgImNhbGxpbmcgdmFsaWRhdGlvbiBieSBkZWNsYXJhdGlvbiIsIE5VTEwpOwoJICAgIH0KCX0KICAgIH0KICAgIC8qIGN0eHQtPnhzaUFzc2VtYmxlID0gMDsgKi8KICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewoJaWYgKGN0eHQtPnNjaGVtYSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZShjdHh0LT5zY2hlbWEpOwoJICAgIGN0eHQtPnNjaGVtYSA9IE5VTEw7Cgl9CiAgICB9CiAgICByZXR1cm4gKHJldCk7ICAgCn0KCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQgbm9kZQogKgogKiBWYWxpZGF0ZSBhIGJyYW5jaCBvZiBhIHRyZWUsIHN0YXJ0aW5nIHdpdGggdGhlIGdpdmVuIEBlbGVtLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgYW5kIGl0cyBzdWJ0cmVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIAogKiBjb2RlIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlT25lRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtKQp7CiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKGVsZW0gPT0gTlVMTCkgfHwgKGVsZW0tPnR5cGUgIT0gWE1MX0VMRU1FTlRfTk9ERSkpCglyZXR1cm4gKC0xKTsKCiAgICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkFQSSBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVPbmVFbGVtZW50LCAiCgkgICAgIm5vIHNjaGVtYSBzcGVjaWZpZWQuXG4iLCBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGN0eHQtPmRvYyA9IGVsZW0tPmRvYzsKICAgIGN0eHQtPmVyciA9IDA7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBjdHh0LT5ub2RlID0gZWxlbTsKICAgIGN0eHQtPnZhbGlkYXRpb25Sb290ID0gZWxlbTsKICAgIHJldHVybiAoeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KGN0eHQpKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBkb2M6ICBhIHBhcnNlZCBkb2N1bWVudCB0cmVlCiAqIEB4c2lBc3NlbWJsZTogc2hvdWxkIHNjaGVtYXRhIGJlIGFkZGVkIGlmIHJlcXVlc3RlZCBieSB0aGUgaW5zdGFuY2U/CiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sRG9jUHRyIGRvYykKewogICAgeG1sTm9kZVB0ciByb290OwogICAgIAogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCSAgICBYTUxfU0NIRU1BVl9ET0NVTUVOVF9FTEVNRU5UX01JU1NJTkcsCgkgICAgKHhtbE5vZGVQdHIpIGRvYywgTlVMTCwKCSAgICAiVGhlIGRvY3VtZW50IGhhcyBubyBkb2N1bWVudCBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAgICAKICAgIC8qCiAgICAgKiBPa2F5LCBzdGFydCB0aGUgcmVjdXJzaXZlIHZhbGlkYXRpb24KICAgICAqLwogICAgY3R4dC0+bm9kZSA9IHJvb3Q7CiAgICBjdHh0LT52YWxpZGF0aW9uUm9vdCA9IHJvb3Q7CiAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoY3R4dCk7CgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEKICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsgICAgCiAgICByZXQtPmF0dHJUb3AgPSBOVUxMOwogICAgcmV0LT5hdHRyID0gTlVMTDsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVWYWxpZEN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogRnJlZSB0aGUgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hRnJlZVZhbGlkQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KGN0eHQtPnBjdHh0KTsKICAgIH0KCiNpZmRlZiBJRENfRU5BQkxFRAogICAgaWYgKGN0eHQtPmlkY05vZGVzICE9IE5VTEwpIHsKCWludCBpOwoJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgaXRlbTsKCglmb3IgKGkgPSAwOyBpIDwgY3R4dC0+bmJJZGNOb2RlczsgaSsrKSB7CgkgICAgaXRlbSA9IGN0eHQtPmlkY05vZGVzW2ldOwkgICAgCgkgICAgeG1sRnJlZShpdGVtLT5rZXlzKTsKCSAgICB4bWxGcmVlKGl0ZW0pOwoJfQoJeG1sRnJlZShjdHh0LT5pZGNOb2Rlcyk7CiAgICB9CgogICAgaWYgKGN0eHQtPmlkY0tleXMgIT0gTlVMTCkgewoJaW50IGk7Cglmb3IgKGkgPSAwOyBpIDwgY3R4dC0+bmJJZGNLZXlzOyBpKyspCgkgICAgeG1sU2NoZW1hSURDRnJlZUtleShjdHh0LT5pZGNLZXlzW2ldKTsKCXhtbEZyZWUoY3R4dC0+aWRjS2V5cyk7CiAgICB9CgogICAgaWYgKGN0eHQtPnhwYXRoU3RhdGVzICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlSURDU3RhdGVPYmpMaXN0KGN0eHQtPnhwYXRoU3RhdGVzKTsKICAgIGlmIChjdHh0LT54cGF0aFN0YXRlUG9vbCAhPSBOVUxMKQoJeG1sU2NoZW1hRnJlZUlEQ1N0YXRlT2JqTGlzdChjdHh0LT54cGF0aFN0YXRlUG9vbCk7CgogICAgLyoKICAgICogQXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbi4KICAgICovCiAgICBpZiAoY3R4dC0+YWlkY3MgIT0gTlVMTCkgewoJeG1sU2NoZW1hSURDQXVnUHRyIGN1ciA9IGN0eHQtPmFpZGNzLCBuZXh0OwoJZG8gewoJICAgIG5leHQgPSBjdXItPm5leHQ7CgkgICAgeG1sRnJlZShjdXIpOwoJICAgIGN1ciA9IG5leHQ7Cgl9IHdoaWxlIChjdXIgIT0gTlVMTCk7CiAgICB9CiNlbmRpZiAvKiBJRENfRU5BQkxFRCAqLwojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIGlmIChjdHh0LT5hdHRySW5mbyAhPSBOVUxMKSB7CglpZiAoY3R4dC0+YXR0ckluZm8tPnZhbHVlICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPmF0dHJJbmZvLT52YWx1ZSk7Cgl4bWxGcmVlKGN0eHQtPmF0dHJJbmZvKTsKICAgIH0KICAgIGlmIChjdHh0LT5lbGVtSW5mb3MgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFFbGVtSW5mb1B0ciBpbmZvOwoJCglmb3IgKGkgPSAwOyBpIDwgY3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKSB7CgkgICAgaW5mbyA9IGN0eHQtPmVsZW1JbmZvc1tpXTsKCSAgICBpZiAoaW5mbyA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmIChpbmZvLT52YWx1ZSAhPSBOVUxMKQoJCXhtbFNjaGVtYUZyZWVWYWx1ZShpbmZvLT52YWx1ZSk7CiNpZmRlZiBJRENfRU5BQkxFRAoJICAgIGlmIChpbmZvLT5pZGNNYXRjaGVycyAhPSBOVUxMKQoJCXhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdChpbmZvLT5pZGNNYXRjaGVycyk7CiNlbmRpZgoJICAgIC8qCgkgICAgKiAgVE9ETzogRnJlZSB0aGUgSURDIHRhYmxlIGlmIHN0aWxsIGV4aXN0ZW50LgoJICAgICovCgoJICAgIC8qCgkgICAgeG1sRnJlZShpbmZvLT5sb2NhbE5hbWUpOwoJICAgIGlmIChpbmZvLT5uYW1lc3BhY2VOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShpbmZvLT5uYW1lc3BhY2VOYW1lKTsKCSAgICAqLwoJICAgIHhtbEZyZWUoaW5mbyk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmVsZW1JbmZvcyk7CiAgICB9CiNlbmRpZgogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoY3R4dC0+cGN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFZhbGlkRXJyb3JzOgogKiBAY3R4dDoJYSBYTUwtU2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgZnVuY3Rpb24gcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbiByZXN1bHQKICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0IHJlc3VsdAogKgogKiBHZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkJCQl4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkT3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFWYWxpZE9wdGlvbgogKgogKiBTZXRzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFTZXRWYWxpZE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSBpbnQgb3B0aW9ucykKCQkJCQkKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVZhbGlkT3B0aW9uLgogICAgKiBUT0RPOiBJcyB0aGVyZSBhbiBvdGhlciwgbW9yZSBlYXN5IHRvIG1haW50YWluLAogICAgKiB3YXk/CiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hU2V0VmFsaWRPcHRpb25zLCAiCgkJImludmFsaWQgb3B0aW9uIGFyZ3VtZW50LlxuIiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7ICAgCiAgICAgICAgfQkKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQgCiAqCiAqIEdldCB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9wdGlvbnMuCiAqIAogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb3IgLTEgb24gZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKCQkJCQkKeyAgICAKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UgCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOyAgICAKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvYzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGRvYzogIGEgcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxEb2NQdHIgZG9jKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIGN0eHQtPmVyciA9IDA7IAogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgCiAgICAvKgogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkFQSSBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVEb2MsICIKCSAgICAibm8gc2NoZW1hIHNwZWNpZmllZCBhbmQgYXNzZW1ibGluZyBvZiBzY2hlbWF0YSAiCgkgICAgInVzaW5nIHhzaTpzY2hlbWFMb2NhdGlvbiBhbmQgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gIgoJICAgICJpcyBub3QgZW5hYmxlZC5cbiIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudChjdHh0LCBkb2MpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW06CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpbnB1dDogIHRoZSBpbnB1dCB0byB1c2UgZm9yIHJlYWRpbmcgdGhlIGRhdGEKICogQGVuYzogIGFuIG9wdGlvbmFsIGVuY29kaW5nIGluZm9ybWF0aW9uCiAqIEBzYXg6ICBhIFNBWCBoYW5kbGVyIGZvciB0aGUgcmVzdWx0aW5nIGV2ZW50cwogKiBAdXNlcl9kYXRhOiAgdGhlIGNvbnRleHQgdG8gcHJvdmlkZSB0byB0aGUgU0FYIGhhbmRsZXIuCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQsIHhtbENoYXJFbmNvZGluZyBlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4LCB2b2lkICp1c2VyX2RhdGEpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5wdXQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwogICAgY3R4dC0+ZW5jID0gZW5jOwogICAgY3R4dC0+c2F4ID0gc2F4OwogICAgY3R4dC0+dXNlcl9kYXRhID0gdXNlcl9kYXRhOwogICAgVE9ETyByZXR1cm4gKDApOwp9CgojZW5kaWYgLyogTElCWE1MX1NDSEVNQVNfRU5BQkxFRCAqLwo=