LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKiAKICogVE9ETzoKICogICAtIHdoZW4gdHlwZXMgYXJlIHJlZGVmaW5lZCBpbiBpbmNsdWRlcywgY2hlY2sgdGhhdCBhbGwKICogICAgIHR5cGVzIGluIHRoZSByZWRlZiBsaXN0IGFyZSBlcXVhbAogKiAgICAgLT4gbmVlZCBhIHR5cGUgZXF1YWxpdHkgb3BlcmF0aW9uLgogKiAgIC0gaWYgd2UgZG9uJ3QgaW50ZW5kIHRvIHVzZSB0aGUgc2NoZW1hIGZvciBzY2hlbWFzLCB3ZSAKICogICAgIG5lZWQgdG8gdmFsaWRhdGUgYWxsIHNjaGVtYSBhdHRyaWJ1dGVzIChyZWYsIHR5cGUsIG5hbWUpCiAqICAgICBhZ2FpbnN0IHRoZWlyIHR5cGVzLgogKi8KI2RlZmluZSBJTl9MSUJYTUwKI2luY2x1ZGUgImxpYnhtbC5oIgoKI2lmZGVmIExJQlhNTF9TQ0hFTUFTX0VOQUJMRUQKCiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxtZW1vcnkuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXIuaD4KI2luY2x1ZGUgPGxpYnhtbC9wYXJzZXJJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC9oYXNoLmg+CiNpbmNsdWRlIDxsaWJ4bWwvdXJpLmg+CgojaW5jbHVkZSA8bGlieG1sL3htbHNjaGVtYXMuaD4KI2luY2x1ZGUgPGxpYnhtbC9zY2hlbWFzSW50ZXJuYWxzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hc3R5cGVzLmg+CiNpbmNsdWRlIDxsaWJ4bWwveG1sYXV0b21hdGEuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxyZWdleHAuaD4KI2luY2x1ZGUgPGxpYnhtbC9kaWN0Lmg+CiNpZmRlZiBMSUJYTUxfUEFUVEVSTl9FTkFCTEVECiNpbmNsdWRlIDxsaWJ4bWwvcGF0dGVybi5oPgojZW5kaWYKCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKLyogI2RlZmluZSBERUJVR19VTklPTl9WQUxJREFUSU9OIDEgKi8KCiNkZWZpbmUgRUxFTV9JTkZPX0VOQUJMRUQgMSAKCiNkZWZpbmUgSURDX0VOQUJMRUQgMQoKI2RlZmluZSBJRENfVkFMVUVfU1VQUE9SVCAxCgojZGVmaW5lIElEQ19YUEFUSF9TVVBQT1JUIDEKCi8qICNkZWZpbmUgREVCVUdfSURDIDEgKi8KCgojZGVmaW5lIFVOQk9VTkRFRCAoMSA8PCAzMCkKI2RlZmluZSBUT0RPIAkJCQkJCQkJXAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCQkJCVwKCSAgICAiVW5pbXBsZW1lbnRlZCBibG9jayBhdCAlczolZFxuIiwJCQkJXAogICAgICAgICAgICBfX0ZJTEVfXywgX19MSU5FX18pOwoKI2RlZmluZSBYTUxfU0NIRU1BU19OT19OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikgIiMjIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzRWxlbURlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgZGVjbC4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkVsZW1lbnQgcmVmLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0ckRlY2wgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIkF0dHJpYnV0ZSBkZWNsLiI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQXR0clJlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiQXR0cmlidXRlIHJlZi4iOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbURlc1NUID0gKGNvbnN0IHhtbENoYXIgKikKICAgICJzaW1wbGUgdHlwZSI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtRGVzQ1QgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImNvbXBsZXggdHlwZSI7CnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFFbGVtTW9kZWxHckRlZiA9IChjb25zdCB4bWxDaGFyICopCiAgICAiTW9kZWwgZ3JvdXAiOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqeG1sU2NoZW1hRWxlbU1vZGVsR3JSZWYgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgIk1vZGVsIGdyb3VwIHJlZi4iOwoKI2RlZmluZSBJU19TQ0hFTUEobm9kZSwgdHlwZSkJCQkJCQlcCiAgICgobm9kZSAhPSBOVUxMKSAmJiAobm9kZS0+bnMgIT0gTlVMTCkgJiYJCQkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIChjb25zdCB4bWxDaGFyICopIHR5cGUpKSAmJgkJXAogICAgKHhtbFN0ckVxdWFsKG5vZGUtPm5zLT5ocmVmLCB4bWxTY2hlbWFOcykpKQoKI2RlZmluZSBGUkVFX0FORF9OVUxMKHN0cikJCQkJCQlcCiAgICBpZiAoc3RyICE9IE5VTEwpIHsJCQkJCQkJXAoJeG1sRnJlZShzdHIpOwkJCQkJCQlcCglzdHIgPSBOVUxMOwkJCQkJCQlcCiAgICB9CgojZGVmaW5lIElTX0FOWVRZUEUoaXRlbSkgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgIFwKICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpICAgCgojZGVmaW5lIElTX0NPTVBMRVhfVFlQRShpdGVtKSAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8ICAgIFwKICAgICAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpCgojZGVmaW5lIElTX1NJTVBMRV9UWVBFKGl0ZW0pICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwgICAgIFwKICAgICAoKGl0ZW0tPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJiAgICAgXAogICAgICAoaXRlbS0+YnVpbHRJblR5cGUgIT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpKSAKCi8qCiNkZWZpbmUgWE1MX1NDSEVNQVNfVkFMX1dUU1BfUFJFU0VSVkUgMAojZGVmaW5lIFhNTF9TQ0hFTUFTX1ZBTF9XVFNQX1JFUExBQ0UgIDEKI2RlZmluZSBYTUxfU0NIRU1BU19WQUxfV1RTUF9DT0xMQVBTRSAyCiovCgojZGVmaW5lIFhNTF9TQ0hFTUFTX1BBUlNFX0VSUk9SCQkxCgojZGVmaW5lIFNDSEVNQVNfUEFSU0VfT1BUSU9OUyBYTUxfUEFSU0VfTk9FTlQKCgovKgoqIFhNTF9TQ0hFTUFfVkFMX0xPQ0FURV9CWV9OU05BTUUgPSAxPDwyCiogbG9jYXRlIHNjaGVtYXRhIHRvIGJlIGltcG9ydGVkCiogdXNpbmcgdGhlIG5hbWVzcGFjZSBuYW1lOyBvdGhlcndpc2UKKiB0aGUgbG9jYXRpb24gVVJJIHdpbGwgYmUgdXNlZCAqLwoKLyoKKiB4bWxTY2hlbWFQYXJzZXJPcHRpb246CioKKiBUaGlzIGlzIHRoZSBzZXQgb2YgWE1MIFNjaGVtYSBwYXJzZXIgb3B0aW9ucy4KKgp0eXBlZGVmIGVudW0gewogICAgWE1MX1NDSEVNQV9QQVJfTE9DQVRFX0JZX05TTkFNRQk9IDE8PDAKCSogbG9jYXRlIHNjaGVtYXRhIHRvIGJlIGltcG9ydGVkCgkqIHVzaW5nIHRoZSBuYW1lc3BhY2UgbmFtZTsgb3RoZXJ3aXNlCgkqIHRoZSBsb2NhdGlvbiBVUkkgd2lsbCBiZSB1c2VkICoKfSB4bWxTY2hlbWFQYXJzZXJPcHRpb247CiovCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQXNzZW1ibGUgeG1sU2NoZW1hQXNzZW1ibGU7CnR5cGVkZWYgeG1sU2NoZW1hQXNzZW1ibGUgKnhtbFNjaGVtYUFzc2VtYmxlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUFzc2VtYmxlIHsKICAgIHZvaWQgKippdGVtczsgIC8qIHVzZWQgZm9yIGR5bmFtaWMgYWRkaXRpb24gb2Ygc2NoZW1hdGEgKi8KICAgIGludCBuYkl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCiAgICBpbnQgc2l6ZUl0ZW1zOyAvKiB1c2VkIGZvciBkeW5hbWljIGFkZGl0aW9uIG9mIHNjaGVtYXRhICovCn07CgpzdHJ1Y3QgX3htbFNjaGVtYVBhcnNlckN0eHQgewogICAgdm9pZCAqdXNlckRhdGE7ICAgICAgICAgICAgIC8qIHVzZXIgc3BlY2lmaWMgZGF0YSBibG9jayAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgZXJyb3I7ICAgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2YgZXJyb3JzICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm5pbmc7ICAgICAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIHdhcm5pbmcgKi8KICAgIHhtbFNjaGVtYVZhbGlkRXJyb3IgZXJyOwogICAgaW50IG5iZXJyb3JzOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHRvcHNjaGVtYTsJLyogVGhlIG1haW4gc2NoZW1hICovCiAgICB4bWxIYXNoVGFibGVQdHIgbmFtZXNwYWNlczsJLyogSGFzaCB0YWJsZSBvZiBuYW1lc3BhY2VzIHRvIHNjaGVtYXMgKi8KCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIGNvbnN0IHhtbENoYXIgKmNvbnRhaW5lcjsgICAvKiB0aGUgY3VycmVudCBlbGVtZW50LCBncm91cCwgLi4uICovCiAgICBpbnQgY291bnRlcjsKCiAgICBjb25zdCB4bWxDaGFyICpVUkw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IHByZXNlcnZlOwkJLyogV2hldGhlciB0aGUgZG9jIHNob3VsZCBiZSBmcmVlZCAgKi8KCiAgICBjb25zdCBjaGFyICpidWZmZXI7CiAgICBpbnQgc2l6ZTsKCiAgICAvKgogICAgICogVXNlZCB0byBidWlsZCBjb21wbGV4IGVsZW1lbnQgY29udGVudCBtb2RlbHMKICAgICAqLwogICAgeG1sQXV0b21hdGFQdHIgYW07CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBlbmQ7CiAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXRlOwoKICAgIHhtbERpY3RQdHIgZGljdDsJCS8qIGRpY3Rpb25uYXJ5IGZvciBpbnRlcm5lZCBzdHJpbmcgbmFtZXMgKi8KICAgIGludCAgICAgICAgaW5jbHVkZXM7CS8qIHRoZSBpbmNsdXNpb24gbGV2ZWwsIDAgZm9yIHJvb3Qgb3IgaW1wb3J0cyAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsgLyogVGhlIGN1cnJlbnQgY29udGV4dCBzaW1wbGUvY29tcGxleCB0eXBlICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHBhcmVudEl0ZW07IC8qIFRoZSBjdXJyZW50IHBhcmVudCBzY2hlbWEgaXRlbSAqLwogICAgeG1sU2NoZW1hQXNzZW1ibGVQdHIgYXNzZW1ibGU7CiAgICBpbnQgb3B0aW9uczsKICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORyA0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFIDUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEIDYKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfRklYRURfVkFMVUUgNwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfREVGQVVMVCA4CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRSA5CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9XSUxEX05PX0RFQ0wgMTAKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwogICAgY29uc3QgeG1sQ2hhciAqdmFsdWU7Cn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hQmFzaWNJdGVtIHhtbFNjaGVtYUJhc2ljSXRlbTsKdHlwZWRlZiB4bWxTY2hlbWFCYXNpY0l0ZW0gKnhtbFNjaGVtYUJhc2ljSXRlbVB0cjsKc3RydWN0IF94bWxTY2hlbWFCYXNpY0l0ZW0gewogICAgeG1sU2NoZW1hVHlwZVR5cGUgdHlwZTsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUl0ZW1RTlJlZiB4bWxTY2hlbWFJdGVtUU5SZWY7CnR5cGVkZWYgeG1sU2NoZW1hSXRlbVFOUmVmICp4bWxTY2hlbWFJdGVtUU5SZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSXRlbVFOUmVmIHsKICAgIHhtbFNjaGVtYUJhc2ljSXRlbVB0ciBpdGVtOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKfTsKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJREMgeG1sU2NoZW1hSURDOwp0eXBlZGVmIHhtbFNjaGVtYUlEQyAqeG1sU2NoZW1hSURDUHRyOwoKLyoqCiAqIHhtbFNjaGVtYUlEQ1NlbGVjdDoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgImZpZWxkIiBhbmQgInNlbGVjdG9yIiBpdGVtLCBob2xkaW5nIHRoZQogKiBYUGF0aCBleHByZXNzaW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ1NlbGVjdCB4bWxTY2hlbWFJRENTZWxlY3Q7CnR5cGVkZWYgeG1sU2NoZW1hSURDU2VsZWN0ICp4bWxTY2hlbWFJRENTZWxlY3RQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU2VsZWN0IHsgICAgCiAgICB4bWxTY2hlbWFJRENTZWxlY3RQdHIgbmV4dDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGM7CiAgICBpbnQgaW5kZXg7IC8qIGFuIGluZGV4IHBvc2l0aW9uIGlmIHNpZ25pZmljYW50IGZvciBJREMga2V5LXNlcXVlbmNlcyAqLwogICAgY29uc3QgeG1sQ2hhciAqeHBhdGg7IC8qIHRoZSBYUGF0aCBleHByZXNzaW9uICovCiAgICB2b2lkICp4cGF0aENvbXA7IC8qIHRoZSBjb21waWxlZCBYUGF0aCBleHByZXNzaW9uICovCn07CgovKioKICogeG1sU2NoZW1hSURDOgogKgogKiBUaGUgaWRlbnRpdHktY29uc3RyYWludCBkZWZpbml0aW9uIGNvbXBvbmVudC4KICovCgpzdHJ1Y3QgX3htbFNjaGVtYUlEQyB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CiAgICB4bWxTY2hlbWFJRENQdHIgbmV4dDsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7ICAgIAogICAgY29uc3QgeG1sQ2hhciAqdGFyZ2V0TmFtZXNwYWNlOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIHNlbGVjdG9yOwogICAgeG1sU2NoZW1hSURDU2VsZWN0UHRyIGZpZWxkczsKICAgIGludCBuYkZpZWxkczsKICAgIHhtbFNjaGVtYUl0ZW1RTlJlZlB0ciByZWY7Cn07CgovKioKICogeG1sU2NoZW1hSURDQXVnOgogKgogKiBUaGUgYXVnbWVudGVkIElEQyBpbmZvcm1hdGlvbiB1c2VkIGZvciB2YWxpZGF0aW9uLgogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUlEQ0F1ZyB4bWxTY2hlbWFJRENBdWc7CnR5cGVkZWYgeG1sU2NoZW1hSURDQXVnICp4bWxTY2hlbWFJRENBdWdQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDQXVnIHsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBuZXh0OyAvKiBuZXh0IGluIGEgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDUHRyIGRlZjsgLyogdGhlIElEQyBkZWZpbml0aW9uICovCiAgICBpbnQgYnViYmxlRGVwdGg7IC8qIHRoZSBsb3dlc3QgbGV2ZWwgdG8gd2hpY2ggSURDIAogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZXMgbmVlZCB0byBiZSBidWJibGVkIHVwd2FyZHMgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDS2V5U2VxdWVuY2U6CiAqCiAqIFRoZSBrZXkgc2VxdWVuY2Ugb2YgYSBub2RlIHRhYmxlIGl0ZW0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB4bWxTY2hlbWFQU1ZJSURDS2V5Owp0eXBlZGVmIHhtbFNjaGVtYVBTVklJRENLZXkgKnhtbFNjaGVtYVBTVklJRENLZXlQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0tleSB7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxTY2hlbWFWYWxQdHIgY29tcFZhbHVlOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVBTVklJRENOb2RlOgogKgogKiBUaGUgbm9kZSB0YWJsZSBpdGVtIG9mIGEgbm9kZSB0YWJsZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFQU1ZJSURDTm9kZSB4bWxTY2hlbWFQU1ZJSURDTm9kZTsKdHlwZWRlZiB4bWxTY2hlbWFQU1ZJSURDTm9kZSAqeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ05vZGUgewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqa2V5czsKfTsKCi8qKgogKiB4bWxTY2hlbWFQU1ZJSURDQmluZGluZzoKICoKICogVGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgYmluZGluZyBpdGVtIG9mIHRoZSBbaWRlbnRpdHktY29uc3RyYWludCB0YWJsZV0uCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmc7CnR5cGVkZWYgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcgKnhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYVBTVklJRENCaW5kaW5nIHsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIG5leHQ7IC8qIG5leHQgYmluZGluZyBvZiBhIHNwZWNpZmljIG5vZGUgKi8KICAgIHhtbFNjaGVtYUlEQ1B0ciBkZWZpbml0aW9uOyAvKiB0aGUgSURDIGRlZmluaXRpb24gKi8KICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICpub2RlVGFibGU7IC8qIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMgKi8KICAgIGludCBuYk5vZGVzOyAvKiBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IHNpemVOb2RlczsgLyogc2l6ZSBvZiB0aGUgbm9kZSB0YWJsZSAqLwogICAgaW50IG5iRHVwbHM7IC8qIG51bWJlciBvZiBhbHJlYWR5IGlkZW50aWZpZWQgZHVwbGljYXRlcyBpbiB0aGUgbm9kZSAKICAgICAgICAgICAgICAgICAgICB0YWJsZSAqLwogICAgLyogaW50IG5iS2V5czsgbnVtYmVyIG9mIGtleXMgaW4gZWFjaCBrZXktc2VxdWVuY2UgKi8KfTsKCiNkZWZpbmUgWFBBVEhfU1RBVEVfT0JKX1RZUEVfSURDX1NFTEVDVE9SIDEKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQgMgoKI2RlZmluZSBYUEFUSF9TVEFURV9PQkpfTUFUQ0hFUyAtMgojZGVmaW5lIFhQQVRIX1NUQVRFX09CSl9CTE9DS0VEIC0zCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSURDTWF0Y2hlciB4bWxTY2hlbWFJRENNYXRjaGVyOwp0eXBlZGVmIHhtbFNjaGVtYUlEQ01hdGNoZXIgKnhtbFNjaGVtYUlEQ01hdGNoZXJQdHI7CgovKioKICogeG1sU2NoZW1hSURDU3RhdGVPYmo6CiAqCiAqIFRoZSBzdGF0ZSBvYmplY3QgdXNlZCB0byBldmFsdWF0ZSBYUGF0aCBleHByZXNzaW9ucy4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJRENTdGF0ZU9iaiB4bWxTY2hlbWFJRENTdGF0ZU9iajsKdHlwZWRlZiB4bWxTY2hlbWFJRENTdGF0ZU9iaiAqeG1sU2NoZW1hSURDU3RhdGVPYmpQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSURDU3RhdGVPYmogewogICAgaW50IHR5cGU7ICAgIAogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgbmV4dDsgLyogbmV4dCBpZiBpbiBhIGxpc3QgKi8KICAgIGludCBkZXB0aDsgLyogZGVwdGggb2YgY3JlYXRpb24gKi8KICAgIGludCAqaGlzdG9yeTsgLyogbGlzdCBvZiAoZGVwdGgsIHN0YXRlLWlkKSB0dXBsZXMgKi8KICAgIGludCBuYkhpc3Rvcnk7CiAgICBpbnQgc2l6ZUhpc3Rvcnk7CiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7IC8qIHRoZSBjb3JyZXNwb25kZW50IGZpZWxkL3NlbGVjdG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXIgKi8KICAgIHhtbFNjaGVtYUlEQ1NlbGVjdFB0ciBzZWw7CiAgICB2b2lkICp4cGF0aEN0eHQ7Cn07CgojZGVmaW5lIElEQ19NQVRDSEVSIDAKCi8qKgogKiB4bWxTY2hlbWFJRENNYXRjaGVyOgogKgogKiBVc2VkIHRvICBJREMgc2VsZWN0b3JzIChhbmQgZmllbGRzKSBzdWNjZXNzaXZlbHkuCiAqLwpzdHJ1Y3QgX3htbFNjaGVtYUlEQ01hdGNoZXIgewogICAgaW50IHR5cGU7CiAgICBpbnQgZGVwdGg7IC8qIHRoZSB0cmVlIGRlcHRoIGF0IGNyZWF0aW9uIHRpbWUgKi8KICAgIHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbmV4dDsgLyogbmV4dCBpbiB0aGUgbGlzdCAqLwogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7IC8qIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gKi8KICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiprZXlTZXFzOyAvKiB0aGUga2V5LXNlcXVlbmNlcyBvZiB0aGUgdGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgKi8KICAgIGludCBzaXplS2V5U2VxczsKICAgIGludCB0YXJnZXREZXB0aDsKfTsKCi8qCiogRWxlbWVudCBpbmZvIGZsYWdzLgoqLwojZGVmaW5lIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX1ZBTFVFX05FRURFRCAxCi8qICNkZWZpbmUgWE1MX1NDSEVNQV9FTEVNX0lORk9fQVRUUiAyICovCi8qICNkZWZpbmUgWE1MX1NDSEVNQV9FTEVNX0lORk9fRUxFTSA0ICovCgovKioKICogeG1sU2NoZW1hTm9kZUluZm86CiAqCiAqIEhvbGRzIGluZm9ybWF0aW9uIG9mIGFuIGVsZW1lbnQgbm9kZS4KICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFOb2RlSW5mbyB4bWxTY2hlbWFOb2RlSW5mbzsKdHlwZWRlZiB4bWxTY2hlbWFOb2RlSW5mbyAqeG1sU2NoZW1hTm9kZUluZm9QdHI7CnN0cnVjdCBfeG1sU2NoZW1hTm9kZUluZm8gewogICAgaW50IGRlcHRoOwogICAgaW50IGZsYWdzOyAvKiBjb21iaW5hdGlvbiBvZiBub2RlIGluZm8gZmxhZ3MgKi8KICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIGNvbnN0IHhtbENoYXIgKmxvY2FsTmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWU7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWY7IC8qIHRoZSBjb21wbGV4L3NpbXBsZSB0eXBlIGRlZmluaXRpb24gaWYgYW55ICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIGRlY2w7IC8qIHRoZSBlbGVtZW50L2F0dHJpYnV0ZSBkZWNsYXJhdGlvbiAqLwogICAgeG1sU2NoZW1hVmFsUHRyIHZhbHVlOyAvKiB0aGUgcHJlLWNvbXB1dGVkIHZhbHVlIGlmIGFueSAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgaWRjVGFibGU7IC8qIHRoZSB0YWJsZSBvZiBQU1ZJIElEQyBiaW5kaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciB0aGUgc2NvcGUgZWxlbWVudCovCiAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIGlkY01hdGNoZXJzOyAvKiB0aGUgSURDIG1hdGNoZXJzIGZvciB0aGUgc2NvcGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgKi8KfTsKCi8qKgogKiB4bWxTY2hlbWFWYWxpZEN0eHQ6CiAqCiAqIEEgU2NoZW1hcyB2YWxpZGF0aW9uIGNvbnRleHQKICovCgpzdHJ1Y3QgX3htbFNjaGVtYVZhbGlkQ3R4dCB7CiAgICB2b2lkICp1c2VyRGF0YTsgICAgICAgICAgICAgLyogdXNlciBzcGVjaWZpYyBkYXRhIGJsb2NrICovCiAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnJvcjsgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiBlcnJvcnMgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2FybmluZzsgLyogdGhlIGNhbGxiYWNrIGluIGNhc2Ugb2Ygd2FybmluZyAqLwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzZXJyb3I7CgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQ7CiAgICB4bWxDaGFyRW5jb2RpbmcgZW5jOwogICAgeG1sU0FYSGFuZGxlclB0ciBzYXg7CiAgICB2b2lkICp1c2VyX2RhdGE7CgogICAgeG1sRG9jUHRyIG15RG9jOwogICAgaW50IGVycjsKICAgIGludCBuYmVycm9yczsKCiAgICB4bWxOb2RlUHRyIG5vZGU7CiAgICB4bWxOb2RlUHRyIGN1cjsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCiAgICB4bWxSZWdFeGVjQ3R4dFB0ciByZWdleHA7CiAgICB4bWxTY2hlbWFWYWxQdHIgdmFsdWU7CgogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHJUb3A7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0cjsKICAgIC8qIHhtbE5vZGVQdHIgc2NvcGU7IG5vdCB1c2VkICovCiAgICBpbnQgdmFsdWVXUzsKICAgIGludCBvcHRpb25zOwogICAgeG1sTm9kZVB0ciB2YWxpZGF0aW9uUm9vdDsgICAgCiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0OwogICAgaW50IHhzaUFzc2VtYmxlOwojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIGludCBkZXB0aDsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyICplbGVtSW5mb3M7IC8qIGFycmF5IG9mIGVsZW1lbnQgaW5mb3JtYXRpb25zICovCiAgICBpbnQgc2l6ZUVsZW1JbmZvczsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIG5vZGVJbmZvOyAvKiB0aGUgY3VycmVudCBlbGVtZW50IGluZm9ybWF0aW9uICovCiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBhdHRySW5mbzsgLyogbm9kZSBpbmZvciBmb3IgdGhlIGN1cnJlbnQgYXR0cmlidXRlICovCiNlbmRpZgojaWZkZWYgSURDX0VOQUJMRUQKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjczsgLyogYSBsaXN0IG9mIGF1Z21lbnRlZCBJREMgaW5mb3JtYXRpb25zICovCgogICAgeG1sU2NoZW1hSURDU3RhdGVPYmpQdHIgeHBhdGhTdGF0ZXM7IC8qIGZpcnN0IGFjdGl2ZSBzdGF0ZSBvYmplY3QuICovCiAgICB4bWxTY2hlbWFJRENTdGF0ZU9ialB0ciB4cGF0aFN0YXRlUG9vbDsgLyogZmlyc3Qgc3RvcmVkIHN0YXRlIG9iamVjdC4gKi8KICAgIAogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKmlkY05vZGVzOyAvKiBsaXN0IG9mIGFsbCBJREMgbm9kZS10YWJsZSBlbnRyaWVzKi8KICAgIGludCBuYklkY05vZGVzOwogICAgaW50IHNpemVJZGNOb2RlczsKCiAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICppZGNLZXlzOyAvKiBsaXN0IG9mIGFsbCBJREMgbm9kZS10YWJsZSBlbnRyaWVzICovCiAgICBpbnQgbmJJZGNLZXlzOwogICAgaW50IHNpemVJZGNLZXlzOwojZW5kaWYKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBpbiB0aGUgc2NoZW1hcyBpbXBvcnRTY2hlbWFzIGhhc2ggdGFibGUKICovCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgeG1sU2NoZW1hSW1wb3J0Owp0eXBlZGVmIHhtbFNjaGVtYUltcG9ydCAqeG1sU2NoZW1hSW1wb3J0UHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUltcG9ydCB7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWE7IC8qIG5vdCB1c2VkIGFueSBtb3JlICovCiAgICB4bWxEb2NQdHIgZG9jOwogICAgaW50IGlzTWFpbjsKfTsKCi8qCiAqIFRoZXNlIGFyZSB0aGUgZW50cmllcyBhc3NvY2lhdGVkIHRvIGluY2x1ZGVzIGluIGEgc2NoZW1hcwogKi8KdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgeG1sU2NoZW1hSW5jbHVkZTsKdHlwZWRlZiB4bWxTY2hlbWFJbmNsdWRlICp4bWxTY2hlbWFJbmNsdWRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUluY2x1ZGUgewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxEb2NQdHIgZG9jOwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX3htbFNjaGVtYVBhcnRpY2xlIHhtbFNjaGVtYVBhcnRpY2xlOwp0eXBlZGVmIHhtbFNjaGVtYVBhcnRpY2xlICp4bWxTY2hlbWFQYXJ0aWNsZVB0cjsKc3RydWN0IF94bWxTY2hlbWFQYXJ0aWNsZSB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgbmV4dDsgLyogdGhlIG5leHQgcGFydGljbGUgaWYgaW4gYSBsaXN0ICovCiAgICBpbnQgbWluT2NjdXJzOwogICAgaW50IG1heE9jY3VyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdGVybTsKfTsKCgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB4bWxTY2hlbWFNb2RlbEdyb3VwOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXAgKnhtbFNjaGVtYU1vZGVsR3JvdXBQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cCB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgaW50IGNvbXBvc2l0b3I7IC8qIG9uZSBvZiBhbGwsIGNob2ljZSBvciBzZXF1ZW5jZSAqLwogICAgeG1sU2NoZW1hUGFydGljbGVQdHIgcGFydGljbGVzOyAvKiBsaXN0IG9mIHBhcnRpY2xlcyAqLwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7Cn07Cgp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB4bWxTY2hlbWFNb2RlbEdyb3VwRGVmOwp0eXBlZGVmIHhtbFNjaGVtYU1vZGVsR3JvdXBEZWYgKnhtbFNjaGVtYU1vZGVsR3JvdXBEZWZQdHI7CnN0cnVjdCBfeG1sU2NoZW1hTW9kZWxHcm91cERlZiB7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5hbWVzcGFjZTsKICAgIHhtbFNjaGVtYU1vZGVsR3JvdXBQdHIgbW9kZWxHcm91cDsKICAgIHhtbFNjaGVtYUFubm90UHRyIGFubm90Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNvbWUgcHJlZGVjbGFyYXRpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFUeXBlRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpOwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHhtbFNjaGVtYVR5cGVUeXBlIHR5cGUpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCQkgaW50IGZpcmVFcnJvcnMsCgkJCQkgaW50IGFwcGx5RmFjZXRzLAoJCQkJIGludCBub3JtYWxpemUsCgkJCQkgaW50IGNoZWNrTm9kZXMpOwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsKTsgCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSk7CnN0YXRpYyBpbnQKeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIGludAp4bWxTY2hlbWFQYXJzZUltcG9ydCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCQkJCQkJCQkqCiAqIAkJCURhdGF0eXBlIGVycm9yIGhhbmRsZXJzCQkJCSoKICoJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hUEVyck1lbW9yeToKICogQG5vZGU6IGEgY29udGV4dCBub2RlCiAqIEBleHRyYTogIGV4dHJhIGluZm9ybWF0aW9ucwogKgogKiBIYW5kbGUgYW4gb3V0IG9mIG1lbW9yeSBjb25kaXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnJNZW1vcnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmV4dHJhLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChjdHh0ICE9IE5VTEwpCiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgIF9feG1sU2ltcGxlRXJyb3IoWE1MX0ZST01fU0NIRU1BU1AsIFhNTF9FUlJfTk9fTUVNT1JZLCBub2RlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICBleHRyYSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBtc2c6IHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIAogKiBIYW5kbGUgYSBwYXJzZXIgZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgdm9pZCAqZGF0YSA9IE5VTEw7CgogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKCXNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgfQogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTUCwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRXJyMjoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQG5vZGU6IHRoZSBjdXJyZW50IGNoaWxkCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycjIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsCiAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgY2hpbGQsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIGlmIChjaGlsZCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY2hpbGQsIGVycm9yLCBtc2csIHN0cjEsIHN0cjIpOwogICAgZWxzZQogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7Cn0KCgovKioKICogeG1sU2NoZW1hUEVyckV4dDoKICogQGN0eHQ6IHRoZSBwYXJzaW5nIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQHN0ckRhdGExOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMjogZXh0cmEgZGF0YQogKiBAc3RyRGF0YTM6IGV4dHJhIGRhdGEKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyckV4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMSwgY29uc3QgeG1sQ2hhciAqIHN0ckRhdGEyLCAKCQljb25zdCB4bWxDaGFyICogc3RyRGF0YTMsIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHIyLCBjb25zdCB4bWxDaGFyICogc3RyMywgY29uc3QgeG1sQ2hhciAqIHN0cjQsCgkJY29uc3QgeG1sQ2hhciAqIHN0cjUpCnsKCiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwoJc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0ckRhdGExLCAoY29uc3QgY2hhciAqKSBzdHJEYXRhMiwgCgkJICAgIChjb25zdCBjaGFyICopIHN0ckRhdGEzLCAwLCAwLCBtc2csIHN0cjEsIHN0cjIsIAoJCSAgICBzdHIzLCBzdHI0LCBzdHI1KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWVHlwZUVyck1lbW9yeToKICogQG5vZGU6IGEgY29udGV4dCBub2RlCiAqIEBleHRyYTogIGV4dHJhIGluZm9ybWF0aW9ucwogKgogKiBIYW5kbGUgYW4gb3V0IG9mIG1lbW9yeSBjb25kaXRpb24KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnJNZW1vcnkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPm5iZXJyb3JzKys7CiAgICAgICAgY3R4dC0+ZXJyID0gWE1MX1NDSEVNQVZfSU5URVJOQUw7CiAgICB9CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNWLCBYTUxfRVJSX05PX01FTU9SWSwgbm9kZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgZXh0cmEpOwp9CgovKioKICogeG1sU2NoZW1hVkVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnIzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBvbGQgc2NoZW1hIGVycm9yIGNvZGVzIGhhdmUgYmVlbiAKICAgICogc3Vic3RpdHV0ZWQgZm9yIHRoZSBnbG9iYWwgZXJyb3IgY29kZXMuCiAgICAqCiAgICAqIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7IAogICAgKi8KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1YsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyMSwgKGNvbnN0IGNoYXIgKikgc3RyMiwKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyMywgMCwgMCwKICAgICAgICAgICAgICAgICAgICBtc2csIHN0cjEsIHN0cjIsIHN0cjMpOwp9CgovKioKICogeG1sU2NoZW1hVkVyckV4dDoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZSAKICogQG1zZzogdGhlIG1lc3NhZ2UKICogQHN0cjE6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjI6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjM6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjQ6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogQHN0cjU6ICBleHRyYSBwYXJhbWV0ZXIgZm9yIHRoZSBtZXNzYWdlIGRpc3BsYXkKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnJFeHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAoJCSBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCAKCQkgY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCAKCQkgY29uc3QgeG1sQ2hhciAqIHN0cjQsIGNvbnN0IHhtbENoYXIgKiBzdHI1KQp7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKCWN0eHQtPmVyciA9IGVycm9yOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CiAgICB9CiAgICAvKiByZWFqdXN0IHRvIGdsb2JhbCBlcnJvciBudW1iZXJzICovCiAgICAgLyogUmVtb3ZlZCwgc2luY2UgdGhlIG9sZCBzY2hlbWEgZXJyb3IgY29kZXMgaGF2ZSBiZWVuIAogICAgKiBzdWJzdGl0dXRlZCBmb3IgdGhlIGdsb2JhbCBlcnJvciBjb2Rlcy4KICAgICoKICAgICogZXJyb3IgKz0gWE1MX1NDSEVNQVZfTk9ST09UIC0gWE1MX1NDSEVNQVNfRVJSX05PUk9PVDsKICAgICovCiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLCBOVUxMLCBOVUxMLCBOVUxMLCAwLCAwLCAKCQkgICAgbXNnLCBzdHIxLCBzdHIyLCBzdHIzLCBzdHI0LCBzdHI1KTsKfQovKioKICogeG1sU2NoZW1hVkVycjoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBvbGQgc2NoZW1hIGVycm9yIGNvZGVzIGhhdmUgYmVlbiAKICAgICogc3Vic3RpdHV0ZWQgZm9yIHRoZSBnbG9iYWwgZXJyb3IgY29kZXMuCiAgICAqCiAgICAqIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICAqLwogICAgX194bWxSYWlzZUVycm9yKHNjaGFubmVsLCBjaGFubmVsLCBkYXRhLCBjdHh0LCBub2RlLCBYTUxfRlJPTV9TQ0hFTUFTViwKICAgICAgICAgICAgICAgICAgICBlcnJvciwgWE1MX0VSUl9FUlJPUiwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKSBzdHIxLCAoY29uc3QgY2hhciAqKSBzdHIyLCBOVUxMLCAwLCAwLAogICAgICAgICAgICAgICAgICAgIG1zZywgc3RyMSwgc3RyMik7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyTmFtZToKICogQGF0dHI6ICB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZQogKgogKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGU7IGlmIHRoZSBhdHRyaWJ1dGUKICogaXMgYSByZWZlcmVuY2UsIHRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2VkIGdsb2JhbCB0eXBlIHdpbGwgYmUgcmV0dXJuZWQuCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldEF0dHJOYW1lKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKSAKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKSAKCXJldHVybihhdHRyLT5yZWYpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPm5hbWUpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSToKICogQHR5cGU6ICB0aGUgdHlwZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCiAqCiAqIFJldHVybnMgdGhlIHRhcmdldCBuYW1lc3BhY2UgVVJJIG9mIHRoZSB0eXBlOyBpZiB0aGUgdHlwZSBpcyBhIHJlZmVyZW5jZSwKICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHJlZmVyZW5jZWQgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRBdHRyVGFyZ2V0TnNVUkkoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsgIAogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKQoJcmV0dXJuIChhdHRyLT5yZWZOcyk7CiAgICBlbHNlCglyZXR1cm4oYXR0ci0+dGFyZ2V0TmFtZXNwYWNlKTsgIAp9CgovKioKICogeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbDoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQHVyaTogIHRoZSBuYW1lc3BhY2UgVVJJCiAqIEBsb2NhbDogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBVUkkgdXNlZAogKiBmb3IgZXJyb3IgcmVwb3J0cy4KICoKICogUmV0dXJucyBhbiBlbXB0eSBzdHJpbmcsIGlmIEBucyBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8gIApzdGF0aWMgY29uc3QgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCh4bWxDaGFyICoqYnVmLAoJCQkgICBjb25zdCB4bWxDaGFyICp1cmksIGNvbnN0IHhtbENoYXIgKmxvY2FsKQp7CiAgICBpZiAoKmJ1ZiAhPSBOVUxMKQoJeG1sRnJlZSgqYnVmKTsKICAgIGlmICh1cmkgPT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyciKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbG9jYWwpOwogICAgfSBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIHVyaSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInLCAnIik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsJCiAgICB9CiAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInfSIpOwogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWw6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEBuczogIHRoZSBuYW1lc3BhY2UKICogQGxvY2FsOiB0aGUgbG9jYWwgbmFtZQogKgogKiBSZXR1cm5zIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIFVSSSB1c2VkCiAqIGZvciBlcnJvciByZXBvcnRzLgogKgogKiBSZXR1cm5zIGFuIGVtcHR5IHN0cmluZywgaWYgQG5zIGlzIE5VTEwsIGEgZm9ybWF0dGVkCiAqIHN0cmluZyBvdGhlcndpc2UuCiAqLyAgCnN0YXRpYyBjb25zdCB4bWxDaGFyKiAgIAp4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKHhtbENoYXIgKipidWYsCgkJCSAgICAgIHhtbE5zUHRyIG5zLCBjb25zdCB4bWxDaGFyICpsb2NhbCkKewogICAgaWYgKCpidWYgIT0gTlVMTCkgewoJeG1sRnJlZSgqYnVmKTsKCSpidWYgPSBOVUxMOwogICAgfQogICAgaWYgKChucyA9PSBOVUxMKSB8fCAobnMtPnByZWZpeCA9PSBOVUxMKSkKCXJldHVybihsb2NhbCk7CiAgICBlbHNlIHsKCSpidWYgPSB4bWxTdHJkdXAobnMtPnByZWZpeCk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICI6Iik7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxvY2FsKTsKICAgIH0KICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRRTmFtZToKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQG5hbWVzcGFjZU5hbWU6ICB0aGUgbmFtZXNwYWNlIG5hbWUKICogQGxvY2FsTmFtZTogdGhlIGxvY2FsIG5hbWUKICoKICogUmV0dXJucyB0aGUgZ2l2ZW4gUU5hbWUgaW4gdGhlIGZvcm1hdCAie25hbWVzcGFjZU5hbWV9bG9jYWxOYW1lIiBvcgogKiBqdXN0ICJsb2NhbE5hbWUiIGlmIEBuYW1lc3BhY2VOYW1lIGlzIE5VTEwuCiAqCiAqIFJldHVybnMgdGhlIGxvY2FsTmFtZSBpZiBAbmFtZXNwYWNlTmFtZSBpcyBOVUxMLCBhIGZvcm1hdHRlZAogKiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8gIApzdGF0aWMgY29uc3QgeG1sQ2hhciogICAKeG1sU2NoZW1hRm9ybWF0UU5hbWUoeG1sQ2hhciAqKmJ1ZiwKCQkgICAgIGNvbnN0IHhtbENoYXIgKm5hbWVzcGFjZU5hbWUsCgkJICAgICBjb25zdCB4bWxDaGFyICpsb2NhbE5hbWUpCnsKICAgIEZSRUVfQU5EX05VTEwoKmJ1ZikKICAgIGlmIChuYW1lc3BhY2VOYW1lID09IE5VTEwpCglyZXR1cm4obG9jYWxOYW1lKTsKICAgIAogICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyIpOwogICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBuYW1lc3BhY2VOYW1lKTsKICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIn0iKTsKICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbG9jYWxOYW1lKTsKICAgIAogICAgcmV0dXJuICgoY29uc3QgeG1sQ2hhciAqKSAqYnVmKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVdpbGRjYXJkUENUb1N0cmluZzoKICogQHBjOiB0aGUgdHlwZSBvZiBwcm9jZXNzQ29udGVudHMKICoKICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdHlwZSBvZiAKICogcHJvY2Vzc0NvbnRlbnRzLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFXaWxkY2FyZFBDVG9TdHJpbmcoaW50IHBjKQp7CiAgICBzd2l0Y2ggKHBjKSB7CgljYXNlIFhNTF9TQ0hFTUFTX0FOWV9TS0lQOgoJICAgIHJldHVybiAoQkFEX0NBU1QgInNraXAiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX0xBWDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJsYXgiKTsKCWNhc2UgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDoKCSAgICByZXR1cm4gKEJBRF9DQVNUICJzdHJpY3QiKTsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIChCQURfQ0FTVCAiaW52YWxpZCBwcm9jZXNzIGNvbnRlbnRzIik7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0OgogKiBAYnVmOiB0aGUgc3RyaW5nIGJ1ZmZlcgogKiBAaXRlbURlczogdGhlIGRlc2lnbmF0aW9uIG9mIHRoZSBpdGVtCiAqIEBpdGVtTmFtZTogdGhlIG5hbWUgb2YgdGhlIGl0ZW0KICogQGl0ZW06IHRoZSBpdGVtIGFzIGFuIG9iamVjdCAKICogQGl0ZW1Ob2RlOiB0aGUgbm9kZSBvZiB0aGUgaXRlbQogKiBAbG9jYWw6IHRoZSBsb2NhbCBuYW1lCiAqIEBwYXJzaW5nOiBpZiB0aGUgZnVuY3Rpb24gaXMgdXNlZCBkdXJpbmcgdGhlIHBhcnNlCiAqCiAqIFJldHVybnMgYSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gaXRlbSB1c2VkCiAqIGZvciBlcnJvciByZXBvcnRzLiAKICoKICogVGhlIGZvbGxvd2luZyBvcmRlciBpcyB1c2VkIHRvIGJ1aWxkIHRoZSByZXN1bHRpbmcgCiAqIGRlc2lnbmF0aW9uIGlmIHRoZSBhcmd1bWVudHMgYXJlIG5vdCBOVUxMOgogKiAxYS4gSWYgaXRlbURlcyBub3QgTlVMTCAtPiBpdGVtRGVzCiAqIDFiLiBJZiAoaXRlbURlcyBub3QgTlVMTCkgYW5kIChpdGVtTmFtZSBub3QgTlVMTCkKICogICAgIC0+IGl0ZW1EZXMgKyBpdGVtTmFtZQogKiAyLiBJZiB0aGUgcHJlY2VkaW5nIHdhcyBOVUxMIGFuZCAoaXRlbSBub3QgTlVMTCkgLT4gaXRlbQogKiAzLiBJZiB0aGUgcHJlY2VkaW5nIHdhcyBOVUxMIGFuZCAoaXRlbU5vZGUgbm90IE5VTEwpIC0+IGl0ZW1Ob2RlCiAqIAogKiBJZiB0aGUgaXRlbU5vZGUgaXMgYW4gYXR0cmlidXRlIG5vZGUsIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogd2lsbCBiZSBhcHBlbmRlZCB0byB0aGUgcmVzdWx0LgogKgogKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIGFuZCBzZXRzIEBidWYgdG8gdGhlIHJlc3VsdGluZyB2YWx1ZS4KICovICAKc3RhdGljIHhtbENoYXIqICAgCnhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoeG1sQ2hhciAqKmJ1ZiwJCSAgICAgCgkJICAgICBjb25zdCB4bWxDaGFyICppdGVtRGVzLAoJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICAgeG1sTm9kZVB0ciBpdGVtTm9kZSwKCQkgICAgIGludCBwYXJzaW5nKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgaW50IG5hbWVkID0gMTsKCiAgICBpZiAoKmJ1ZiAhPSBOVUxMKSB7Cgl4bWxGcmVlKCpidWYpOwoJKmJ1ZiA9IE5VTEw7CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKGl0ZW1EZXMgIT0gTlVMTCkgewoJKmJ1ZiA9IHhtbFN0cmR1cChpdGVtRGVzKTsJCiAgICB9IGVsc2UgaWYgKGl0ZW0gIT0gTlVMTCkgewoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKCSAgICBpZiAoaXRlbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInYW55VHlwZSciKTsKCSAgICBlbHNlIGlmIChpdGVtLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIidhbnlTaW1wbGVUeXBlJyIpOwoJICAgIGVsc2UgewoJCS8qICpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImJpICIpOyAqLwoJCS8qICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgeG1sU2NoZW1hRWxlbURlc1NUKTsgKi8KCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICInIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzU1QpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5uYW1lKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyZHVwKHhtbFNjaGVtYUVsZW1EZXNTVCk7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCSAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0NUKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgaXRlbS0+bmFtZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0gZWxzZSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtRGVzQ1QpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURTogewoJCXhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyOwoJICAgIAoJCWF0dHIgPSAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtOwkgICAgCgkJaWYgKChhdHRyLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMKSB8fAoJCSAgICAoYXR0ci0+cmVmID09IE5VTEwpKSB7CgkJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0F0dHJEZWNsKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5uYW1lKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCX0gZWxzZSB7CgkJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0F0dHJSZWYpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGF0dHItPnJlZlByZWZpeCk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIjoiKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBhdHRyLT5yZWYpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkJfQkKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOiB7CgkJeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtOwoKCQllbGVtID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW07CSAgICAKCQlpZiAoKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpIHx8IAoJCSAgICAoZWxlbS0+cmVmID09IE5VTEwpKSB7CgkJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0VsZW1EZWNsKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5uYW1lKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJCX0gZWxzZSB7CgkJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbURlc0VsZW1SZWYpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIgJyIpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIGVsZW0tPnJlZlByZWZpeCk7CgkJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIjoiKTsKCQkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5yZWYpOwoJCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkJfQoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19VTklRVUU6CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoJCQoJICAgIGlmIChpdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFKQoJCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInVuaXF1ZSAnIik7CgkgICAgZWxzZSBpZiAoaXRlbS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJrZXkgJyIpOwoJICAgIGVsc2UKCQkqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJrZXlSZWYgJyIpOwoJICAgICpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgKCh4bWxTY2hlbWFJRENQdHIpIGl0ZW0pLT5uYW1lKTsKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgoJICAgICpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hV2lsZGNhcmRQQ1RvU3RyaW5nKAoJCSAgICAoKHhtbFNjaGVtYVdpbGRjYXJkUHRyKSBpdGVtKS0+cHJvY2Vzc0NvbnRlbnRzKSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiIHdpbGRjYXJkIik7CgkgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKCSAgICAqYnVmID0geG1sU3RyZHVwKEJBRF9DQVNUICJmYWNldCAnIik7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhpdGVtLT50eXBlKSk7CgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkgICAgKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAibm90YXRpb24iKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cCh4bWxTY2hlbWFFbGVtTW9kZWxHckRlZik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGl0ZW0tPm5hbWUpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9IGVsc2UgewoJCSpidWYgPSB4bWxTdHJkdXAoeG1sU2NoZW1hRWxlbU1vZGVsR3JSZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiAnIik7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBpdGVtLT5yZWYpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKCSAgICB9CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIG5hbWVkID0gMDsKCX0KICAgIH0gZWxzZSAKCW5hbWVkID0gMDsKCiAgICBpZiAoKG5hbWVkID09IDApICYmIChpdGVtTm9kZSAhPSBOVUxMKSkgewoJeG1sTm9kZVB0ciBlbGVtOwoKCWlmIChpdGVtTm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkgICAgZWxlbSA9IGl0ZW1Ob2RlLT5wYXJlbnQ7CgllbHNlIAoJICAgIGVsZW0gPSBpdGVtTm9kZTsKCSpidWYgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoJaWYgKHBhcnNpbmcpCgkgICAgKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBlbGVtLT5uYW1lKTsKCWVsc2UKCSAgICAqYnVmID0geG1sU3RyY2F0KCpidWYsIAoJCXhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ciwgZWxlbS0+bnMsIGVsZW0tPm5hbWUpKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiciKTsKICAgIH0KICAgIGlmICgoaXRlbU5vZGUgIT0gTlVMTCkgJiYgKGl0ZW1Ob2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkpIHsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgQkFEX0NBU1QgIiwgYXR0cmlidXRlICciKTsKCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgeG1sU2NoZW1hRm9ybWF0TnNQcmVmaXhMb2NhbCgmc3RyLCAKCSAgICBpdGVtTm9kZS0+bnMsIGl0ZW1Ob2RlLT5uYW1lKSk7CgkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CiAgICB9CiAgICBGUkVFX0FORF9OVUxMKHN0cik7CiAgICAKICAgIHJldHVybiAoKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFQRm9ybWF0SXRlbURlczoKICogQGJ1ZjogdGhlIHN0cmluZyBidWZmZXIKICogQGl0ZW06IHRoZSBpdGVtIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAaXRlbU5vZGU6IHRoZSBpdGVtIGFzIGEgbm9kZQogKgogKiBJZiB0aGUgcG9pbnRlciB0byBAYnVmIGlzIG5vdCBOVUxMIGFuZCBAYnV0IGhvbGRzIG5vIHZhbHVlLAogKiB0aGUgdmFsdWUgaXMgc2V0IHRvIGEgaXRlbSBkZXNpZ25hdGlvbiB1c2luZyAKICogeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydC4gVGhpcyBvbmUgYXZvaWRzIGFkZGluZwogKiBhbiBhdHRyaWJ1dGUgZGVzaWduYXRpb24gcG9zdGZpeC4KICoKICogUmV0dXJucyBhIHN0cmluZyBvZiBhbGwgZW51bWVyYXRpb24gZWxlbWVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVxdWVzdEl0ZW1EZXMoeG1sQ2hhciAqKmJ1ZiwKCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICAgICB4bWxOb2RlUHRyIGl0ZW1Ob2RlKQp7CiAgICBpZiAoKGJ1ZiA9PSAwKSB8fCAoKmJ1ZiAhPSBOVUxMKSkgCglyZXR1cm47CiAgICBpZiAoaXRlbU5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJaXRlbU5vZGUgPSBpdGVtTm9kZS0+cGFyZW50OwogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChidWYsIE5VTEwsIGl0ZW0sIGl0ZW1Ob2RlLCAxKTsJCn0KCi8qKgogKiB4bWxTY2hlbWFGb3JtYXRGYWNldEVudW1TZXQ6CiAqIEBidWY6IHRoZSBzdHJpbmcgYnVmZmVyCiAqIEB0eXBlOiB0aGUgdHlwZSBob2xkaW5nIHRoZSBlbnVtZXJhdGlvbiBmYWNldHMKICoKICogQnVpbGRzIGEgc3RyaW5nIGNvbnNpc3Rpbmcgb2YgYWxsIGVudW1lcmF0aW9uIGVsZW1lbnRzLgogKgogKiBSZXR1cm5zIGEgc3RyaW5nIG9mIGFsbCBlbnVtZXJhdGlvbiBlbGVtZW50cy4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KHhtbENoYXIgKipidWYsIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGxpbms7CgogICAgaWYgKCpidWYgIT0gTlVMTCkKCXhtbEZyZWUoKmJ1Zik7ICAgIAogICAgKmJ1ZiA9IE5VTEw7CiAgICBmb3IgKGxpbmsgPSB0eXBlLT5mYWNldFNldDsgbGluayAhPSBOVUxMOyBsaW5rID0gbGluay0+bmV4dCkgewoJaWYgKGxpbmstPmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pIHsKCSAgICBpZiAoKmJ1ZiA9PSBOVUxMKSB7CgkJKmJ1ZiA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJyIpOwoJCSpidWYgPSB4bWxTdHJjYXQoKmJ1ZiwgbGluay0+ZmFjZXQtPnZhbHVlKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICInIik7CgkgICAgfSBlbHNlIHsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIEJBRF9DQVNUICIsICciKTsKCQkqYnVmID0geG1sU3RyY2F0KCpidWYsIGxpbmstPmZhY2V0LT52YWx1ZSk7CgkJKmJ1ZiA9IHhtbFN0cmNhdCgqYnVmLCBCQURfQ0FTVCAiJyIpOwoJICAgIH0KCX0KICAgIH0KICAgIHJldHVybiAoKGNvbnN0IHhtbENoYXIgKikgKmJ1Zik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWRmFjZXRFcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIG5vZGUgdG8gYmUgdmFsaWRhdGVkICAKICogQHZhbHVlOiB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICogQHR5cGU6IHRoZSB0eXBlIGhvbGRpbmcgdGhlIGZhY2V0CiAqIEBmYWNldDogdGhlIGZhY2V0CiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZSBvZiBOVUxMCiAqIEBzdHIxOiBleHRyYSBkYXRhCiAqIEBzdHIyOiBleHRyYSBkYXRhCiAqIEBzdHIzOiBleHRyYSBkYXRhCiAqCiAqIFJlcG9ydHMgYSBmYWNldCB2YWxpZGF0aW9uIGVycm9yLgogKiBUT0RPOiBTaG91bGQgdGhpcyByZXBvcnQgdGhlIHZhbHVlIG9mIGFuIGVsZW1lbnQgYXMgd2VsbD8KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZGYWNldEVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgIHhtbE5vZGVQdHIgbm9kZSwJCSAgIAoJCSAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgIHVuc2lnbmVkIGxvbmcgbGVuZ3RoLAoJCSAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldCwJCSAgIAoJCSAgIGNvbnN0IGNoYXIgKm1lc3NhZ2UsCgkJICAgY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkgICBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbENoYXIgKnN0ciA9IE5VTEwsICptc2cgPSBOVUxMOwogICAgeG1sU2NoZW1hVHlwZVR5cGUgZmFjZXRUeXBlOwoKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgTlVMTCwgbm9kZSwgMCk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIiwgZmFjZXQgJyIpOwogICAgaWYgKGVycm9yID09IFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRCkgewoJZmFjZXRUeXBlID0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjsKCS8qCgkqIElmIGVudW1lcmF0aW9ucyBhcmUgdmFsaWRhdGVkLCBvbmUgbXVzdCBub3QgZXhwZWN0IHRoZQoJKiBmYWNldCB0byBiZSBnaXZlbi4KCSovCQogICAgfSBlbHNlCQoJZmFjZXRUeXBlID0gZmFjZXQtPnR5cGU7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldFR5cGUpKTsKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInXTogIik7CiAgICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CgkvKgoJKiBVc2UgYSBkZWZhdWx0IG1lc3NhZ2UuCgkqLwoJaWYgKChmYWNldFR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEgpIHx8CgkgICAgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkgfHwKCSAgICAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKSkgewoKCSAgICBjaGFyIGxlblsyNV0sIGFjdExlblsyNV07CgoJICAgIC8qIEZJWE1FLCBUT0RPOiBXaGF0IGlzIHRoZSBtYXggZXhwZWN0ZWQgc3RyaW5nIGxlbmd0aCBvZiB0aGUKCSAgICAqIHRoaXMgdmFsdWU/CgkgICAgKi8KCSAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGhhcyBhIGxlbmd0aCBvZiAnJXMnOyAiKTsKCSAgICBlbHNlCgkJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSBoYXMgYSBsZW5ndGggb2YgJyVzJzsgIik7CgoJICAgIHNucHJpbnRmKGxlbiwgMjQsICIlbHUiLCB4bWxTY2hlbWFHZXRGYWNldFZhbHVlQXNVTG9uZyhmYWNldCkpOwoJICAgIHNucHJpbnRmKGFjdExlbiwgMjQsICIlbHUiLCBsZW5ndGgpOwoKCSAgICBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGRpZmZlcnMgZnJvbSB0aGUgYWxsb3dlZCBsZW5ndGggb2YgJyVzJy5cbiIpOyAgICAgCgkgICAgZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIKQoJCW1zZyA9IHhtbFN0cmNhdChtc2csIAoJCUJBRF9DQVNUICJ0aGlzIGV4Y2VlZHMgdGhlIGFsbG93ZWQgbWF4aW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSCkKCQltc2cgPSB4bWxTdHJjYXQobXNnLCAKCQlCQURfQ0FTVCAidGhpcyB1bmRlcnJ1bnMgdGhlIGFsbG93ZWQgbWluaW11bSBsZW5ndGggb2YgJyVzJy5cbiIpOwoJICAgIAoJICAgIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkKCQl4bWxTY2hlbWFWRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLAoJCSAgICAoY29uc3QgY2hhciAqKSBtc2csCgkJICAgIHZhbHVlLCAoY29uc3QgeG1sQ2hhciAqKSBhY3RMZW4sIChjb25zdCB4bWxDaGFyICopIGxlbiwKCQkgICAgTlVMTCwgTlVMTCk7CgkgICAgZWxzZSAKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAgCgkJICAgIChjb25zdCBjaGFyICopIG1zZywKCQkgICAgKGNvbnN0IHhtbENoYXIgKikgYWN0TGVuLCAoY29uc3QgeG1sQ2hhciAqKSBsZW4pOwoJCgl9IGVsc2UgaWYgKGZhY2V0VHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBhbiBlbGVtZW50ICIKCQkib2YgdGhlIHNldCB7JXN9LlxuIik7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgCgkJeG1sU2NoZW1hRm9ybWF0RmFjZXRFbnVtU2V0KCZzdHIsIHR5cGUpKTsKCX0gZWxzZSBpZiAoZmFjZXRUeXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgewoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgJyVzJyBpcyBub3QgYWNjZXB0ZWQgIgoJCSJieSB0aGUgcGF0dGVybiAnJXMnLlxuIik7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCB2YWx1ZSwgCgkJZmFjZXQtPnZhbHVlKTsJICAgICAgIAoJfSBlbHNlIGlmIChub2RlLT50eXBlID09IFhNTF9BVFRSSUJVVEVfTk9ERSkgewkJCgkgICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIlRoZSB2YWx1ZSAnJXMnIGlzIG5vdCBmYWNldC12YWxpZC5cbiIpOwoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwoJfSBlbHNlIHsJICAgIAoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJUaGUgdmFsdWUgaXMgbm90IGZhY2V0LXZhbGlkLlxuIik7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBlcnJvciwgKGNvbnN0IGNoYXIgKikgbXNnLCBOVUxMLCBOVUxMKTsKCX0KICAgIH0gZWxzZSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKCXhtbFNjaGVtYVZFcnIzKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIHN0cjEsIHN0cjIsIHN0cjMpOwogICAgfSAgICAgICAgCiAgICBGUkVFX0FORF9OVUxMKHN0cikKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQHR5cGU6IHRoZSB0eXBlIHVzZWQgZm9yIHZhbGlkYXRpb24KICogQG5vZGU6IHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIHZhbGlkYXRlZCB2YWx1ZQogKiBAdmFsdWU6IHRoZSB2YWxpZGF0ZWQgdmFsdWUKICoKICogUmVwb3J0cyBhIHNpbXBsZSB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqIFRPRE86IFNob3VsZCB0aGlzIHJlcG9ydCB0aGUgdmFsdWUgb2YgYW4gZWxlbWVudCBhcyB3ZWxsPwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQkJCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJm1zZywgTlVMTCwgIE5VTEwsIG5vZGUsIDApOyAgICAKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLCBOVUxMLCAwKSk7CiAgICBpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdOiBUaGUgdmFsdWUgJyVzJyBpcyBub3QgdmFsaWQuXG4iKTsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgdmFsdWUsIE5VTEwpOwogICAgfSBlbHNlIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdOiBUaGUgY2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IHZhbGlkLlxuIik7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgfQogICAgRlJFRV9BTkRfTlVMTChzdHIpCQogICAgeG1sRnJlZShtc2cpOwp9CgovKioKICogeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG5vZGU6IHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIHZhbGlkYXRlZCB2YWx1ZQogKiBAdHlwZTogdGhlIGNvbXBsZXggdHlwZSB1c2VkIGZvciB2YWxpZGF0aW9uCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKgogKiBSZXBvcnRzIGEgY29tcGxleCB0eXBlIHZhbGlkYXRpb24gZXJyb3IuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAkJCQoJCQljb25zdCBjaGFyICptZXNzYWdlKQp7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMLCAqbXNnID0gTlVMTDsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCAgTlVMTCwgbm9kZSwgMCk7CiAgICAvKiBTcGVjaWZ5IHRoZSBjb21wbGV4IHR5cGUgb25seSBpZiBpdCBpcyBnbG9iYWwuICovCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIl0iKTsKICAgIH0KICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICI6ICVzLlxuIik7ICAgCiAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAoY29uc3QgY2hhciAqKSBtc2csCgkoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlLCBOVUxMKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyKQkKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVsZW1FcnI6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIG5vZGUgY29udGFpbmluZyB0aGUgdmFsaWRhdGVkIHZhbHVlCiAqIEB0eXBlOiB0aGUgY29tcGxleCB0eXBlIHVzZWQgZm9yIHZhbGlkYXRpb24KICogQG1lc3NhZ2U6IHRoZSBlcnJvciBtZXNzYWdlCiAqCiAqIFJlcG9ydHMgYSBjb21wbGV4IHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDb21wbGV4VHlwZUVsZW1FcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAkJCQoJCQljb25zdCBjaGFyICptZXNzYWdlLAoJCQlpbnQgbmJ2YWwsCgkJCWludCBuYm5lZywKCQkJeG1sQ2hhciAqKnZhbHVlcykKewogICAgeG1sQ2hhciAqc3RyID0gTlVMTCwgKm1zZyA9IE5VTEw7CiAgICB4bWxDaGFyICpsb2NhbE5hbWUsICpuc05hbWU7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBpbnQgaTsKICAgIAogICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmbXNnLCBOVUxMLCAgTlVMTCwgbm9kZSwgMCk7CiAgICAvKiBTcGVjaWZ5IHRoZSBjb21wbGV4IHR5cGUgb25seSBpZiBpdCBpcyBnbG9iYWwuICovCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFsiKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZSwgTlVMTCwgMCkpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIl0iKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1QgIjogIik7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCAoY29uc3QgeG1sQ2hhciAqKSBtZXNzYWdlKTsKICAgIC8qCiAgICAqIE5vdGUgdGhhdCBpcyBkb2VzIG5vdCBtYWtlIHNlbnNlIHRvIHJlcG9ydCB0aGF0IHdlIGhhdmUgYQogICAgKiB3aWxkY2FyZCBoZXJlLCBzaW5jZSB0aGUgd2lsZGNhcmQgbWlnaHQgYmUgdW5mb2xkZWQgaW50bwogICAgKiBtdWx0aXBsZSB0cmFuc2l0aW9ucy4KICAgICovCiAgICBpZiAobmJ2YWwgKyBuYm5lZyA+IDApIHsKCWlmIChuYnZhbCArIG5ibmVnID4gMSkgewoJICAgIHN0ciA9IHhtbFN0cmR1cChCQURfQ0FTVCAiLiBFeHBlY3RlZCBpcyBvbmUgb2YgKCAiKTsKCX0gZWxzZQoJICAgIHN0ciA9IHhtbFN0cmR1cChCQURfQ0FTVCAiLiBFeHBlY3RlZCBpcyAoICIpOwoJbnNOYW1lID0gTlVMTDsKICAgIAkgICAgCglmb3IgKGkgPSAwOyBpIDwgbmJ2YWwgKyBuYm5lZzsgaSsrKSB7CgkgICAgY3VyID0gdmFsdWVzW2ldOwoJICAgIC8qCgkgICAgKiBHZXQgdGhlIGxvY2FsIG5hbWUuCgkgICAgKi8KCSAgICBsb2NhbE5hbWUgPSBOVUxMOwoJICAgIAoJICAgIGVuZCA9IGN1cjsKCSAgICBpZiAoKmVuZCA9PSAnKicpIHsKCQlsb2NhbE5hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIioiKTsKCQkqZW5kKys7CgkgICAgfSBlbHNlIHsKCQl3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCplbmQgIT0gJ3wnKSkKCQkgICAgZW5kKys7CgkJbG9jYWxOYW1lID0geG1sU3RybmNhdChsb2NhbE5hbWUsIEJBRF9DQVNUIGN1ciwgZW5kIC0gY3VyKTsKCSAgICB9CQkKCSAgICBpZiAoKmVuZCAhPSAwKSB7CQkgICAgCgkJKmVuZCsrOwoJCS8qCgkJKiBTa2lwICIqfCoiIGlmIHRoZXkgY29tZSB3aXRoIG5lZ2F0ZWQgZXhwcmVzc2lvbnMsIHNpbmNlCgkJKiB0aGV5IHJlcHJlc2VudCB0aGUgc2FtZSBuZWdhdGVkIHdpbGRjYXJkLgoJCSovCgkJaWYgKChuYm5lZyA9PSAwKSB8fCAoKmVuZCAhPSAnKicpIHx8ICgqbG9jYWxOYW1lICE9ICcqJykpIHsKCQkgICAgLyoKCQkgICAgKiBHZXQgdGhlIG5hbWVzcGFjZSBuYW1lLgoJCSAgICAqLwoJCSAgICBjdXIgPSBlbmQ7CgkJICAgIGlmICgqZW5kID09ICcqJykgewoJCQluc05hbWUgPSB4bWxTdHJkdXAoQkFEX0NBU1QgInsqfSIpOwoJCSAgICB9IGVsc2UgewoJCQl3aGlsZSAoKmVuZCAhPSAwKQoJCQkgICAgZW5kKys7CgkJCQoJCQlpZiAoaSA+PSBuYnZhbCkKCQkJICAgIG5zTmFtZSA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyMjb3RoZXI6Iik7CgkJCWVsc2UKCQkJICAgIG5zTmFtZSA9IHhtbFN0cmR1cChCQURfQ0FTVCAieyIpOwoJCQkKCQkJbnNOYW1lID0geG1sU3RybmNhdChuc05hbWUsIEJBRF9DQVNUIGN1ciwgZW5kIC0gY3VyKTsKCQkJbnNOYW1lID0geG1sU3RyY2F0KG5zTmFtZSwgQkFEX0NBU1QgIn0iKTsKCQkgICAgfQoJCSAgICBzdHIgPSB4bWxTdHJjYXQoc3RyLCBCQURfQ0FTVCBuc05hbWUpOwoJCSAgICBGUkVFX0FORF9OVUxMKG5zTmFtZSkKCQl9IGVsc2UgewoJCSAgICBGUkVFX0FORF9OVUxMKGxvY2FsTmFtZSk7CgkJICAgIGNvbnRpbnVlOwoJCX0KCSAgICB9CSAgICAgICAgCgkgICAgc3RyID0geG1sU3RyY2F0KHN0ciwgQkFEX0NBU1QgbG9jYWxOYW1lKTsKCSAgICBGUkVFX0FORF9OVUxMKGxvY2FsTmFtZSk7CgkJCgkgICAgaWYgKGkgPCBuYnZhbCArIG5ibmVnIC0xKQoJCXN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUICIsICIpOwoJfQkKCXN0ciA9IHhtbFN0cmNhdChzdHIsIEJBRF9DQVNUICIgKSIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgQkFEX0NBU1Qgc3RyKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfSAgICAKICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIuXG4iKTsKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywgTlVMTCwgTlVMTCk7ICAgIAkKICAgIHhtbEZyZWUobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBNaXNzaW5nQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBvd25lckRlczogdGhlIGRlc2lnbmF0aW9uIG9mICB0aGUgb3duZXIKICogQG93bmVyTmFtZTogdGhlIG5hbWUgb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGFzIGFuIGVsZW1lbnQgbm9kZQogKiBAbm9kZTogdGhlIHBhcmVudCBlbGVtZW50IG5vZGUgb2YgdGhlIG1pc3NpbmcgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTWlzc2luZ0F0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgY2hhciAqbWVzc2FnZSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQob3duZXJEZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAgICAKICAgIGlmIChtZXNzYWdlICE9IE5VTEwpCgl4bWxTY2hlbWFQRXJyKGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsICIlczogJXMuXG4iLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG1lc3NhZ2UpOwogICAgZWxzZQkKCXhtbFNjaGVtYVBFcnIoY3R4dCwgb3duZXJFbGVtLCBlcnJvciwgCgkgICAgIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgcmVxdWlyZWQgYnV0IG1pc3NpbmcuXG4iLCAKCSAgICBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIG5hbWUpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDb21wVHlwZVRvU3RyaW5nOgogKiBAdHlwZTogdGhlIHR5cGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqCiAqIFJldHVybnMgdGhlIGNvbXBvbmVudCBuYW1lIG9mIGEgc2NoZW1hIGl0ZW0uCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqCnhtbFNjaGVtYUNvbXBUeXBlVG9TdHJpbmcoeG1sU2NoZW1hVHlwZVR5cGUgdHlwZSkKewogICAgc3dpdGNoICh0eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgcmV0dXJuKCJzaW1wbGUgdHlwZSBkZWZpbml0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJICAgIHJldHVybigiY29tcGxleCB0eXBlIGRlZmluaXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgcmV0dXJuKCJlbGVtZW50IGRlY2xhcmF0aW9uIik7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkgICAgcmV0dXJuKCJhdHRyaWJ1dGUgZGVjbGFyYXRpb24iKTsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIHJldHVybigibW9kZWwgZ3JvdXAgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkgICAgcmV0dXJuKCJhdHRyaWJ1dGUgZ3JvdXAgZGVmaW5pdGlvbiIpOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CgkgICAgcmV0dXJuKCJub3RhdGlvbiBkZWNsYXJhdGlvbiIpOwoJZGVmYXVsdDoKCSAgICByZXR1cm4oIk5vdCBhIHNjaGVtYSBjb21wb25lbnQiKTsKICAgIH0KfQovKioKICogeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiAgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBvd25lciBhcyBhIHNjaGVtYSBvYmplY3QKICogQG93bmVyRWxlbTogdGhlIG93bmVyIGFzIGFuIGVsZW1lbnQgbm9kZQogKiBAbmFtZTogdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSBRTmFtZSAKICogQHJlZk5hbWU6IHRoZSByZWZlcmVuY2VkIGxvY2FsIG5hbWUKICogQHJlZlVSSTogdGhlIHJlZmVyZW5jZWQgbmFtZXNwYWNlIFVSSQogKiBAbWVzc2FnZTogb3B0aW9uYWwgbWVzc2FnZQogKgogKiBVc2VkIHRvIHJlcG9ydCBRTmFtZSBhdHRyaWJ1dGUgdmFsdWVzIHRoYXQgZmFpbGVkIHRvIHJlc29sdmUKICogdG8gc2NoZW1hIGNvbXBvbmVudHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkJCSAKCQkJIHhtbENoYXIgKipvd25lckRlcywKCQkJIHhtbFNjaGVtYVR5cGVQdHIgb3duZXJJdGVtLAoJCQkgeG1sTm9kZVB0ciBvd25lckVsZW0sCgkJCSBjb25zdCBjaGFyICpuYW1lLAoJCQkgY29uc3QgeG1sQ2hhciAqcmVmTmFtZSwKCQkJIGNvbnN0IHhtbENoYXIgKnJlZlVSSSwKCQkJIHhtbFNjaGVtYVR5cGVUeXBlIHJlZlR5cGUsCgkJCSBjb25zdCBjaGFyICpyZWZUeXBlU3RyKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgb3duZXJFbGVtLCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UKCWRlcyA9ICpvd25lckRlczsKICAgIGlmIChyZWZUeXBlU3RyID09IE5VTEwpCglyZWZUeXBlU3RyID0geG1sU2NoZW1hQ29tcFR5cGVUb1N0cmluZyhyZWZUeXBlKTsgICAgCgl4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG93bmVyRWxlbSwgZXJyb3IsIAoJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkgICAgIiVzLCBhdHRyaWJ1dGUgJyVzJzogVGhlIFFOYW1lIHZhbHVlICVzIGRvZXMgbm90IHJlc29sdmUgdG8gYShuKSAiCgkgICAgIiVzLlxuIiwgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBuYW1lLCAKCSAgICB4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHJBLCByZWZVUkksIHJlZk5hbWUpLCAKCSAgICBCQURfQ0FTVCByZWZUeXBlU3RyLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCi8qKgogKiB4bWxTY2hlbWFQQ3VzdG9tQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAb3duZXJEZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgb3duZXIKICogQG93bmVySXRlbTogdGhlIG93bmVyIGFzIGEgc2NoZW1hIG9iamVjdAogKiBAYXR0cjogdGhlIGlsbGVnYWwgYXR0cmlidXRlIG5vZGUgCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUgZHVyaW5nIHRoZSBwYXJzZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21BdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJeG1sUGFyc2VyRXJyb3JzIGVycm9yLAkKCQkJeG1sQ2hhciAqKm93bmVyRGVzLAoJCQl4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJeG1sQXR0clB0ciBhdHRyLAoJCQljb25zdCBjaGFyICptc2cpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CgogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZkZXMsIE5VTEwsIG93bmVySXRlbSwgYXR0ci0+cGFyZW50LCAxKTsKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAgIAogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsCgkiJXMsIGF0dHJpYnV0ZSAnJXMnOiAlcy5cbiIsIAoJQkFEX0NBU1QgZGVzLCBhdHRyLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSBtc2csIE5VTEwsIE5VTEwpOwogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGF0dHJpYnV0ZSdzIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBhdHRyaWJ1dGUncyBvd25lciBpdGVtCiAqIEBhdHRyOiB0aGUgaWxsZWdhbCBhdHRyaWJ1dGUgbm9kZSAKICoKICogUmVwb3J0cyBhbiBpbGxlZ2FsIGF0dHJpYnV0ZSBkdXJpbmcgdGhlIHBhcnNlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUElsbGVnYWxBdHRyRXJyKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSB4bWxDaGFyICoqb3duZXJEZXMsCgkJCSB4bWxTY2hlbWFUeXBlUHRyIG93bmVySXRlbSwKCQkJIHhtbEF0dHJQdHIgYXR0cikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMOwoKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgICAKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCAKCSIlczogVGhlIGF0dHJpYnV0ZSAnJXMnIGlzIG5vdCBhbGxvd2VkLlxuIiwgQkFEX0NBU1QgZGVzLCAKCXhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIGF0dHItPm5zLCBhdHRyLT5uYW1lKSk7CiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQQXF1aXJlRGVzOgogKiBAZGVzOiB0aGUgZmlyc3QgZGVzaWduYXRpb24gCiAqIEBpdGVtRGVzOiB0aGUgc2Vjb25kIGRlc2lnbmF0aW9uCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gCiAqIEBpdGVtRWxlbTogdGhlIG5vZGUgb2YgdGhlIHNjaGVtYSBpdGVtCiAqCiAqIENyZWF0ZXMgYSBkZXNpZ25hdGlvbiBmb3IgYW4gaXRlbS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBBcXVpcmVEZXMoeG1sQ2hhciAqKmRlcywKCQkgICAgeG1sQ2hhciAqKml0ZW1EZXMsIAoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCgkJICAgIHhtbE5vZGVQdHIgaXRlbUVsZW0pCnsKICAgIGlmIChpdGVtRGVzID09IE5VTEwpCgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KGRlcywgTlVMTCwgaXRlbSwgaXRlbUVsZW0sIDEpOwogICAgZWxzZSBpZiAoKml0ZW1EZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChpdGVtRGVzLCBOVUxMLCBpdGVtLCBpdGVtRWxlbSwgMSk7CgkqZGVzID0gKml0ZW1EZXM7CiAgICB9IGVsc2UgCgkqZGVzID0gKml0ZW1EZXM7ICAKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGFuIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMjogYW4gb3B0aW9uYWwgcGFyYW0gZm9yIHRoZSBlcnJvciBtZXNzYWdlCiAqIEBzdHIzOiBhbiBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnJFeHQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIyLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIzKQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtKTsgICAKICAgIG1zZyA9IHhtbFN0cmR1cChCQURfQ0FTVCAiJXM6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICBpZiAoKGl0ZW1FbGVtID09IE5VTEwpICYmIChpdGVtICE9IE5VTEwpKQoJaXRlbUVsZW0gPSBpdGVtLT5ub2RlOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtRWxlbSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsIAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIHN0cjEsIHN0cjIsIHN0cjMsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwobXNnKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBDdXN0b21FcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIGl0ZW0KICogQGl0ZW06IHRoZSBzY2hlbWEgaXRlbQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgaXRlbQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBlcnJvciBkdXJpbmcgcGFyc2luZy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBDdXN0b21FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyRXh0KGN0eHQsIGVycm9yLCBpdGVtRGVzLCBpdGVtLCBpdGVtRWxlbSwgbWVzc2FnZSwKCXN0cjEsIE5VTEwsIE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hUEF0dHJVc2VFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGl0ZW1EZXM6IHRoZSBkZXNpZ25hdGlvbiBvZiB0aGUgc2NoZW1hIHR5cGUKICogQGl0ZW06IHRoZSBzY2hlbWEgdHlwZQogKiBAaXRlbUVsZW06IHRoZSBub2RlIG9mIHRoZSBzY2hlbWEgdHlwZQogKiBAYXR0cjogdGhlIGludmFsaWQgc2NoZW1hIGF0dHJpYnV0ZQogKiBAbWVzc2FnZTogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IHRoZSBvcHRpb25hbCBwYXJhbSBmb3IgdGhlIGVycm9yIG1lc3NhZ2UKICoKICogUmVwb3J0cyBhbiBhdHRyaWJ1dGUgdXNlIGVycm9yIGR1cmluZyBwYXJzaW5nLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEF0dHJVc2VFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCSAgICB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCQoJCSAgICB4bWxDaGFyICoqaXRlbURlcywKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCSAgICB4bWxOb2RlUHRyIGl0ZW1FbGVtLAoJCSAgICBjb25zdCB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ciwKCQkgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgY29uc3QgeG1sQ2hhciAqc3RyMSkKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMLCAqbXNnID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW1FbGVtKTsKICAgIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ckEsIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShhdHRyKSwgCgl4bWxTY2hlbWFHZXRBdHRyTmFtZShhdHRyKSk7CiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiVzLCBhdHRyLiB1c2UgJXM6ICIpOwogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CiAgICBpZiAoKGl0ZW1FbGVtID09IE5VTEwpICYmIChpdGVtICE9IE5VTEwpKQoJaXRlbUVsZW0gPSBpdGVtLT5ub2RlOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtRWxlbSwgZXJyb3IsIE5VTEwsIE5VTEwsIE5VTEwsIAoJKGNvbnN0IGNoYXIgKikgbXNnLCBCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIHN0ckEsIHN0cjEsIE5VTEwsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyQSk7CiAgICB4bWxGcmVlKG1zZyk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHR5cGUKICogQGl0ZW06IHRoZSBzY2hlbWEgdHlwZQogKiBAYmFzZUl0ZW06IHRoZSBiYXNlIHR5cGUgb2YgdHlwZQogKiBAZmFjZXQ6IHRoZSBpbGxlZ2FsIGZhY2V0CiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBmYWNldCBmb3IgYXRvbWljIHNpbXBsZSB0eXBlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRBdG9taWNFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZUl0ZW0sCgkJCSAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEwsICpzdHJUID0gTlVMTDsKCiAgICB4bWxTY2hlbWFQQXF1aXJlRGVzKCZkZXMsIGl0ZW1EZXMsIGl0ZW0sIGl0ZW0tPm5vZGUpOwogICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBpdGVtLT5ub2RlLCBlcnJvciwgTlVMTCwgTlVMTCwgTlVMTCwKCSIlczogVGhlIGZhY2V0ICclcycgaXMgbm90IGFsbG93ZWQgb24gdHlwZXMgZGVyaXZlZCBmcm9tIHRoZSAiCgkidHlwZSAlcy5cbiIsCglCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0clQsIE5VTEwsIGJhc2VJdGVtLCBOVUxMLCAxKSwKCU5VTEwsIE5VTEwpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBpdGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHNjaGVtYSBpdGVtIGludm9sdmVkCiAqIEBpdGVtOiB0aGUgc2NoZW1hIGl0ZW0gaW52b2x2ZWQKICogQGZhY2V0OiB0aGUgaWxsZWdhbCBmYWNldAogKgogKiBSZXBvcnRzIGFuIGlsbGVnYWwgZmFjZXQgZm9yIDxsaXN0PiBhbmQgPHVuaW9uPi4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVBJbGxlZ2FsRmFjZXRMaXN0VW5pb25FcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCgkJCSAgeG1sQ2hhciAqKml0ZW1EZXMsCgkJCSAgeG1sU2NoZW1hVHlwZVB0ciBpdGVtLAoJCQkgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0KQp7CiAgICB4bWxDaGFyICpkZXMgPSBOVUxMLCAqc3RyVCA9IE5VTEw7CgogICAgeG1sU2NoZW1hUEFxdWlyZURlcygmZGVzLCBpdGVtRGVzLCBpdGVtLCBpdGVtLT5ub2RlKTsKICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgaXRlbS0+bm9kZSwgZXJyb3IsIAoJIiVzOiBUaGUgZmFjZXQgJyVzJyBpcyBub3QgYWxsb3dlZC5cbiIsIAoJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSkpOwogICAgaWYgKGl0ZW1EZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKTsKICAgIEZSRUVfQU5EX05VTEwoc3RyVCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEBlbGVtRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIHBhcmVudCBlbGVtZW50IG5vZGUKICogQGF0dHI6IHRoZSBiYWQgYXR0cmlidXRlIG5vZGUKICogQHR5cGU6IHRoZSBjb3JyZXNwb25kaW5nIHR5cGUgb2YgdGhlIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQTXV0dWFsRXhjbEF0dHJFcnIoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCQkgeG1sQ2hhciAqKm93bmVyRGVzLAoJCQkgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCSB4bWxBdHRyUHRyIGF0dHIsCQkJIAoJCQkgY29uc3QgY2hhciAqbmFtZTEsCgkJCSBjb25zdCBjaGFyICpuYW1lMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTDsKCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJmRlcywgTlVMTCwgb3duZXJJdGVtLCBhdHRyLT5wYXJlbnQsIDEpOwkKICAgIGVsc2UgaWYgKCpvd25lckRlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KG93bmVyRGVzLCBOVUxMLCBvd25lckl0ZW0sIGF0dHItPnBhcmVudCwgMSk7CglkZXMgPSAqb3duZXJEZXM7CiAgICB9IGVsc2UgCglkZXMgPSAqb3duZXJEZXM7ICAKICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJIiVzOiBUaGUgYXR0cmlidXRlcyAnJXMnIGFuZCAnJXMnIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuXG4iLCAKCUJBRF9DQVNUIGRlcywgQkFEX0NBU1QgbmFtZTEsIEJBRF9DQVNUIG5hbWUyLCBOVUxMLCBOVUxMKTsKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJRlJFRV9BTkRfTlVMTChkZXMpCn0KCi8qKgogKiB4bWxTY2hlbWFQU2ltcGxlVHlwZUVycjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlCiAqIEB0eXBlOiB0aGUgdHlwZSBzcGVjaWZpZXIKICogQG93bmVyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIG93bmVyCiAqIEBvd25lckl0ZW06IHRoZSBzY2hlbWEgb2JqZWN0IGlmIGV4aXN0ZW50IAogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB2YWx1ZTogdGhlIHZhbGlkYXRlZCB2YWx1ZQogKgogKiBSZXBvcnRzIGEgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBlcnJvci4KICogVE9ETzogU2hvdWxkIHRoaXMgcmVwb3J0IHRoZSB2YWx1ZSBvZiBhbiBlbGVtZW50IGFzIHdlbGw/CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQU2ltcGxlVHlwZUVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQl4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCXhtbENoYXIgKipvd25lckRlcywKCQkJeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJCXhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQljb25zdCBjaGFyICp0eXBlRGVzLAoJCQljb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJY29uc3QgY2hhciAqbWVzc2FnZSwKCQkJY29uc3QgeG1sQ2hhciAqc3RyMSwKCQkJY29uc3QgeG1sQ2hhciAqc3RyMikKewogICAgeG1sQ2hhciAqZGVzID0gTlVMTCwgKnN0ckEgPSBOVUxMLCAqc3RyVCA9IE5VTEw7ICAgIAogICAgCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCXhtbFNjaGVtYVBSZXF1ZXN0SXRlbURlcygmZGVzLCBvd25lckl0ZW0sIG5vZGUpOwogICAgZWxzZSBpZiAoKm93bmVyRGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVBSZXF1ZXN0SXRlbURlcyhvd25lckRlcywgb3duZXJJdGVtLCBub2RlKTsKCWRlcyA9ICpvd25lckRlczsKICAgIH0gZWxzZSAKCWRlcyA9ICpvd25lckRlczsgICAKICAgIGlmICh0eXBlICE9IE5VTEwpCgl0eXBlRGVzID0gKGNvbnN0IGNoYXIgKikgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyVCwgTlVMTCwgdHlwZSwgTlVMTCwgMSk7CiAgICBpZiAobWVzc2FnZSA9PSBOVUxMKSB7CgkvKgoJKiBVc2UgZGVmYXVsdCBtZXNzYWdlcy4KCSovCglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCSIlcywgYXR0cmlidXRlICclcycgWyVzXTogVGhlIHZhbHVlICclcycgaXMgbm90ICIKCQkidmFsaWQuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIHhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIG5vZGUtPm5zLCAKCQlub2RlLT5uYW1lKSwgQkFEX0NBU1QgdHlwZURlcywgdmFsdWUsIE5VTEwpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIGVycm9yLCAKCQkiJXMgWyVzXTogVGhlIGNoYXJhY3RlciBjb250ZW50IGlzIG5vdCB2YWxpZC5cbiIsCgkJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCB0eXBlRGVzKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxDaGFyICptc2c7CgoJbXNnID0geG1sU3RyZHVwKEJBRF9DQVNUICIlcyIpOwoJaWYgKG5vZGUtPnR5cGUgPT0gWE1MX0FUVFJJQlVURV9OT0RFKQoJICAgIG1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIsIGF0dHJpYnV0ZSAnJXMnIik7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiIFslc106ICIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7Cgltc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCShjb25zdCBjaGFyICopIG1zZywgCgkJQkFEX0NBU1QgZGVzLCB4bWxTY2hlbWFGb3JtYXROc1ByZWZpeExvY2FsKCZzdHJBLCAKCQlub2RlLT5ucywgbm9kZS0+bmFtZSksIEJBRF9DQVNUIHR5cGVEZXMsIHN0cjEsIHN0cjIpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIG5vZGUsIGVycm9yLCBOVUxMLCBOVUxMLCBOVUxMLAoJCShjb25zdCBjaGFyICopIG1zZywgCgkJQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCB0eXBlRGVzLCBzdHIxLCBzdHIyLCBOVUxMKTsKCX0KCXhtbEZyZWUobXNnKTsKICAgIH0KICAgIC8qIENsZWFudXAuICovCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCiAgICBGUkVFX0FORF9OVUxMKHN0clQpCiAgICBpZiAob3duZXJEZXMgPT0gTlVMTCkKCUZSRUVfQU5EX05VTEwoZGVzKQp9CgovKioKICogeG1sU2NoZW1hUENvbnRlbnRFcnI6CiAqIEBjdHh0OiB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG9ud2VyRGVzOiB0aGUgZGVzaWduYXRpb24gb2YgdGhlIGhvbGRlciBvZiB0aGUgY29udGVudAogKiBAb3duZXJJdGVtOiB0aGUgb3duZXIgaXRlbSBvZiB0aGUgaG9sZGVyIG9mIHRoZSBjb250ZW50CiAqIEBvd25lckVsZW06IHRoZSBub2RlIG9mIHRoZSBob2xkZXIgb2YgdGhlIGNvbnRlbnQKICogQGNoaWxkOiB0aGUgaW52YWxpZCBjaGlsZCBub2RlCiAqIEBtZXNzYWdlOiB0aGUgb3B0aW9uYWwgZXJyb3IgbWVzc2FnZQogKiBAY29udGVudDogdGhlIG9wdGlvbmFsIHN0cmluZyBkZXNjcmliaW5nIHRoZSBjb3JyZWN0IGNvbnRlbnQKICoKICogUmVwb3J0cyBhbiBlcnJvciBjb25jZXJuaW5nIHRoZSBjb250ZW50IG9mIGEgc2NoZW1hIGVsZW1lbnQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQQ29udGVudEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCSAgICAgeG1sUGFyc2VyRXJyb3JzIGVycm9yLAoJCSAgICAgeG1sQ2hhciAqKm93bmVyRGVzLAoJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBvd25lckl0ZW0sCgkJICAgICB4bWxOb2RlUHRyIG93bmVyRWxlbSwJCSAgICAgCgkJICAgICB4bWxOb2RlUHRyIGNoaWxkLAoJCSAgICAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkgICAgIGNvbnN0IGNoYXIgKmNvbnRlbnQpCnsKICAgIHhtbENoYXIgKmRlcyA9IE5VTEw7CiAgICAKICAgIGlmIChvd25lckRlcyA9PSBOVUxMKQoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmZGVzLCBOVUxMLCBvd25lckl0ZW0sIG93bmVyRWxlbSwgMSk7CiAgICBlbHNlIGlmICgqb3duZXJEZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydChvd25lckRlcywgTlVMTCwgb3duZXJJdGVtLCBvd25lckVsZW0sIDEpOwoJZGVzID0gKm93bmVyRGVzOwogICAgfSBlbHNlIAoJZGVzID0gKm93bmVyRGVzOyAgIAogICAgaWYgKG1lc3NhZ2UgIT0gTlVMTCkKCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLCAKCSAgICAiJXM6ICVzLlxuIiwgCgkgICAgQkFEX0NBU1QgZGVzLCBCQURfQ0FTVCBtZXNzYWdlKTsKICAgIGVsc2UgewoJaWYgKGNvbnRlbnQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG93bmVyRWxlbSwgY2hpbGQsIGVycm9yLCAKCQkiJXM6IFRoZSBjb250ZW50IGlzIG5vdCB2YWxpZC4gRXhwZWN0ZWQgaXMgJXMuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIEJBRF9DQVNUIGNvbnRlbnQpOwoJfSBlbHNlIHsKCSAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBvd25lckVsZW0sIGNoaWxkLCBlcnJvciwgCgkJIiVzOiBUaGUgY29udGVudCBpcyBub3QgdmFsaWQuXG4iLCAKCQlCQURfQ0FTVCBkZXMsIE5VTEwpOwoJfQogICAgfQogICAgaWYgKG93bmVyRGVzID09IE5VTEwpCglGUkVFX0FORF9OVUxMKGRlcykKfSAgIAoKLyoqCiAqIHhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycjoKICogQGN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQGF0dHI6IHRoZSBpbGxlZ2FsIGF0dHJpYnV0ZSBub2RlCiAqCiAqIFJlcG9ydHMgYW4gaWxsZWdhbCBhdHRyaWJ1dGUuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFWSWxsZWdhbEF0dHJFcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSB4bWxQYXJzZXJFcnJvcnMgZXJyb3IsCgkJCSB4bWxBdHRyUHRyIGF0dHIpCnsKICAgIHhtbENoYXIgKnN0ckUgPSBOVUxMLCAqc3RyQSA9IE5VTEw7CiAgICAKICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAkKCWVycm9yLAoJLyogWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLCAqLwoJIiVzOiBUaGUgYXR0cmlidXRlICclcycgaXMgbm90IGFsbG93ZWQuXG4iLAoJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyRSwgTlVMTCwgTlVMTCwgYXR0ci0+cGFyZW50LCAwKSwKCXhtbFNjaGVtYUZvcm1hdE5zUHJlZml4TG9jYWwoJnN0ckEsIGF0dHItPm5zLCBhdHRyLT5uYW1lKSk7CiAgICBGUkVFX0FORF9OVUxMKHN0ckUpCiAgICBGUkVFX0FORF9OVUxMKHN0ckEpCn0KCgpzdGF0aWMgaW50CnhtbFNjaGVtYUlzR2xvYmFsSXRlbSh4bWxTY2hlbWFUeXBlUHRyIGl0ZW0pCnsKICAgIHN3aXRjaCAoaXRlbS0+dHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgoJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMKQoJCXJldHVybigxKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkgICAgaWYgKCAoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIGl0ZW0pLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKQoJCXJldHVybigxKTsKCSAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKCSAgICBpZiAoICgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSBpdGVtKS0+ZmxhZ3MgJiAKCQlYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkKCQlyZXR1cm4oMSk7CgkgICAgYnJlYWs7CgkvKiBOb3RlIHRoYXQgYXR0cmlidXRlIGdyb3VwcyBhcmUgYWx3YXlzIGdsb2JhbC4gKi8KCWRlZmF1bHQ6CgkgICAgcmV0dXJuKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVN0cmVhbVZDdXN0b21FcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LAoJCQkgIHhtbFBhcnNlckVycm9ycyBlcnJvciwKCQkJICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBub2RlSW5mbywKCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgY29uc3QgY2hhciAqbWVzc2FnZSwKCQkJICBjb25zdCB4bWxDaGFyICpzdHIxLAoJCQkgIGNvbnN0IHhtbENoYXIgKnN0cjIpCnsKICAgIHhtbENoYXIgKm1zZyA9IE5VTEwsICpzdHIgPSBOVUxMOyAKCiAgICBtc2cgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIkVsZW1lbnQgJyIpOwoKICAgIGlmICh2Y3R4dC0+ZWxlbUluZm9zW3ZjdHh0LT5kZXB0aF0gIT0gbm9kZUluZm8pIHsKCXhtbFNjaGVtYU5vZGVJbmZvUHRyIGVsZW1JbmZvOwoJLyoKCSogVGhlIG5vZGUgaW5mbyBpcyBhbiBhdHRyaWJ1dGUgaW5mby4KCSovCgllbGVtSW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbdmN0eHQtPmRlcHRoXTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIHhtbFNjaGVtYUZvcm1hdFFOYW1lKCZzdHIsCgkgICAgZWxlbUluZm8tPm5hbWVzcGFjZU5hbWUsIGVsZW1JbmZvLT5sb2NhbE5hbWUpKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICInLCAiKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJhdHRyaWJ1dGUgJyIpOwogICAgfQogICAgbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0UU5hbWUoJnN0ciwKCW5vZGVJbmZvLT5uYW1lc3BhY2VOYW1lLCBub2RlSW5mby0+bG9jYWxOYW1lKSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiJyIpOwogICAgCiAgICBpZiAoKHR5cGUgIT0gTlVMTCkgJiYgKHhtbFNjaGVtYUlzR2xvYmFsSXRlbSh0eXBlKSkpIHsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICIgWyIpOwoJbXNnID0geG1sU3RyY2F0KG1zZywgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsIDApKTsKCW1zZyA9IHhtbFN0cmNhdChtc2csIEJBRF9DQVNUICJdIik7CiAgICB9CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiOiAiKTsKICAgIAogICAgbXNnID0geG1sU3RyY2F0KG1zZywgKGNvbnN0IHhtbENoYXIgKikgbWVzc2FnZSk7CiAgICBtc2cgPSB4bWxTdHJjYXQobXNnLCBCQURfQ0FTVCAiLlxuIik7ICAgCiAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCBub2RlSW5mby0+bm9kZSwgZXJyb3IsIChjb25zdCBjaGFyICopIG1zZywKCXN0cjEsIHN0cjIpOwogICAgRlJFRV9BTkRfTlVMTChtc2cpCiAgICBGUkVFX0FORF9OVUxMKHN0cikgICAgCn0KCi8qKgogKiB4bWxTY2hlbWFWQ3VzdG9tRXJyOgogKiBAY3R4dDogdGhlIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbm9kZTogdGhlIHZhbGlkYXRlZCBub2RlCiAqIEB0eXBlOiB0aGUgc2NoZW1hIHR5cGUgb2YgdGhlIHZhbGlkYXRlZCBub2RlCiAqIEBtZXNzYWdlOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogdGhlIG9wdGlvbmFsIHBhcmFtIGZvciB0aGUgbWVzc2FnZQogKgogKiBSZXBvcnRzIGEgdmFsaWRhdGlvbiBlcnJvci4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZDdXN0b21FcnIoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJICAgIHhtbFBhcnNlckVycm9ycyBlcnJvciwJCQkgICAgCgkJICAgIHhtbE5vZGVQdHIgbm9kZSwKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCSAgICBjb25zdCBjaGFyICptZXNzYWdlLAoJCSAgICBjb25zdCB4bWxDaGFyICpzdHIxKQp7CiAgICB4bWxDaGFyICptc2cgPSBOVUxMLCAqc3RyID0gTlVMTDsKICAgIAogICAgaWYgKG5vZGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVkN1c3RvbUVyciwgbm8gbm9kZSAiCgkgICAgImdpdmVuLlxuIiwgTlVMTCwgTlVMTCk7CglyZXR1cm47CiAgICB9CiAgICAvKiBUT0RPOiBBcmUgdGhlIEhUTUwgYW5kIERPQ0IgZG9jIG5vZGVzIGV4cGVjdGVkIGhlcmU/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+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHx8CgkgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpKSB7CglyZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIHR5cGUtPnN1YnR5cGVzLCAKCSAgICB2YWxUeXBlKSk7CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFByaW1pdGl2ZVR5cGU6CiAqIEB0eXBlOiAgdGhlIHNpbXBsZVR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBwcmltaXRpdmUgdHlwZSBvZiB0aGUgZ2l2ZW4gdHlwZSBvcgogKiBOVUxMIGluIGNhc2Ugb2YgZXJyb3IuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewoKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCS8qCgkqIE5vdGUgdGhhdCBhbnlTaW1wbGVUeXBlIGlzIGFjdHVhbGx5IG5vdCBhIHByaW1pdGl2ZSB0eXBlCgkqIGJ1dCB3ZSBuZWVkIHRoYXQgaGVyZS4KCSovCglpZiAoKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpIHx8CgkgICAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0JVSUxUSU5fUFJJTUlUSVZFKSkKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KCiNpZiAwCi8qKgogKiB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZUFuY2VzdG9yOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3Rvcih4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCWlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCSAgICByZXR1cm4gKHR5cGUpOwoJdHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgfQoKICAgIHJldHVybiAoTlVMTCk7Cn0KI2VuZGlmCgoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogQGN1cjogdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBsaXN0CiAqIEBsYXN0VXNlOiB0aGUgdG9wIG9mIHRoZSBhdHRyaWJ1dGUgdXNlIGxpc3QKICoKICogQnVpbGRzIHRoZSBhdHRyaWJ1dGUgdXNlcyBsaXN0IG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFRoaXMgb25lIGlzIHN1cHBvc2VkIHRvIGJlIGNhbGxlZCBieSAKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uIG9ubHkuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGN1ciwKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyICp1c2VzLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKmxhc3RVc2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgdG1wOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CglpZiAoY3VyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgewoJICAgIC8qIAoJICAgICAqIFczQzogIjIgVGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGF0dHJpYnV0ZSBncm91cHMgt3Jlc29sdmVktyAKCSAgICAgKiB0byBieSB0aGUgt2FjdHVhbCB2YWx1ZbdzIG9mIHRoZSByZWYgW2F0dHJpYnV0ZV0gb2YgdGhlIAoJICAgICAqIDxhdHRyaWJ1dGVHcm91cD4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgCgkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgY3VyKS0+YXR0cmlidXRlcywgdXNlcywgCgkJbGFzdFVzZSkgPT0gLTEpIHsKCQlyZXR1cm4gKC0xKTsJICAgIAoJICAgIH0KCX0gZWxzZSB7CgkgICAgLyogVzNDOiAiMSBUaGUgc2V0IG9mIGF0dHJpYnV0ZSB1c2VzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIAoJICAgICAqIDxhdHRyaWJ1dGU+IFtjaGlsZHJlbl0sIGlmIGFueS4iCgkgICAgICovCSAgICAJICAgIAoJICAgIHRtcCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyKSAKCQl4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmspKTsKCSAgICBpZiAodG1wID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyIsIE5VTEwpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCSAgICB0bXAtPmF0dHIgPSBjdXI7CgkgICAgdG1wLT5uZXh0ID0gTlVMTDsKCSAgICBpZiAoKnVzZXMgPT0gTlVMTCkKCQkqdXNlcyA9IHRtcDsJCSAgICAKCSAgICBlbHNlIAoJCSgqbGFzdFVzZSktPm5leHQgPSB0bXA7CgkgICAgKmxhc3RVc2UgPSB0bXA7CSAgICAKCX0JCgljdXIgPSBjdXItPm5leHQ7CiAgICB9CQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGRlc3Q6ICB0aGUgZGVzdGluYXRpb24gd2lsZGNhcmQKICogQHNvdXJjZTogdGhlIHNvdXJjZSB3aWxkY2FyZAogKgogKiBDbG9uZXMgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cyBvZiBzb3VyY2UKICogYW5kIGFzc2lnbmVzIHRoZW0gdG8gZGVzdC4KICogUmV0dXJucyAtMSBvbiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciAqZGVzdCwKCQkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBzb3VyY2UpCQkJCSAgICAKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIHRtcCwgbGFzdDsKCiAgICBpZiAoKHNvdXJjZSA9PSBOVUxMKSB8fCAoKmRlc3QgPT0gTlVMTCkpCglyZXR1cm4oLTEpOyAgICAKICAgICgqZGVzdCktPmFueSA9IHNvdXJjZS0+YW55OwogICAgY3VyID0gc291cmNlLT5uc1NldDsKICAgIGxhc3QgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7Cgl0bXAgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmICh0bXAgPT0gTlVMTCkKCSAgICByZXR1cm4oLTEpOwoJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgICgqZGVzdCktPm5zU2V0ID0gdG1wOwoJZWxzZSAKCSAgICBsYXN0LT5uZXh0ID0gdG1wOwoJbGFzdCA9IHRtcDsKCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0gICAgCiAgICBpZiAoKCpkZXN0KS0+bmVnTnNTZXQgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KCgqZGVzdCktPm5lZ05zU2V0KTsJICAgCiAgICBpZiAoc291cmNlLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkoKmRlc3QpLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJaWYgKCgqZGVzdCktPm5lZ05zU2V0ID09IE5VTEwpCgkgICAgcmV0dXJuKC0xKTsKCSgqZGVzdCktPm5lZ05zU2V0LT52YWx1ZSA9IHNvdXJjZS0+bmVnTnNTZXQtPnZhbHVlOwkgICAgCiAgICB9IGVsc2UKCSgqZGVzdCktPm5lZ05zU2V0ID0gTlVMTDsKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGNvbXBsZXRlV2lsZDogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAY3VyV2lsZDogdGhlIHNlY29uZCB3aWxkY2FyZCAKICoKICogVW5pb25zIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyB1bmlvbi4KICogUmV0dXJucyBhIHBvc2l0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZSwgLTEgaW4gY2FzZSBvZiBhbgogKiBpbnRlcm5hbCBlcnJvciwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJICAgIAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY29tcGxldGVXaWxkLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY3VyV2lsZCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckIsIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZSAKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCQoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCSAgICAKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCQkKCQkvKiAKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuIAoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUKICAgICovCiAgICBpZiAoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSB7CQoJaWYgKGNvbXBsZXRlV2lsZC0+YW55ID09IDApIHsKCSAgICBjb21wbGV0ZVdpbGQtPmFueSA9IDE7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJeG1sRnJlZShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCSAgICB9Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgLyoKICAgICogMyBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3KSwgCiAgICAqIHRoZW4gdGhlIHVuaW9uIG9mIHRob3NlIHNldHMgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgewkJCglpbnQgZm91bmQ7Cgl4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIHN0YXJ0OwoJCgljdXIgPSBjdXJXaWxkLT5uc1NldDsKCXN0YXJ0ID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGZvdW5kID0gMDsKCSAgICBjdXJCID0gc3RhcnQ7CgkgICAgd2hpbGUgKGN1ckIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJICAgIGZvdW5kID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCWN1ckIgPSBjdXJCLT5uZXh0OwoJICAgIH0KCSAgICBpZiAoIWZvdW5kKSB7CgkJdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJaWYgKHRtcCA9PSBOVUxMKSAKCQkgICAgcmV0dXJuICgtMSk7CgkJdG1wLT52YWx1ZSA9IGN1ci0+dmFsdWU7CgkJdG1wLT5uZXh0ID0gY29tcGxldGVXaWxkLT5uc1NldDsJCSAgICAJCSAgICAKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gdG1wOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQoJCSAgICAJCQoJcmV0dXJuKDApOwogICAgfSAgICAKICAgIC8qCiAgICAqIDQgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCB2YWx1ZXMgKG5hbWVzcGFjZSBuYW1lcyAKICAgICogb3Igt2Fic2VudLcpLCB0aGVuIGEgcGFpciBvZiBub3QgYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gTlVMTDsKCglyZXR1cm4oMCk7CiAgICB9CiAgICAvKiAKICAgICAqIDUuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpbnQgbnNGb3VuZCwgYWJzZW50Rm91bmQgPSAwOwoJCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCSAgICBjdXJCID0gY3VyV2lsZC0+bmVnTnNTZXQ7Cgl9IGVsc2UgewoJICAgIGN1ciA9IGN1cldpbGQtPm5zU2V0OwoJICAgIGN1ckIgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0OwoJfQoJbnNGb3VuZCA9IDA7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyLT52YWx1ZSA9PSBOVUxMKSAKCQlhYnNlbnRGb3VuZCA9IDE7CgkgICAgZWxzZSBpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkKCQluc0ZvdW5kID0gMTsKCSAgICBpZiAobnNGb3VuZCAmJiBhYnNlbnRGb3VuZCkKCQlicmVhazsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQoKCWlmIChuc0ZvdW5kICYmIGFic2VudEZvdW5kKSB7CgkgICAgLyoKCSAgICAqIDUuMSBJZiB0aGUgc2V0IFMgaW5jbHVkZXMgYm90aCB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgCgkgICAgKiBuYW1lIGFuZCC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8gICAgCgkgICAgY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCXhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IE5VTEw7CgkgICAgfQoJfSBlbHNlIGlmIChuc0ZvdW5kICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjIgSWYgdGhlIHNldCBTIGluY2x1ZGVzIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSBuYW1lIAoJICAgICogYnV0IG5vdCC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IGFuZCC3YWJzZW50tyBtdXN0IAoJICAgICogYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4zIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tyBidXQgbm90IHRoZSBuZWdhdGVkIAoJICAgICogbmFtZXNwYWNlIG5hbWUsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLCAKCQlYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUsCgkJIlRoZSB1bmlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGUuXG4iLAoJCU5VTEwsIE5VTEwpOwkKCSAgICByZXR1cm4oWE1MX1NDSEVNQVBfVU5JT05fTk9UX0VYUFJFU1NJQkxFKTsKCX0gZWxzZSBpZiAoKCFuc0ZvdW5kKSAmJiAoIWFic2VudEZvdW5kKSkgewoJICAgIC8qIAoJICAgICogNS40IElmIHRoZSBzZXQgUyBkb2VzIG5vdCBpbmNsdWRlIGVpdGhlciB0aGUgbmVnYXRlZCBuYW1lc3BhY2UgCgkgICAgKiBuYW1lIG9yILdhYnNlbnS3LCB0aGVuIHdoaWNoZXZlciBvZiBPMSBvciBPMiBpcyBhIHBhaXIgb2Ygbm90IAoJICAgICogYW5kIGEgbmFtZXNwYWNlIG5hbWUgbXVzdCBiZSB0aGUgdmFsdWUuCgkgICAgKi8KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IE5VTEw7CgkJfQoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKC0xKTsKCQljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICB9Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgLyogCiAgICAgKiA2LgogICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIAoJKGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7CgoJaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7Cgl9IGVsc2UgewoJICAgIGN1ciA9IGN1cldpbGQtPm5zU2V0OwoJfQkKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIHsKCQkvKgoJCSogNi4xIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tywgdGhlbiBhbnkgbXVzdCBiZSB0aGUgCgkJKiB2YWx1ZS4KCQkqLwoJCWNvbXBsZXRlV2lsZC0+YW55ID0gMTsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJCSAgICB4bWxGcmVlKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0gTlVMTDsKCQl9CgkJcmV0dXJuICgwKTsKCSAgICB9CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkJCQoJaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA2LjIgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgt2Fic2VudLcsIHRoZW4gYSBwYWlyIG9mIG5vdCAKCSAgICAqIGFuZCC3YWJzZW50tyBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGcmVlV2lsZGNhcmROc1NldChjb21wbGV0ZVdpbGQtPm5zU2V0KTsKCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCSAgICB9CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJcmV0dXJuICgtMSk7CgkgICAgY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSBOVUxMOwoJfQoJcmV0dXJuICgwKTsKICAgIH0KICAgIHJldHVybiAoMCk7Cgp9CgovKioKICogeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGNvbXBsZXRlV2lsZDogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAY3VyV2lsZDogdGhlIHNlY29uZCB3aWxkY2FyZCAKICoKICogSW50ZXJzZWN0cyB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnRzIG9mIHRoZSBnaXZlbiB3aWxkY2FyZHMuCiAqIEBjb21wbGV0ZVdpbGQgd2lsbCBob2xkIHRoZSByZXN1bHRpbmcgaW50ZXJzZWN0aW9uLgogKiBSZXR1cm5zIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLCAtMSBpbiBjYXNlIG9mIGFuCiAqIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSW50ZXJzZWN0V2lsZGNhcmRzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJICAgIAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY29tcGxldGVXaWxkLAoJCQkgICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgY3VyV2lsZCkKewogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXIsIGN1ckIsIHByZXYsICB0bXA7CgogICAgLyoKICAgICogMSBJZiBPMSBhbmQgTzIgYXJlIHRoZSBzYW1lIHZhbHVlLCB0aGVuIHRoYXQgdmFsdWUgbXVzdCBiZSB0aGUgCiAgICAqIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgPT0gY3VyV2lsZC0+YW55KSAmJgoJKChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uc1NldCA9PSBOVUxMKSkgJiYKCSgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSA9PSAoY3VyV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkpKSB7CgkKCWlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB8fAoJICAgIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9PSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpKSB7CgkgICAgCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCWludCBmb3VuZCA9IDA7CgkJCgkJLyogCgkJKiBDaGVjayBlcXVhbGl0eSBvZiBzZXRzLiAKCQkqLwoJCWN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJICAgIGZvdW5kID0gMDsKCQkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJCWlmIChjdXItPnZhbHVlID09IGN1ckItPnZhbHVlKSB7CgkJCSAgICBmb3VuZCA9IDE7CgkJCSAgICBicmVhazsKCQkJfQoJCQljdXJCID0gY3VyQi0+bmV4dDsKCQkgICAgfQoJCSAgICBpZiAoIWZvdW5kKQoJCQlicmVhazsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCX0KCQlpZiAoZm91bmQpCgkJICAgIHJldHVybigwKTsKCSAgICB9IGVsc2UKCQlyZXR1cm4oMCk7Cgl9CiAgICB9CSAgICAgICAgCiAgICAvKgogICAgKiAyIElmIGVpdGhlciBPMSBvciBPMiBpcyBhbnksIHRoZW4gdGhlIG90aGVyIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5hbnkgIT0gY3VyV2lsZC0+YW55KSAmJiAoY29tcGxldGVXaWxkLT5hbnkpKSB7CQkgICAgCglpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsJICAgIAoJcmV0dXJuKDApOwogICAgfQkgICAgICAgICAgICAKICAgIC8qCiAgICAqIDMgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgYW5kIGEgdmFsdWUgKGEgbmFtZXNwYWNlIAogICAgKiBuYW1lIG9yILdhYnNlbnS3KSBhbmQgdGhlIG90aGVyIGlzIGEgc2V0IG9mIChuYW1lc3BhY2UgbmFtZXMgb3IgCiAgICAqILdhYnNlbnS3KSwgdGhlbiB0aGF0IHNldCwgbWludXMgdGhlIG5lZ2F0ZWQgdmFsdWUgaWYgaXQgd2FzIGluIAogICAgKiB0aGUgc2V0LCBtaW51cyC3YWJzZW50tyBpZiBpdCB3YXMgaW4gdGhlIHNldCwgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKCgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHx8CgkoKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpKSkgewoJY29uc3QgeG1sQ2hhciAqbmVnOwoJCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCA9PSBOVUxMKSB7CgkgICAgbmVnID0gY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkgICAgaWYgKHhtbFNjaGVtYUNsb25lV2lsZGNhcmROc0NvbnN0cmFpbnRzKGN0eHQsICZjb21wbGV0ZVdpbGQsIGN1cldpbGQpID09IC0xKQoJCXJldHVybigtMSk7Cgl9IGVsc2UKCSAgICBuZWcgPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7CgkvKgoJKiBSZW1vdmUgYWJzZW50IGFuZCBuZWdhdGVkLgoJKi8KCXByZXYgPSBOVUxMOwoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIGlmIChjdXItPnZhbHVlID09IE5VTEwpIHsKCQlpZiAocHJldiA9PSBOVUxMKSAKCQkgICAgY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQllbHNlIAoJCSAgICBwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQlicmVhazsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CglpZiAobmVnICE9IE5VTEwpIHsKCSAgICBwcmV2ID0gTlVMTDsKCSAgICBjdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWlmIChjdXItPnZhbHVlID09IG5lZykgewoJCSAgICBpZiAocHJldiA9PSBOVUxMKSAKCQkJY29tcGxldGVXaWxkLT5uc1NldCA9IGN1ci0+bmV4dDsKCQkgICAgZWxzZSAKCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkgICAgeG1sRnJlZShjdXIpOwoJCSAgICBicmVhazsKCQl9CgkJcHJldiA9IGN1cjsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJfQoKCXJldHVybigwKTsKICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDQgSWYgYm90aCBPMSBhbmQgTzIgYXJlIHNldHMgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50tyksIAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhvc2Ugc2V0cyBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5zU2V0ICE9IE5VTEwpKSB7CQkKCWludCBmb3VuZDsKCQoJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCXByZXYgPSBOVUxMOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgZm91bmQgPSAwOwoJICAgIGN1ckIgPSBjdXJXaWxkLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyQiAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkgICAgZm91bmQgPSAxOwoJCSAgICBicmVhazsKCQl9CgkJY3VyQiA9IGN1ckItPm5leHQ7CgkgICAgfQoJICAgIGlmICghZm91bmQpIHsKCQlpZiAocHJldiA9PSBOVUxMKQoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UgCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUoY3VyKTsKCQljdXIgPSB0bXA7CQkKCQljb250aW51ZTsKCSAgICB9CgkgICAgcHJldiA9IGN1cjsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQoJCSAgICAJCQoJcmV0dXJuKDApOwogICAgfSAgICAKICAgIC8qIDUgSWYgdGhlIHR3byBhcmUgbmVnYXRpb25zIG9mIGRpZmZlcmVudCBuYW1lc3BhY2UgbmFtZXMsIAogICAgKiB0aGVuIHRoZSBpbnRlcnNlY3Rpb24gaXMgbm90IGV4cHJlc3NpYmxlCiAgICAqLwkgICAgCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IE5VTEwpKSB7CgoJeG1sU2NoZW1hUEVycihjdHh0LCBjb21wbGV0ZVdpbGQtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUsCgkgICAgIlRoZSBpbnRlcnNlY3Rpb24gb2YgdGhlIHdpbGNhcmQgaXMgbm90IGV4cHJlc3NpYmxlLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsJCglyZXR1cm4oWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSk7CiAgICB9CQkgICAgCiAgICAvKiAKICAgICogNiBJZiB0aGUgb25lIGlzIGEgbmVnYXRpb24gb2YgYSBuYW1lc3BhY2UgbmFtZSBhbmQgdGhlIG90aGVyIAogICAgKiBpcyBhIG5lZ2F0aW9uIG9mILdhYnNlbnS3LCB0aGVuIHRoZSBvbmUgd2hpY2ggaXMgdGhlIG5lZ2F0aW9uIAogICAgKiBvZiBhIG5hbWVzcGFjZSBuYW1lIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkpIHsJCgljb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9ICBjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWU7IAogICAgfQogICAgcmV0dXJuKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB3aWxkQTogIHRoZSBmaXJzdCB3aWxkY2FyZAogKiBAd2lsZEI6IHRoZSBzZWNvbmQgd2lsZGNhcmQgCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgbmFtZXNwYWNlIGNvbnN0cmFpbnQgb2YgQHdpbGRBIGlzIGFuIGludGVuc2lvbmFsIAogKiBzdWJzZXQgb2YgQHdpbGRCLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldCh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkQSwKCQkJCSAgICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRCKQp7ICAgIAoKICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogV2lsZGNhcmQgU3Vic2V0IAogICAgKi8KICAgIC8qCiAgICAqIDEgc3VwZXIgbXVzdCBiZSBhbnkuIAogICAgKi8KICAgIGlmICh3aWxkQi0+YW55KQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIDIuMSBzdWIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yILdhYnNlbnS3LgogICAgKiAyLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCB0aGUgc2FtZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKHdpbGRBLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHdpbGRCLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHdpbGRBLT5uZWdOc1NldC0+dmFsdWUgPT0gd2lsZEEtPm5lZ05zU2V0LT52YWx1ZSkpCglyZXR1cm4gKDEpOyAgICAKICAgIC8qIAogICAgKiAzLjEgc3ViIG11c3QgYmUgYSBzZXQgd2hvc2UgbWVtYmVycyBhcmUgZWl0aGVyIG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50ty4gCiAgICAqLwogICAgaWYgKHdpbGRBLT5uc1NldCAhPSBOVUxMKSB7CgkvKgoJKiAzLjIuMSBzdXBlciBtdXN0IGJlIHRoZSBzYW1lIHNldCBvciBhIHN1cGVyc2V0IHRoZXJlb2YuIAoJKi8KCWlmICh3aWxkQi0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCOwoJICAgIGludCBmb3VuZCA9IDA7CgkgICAgCgkgICAgY3VyID0gd2lsZEEtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWZvdW5kID0gMDsKCQljdXJCID0gd2lsZEItPm5zU2V0OwoJCXdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkgICAgaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJZm91bmQgPSAxOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBjdXJCID0gY3VyQi0+bmV4dDsKCQl9CgkJaWYgKCFmb3VuZCkKCQkgICAgcmV0dXJuICgwKTsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmIChmb3VuZCkKCQlyZXR1cm4gKDEpOyAKCX0gZWxzZSBpZiAod2lsZEItPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCSAgICAvKgoJICAgICogMy4yLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yIAoJICAgICogt2Fic2VudLcgYW5kIHRoYXQgdmFsdWUgbXVzdCBub3QgYmUgaW4gc3ViJ3Mgc2V0LiAKCSAgICAqLwoJICAgIGN1ciA9IHdpbGRBLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsJCQoJCWlmIChjdXItPnZhbHVlID09IHdpbGRCLT5uZWdOc1NldC0+dmFsdWUpCgkJICAgIHJldHVybiAoMCk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0gIAoJICAgIHJldHVybiAoMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGF0dHJzOiB0aGUgYXR0cmlidXRlIGxpc3QgCiAqIEBjb21wbGV0ZVdpbGQ6IHRoZSByZXN1bHRpbmcgY29tcGxldGUgd2lsZGNhcmQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJCSAgICAKCQkJCSAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRycywKCQkJCSAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpjb21wbGV0ZVdpbGQpCQkJCQp7ICAgICAgICAKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CglpZiAoYXR0cnMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3JvdXA7CgoJICAgIGdyb3VwID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhdHRyczsKCSAgICAvKgoJICAgICogSGFuZGxlIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2VzLgoJICAgICovCgkgICAgaWYgKGdyb3VwLT5yZWYgIT0gTlVMTCkgewoJCWlmIChncm91cC0+cmVmSXRlbSA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogVE9ETzogU2hvdWxkIHdlIHJhaXNlIGEgd2FybmluZyBoZXJlPwoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRoZSByZWZlcmVuY2VkIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIGNvdWxkIG5vdAoJCSAgICAqIGJlIHJlc29sdmVkIGJlZm9yZWhhbmQsIHNvIHNraXAuCgkJICAgICovCgkJICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZQoJCSAgICBncm91cCA9IGdyb3VwLT5yZWZJdGVtOwoJICAgIH0JICAgIAoJICAgIC8qCgkgICAgKiBGb3IgZXZlcnkgYXR0cmlidXRlIGdyb3VwIGRlZmluaXRpb24sIGFuIGludGVyc2VjdGVkIHdpbGRjYXJkIAoJICAgICogd2lsbCBiZSBjcmVhdGVkIChhc3N1bWVkIHRoYXQgYSB3aWxkY2FyZCBleGlzdHMgb24gdGhlIAoJICAgICogcGFydGljdWxhciBhdHRyLiBnci4gZGVmLiBvciBvbiBhbnkgY29udGFpbmVkIGF0dHIuIGdyLiBkZWYgCgkgICAgKiBhdCBhbGwpLgoJICAgICogVGhlIGZsYWcgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQgZW5zdXJlcwoJICAgICogdGhhdCB0aGUgaW50ZXJzZWN0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIG9ubHkgb25jZS4KCSAgICAqLwoJICAgIGlmICgoZ3JvdXAtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQpID09IDApIHsKCQlpZiAoZ3JvdXAtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewoJCSAgICBpZiAoeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJCQlncm91cC0+YXR0cmlidXRlcywgJmdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpCgkJCXJldHVybiAoLTEpOwoJCX0KCQlncm91cC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUkdST1VQX1dJTERDQVJEX0JVSUxERUQ7CgkgICAgfQkJCgkgICAgaWYgKGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CQkKCQlpZiAoKmNvbXBsZXRlV2lsZCA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICogQ29weSB0aGUgZmlyc3QgZW5jb3VudGVyZWQgd2lsZGNhcmQgYXMgY29udGV4dCwgZXhjZXB0IGZvciB0aGUgYW5ub3RhdGlvbi4KCQkgICAgKi8KCQkgICAgKmNvbXBsZXRlV2lsZCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQpOwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURTsJICAgCgkJICAgIGlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAKCQkJY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4gKC0xKTsKCQkgICAgKCpjb21wbGV0ZVdpbGQpLT5wcm9jZXNzQ29udGVudHMgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50czsKCQkgICAgLyoKCQkgICAgKiBBbHRob3VnaCB0aGUgY29tcGxldGUgd2lsZGNhcmQgbWlnaHQgbm90IGNvcnJlc3BvbmQgdG8gYW55CgkJICAgICogbm9kZSBpbiB0aGUgc2NoZW1hLCB3ZSB3aWxsIHNhdmUgdGhpcyBjb250ZXh0IG5vZGUuCgkJICAgICogVE9ETzogSG1tLCBpcyB0aGlzIHNhbmU/CgkJICAgICovCgkJICAgICgqY29tcGxldGVXaWxkKS0+bm9kZSA9IGdyb3VwLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bm9kZTsgIAoJCSAgICAKCQl9IGVsc2UgaWYgKHhtbFNjaGVtYUludGVyc2VjdFdpbGRjYXJkcyhjdHh0LCAqY29tcGxldGVXaWxkLCBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZCgqY29tcGxldGVXaWxkKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkgICAgfQoJfQoJYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgCQkgICAgICAgICAgICAgICAgIAogICAgcmV0dXJuICgwKTsgICAKfQoKc3RhdGljIGludAp4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGl0ZW0sCgkJCQkgICAgIGludCAqZml4ZWQsCgkJCQkgICAgIGNvbnN0IHhtbENoYXIgKip2YWx1ZSwKCQkJCSAgICAgeG1sU2NoZW1hVmFsUHRyICp2YWwpCnsKICAgICpmaXhlZCA9IDA7CiAgICAqdmFsdWUgPSBOVUxMOwogICAgaWYgKHZhbCAhPSAwKSAKCSp2YWwgPSBOVUxMOwoKICAgIGlmIChpdGVtLT5kZWZWYWx1ZSA9PSBOVUxMKQoJaXRlbSA9IGl0ZW0tPnJlZkRlY2w7CgogICAgaWYgKGl0ZW0gPT0gTlVMTCkKCXJldHVybiAoMCk7CgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpIHsKCSp2YWx1ZSA9IGl0ZW0tPmRlZlZhbHVlOwoJaWYgKHZhbCAhPSAwKQoJICAgICp2YWwgPSBpdGVtLT5kZWZWYWw7CglpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKQoJICAgICpmaXhlZCA9IDE7CglyZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQovKioKICogeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnM6CiAqIEB3aWxkOiAgdGhlIHdpbGRjYXJkCiAqIEBuczogIHRoZSBuYW1lc3BhY2UKICogCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgZ2l2ZW4gbmFtZXNwYWNlIG1hdGNoZXMgdGhlIHdpbGRjYXJkLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnMoeG1sU2NoZW1hV2lsZGNhcmRQdHIgd2lsZCwgY29uc3QgeG1sQ2hhciogbnMpCnsKICAgIGlmICh3aWxkID09IE5VTEwpCglyZXR1cm4oMCk7CgogICAgaWYgKHdpbGQtPmFueSkKCXJldHVybigxKTsKICAgIGVsc2UgaWYgKHdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyOwoKCWN1ciA9IHdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKGN1ci0+dmFsdWUsIG5zKSkKCQlyZXR1cm4oMSk7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQogICAgfSBlbHNlIGlmICgod2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKG5zICE9IE5VTEwpICYmIAoJKCF4bWxTdHJFcXVhbCh3aWxkLT5uZWdOc1NldC0+dmFsdWUsIG5zKSkpCglyZXR1cm4oMSk7CQoJCiAgICByZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbgogKiAKICoKICogQnVpbGRzIHRoZSB3aWxkY2FyZCBhbmQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFJldHVybnMgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJzLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgY3VyLCBiYXNlLCB0bXAsIGlkID0gTlVMTCwgcHJldiA9IE5VTEwsIHVzZXMgPSBOVUxMLCAKCWxhc3RVc2UgPSBOVUxMLCBsYXN0QmFzZVVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0cnM7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFueVR5cGU7CiAgICBpbnQgYmFzZUlzQW55VHlwZSA9IDA7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwogICAgaW50IGVyciA9IDA7CgogICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwogICAgLyogCiAgICAgKiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiB3aXRoIGNvbXBsZXggY29udGVudCBTY2hlbWEgQ29tcG9uZW50LgogICAgICoKICAgICAqIEF0dHJpYnV0ZSB1c2VzLgogICAgICogVE9ETzogQWRkIGNoZWNrcyBmb3IgYWJzZW50IHJlZmVyZW5jZWQgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBhbmQKICAgICAqIHNpbXBsZSB0eXBlcy4KICAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCQkgICAgICAiYXR0cmlidXRlIHVzZXMgYWxyZWFkeSBidWlsZGVkLlxuIiwKCQkgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmICh0eXBlLT5iYXNlVHlwZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJCSAgICAgICJjb21wbGV4IHR5cGUgJyVzJyBoYXMgbm8gYmFzZSB0eXBlLlxuIiwKCQkgICAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZVR5cGUgPT0gYW55VHlwZSkKCWJhc2VJc0FueVR5cGUgPSAxOwogICAgLyoKICAgICAqIEluaGVyaXQgdGhlIGF0dHJpYnV0ZSB1c2VzIG9mIHRoZSBiYXNlIHR5cGUuCiAgICAgKi8KICAgIC8qCiAgICAgKiBOT1RFOiBJdCBpcyBhbGxvd2VkIHRvICJleHRlbmQiIHRoZSBhbnlUeXBlIGNvbXBsZXggdHlwZS4KICAgICAqLwogICAgaWYgKCFiYXNlSXNBbnlUeXBlKSB7CglpZiAoYmFzZVR5cGUgIT0gTlVMTCkgewoJICAgIGZvciAoY3VyID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVVzZXM7IGN1ciAhPSBOVUxMOyBjdXIgPSBjdXItPm5leHQpIHsKCQl0bXAgPSAoeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0cikgCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlTGluaykpOwoJCWlmICh0bXAgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsIAoJCQkiYnVpbGRpbmcgYXR0cmlidXRlIHVzZXMgb2YgY29tcGxleFR5cGUiLCBOVUxMKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCXRtcC0+YXR0ciA9IGN1ci0+YXR0cjsKCQl0bXAtPm5leHQgPSBOVUxMOwoJCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHRtcDsKCQl9IGVsc2UgCgkJICAgIGxhc3RCYXNlVXNlLT5uZXh0ID0gdG1wOwoJCWxhc3RCYXNlVXNlID0gdG1wOyAKCSAgICB9Cgl9CiAgICB9CiAgICBpZiAoKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpICYmIAoJKCh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB8fCAKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSkpIHsKCS8qIAoJKiB0eXBlIC0tPiAoPHNpbXBsZUNvbnRlbnQ+fDxjb21wbGV4Q29udGVudD4pIAoJKiAgICAgICAgLS0+ICg8cmVzdHJpY3Rpb24+fDxleHRlbnNpb24+KSAtLT4gYXR0cmlidXRlcwoJKi8gCglhdHRycyA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlczsKICAgIH0gZWxzZSB7CgkvKiBTaG9ydCBoYW5kIGZvcm0gb2YgdGhlIGNvbXBsZXhUeXBlLiAqLwoJYXR0cnMgPSB0eXBlLT5hdHRyaWJ1dGVzOwogICAgfQogICAgLyoKICAgICogSGFuZGxlIGF0dHJpYnV0ZSB3aWxkY2FyZHMuCiAgICAqLwkKICAgIGVyciA9IHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCAKCWF0dHJzLCAmdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpOyAgICAKICAgIC8qCiAgICAqIE5PVEU6IER1cmluZyB0aGUgcGFyc2UgdGltZSwgdGhlIHdpbGRjYXJkIGlzIGNyZWF0ZWQgb24gdGhlIGNvbXBsZXhUeXBlCiAgICAqIGRpcmVjdGx5LCBpZiBlbmNvdW50ZXJlZCBpbiBhIDxyZXN0cmljdGlvbj4gb3IgPGV4dGVuc2lvbj4gZWxlbWVudC4KICAgICovCiAgICBpZiAoZXJyID09IC0xKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkgICAgImZhaWxlZCB0byBidWlsZCBhbiBpbnRlcnNlY3RlZCBhdHRyaWJ1dGUgd2lsZGNhcmQuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CgogICAgaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSAmJiAKCSgoYmFzZUlzQW55VHlwZSkgfHwKCSAoKGJhc2VUeXBlICE9IE5VTEwpICYmIAkgICAgCgkgIChiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYJICAgICAgCgkgIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkpKSkgewkgICAgCglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBVbmlvbiB0aGUgY29tcGxldGUgd2lsZGNhcmQgd2l0aCB0aGUgYmFzZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFVbmlvbldpbGRjYXJkcyhjdHh0LCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQlyZXR1cm4gKC0xKTsKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIEp1c3QgaW5oZXJpdCB0aGUgd2lsZGNhcmQuCgkgICAgKi8KCSAgICAvKgoJICAgICogTk9URTogVGhpcyBpcyB0aGUgb25seSBjYXNlIHdoZXJlIGFuIGF0dHJpYnV0ZSAKICAgICAgICAgICAgKiB3aWxkY2FyZCBpcyBzaGFyZWQuCiAgICAgICAgICAgICovCgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEKQoJCXR5cGUtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZDsKCX0KICAgIH0KICAgIAogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsKCSAgICAvKiAKCSAgICAqIERlcml2YXRpb24gVmFsaWQgKFJlc3RyaWN0aW9uLCBDb21wbGV4KSAJICAgIAoJICAgICogNC4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgYWxzbyBoYXZlIG9uZS4gCgkgICAgKi8KCSAgICBpZiAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID09IE5VTEwpIHsJICAKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAKCQkgICAgIlRoZSB0eXBlIGhhcyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQsICIKCQkgICAgImJ1dCB0aGUgYmFzZSB0eXBlICVzIGRvZXMgbm90IGhhdmUgb25lIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoMSk7CgkgICAgfSBlbHNlIGlmICh4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KAoJCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCBiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IDApIHsKCQkvKiA0LjIgKi8KCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8yLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCSAgICAiVGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyBub3QgYSB2YWxpZCAiIAoJCSAgICAic3Vic2V0IG9mIHRoZSB3aWxkY2FyZCBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkgICAgCgkJcmV0dXJuICgxKTsKCSAgICB9CgkgICAgLyogNC4zIFVubGVzcyB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyB0aGUgt3VyLXR5cGUgCgkgICAgKiBkZWZpbml0aW9utywgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uJ3Mge2F0dHJpYnV0ZSAKCSAgICAqIHdpbGRjYXJkfSdzIHtwcm9jZXNzIGNvbnRlbnRzfSBtdXN0IGJlIGlkZW50aWNhbCB0byBvciAKCSAgICAqIHN0cm9uZ2VyIHRoYW4gdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0ncyB7YXR0cmlidXRlIAoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9LCB3aGVyZSBzdHJpY3QgaXMgc3Ryb25nZXIgCgkgICAgKiB0aGFuIGxheCBpcyBzdHJvbmdlciB0aGFuIHNraXAuCgkgICAgKi8KCSAgICBpZiAoKHR5cGUtPmJhc2VUeXBlICE9IGFueVR5cGUpICYmIAoJCSh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzIDwgCgkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMywKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkgICAgIlRoZSAncHJvY2VzcyBjb250ZW50cycgb2YgdGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyB3ZWFrZXIgdGhhbiAiCgkJICAgICJ0aGUgb25lIGluIHRoZSBiYXNlIHR5cGUgJXMiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CgkJRlJFRV9BTkRfTlVMTChzdHIpCgkJcmV0dXJuICgxKTsKCSAgICB9Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsKCS8qCgkqIERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikKCSogQXQgdGhpcyBwb2ludCB0aGUgdHlwZSBhbmQgdGhlIGJhc2UgaGF2ZSBib3RoLCBlaXRoZXIKCSogbm8gd2lsZGNhcmQgb3IgYSB3aWxkY2FyZC4KCSovCglpZiAoKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJICAgIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpKSB7CgkgICAgLyogMS4zICovCgkgICAgaWYgKHhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQoCgkJYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gMCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX0NUX0VYVEVORFNfMV8zLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAJCQoJCSAgICAiVGhlIGF0dHJpYnV0ZSB3aWxkY2FyZCBpcyBub3QgYSB2YWxpZCAiIAoJCSAgICAic3VwZXJzZXQgb2YgdGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlICVzIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCgkJcmV0dXJuICgxKTsJCQoJICAgIH0KCX0JCQogICAgfQkKCiAgICAvKgogICAgICogR2F0aGVyIGF0dHJpYnV0ZSB1c2VzIGRlZmluZWQgYnkgdGhpcyB0eXBlLgogICAgICovCiAgICBpZiAoYXR0cnMgIT0gTlVMTCkgewoJaWYgKHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKGN0eHQsIGF0dHJzLCAKCSAgICAmdXNlcywgJmxhc3RVc2UpID09IC0xKSB7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICAvKiAzLjQuNiAtPiBDb21wbGV4IFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QgNC4KICAgICAqICJUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAogICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuIgogICAgICoKICAgICAqIEZvciAiZXh0ZW5zaW9uIiB0aGlzIGlzIGRvbmUgZnVydGhlciBkb3duLgogICAgICovCiAgICBpZiAoKHVzZXMgIT0gTlVMTCkgJiYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSA9PSAwKSkgewoJY3VyID0gdXNlczsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIHRtcCA9IGN1ci0+bmV4dDsKCSAgICB3aGlsZSAodG1wICE9IE5VTEwpIHsJICAgIAoJCWlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJICAgIHhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpKSAmJgoJCSAgICAoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGN1ci0+YXR0ciApLCAKCQkgICAgeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKHRtcC0+YXR0cikpKSkgewoKCQkgICAgeG1sU2NoZW1hUEF0dHJVc2VFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF80LCAKCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAkJCQoJCQkiRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2UgJXMgc3BlY2lmaWVkIiwKCQkJeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyLCAKCQkJICAgIHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpLCAKCQkJICAgIHhtbFNjaGVtYUdldEF0dHJOYW1lKHRtcC0+YXR0cikpCgkJICAgICk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQkJICAgIAkJICAgIAoJCSAgICBicmVhazsKCQl9CgkJdG1wID0gdG1wLT5uZXh0OwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9CQogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewkKCS8qCgkgKiBEZXJpdmUgYnkgcmVzdHJpY3Rpb24uCgkgKi8KCWlmIChiYXNlSXNBbnlUeXBlKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7Cgl9IGVsc2UgewoJICAgIGludCBmb3VuZDsKCSAgICBjb25zdCB4bWxDaGFyICpiRWZmVmFsdWU7CgkgICAgaW50IGVmZkZpeGVkOwoKCSAgICBjdXIgPSB1c2VzOwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWZvdW5kID0gMDsKCQliYXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCQl3aGlsZSAoYmFzZSAhPSBOVUxMKSB7CgkJICAgIGlmICh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0QXR0ck5hbWUoYmFzZS0+YXR0cikpICYmCgkJCXhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGJhc2UtPmF0dHIpKSkgewoJCQkKCQkJZm91bmQgPSAxOwkJCQoJCQkKCQkJaWYgKChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9PUFRJT05BTCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDIuMS4xCgkJCSAgICAqLwkKCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzJfMV8xLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAoJCQkJIlRoZSAnb3B0aW9uYWwnIHVzZSBpcyBpbmNvbnNpc3RlbnQgd2l0aCBhIG1hdGNoaW5nICIKCQkJCSIncmVxdWlyZWQnIHVzZSBvZiB0aGUgYmFzZSB0eXBlIiwgTlVMTCk7CQkJCQoJCQl9IGVsc2UgaWYgKChjdXItPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSAmJgoJCQkgICAgKGJhc2UtPmF0dHItPm9jY3VycyA9PSBYTUxfU0NIRU1BU19BVFRSX1VTRV9SRVFVSVJFRCkpIHsKCQkJICAgIC8qCgkJCSAgICAqIGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gMyAKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzMsIAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwgCQkKCQkJCSJBIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UgZm9yIHRoZSAncmVxdWlyZWQnICIKCQkJCSJhdHRyaWJ1dGUgdXNlICVzIG9mIHRoZSBiYXNlIHR5cGUgaXMgbWlzc2luZyIsCgkJCQl4bWxTY2hlbWFGb3JtYXROc1VyaUxvY2FsKCZzdHIsIAoJCQkJeG1sU2NoZW1hR2V0QXR0clRhcmdldE5zVVJJKGJhc2UtPmF0dHIpLCAKCQkJCXhtbFNjaGVtYUdldEF0dHJOYW1lKGJhc2UtPmF0dHIpKSk7CQoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCX0gZWxzZSB7CgkJCSAgICAvKgoJCQkgICAgKiAyLjEuMyBbRGVmaW5pdGlvbjpdICBMZXQgdGhlIGVmZmVjdGl2ZSB2YWx1ZSAKCQkJICAgICogY29uc3RyYWludCBvZiBhbiBhdHRyaWJ1dGUgdXNlIGJlIGl0cyB7dmFsdWUgCgkJCSAgICAqIGNvbnN0cmFpbnR9LCBpZiBwcmVzZW50LCBvdGhlcndpc2UgaXRzIHthdHRyaWJ1dGUgCgkJCSAgICAqIGRlY2xhcmF0aW9ufSdzIHt2YWx1ZSBjb25zdHJhaW50fSAuIAoJCQkgICAgKi8KCQkJICAgIHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiYXNlLT5hdHRyLCAmZWZmRml4ZWQsIAoJCQkJJmJFZmZWYWx1ZSwgMCk7CQkJICAgCQkJCQkJCSAgICAKCQkJICAgIC8qCgkJCSAgICAqIDIuMS4zIC4uLiBvbmUgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWUKCQkJICAgICoKCQkJICAgICogMi4xLjMuMSBCJ3Mgt2VmZmVjdGl2ZSB2YWx1ZSBjb25zdHJhaW50tyBpcyAKCQkJICAgICogt2Fic2VudLcgb3IgZGVmYXVsdC4KCQkJICAgICovCgkJCSAgICBpZiAoKGJFZmZWYWx1ZSAhPSBOVUxMKSAmJgoJCQkJKGVmZkZpeGVkID09IDEpKSB7CgkJCQljb25zdCB4bWxDaGFyICpyRWZmVmFsdWUgPSBOVUxMOwoKCQkJCXhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludChiYXNlLT5hdHRyLCAmZWZmRml4ZWQsIAoJCQkJICAgICZyRWZmVmFsdWUsIDApOwkKCQkJCS8qCgkJCQkqIDIuMS4zLjIgUidzILdlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludLcgaXMgCgkJCQkqIGZpeGVkIHdpdGggdGhlIHNhbWUgc3RyaW5nIGFzIEIncy4KCQkJCSovCgkJCQlpZiAoKGVmZkZpeGVkID09IDApIHx8CgkJCQkgICAgKCEgeG1sU3RyRXF1YWwockVmZlZhbHVlLCBiRWZmVmFsdWUpKSkgewoJCQkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzFfMywgCgkJCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAkJCgkJCQkJIlRoZSBlZmZlY3RpdmUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgIgoJCQkJCSJhdHRyaWJ1dGUgdXNlIGlzIGluY29uc2lzdGVudCB3aXRoICIKCQkJCQkiaXRzIGNvcnJlc3BvbmRlbnQgb2YgdGhlIGJhc2UgdHlwZSIsCgkJCQkJTlVMTCk7CQkJCQkgICAgCgkJCQl9CgkJCSAgICB9CgkJCSAgICAvKgoJCQkgICAgKiBUT0RPOiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjEuMiAoe3R5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQpCgkJCSAgICAqLwoJCQkgICAgLyoKCQkJICAgICogT3ZlcnJpZGUgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqLwoJCQkgICAgYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJfQoJCQkJCQkJCQoJCQlicmVhazsKCQkgICAgfQkJCQkKCQkgICAgYmFzZSA9IGJhc2UtPm5leHQ7CgkJfQoJCQoJCWlmICghZm91bmQpIHsKCQkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzICE9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQkJLyoKCQkJKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjIKCQkJKi8KCQkJaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJCQkgICAgeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnModHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsCgkJCQljdXItPmF0dHItPnRhcmdldE5hbWVzcGFjZSkpCgkJCSAgICBmb3VuZCA9IDE7CgoJCQlpZiAoIWZvdW5kKSB7CgkJCSAgICB4bWxTY2hlbWFQQXR0clVzZUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfREVSSVZBVElPTl9PS19SRVNUUklDVElPTl8yXzIsIAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwgY3VyLT5hdHRyLAkJCgkJCQkiTmVpdGhlciBhIG1hdGNoaW5nIGF0dHJpYnV0ZSB1c2UsICIKCQkJCSJub3IgYSBtYXRjaGluZyB3aWxkY2FyZCBpbiB0aGUgYmFzZSB0eXBlIGRvZXMgZXhpc3QiLAoJCQkJTlVMTCk7CgkJCX0gZWxzZSB7CgkJCSAgICAvKiAKCQkJICAgICogQWRkIHRoZSBhdHRyaWJ1dGUgdXNlLgoJCQkgICAgKgoJCQkgICAgKiBOb3RlIHRoYXQgdGhpcyBtYXkgbGVhZCB0byBmdW5ueSBkZXJpdmF0aW9uIGVycm9yIHJlcG9ydHMsIGlmCgkJCSAgICAqIG11bHRpcGxlIGVxdWFsIGF0dHJpYnV0ZSB1c2VzIGV4aXN0OyBidXQgdGhpcyBpcyBub3QKCQkJICAgICogYWxsb3dlZCBhbnl3YXksIGFuZCBpdCB3aWxsIGJlIHJlcG9ydGVkIGJlZm9yZWhhbmQuCgkJCSAgICAqLwoJCQkgICAgdG1wID0gY3VyOwoJCQkgICAgaWYgKHByZXYgIT0gTlVMTCkKCQkJCXByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJCSAgICBlbHNlIAoJCQkJdXNlcyA9IGN1ci0+bmV4dDsKCQkJICAgIGN1ciA9IGN1ci0+bmV4dDsgICAgCQkJCgkJCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJCQl0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdG1wOwoJCQkgICAgfSBlbHNlIAoJCQkJbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJCSAgICBsYXN0QmFzZVVzZSA9IHRtcDsJCQoJCQkgICAgCgkJCSAgICBjb250aW51ZTsKCQkJfQoJCSAgICB9CgkJfQkJICAgIAkgICAgCgkJcHJldiA9IGN1cjsJCgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCSAgICBpZiAodXNlcyAhPSBOVUxMKQoJCXhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0KHVzZXMpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7IAoJLyoKCSAqIFRoZSBzcGVjIGFsbG93cyBvbmx5IGFwcGVuZGluZywgYW5kIG5vdCBvdGhlciBraW5kcyBvZiBleHRlbnNpb25zLgoJICoKCSAqIFRoaXMgZW5zdXJlczogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pIDogMS4yIAoJICovCglpZiAodXNlcyAhPSBOVUxMKSB7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwoJICAgIH0gZWxzZSAKCQlsYXN0QmFzZVVzZS0+bmV4dCA9IHVzZXM7Cgl9CiAgICB9IGVsc2UgewoJLyogCgkqIERlcml2ZSBpbXBsaWNpdGVseSBmcm9tIHRoZSB1ci10eXBlLgoJKi8KCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB1c2VzOwogICAgfQogICAgLyoKICAgICAqIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgICovCiAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyAhPSBOVUxMKSB7CgljdXIgPSB0eXBlLT5hdHRyaWJ1dGVVc2VzOwoJcHJldiA9IE5VTEw7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogNC4gVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKCSAgICAqIG5vdCBoYXZlIGlkZW50aWNhbCB7bmFtZX1zIGFuZCB7dGFyZ2V0IG5hbWVzcGFjZX1zLgoJICAgICoKCSAgICAqIE5vdGUgdGhhdCB0aGlzIHdhcyBhbHJlYWR5IGRvbmUgZm9yICJyZXN0cmljdGlvbiIgYW5kIHR5cGVzIGRlcml2ZWQgZnJvbQoJICAgICogdGhlIHVyLXR5cGUuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJCXRtcCA9IGN1ci0+bmV4dDsKCQl3aGlsZSAodG1wICE9IE5VTEwpIHsJICAgIAoJCSAgICBpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkJKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSShjdXItPmF0dHIgKSwgCgkJCXhtbFNjaGVtYUdldEF0dHJUYXJnZXROc1VSSSh0bXAtPmF0dHIpKSkpIHsKCgkJCXhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsIAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwgdG1wLT5hdHRyLAkJCgkJCSAgICAiRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2Ugc3BlY2lmaWVkIiwgTlVMTCk7CgkJCWJyZWFrOwoJCSAgICB9CgkJICAgIHRtcCA9IHRtcC0+bmV4dDsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiA1LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUge3R5cGUgZGVmaW5pdGlvbn1zIHdoaWNoIGFyZSBvciBhcmUgZGVyaXZlZCBmcm9tIElELgoJICAgICovCgkgICAgaWYgKChjdXItPmF0dHItPnN1YnR5cGVzICE9IE5VTEwpICYmIAoJCSh4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoY3R4dCwgKHhtbFNjaGVtYVR5cGVQdHIpIGN1ci0+YXR0ciwgWE1MX1NDSEVNQVNfSUQpKSkgewoJCWlmIChpZCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBBdHRyVXNlRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNSwgCgkJCU5VTEwsIHR5cGUsIE5VTEwsIGN1ci0+YXR0ciwKCQkJIlRoZXJlIG11c3Qgbm90IGV4aXN0IG1vcmUgdGhhbiBvbmUgYXR0cmlidXRlIHVzZSwgIgoJCQkiZGVjbGFyZWQgb2YgdHlwZSAnSUQnIG9yIGRlcml2ZWQgZnJvbSBpdCIsIAoJCQlOVUxMKTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJfSAKCQlpZCA9IGN1cjsKCSAgICB9CgkgICAgLyoKCSAgICAqIFJlbW92ZSAicHJvaGliaXRlZCIgYXR0cmlidXRlIHVzZXMuIFRoZSByZWFzb24gdGhpcyBpcyBkb25lIGF0IHRoaXMgbGF0ZSAKCSAgICAqIHN0YWdlIGlzIHRvIGJlIGFibGUgdG8gY2F0Y2ggZHVibGljYXRlIGF0dHJpYnV0ZSB1c2VzLiBTbyB3ZSBoYWQgdG8ga2VlcAoJICAgICogcHJvaGliaXRlZCB1c2VzIGluIHRoZSBsaXN0IGFzIHdlbGwuCgkgICAgKi8KCSAgICBpZiAoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgewoJCXRtcCA9IGN1cjsKCQlpZiAocHJldiA9PSBOVUxMKQoJCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gY3VyLT5uZXh0OwoJCWVsc2UKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQljdXIgPSBjdXItPm5leHQ7CgkJeG1sRnJlZSh0bXApOwoJICAgIH0gZWxzZSB7CgkJcHJldiA9IGN1cjsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJfSAgICAKICAgIH0KICAgIC8qCQogICAgICogVE9ETzogVGhpcyBjaGVjayBzaG91bGQgYmUgcmVtb3ZlZCBpZiB3ZSBhcmUgMTAwJSBzdXJlIG9mCiAgICAgKiB0aGUgYmFzZSB0eXBlIGF0dHJpYnV0ZSB1c2VzIGFscmVhZHkgYmVpbmcgYnVpbHQuCiAgICAgKi8KICAgIGlmICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgKCFiYXNlSXNBbnlUeXBlKSAmJgoJKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgoJKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgYmFzZVR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOiAiCgkgICAgImF0dHJpYnV0ZSB1c2VzIG5vdCBidWlsZGVkIG9uIGJhc2UgdHlwZSAnJXMnLlxuIiwKCSAgICBiYXNlVHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9ICAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYQogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQGZpbmFsOiB0aGUgZmluYWwKICoKICogRXZhbHVhdGVzIGlmIGEgdHlwZSBkZWZpbml0aW9uIGNvbnRhaW5zIHRoZSBnaXZlbiAiZmluYWwiLgogKiBUaGlzIGRvZXMgdGFrZSAiZmluYWxEZWZhdWx0IiBpbnRvIGFjY291bnQgYXMgd2VsbC4KICoKICogUmV0dXJucyAxIGlmIHRoZSB0eXBlIGRvZXMgY29udGFpbnQgdGhlIGdpdmVuICJmaW5hbCIsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyh4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCBmaW5hbCkKewogICAgaW50IHRmaW5hbCA9IGZpbmFsLCB0ZmxhZ3MgPSB0eXBlLT5mbGFnczsKCiAgICBpZiAodHlwZSA9PSBOVUxMKQoJcmV0dXJuICgwKTsgICAgCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0RFRkFVTFQpIHsKCXN3aXRjaCAoZmluYWwpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT046CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTjsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNUOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVDsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfVU5JT046CgkJdGZpbmFsID0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsKCQlicmVhazsKCX0KCXRmbGFncyA9IHNjaGVtYS0+ZmxhZ3M7CiAgICB9CiAgICBpZiAodGZsYWdzICYgdGZpbmFsKSAKCXJldHVybiAoMSk7CiAgICBlbHNlCglyZXR1cm4gKDApOwogICAgCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlczoKICogQHR5cGU6ICB0aGUgVW5pb24gU2ltcGxlIFR5cGUKICoKICogUmV0dXJucyBhIGxpc3Qgb2YgbWVtYmVyIHR5cGVzIG9mIEB0eXBlIGlmIGV4aXN0aW5nLCAKICogcmV0dXJucyBOVUxMIG90aGVyd2lzZS4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlTGlua1B0cgp4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCWlmICh0eXBlLT5tZW1iZXJUeXBlcyAhPSBOVUxMKQoJICAgIHJldHVybiAodHlwZS0+bWVtYmVyVHlwZXMpOwoJZWxzZQoJICAgIHR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlOgogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIGl0ZW0gdHlwZSBkZWZpbml0aW9uIG9mIHRoZSBsaXN0IHNpbXBsZSB0eXBlLgogKi8gCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgIAogICAgaWYgKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKQoJcmV0dXJuIChOVUxMKTsKICAgIC8qCiAgICAqIE5vdGU6IEluIGxpYnhtbDIsIHRoZSBidWlsdC1pbiB0eXBlcyBkbyBub3QgcmVmbGVjdCAKICAgICogdGhlIGRhdGF0eXBlIGhpZXJhcmNoeSAoeWV0PykgLSB3ZSBoYXZlIHRvIHRyZWF0IHRoZW0KICAgICogaW4gYSBzcGVjaWFsIHdheS4KICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIAoJcmV0dXJuICh4bWxTY2hlbWFHZXRCdWlsdEluTGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKSk7CiAgICBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0xJU1QpCgkvKiAxIElmIHRoZSA8bGlzdD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIHRoZSB0eXBlIAoJKiBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSAKCSogaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb2YgPGxpc3Q+LCBpZiBwcmVzZW50LCBvdGhlcndpc2UgCgkqIHRoZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+IAoJKiBhbW9uZyB0aGUgW2NoaWxkcmVuXSBvZiA8bGlzdD4uCgkqLwoJcmV0dXJuICh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMpOwogICAgZWxzZSB7CgkvKiAyIElmIHRoZSA8cmVzdHJpY3Rpb24+IG9wdGlvbiBpcyBjaG9zZW4sIHRoZW4gdGhlIAoJKiB7aXRlbSB0eXBlIGRlZmluaXRpb259IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgoJKi8gICAgCglyZXR1cm4gKHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZS0+YmFzZVR5cGUpKTsKICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LOgogKiBAdHlwZTogIHRoZSBkZXJpdmVkIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICogQGJhc2VUeXBlOiAgdGhlIGJhc2UgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyB3aGV0ZXIgQHR5cGUgY2FuIGJlIHZhbGlkbHkgCiAqIGRlcml2ZWQgZnJvbSBAYmFzZVR5cGUuCiAqCiAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCBhbiBwb3NpdGl2ZSBlcnJvciBjb2RlIG90aGVyd2lzZS4KICovIApzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soeG1sU2NoZW1hUHRyIHNjaGVtYSwKCQkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlLAoJCQkJICAgICBpbnQgc3Vic2V0KQp7ICAgCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKQogICAgKgogICAgKgogICAgKiAxIFRoZXkgYXJlIHRoZSBzYW1lIHR5cGUgZGVmaW5pdGlvbi4KICAgICogVE9ETzogVGhlIGlkZW50eSBjaGVjayBtaWdodCBoYXZlIHRvIGJlIG1vcmUgY29tcGxleCB0aGFuIHRoaXMuCiAgICAqLwogICAgaWYgKHR5cGUgPT0gYmFzZVR5cGUpCglyZXR1cm4gKDApOyAgICAKICAgIC8qIAogICAgKiAyLjEgcmVzdHJpY3Rpb24gaXMgbm90IGluIHRoZSBzdWJzZXQsIG9yIGluIHRoZSB7ZmluYWx9CiAgICAqIG9mIGl0cyBvd24ge2Jhc2UgdHlwZSBkZWZpbml0aW9ufTsKICAgICovCiAgICBpZiAoKHN1YnNldCAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pIHx8CgkoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoc2NoZW1hLCAKCSAgICB0eXBlLT5iYXNlVHlwZSwgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpKSB7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9ERVJJVkVEX09LXzJfMSk7IAogICAgfQogICAgLyogMi4yICovCiAgICBpZiAodHlwZS0+YmFzZVR5cGUgPT0gYmFzZVR5cGUpIHsKCS8qCgkqIDIuMi4xIEQncyC3YmFzZSB0eXBlIGRlZmluaXRpb263IGlzIEIuCgkqLwoJcmV0dXJuICgwKTsKICAgIH0gICAKICAgIC8qIAogICAgKiAyLjIuMiBEJ3Mgt2Jhc2UgdHlwZSBkZWZpbml0aW9utyBpcyBub3QgdGhlILd1ci10eXBlIGRlZmluaXRpb263IAogICAgKiBhbmQgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gQiBnaXZlbiB0aGUgc3Vic2V0LCBhcyBkZWZpbmVkIGJ5IHRoaXMgCiAgICAqIGNvbnN0cmFpbnQuICAgIAogICAgKi8KICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSkpICYmCgkoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhzY2hlbWEsIHR5cGUtPmJhc2VUeXBlLCBiYXNlVHlwZSwgc3Vic2V0KSA9PSAwKSkgewoJcmV0dXJuICgwKTsJCQogICAgfSAKICAgIC8qIAogICAgKiAyLjIuMyBEJ3Mge3ZhcmlldHl9IGlzIGxpc3Qgb3IgdW5pb24gYW5kIEIgaXMgdGhlILdzaW1wbGUgdXItdHlwZSAKICAgICogZGVmaW5pdGlvbrcuCiAgICAqLwogICAgaWYgKCgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgfHwKCSh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikpICYmCgkoYmFzZVR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpKSB7CglyZXR1cm4gKDApOwogICAgfSAgICAKICAgIC8qIAogICAgKiAyLjIuNCBCJ3Mge3ZhcmlldHl9IGlzIHVuaW9uIGFuZCBEIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIGEgdHlwZSAKICAgICogZGVmaW5pdGlvbiBpbiBCJ3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgc3Vic2V0LCBhcyAKICAgICogZGVmaW5lZCBieSB0aGlzIGNvbnN0cmFpbnQuCiAgICAqCiAgICAqIE5PVEU6IFRoaXMgc2VlbXMgbm90IHRvIGludm9sdmUgYnVpbHQtaW4gdHlwZXMsIHNpbmNlIHRoZXJlIGlzIG5vCiAgICAqIGJ1aWx0LWluIFVuaW9uIFNpbXBsZSBUeXBlLgogICAgKi8KICAgIGlmIChiYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIGN1cjsKCgljdXIgPSBiYXNlVHlwZS0+bWVtYmVyVHlwZXM7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhzY2hlbWEsIHR5cGUsIAoJCWN1ci0+dHlwZSwgc3Vic2V0KSA9PSAwKQoJCXJldHVybiAoMCk7CgkgICAgY3VyID0gY3VyLT5uZXh0OwoJfQkKICAgIH0KICAgIAogICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzIpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1RQcm9wc0NvcnJlY3Q6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBzdC1wcm9wcy1jb3JyZWN0LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHByb3BlcnRpZXMgYXJlIGNvcnJlY3QsCiAqIGlmIG5vdCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrU1RQcm9wc0NvcnJlY3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSB0eXBlLT5iYXNlVHlwZSwgYW55U2ltcGxlVHlwZSwKCWFueVR5cGU7CiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgIC8qIFNUQVRFOiBlcnJvciBmdW5jcyBjb252ZXJ0ZWQuICovCiAgICAvKgogICAgKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IFNpbXBsZSBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAqCiAgICAqIE5PVEU6IFRoaXMgaXMgc29tZWhvdyByZWR1bmRhbnQsIHNpbmNlIHdlIGFjdHVhbGx5IGJ1aWx0IGEgc2ltcGxlIHR5cGUKICAgICogdG8gaGF2ZSBhbGwgdGhlIG5lZWRlZCBpbmZvcm1hdGlvbjsgdGhpcyBhY3RzIGFzIGFuIHNlbGYgdGVzdC4KICAgICovCiAgICBhbnlTaW1wbGVUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKiAKICAgICogVE9ETzogMSBUaGUgdmFsdWVzIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiBtdXN0IGJlIGFzIAogICAgKiBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gRGF0YXR5cGUgZGVmaW5pdGlvbiwgbW9kdWxvIHRoZSAKICAgICogaW1wYWN0IG9mIE1pc3NpbmcgU3ViLWNvbXBvbmVudHMgKKc1LjMpLgogICAgKi8KICAgIC8qIEJhc2UgdHlwZTogSWYgdGhlIGRhdGF0eXBlIGhhcyBiZWVuILdkZXJpdmVktyBieSC3cmVzdHJpY3Rpb263IAogICAgKiB0aGVuIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGNvbXBvbmVudCBmcm9tIHdoaWNoIGl0IGlzILdkZXJpdmVktywgCiAgICAqIG90aGVyd2lzZSB0aGUgU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBmb3IgYW55U2ltcGxlVHlwZSAopzQuMS42KS4gCiAgICAqLwogICAgaWYgKGJhc2VUeXBlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIk5vIGJhc2UgdHlwZSBleGlzdGVudCIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgaWYgKChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSAmJgoJKChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHx8CgkgKGJhc2VUeXBlID09IGFueVR5cGUpKSkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCSAgICAiVGhlIGJhc2UgdHlwZSAlcyBpcyBub3QgYSBzaW1wbGUgdHlwZSIsIAoJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgYmFzZVR5cGUsIE5VTEwsIDEpKTsKCUZSRUVfQU5EX05VTEwoc3RyKQkKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIGlmICgoYmFzZVR5cGUgIT0gYW55U2ltcGxlVHlwZSkgJiYKCSh0eXBlLT5zdWJ0eXBlcy0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJBIHR5cGUsIGRlcml2ZWQgYnkgbGlzdCBvciB1bmlvbiwgbXVzdCBoYXZlIgoJICAgICJ0aGUgc2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbiBhcyBiYXNlIHR5cGUsIG5vdCAlcyIsCgkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBiYXNlVHlwZSwgTlVMTCwgMSkpOwoJRlJFRV9BTkRfTlVMTChzdHIpCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICAvKiAKICAgICogVmFyaWV0eTogT25lIG9mIHthdG9taWMsIGxpc3QsIHVuaW9ufS4gCiAgICAqLwogICAgaWYgKCgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSAmJgoJKCh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgPT0gMCkgJiYKCSgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgPT0gMCkpIHsKCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIlRoZSB2YXJpZXR5IGlzIGFic2VudCIsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgLyogVE9ETzogRmluaXNoIHRoaXMuIEhtbSwgaXMgdGhpcyBmaW5pc2hlZD8gKi8KCiAgICAvKgogICAgKiAyIEFsbCBzaW1wbGUgdHlwZSBkZWZpbml0aW9ucyBtdXN0IGJlIGRlcml2ZWQgdWx0aW1hdGVseSBmcm9tIHRoZSC3c2ltcGxlIAogICAgKiB1ci10eXBlIGRlZmluaXRpb24gKHNvtyBjaXJjdWxhciBkZWZpbml0aW9ucyBhcmUgZGlzYWxsb3dlZCkuIFRoYXQgaXMsIGl0IAogICAgKiBtdXN0IGJlIHBvc3NpYmxlIHRvIHJlYWNoIGEgYnVpbHQtaW4gcHJpbWl0aXZlIGRhdGF0eXBlIG9yIHRoZSC3c2ltcGxlIAogICAgKiB1ci10eXBlIGRlZmluaXRpb263IGJ5IHJlcGVhdGVkbHkgZm9sbG93aW5nIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgogICAgKi8gICAgCiAgICBiYXNlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgd2hpbGUgKChiYXNlVHlwZSAhPSBOVUxMKSAmJiAoYmFzZVR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkgewoJaWYgKGJhc2VUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikKCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZVR5cGUsIGN0eHQsICBOVUxMKTsKCWlmIChiYXNlVHlwZSA9PSBhbnlTaW1wbGVUeXBlKQoJICAgIGJyZWFrOwoJZWxzZSBpZiAoYmFzZVR5cGUgPT0gdHlwZSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwJCgkgICAgIlRoZSBkZWZpbml0aW9uIGlzIGNpcmN1bGFyIiwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzIpOwoJfQkgICAKCWJhc2VUeXBlID0gYmFzZVR5cGUtPmJhc2VUeXBlOwogICAgfSAgIAogICAgLyoKICAgICogMyBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIHJlc3RyaWN0aW9uLgogICAgKi8KICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIGJhc2VUeXBlLCAKCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8zLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJICAgICJUaGUgJ2ZpbmFsJyBvZiBpdHMgYmFzZSB0eXBlICVzIG11c3Qgbm90IGNvbnRhaW4gIgoJICAgICIncmVzdHJpY3Rpb24nIiwKCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIGJhc2VUeXBlLCBOVUxMLCAxKSk7CglGUkVFX0FORF9OVUxMKHN0cikJCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMyk7CiAgICB9ICAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gQHR5cGUgKHNpbXBsZVR5cGUpIGlzIGRlcml2ZWQgCiAqIHZhbGlkbHkgYnkgcmVzdHJpY3Rpb24uCiAqCiAqIFJldHVybnMgLTEgb24gaW50ZXJuYWwgZXJyb3JzLCAwIGlmIHRoZSB0eXBlIGlzIHZhbGlkbHkgZGVyaXZlZCwgCiAqIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgCiAgICB4bWxDaGFyICpzdHIgPSBOVUxMOwoKICAgIC8qIFNUQVRFOiBlcnJvciBmdW5jcyBjb252ZXJ0ZWQuICovCgogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246IFRoZSBnaXZlbiAiCgkgICAgInR5cGUgJyVzJyBpcyBub3QgYSB1c2VyLWRlcml2ZWQgc2ltcGxlVHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHByaW1pdGl2ZTsKCS8qIAoJKiAxLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhbiBhdG9taWMgc2ltcGxlIAoJKiB0eXBlIGRlZmluaXRpb24gb3IgYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUuCgkqLwkKCWlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAkKCQkiVGhlIGJhc2UgdHlwZSAlcyBpcyBub3QgYW4gYXRvbWljIHNpbXBsZSB0eXBlIiwKCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMSk7Cgl9CgkvKiAxLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiAKCSogcmVzdHJpY3Rpb24uCgkqLwoJLyogT1BUSU1JWkUgVE9ETyA6IFRoaXMgaXMgYWxyZWFkeSBkb25lIGluIHhtbFNjaGVtYUNoZWNrU3RQcm9wc0NvcnJlY3QgKi8KCWlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLCAKCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMiwKCQlOVUxMLCB0eXBlLCBOVUxMLAkKCQkiVGhlIGZpbmFsIG9mIGl0cyBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMik7Cgl9CgkKCS8qIAoJKiAxLjMuMSBERiBtdXN0IGJlIGFuIGFsbG93ZWQgY29uc3RyYWluaW5nIGZhY2V0IGZvciB0aGUge3ByaW1pdGl2ZQoJKiB0eXBlIGRlZmluaXRpb259LCBhcyBzcGVjaWZpZWQgaW4gdGhlIGFwcHJvcHJpYXRlIHN1YnNlY3Rpb24gb2YgMy4yIAoJKiBQcmltaXRpdmUgZGF0YXR5cGVzLgoJKi8KCWlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIGludCBvayA9IDE7CgkgICAgCgkgICAgcHJpbWl0aXZlID0geG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh0eXBlKTsKCSAgICBpZiAocHJpbWl0aXZlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJICAgIFhNTF9FUlJfSU5URVJOQUxfRVJST1IsCgkJICAgICJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiBmYWlsZWQgIgoJCSAgICAidG8gZ2V0IHByaW1pdGl2ZSB0eXBlIG9mIHR5cGUgJyVzJy5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJCXJldHVybiAoLTEpOwoJICAgIH0JICAgIAoJICAgIGZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJICAgIGRvIHsKCQlpZiAoeG1sU2NoZW1hSXNCdWlsdEluVHlwZUZhY2V0KHByaW1pdGl2ZSwgZmFjZXQtPnR5cGUpID09IDApIHsKCQkgICAgb2sgPSAwOwoJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0QXRvbWljRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEsCgkJCU5VTEwsIHR5cGUsIHByaW1pdGl2ZSwgZmFjZXQpOwkJICAgIAkJICAgIAkJICAgIAoJCX0KCQlmYWNldCA9IGZhY2V0LT5uZXh0OwoJICAgIH0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwkgICAgCgkgICAgaWYgKG9rID09IDApCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfM18xKTsJICAgIAoJfQoJLyoKCSogVE9ETzogMS4zLjIgKGZhY2V0IGRlcml2YXRpb24pCgkqLwogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGl0ZW1UeXBlID0gTlVMTDsKCglpdGVtVHlwZSA9IHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZSk7CglpZiAoaXRlbVR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQlYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogIgoJCSJmYWlsZWQgdG8gZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSBvZiB0eXBlICclcycuXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogMi4xIFRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiBhdG9taWMgb3IgCgkqIHVuaW9uIChpbiB3aGljaCBjYXNlIGFsbCB0aGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSAKCSogbXVzdCBiZSBhdG9taWMpLgoJKi8KCWlmICgoKGl0ZW1UeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmICAKCSAgICAoKGl0ZW1UeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgPT0gMCkpIHsJICAgIAoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAkKCQkiVGhlIGl0ZW0gdHlwZSAlcyBtdXN0IGhhdmUgYSB2YXJpZXR5IG9mIGF0b21pYyBvciB1bmlvbiIsCgkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBpdGVtVHlwZSwgTlVMTCwgMSkpOwoJICAgIEZSRUVfQU5EX05VTEwoc3RyKQkgICAgCgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSk7Cgl9IGVsc2UgaWYgKGl0ZW1UeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcjsKCgkgICAgbWVtYmVyID0gaXRlbVR5cGUtPm1lbWJlclR5cGVzOwoJICAgIHdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJCWlmICgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCQkiVGhlIGl0ZW0gdHlwZSBpcyBhIHVuaW9uIHR5cGUsIGJ1dCB0aGUgIgoJCQkibWVtYmVyIHR5cGUgJXMgb2YgdGhpcyBpdGVtIHR5cGUgaXMgbm90IGF0b21pYyIsCgkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQkJICAgIAoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCX0KCQoJaWYgKHR5cGUtPmJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkgICAgLyoKCSAgICAqIFRoaXMgaXMgdGhlIGNhc2UgaWYgd2UgaGF2ZTogPHNpbXBsZVR5cGU+PGxpc3QgLi4KCSAgICAqLwoJICAgIC8qCgkgICAgKiAyLjMuMSAKCSAgICAqIDIuMy4xLjEgVGhlIHtmaW5hbH0gb2YgdGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgCgkgICAgKiBjb250YWluIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCAKCQlpdGVtVHlwZSwgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9MSVNUKSkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAkKCQkgICAgIlRoZSBmaW5hbCBvZiBpdHMgaXRlbSB0eXBlICVzIG11c3Qgbm90IGNvbnRhaW4gJ2xpc3QnIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBpdGVtVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4xLjIgVGhlIHtmYWNldHN9IG11c3Qgb25seSBjb250YWluIHRoZSB3aGl0ZVNwYWNlCgkgICAgKiBmYWNldCBjb21wb25lbnQuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yLAoJCQkgICAgTlVMTCwgdHlwZSwgZmFjZXQpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzFfMik7CgkJICAgIH0KCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFRPRE86IERhdGF0eXBlcyBzdGF0ZXM6IAoJICAgICogQSC3bGlzdLcgZGF0YXR5cGUgY2FuIGJlILdkZXJpdmVktyBmcm9tIGFuILdhdG9taWO3IGRhdGF0eXBlIAoJICAgICogd2hvc2Ugt2xleGljYWwgc3BhY2W3IGFsbG93cyBzcGFjZSAoc3VjaCBhcyBzdHJpbmcgb3IgYW55VVJJKW9yIAoJICAgICogYSC3dW5pb263IGRhdGF0eXBlIGFueSBvZiB3aG9zZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9J3MgCgkgICAgKiC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlLgoJICAgICovCgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGlmIHdlIGhhdmU6IDxzaW1wbGVUeXBlPjxyZXN0cmljdGlvbiAuLi4KCSAgICAqLwoJICAgIC8qCgkgICAgKiAyLjMuMiAKCSAgICAqIDIuMy4yLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoKHR5cGUtPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJCSAgICAiVGhlIGJhc2UgdHlwZSAlcyBtdXN0IGJlIGEgbGlzdCB0eXBlIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCQkJCgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJICAgICogY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzIsCgkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCQoJCSAgICAiVGhlIGZpbmFsIG9mIHRoZSBiYXNlIHR5cGUgJXMgbXVzdCBub3QgY29udGFpbiAncmVzdHJpY3Rpb24nIiwKCQkgICAgeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCB0eXBlLT5iYXNlVHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQkJCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMik7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMi4zIFRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIAoJICAgICogZnJvbSB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gZ2l2ZW4KCSAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2VJdGVtVHlwZTsKCgkJYmFzZUl0ZW1UeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlLT5iYXNlVHlwZSk7CgkJaWYgKGJhc2VJdGVtVHlwZSA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkJInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246ICIKCQkJIkxpc3Qgc2ltcGxlIHR5cGUgJyVzJzogRmFpbGVkIHRvICIKCQkJImV2YWx1YXRlIHRoZSBpdGVtIHR5cGUgb2YgaXRzIGJhc2UgdHlwZSAnJXMnLlxuIiwKCQkJdHlwZS0+bmFtZSwgdHlwZS0+YmFzZVR5cGUtPm5hbWUpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJaWYgKChpdGVtVHlwZSAhPSBiYXNlSXRlbVR5cGUpICYmCgkJICAgICh4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKGN0eHQtPnNjaGVtYSwgaXRlbVR5cGUsCgkJICAgIGJhc2VJdGVtVHlwZSwgMCkgIT0gMCkpIHsKCQkgICAgeG1sQ2hhciAqc3RyQklUID0gTlVMTCwgKnN0ckJUID0gTlVMTDsKCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzMsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCQoJCQkiVGhlIGl0ZW0gdHlwZSAlcyBpcyBub3QgdmFsaWRseSBkZXJpdmVkIGZyb20gdGhlICIKCQkJIml0ZW0gdHlwZSAlcyBvZiB0aGUgYmFzZSB0eXBlICVzIiwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyLCBOVUxMLCBpdGVtVHlwZSwgTlVMTCwgMSksCgkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJJVCwgTlVMTCwgYmFzZUl0ZW1UeXBlLCBOVUxMLCAxKSwKCQkJeG1sU2NoZW1hRm9ybWF0SXRlbUZvclJlcG9ydCgmc3RyQlQsIE5VTEwsIHR5cGUtPmJhc2VUeXBlLCBOVUxMLCAxKSk7CgoJCSAgICBGUkVFX0FORF9OVUxMKHN0cikKCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCSVQpCgkJICAgIEZSRUVfQU5EX05VTEwoc3RyQlQpCQkgICAgCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8zKTsKCQl9CgkgICAgfQoJICAgIAoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgkJLyogCgkJKiAyLjMuMi40IE9ubHkgbGVuZ3RoLCBtaW5MZW5ndGgsIG1heExlbmd0aCwgd2hpdGVTcGFjZSwgcGF0dGVybiAKCQkqIGFuZCBlbnVtZXJhdGlvbiBmYWNldCBjb21wb25lbnRzIGFyZSBhbGxvd2VkIGFtb25nIHRoZSB7ZmFjZXRzfS4KCQkqLwoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkJICAgIC8qCgkJCSAgICAqIFRPRE86IDIuNS4xLjIgTGlzdCBkYXRhdHlwZXMKCQkJICAgICogVGhlIHZhbHVlIG9mILd3aGl0ZVNwYWNltyBpcyBmaXhlZCB0byB0aGUgdmFsdWUgY29sbGFwc2UuIAoJCQkgICAgKi8KCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQkJICAgIGJyZWFrOwoJCQlkZWZhdWx0OiB7CgkJCSAgICB4bWxTY2hlbWFQSWxsZWdhbEZhY2V0TGlzdFVuaW9uRXJyKGN0eHQsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzQsCgkJCQlOVUxMLCB0eXBlLCBmYWNldCk7CgkJCSAgICAvKgoJCQkgICAgKiBXZSBjb3VsZCByZXR1cm4sIGJ1dCBpdCdzIG5pY2VyIHRvIHJlcG9ydCBhbGwgCgkJCSAgICAqIGludmFsaWQgZmFjZXRzLgoJCQkgICAgKi8KCQkJICAgIG9rID0gMDsJCQkgICAgCgkJCX0KCQkgICAgfQkJICAgIAoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJCWlmIChvayA9PSAwKQoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfNCk7CgkJLyoKCQkqIFRPRE86IDIuMy4yLjUgRm9yIGVhY2ggZmFjZXQgaW4gdGhlIHtmYWNldHN9IChjYWxsIHRoaXMgREYpLCBpZiB0aGVyZQoJCSogaXMgYSBmYWNldCBvZiB0aGUgc2FtZSBraW5kIGluIHRoZSB7ZmFjZXRzfSBvZiB0aGUge2Jhc2UgdHlwZSAKCQkqIGRlZmluaXRpb259IChjYWxsIHRoaXMgQkYpLHRoZW4gdGhlIERGJ3Mge3ZhbHVlfSBtdXN0IGJlIGEgdmFsaWQgCgkJKiByZXN0cmljdGlvbiBvZiBCRidzIHt2YWx1ZX0gYXMgZGVmaW5lZCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCgkJKi8KCSAgICB9CSAgICAKCSAgICAKCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7CgkvKgoJKiAzLjEgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBhbGwgaGF2ZSB7dmFyaWV0eX0gb2YgCgkqIGF0b21pYyBvciBsaXN0LgoJKi8KCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlcjsKCgltZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJICAgIGlmICgoKG1lbWJlci0+dHlwZS0+ZmxhZ3MgJiAKCQlYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSA9PSAwKSAmJiAKCQkoKG1lbWJlci0+dHlwZS0+ZmxhZ3MgJiAKCQlYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgPT0gMCkpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18xLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCSAgICAiVGhlIG1lbWJlciB0eXBlICVzIGlzIG5laXRoZXIgYW4gYXRvbWljLCBub3IgYSBsaXN0IHR5cGUiLAoJCSAgICB4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHIsIE5VTEwsIG1lbWJlci0+dHlwZSwgTlVMTCwgMSkpOwoJCUZSRUVfQU5EX05VTEwoc3RyKQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEpOwoJICAgIH0KCSAgICBtZW1iZXIgPSBtZW1iZXItPm5leHQ7Cgl9CgkvKgoJKiAzLjMuMSBJZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBpcyB0aGUgt3NpbXBsZSB1ci10eXBlIAoJKiBkZWZpbml0aW9utyAKCSovCglpZiAodHlwZS0+YmFzZVR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpIHsKCSAgICAvKgoJICAgICogMy4zLjEuMSBBbGwgb2YgdGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gbXVzdCBoYXZlIGEgCgkgICAgKiB7ZmluYWx9IHdoaWNoIGRvZXMgbm90IGNvbnRhaW4gdW5pb24uCgkgICAgKi8KCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQlpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCBtZW1iZXItPnR5cGUsIAoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OKSkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzEsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJUaGUgZmluYWwgb2YgbWVtYmVyIHR5cGUgJXMgY29udGFpbnMgJ3VuaW9uJyIsCgkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSk7CgkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQkJICAgCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMSk7CgkJfQoJCW1lbWJlciA9IG1lbWJlci0+bmV4dDsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4xLjIgVGhlIHtmYWNldHN9IG11c3QgYmUgZW1wdHkuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMV8yLAoJCSAgICBOVUxMLCB0eXBlLCBOVUxMLCAKCQkgICAgIk5vIGZhY2V0cyBhbGxvd2VkIiwgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIpOwoJICAgIH0KCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIDMuMy4yLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIHVuaW9uLgoJICAgICovCgkgICAgaWYgKCh0eXBlLT5iYXNlVHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pID09IDApIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBiYXNlIHR5cGUgJXMgaXMgbm90IGEgdW5pb24gdHlwZSIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiAzLjMuMi4yIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoY3R4dC0+c2NoZW1hLCB0eXBlLT5iYXNlVHlwZSwgCgkJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMiwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBmaW5hbCBvZiBpdHMgYmFzZSB0eXBlICVzIG11c3Qgbm90IGNvbnRhaW4gJ3Jlc3RyaWN0aW9uJyIsCgkJICAgIHhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQlGUkVFX0FORF9OVUxMKHN0cikJCQoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjMgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLCBtdXN0IGJlIHZhbGlkbHkgCgkgICAgKiBkZXJpdmVkIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBkZWZpbml0aW9ucyBpbiB0aGUge2Jhc2UgCgkgICAgKiB0eXBlIGRlZmluaXRpb259J3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgZW1wdHkgc2V0LCAKCSAgICAqIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlTGlua1B0ciBiYXNlTWVtYmVyOwoKCQkvKgoJCSogT1BUSU1JWkU6IGlmIHRoZSB0eXBlIGlzIHJlc3RyaWN0aW5nLCBpdCBoYXMgbm8gbG9jYWwgZGVmaW5lZCAKCQkqIG1lbWJlciB0eXBlcyBhbmQgaW5oZXJpdHMgdGhlIG1lbWJlciB0eXBlcyBvZiB0aGUgYmFzZSB0eXBlOyAKCQkqIHRodXMgYSBjaGVjayBmb3IgZXF1YWxpdHkgY2FuIGJlIHNraXBwZWQuCgkJKi8KCQkvKgoJCSogRXZlbiB3b3JzZTogSSBjYW5ub3Qgc2VlIGEgc2NlbmFyaW8gd2hlcmUgYSByZXN0cmljdGluZwoJCSogdW5pb24gc2ltcGxlIHR5cGUgY2FuIGhhdmUgb3RoZXIgbWVtYmVyIHR5cGVzIGFzIHRoZSBtZW1iZXIgCgkJKiB0eXBlcyBvZiBpdCdzIGJhc2UgdHlwZS4gVGhpcyBjaGVjayBzZWVtcyBub3QgbmVjZXNzYXJ5IHdpdGgKCQkqIHJlc3BlY3QgdG8gdGhlIGRlcml2YXRpb24gcHJvY2VzcyBpbiBsaWJ4bWwyLgoJCSogQnV0IG5lY2Vzc2FyeSBpZiBjb25zdHJ1Y3RpbmcgdHlwZXMgd2l0aCBhbiBBUEkuCgkJKi8KCQlpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkgewoJCSAgICBtZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCQkgICAgYmFzZU1lbWJlciA9IHhtbFNjaGVtYUdldFVuaW9uU2ltcGxlVHlwZU1lbWJlclR5cGVzKHR5cGUtPmJhc2VUeXBlKTsKCQkgICAgaWYgKChtZW1iZXIgPT0gTlVMTCkgJiYgKGJhc2VNZW1iZXIgIT0gTlVMTCkpIHsJCSAgIAoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogIgoJCQkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb24gIgoJCQkgICAgIigzLjMuMi4zKSwgdW5pb24gc2ltcGxlIHR5cGUgJyVzJywgdW5lcXVhbCBudW1iZXIgIgoJCQkgICAgIm9mIG1lbWJlciB0eXBlcyBpbiB0aGUgYmFzZSB0eXBlXG4iLAoJCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIH0JCQoJCSAgICB3aGlsZSAobWVtYmVyICE9IE5VTEwpIHsKCQkJaWYgKGJhc2VNZW1iZXIgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCQkiSW50ZXJuYWwgZXJyb3I6ICIKCQkJCSJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uICIKCQkJCSIoMy4zLjIuMyksIHVuaW9uIHNpbXBsZSB0eXBlICclcycsIHVuZXF1YWwgbnVtYmVyICIKCQkJCSJvZiBtZW1iZXIgdHlwZXMgaW4gdGhlIGJhc2UgdHlwZS5cbiIsCgkJCQl0eXBlLT5uYW1lLCBOVUxMKTsKCQkJfQoJCQlpZiAoKG1lbWJlci0+dHlwZSAhPSBiYXNlTWVtYmVyLT50eXBlKSAmJgoJCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soY3R4dC0+c2NoZW1hLCAKCQkJICAgIG1lbWJlci0+dHlwZSwgYmFzZU1lbWJlci0+dHlwZSwgMCkgIT0gMCkpIHsKCQkJICAgIHhtbENoYXIgKnN0ckJNVCA9IE5VTEwsICpzdHJCVCA9IE5VTEw7CgoJCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVyckV4dChjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8zLAoJCQkJTlVMTCwgdHlwZSwgTlVMTCwKCQkJCSJUaGUgbWVtYmVyIHR5cGUgJXMgaXMgbm90IHZhbGlkbHkgZGVyaXZlZCBmcm9tIGl0cyAiCgkJCQkiY29ycmVzcG9uZGluZyBtZW1iZXIgdHlwZSAlcyBvZiB0aGUgYmFzZSB0eXBlICVzIiwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ciwgTlVMTCwgbWVtYmVyLT50eXBlLCBOVUxMLCAxKSwKCQkJCXhtbFNjaGVtYUZvcm1hdEl0ZW1Gb3JSZXBvcnQoJnN0ckJNVCwgTlVMTCwgYmFzZU1lbWJlci0+dHlwZSwgTlVMTCwgMSksCgkJCQl4bWxTY2hlbWFGb3JtYXRJdGVtRm9yUmVwb3J0KCZzdHJCVCwgTlVMTCwgdHlwZS0+YmFzZVR5cGUsIE5VTEwsIDEpKTsKCQkJICAgIEZSRUVfQU5EX05VTEwoc3RyKQoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHJCTVQpCgkJCSAgICBGUkVFX0FORF9OVUxMKHN0ckJUKQoJCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzMpOwoJCQl9CQkKCQkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJCQliYXNlTWVtYmVyID0gYmFzZU1lbWJlci0+bmV4dDsKCQkgICAgfQoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjQgT25seSBwYXR0ZXJuIGFuZCBlbnVtZXJhdGlvbiBmYWNldCBjb21wb25lbnRzIGFyZSAKCSAgICAqIGFsbG93ZWQgYW1vbmcgdGhlIHtmYWNldHN9LgoJICAgICovCSAgICAKCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQl4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCQlpbnQgb2sgPSAxOwoKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmICgoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOKSAmJgoJCQkoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsKCQkJeG1sU2NoZW1hUElsbGVnYWxGYWNldExpc3RVbmlvbkVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80LAoJCQkJTlVMTCwgdHlwZSwgZmFjZXQpOwkJCQoJCQlvayA9IDA7CQkJICAgIAoJCSAgICB9CQkgICAgCgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl80KTsKCQkgICAgCgkgICAgfQoJICAgIC8qCgkgICAgKiBUT0RPOiAzLjMuMi41IChmYWNldCBkZXJpdmF0aW9uKQoJICAgICovCgl9CiAgICB9CgogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZToKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24KICoKICogQ2hlY2tzIGNyYy1zaW1wbGUtdHlwZSBjb25zdHJhaW50cy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLAogKiBpZiBub3QgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIGFuZCAtMSBvbiBpbnRlcm5hbAogKiBlcnJvcnMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAKICAgIC8qCiAgICAqIE5PVEU6IHNyYy1zaW1wbGUtdHlwZSAyLTQgYXJlIHJlZHVuZGFudCwgc2luY2UgdGhlIGNoZWNrcwogICAgKiB3ZXJlIGFyZSBkb25lIGZvciB0aGUgY29ycmVzcG9uZGluZyA8cmVzdHJpY3Rpb24+LCA8bGlzdD4gYW5kIDx1bmlvbj4KICAgICogZWxlbWVudHMsIGJ1dCBXM0Mgd2FudHMgYSA8c2ltcGxlVHlwZT4gZXJyb3IgYXMgd2VsbCwgc28gaXQgZ2V0cyBvbmUuCiAgICAqIE1hYnkgdGhpcyBjYW4gYmUgc2tpcHBlZCBpbiB0aGUgZnV0dXJlLCBpZiB3ZSBnZXQgc3VyZSBpdCdzIG5vdCBuZWVkZWQuCiAgICAqLwogICAgaWYgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZSwgIgoJCSJubyBzdWJ0eXBlIG9uIHNpbXBsZSB0eXBlICclcycuXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKiAKICAgICogc3JjLXNpbXBsZS10eXBlLjEgVGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgaWYgYW55LAogICAgKiBtdXN0IHNhdGlzZnkgdGhlIGNvbmRpdGlvbnMgc2V0IG91dCBpbiBDb25zdHJhaW50cyBvbiBTaW1wbGUgVHlwZSAKICAgICogRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50cyAopzMuMTQuNikuICAgIAogICAgKi8KICAgIGlmICgoeG1sU2NoZW1hQ2hlY2tTVFByb3BzQ29ycmVjdChjdHh0LCB0eXBlKSAhPSAwKSB8fAoJKHhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoY3R4dCwgdHlwZSkgIT0gMCkpIHsKCS8qCgkqIFRPRE86IFJlbW92ZWQgdGhpcywgc2luY2UgaXQgZ290IGFubm95aW5nIHRvIGdldCBhbgoJKiBleHRyYSBlcnJvciByZXBvcnQsIGlmIGFueXRoaW5nIGZhaWxlZCB1bnRpbCBub3cuCgkqIEVuYWJsZSB0aGlzIGlmIG5lZWRlZC4KCSovCgkvKgoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xLAoJICAgICJTaW1wbGUgdHlwZSAnJXMnIGRvZXMgbm90IHNhdGlzZnkgdGhlIGNvbnN0cmFpbnRzICIKCSAgICAib24gc2ltcGxlIHR5cGUgZGVmaW5pdGlvbnMuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJKi8KCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEpOwogICAgfQoKICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT04pIHsKCS8qCgkqIHNyYy1zaW1wbGUtdHlwZS4yIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgCgkqIGVpdGhlciBpdCBtdXN0IGhhdmUgYSBiYXNlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyAKCSogW2NoaWxkcmVuXSwgYnV0IG5vdCBib3RoLgoJKi8JCgkvKgoJKiBYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMgoJKiBOT1RFOiBUaGlzIHdhcyByZW1vdmVkLCBzaW5jZSB0aGlzIHdpbGwgYmUgYWxyZWFkeSBoYW5kbGVkCgkqIGluIHRoZSBwYXJzZSBmdW5jdGlvbiBmb3IgPHJlc3RyaWN0aW9uPi4gCgkqLwkKICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0xJU1QpIHsKCS8qIHNyYy1zaW1wbGUtdHlwZS4zIElmIHRoZSA8bGlzdD4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCBlaXRoZXIgaXQgbXVzdCBoYXZlIAoJKiBhbiBpdGVtVHlwZSBbYXR0cmlidXRlXSBvciBhIDxzaW1wbGVUeXBlPiBhbW9uZyBpdHMgW2NoaWxkcmVuXSwgCgkqIGJ1dCBub3QgYm90aC4KCSogTk9URTogYmFzZVR5cGUgaXMgc2V0IHRvIHRoZSBsb2NhbCBzaW1wbGUgdHlwZSBkZWZpbml0b24sCgkqIGlmIGV4aXN0ZW50LCBhdCBwYXJzZSB0aW1lLiBUaGlzIGlzIGEgaGFjayBhbmQgbm90IG5pY2UuCgkqLwoJLyoKCSogVE9ETzogUmVtb3ZlIHRoaXMsIGFuZCBhZGQgdGhlIGNoZWNrIHRvIHRoZSBwYXJzZSBmdW5jdGlvbiBvZiA8bGlzdD4uCgkqLwoJaWYgKCgodHlwZS0+c3VidHlwZXMtPmJhc2UgPT0gTlVMTCkgJiYgCgkgICAgICh0eXBlLT5iYXNlVHlwZSA9PSBOVUxMKSkgfHwJICAgICAgCgkgICAgKCh0eXBlLT5zdWJ0eXBlcy0+YmFzZSAhPSBOVUxMKSAmJgoJICAgICAodHlwZS0+c3VidHlwZXMtPmJhc2VUeXBlICE9IE5VTEwpKSkgewoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzMsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiRWl0aGVyIHRoZSBhdHRyaWJ1dGUgJ2l0ZW1UeXBlJyBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCQkibXVzdCBiZSBwcmVzZW50IG9uIHRoZSA8bGlzdD4gY2hpbGQgIiwgTlVMTCk7CSAgICAKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8zKTsKCX0KICAgIAoKICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBtZW1iZXI7Cgl4bWxTY2hlbWFUeXBlUHRyIGFuY2VzdG9yLCBhbnlTaW1wbGVUeXBlOwoKCWFueVNpbXBsZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCgkvKiBzcmMtc2ltcGxlLXR5cGUuNCBDaXJjdWxhciB1bmlvbiB0eXBlIGRlZmluaXRpb24gaXMgZGlzYWxsb3dlZC4gVGhhdCBpcywgaWYgCgkqIHRoZSA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlcmUgbXVzdCBub3QgYmUgYW55IGVudHJpZXMgCgkqIGluIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSBhdCBhbnkgZGVwdGggd2hpY2ggcmVzb2x2ZSB0byB0aGUgCgkqIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSA8c2ltcGxlVHlwZT4uCgkqLwkKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgYW5jZXN0b3IgPSBtZW1iZXItPnR5cGU7CgkgICAgd2hpbGUgKChhbmNlc3RvciAhPSBOVUxMKSAmJiAoYW5jZXN0b3ItPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkgewoJCWlmIChhbmNlc3Rvci0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChhbmNlc3RvciwgY3R4dCwgIE5VTEwpOwoJCWlmIChhbmNlc3RvciA9PSBhbnlTaW1wbGVUeXBlKQoJCSAgICBicmVhazsKCQllbHNlIGlmIChhbmNlc3RvciA9PSB0eXBlKSB7CgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80LAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiVGhlIGRlZmluaXRpb24gaXMgY2lyY3VsYXIiLCBOVUxMKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfNCk7CgkJfSBlbHNlIGlmIChhbmNlc3Rvci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJCSAgICAvKgoJCSAgICAqIFRPRE8sIEZJWE1FOiBBbHRob3VnaCBhIGxpc3Qgc2ltcGxlIHR5cGUgbXVzdCBub3QgaGF2ZSBhIHVuaW9uIFNUCgkJICAgICogdHlwZSBhcyBpdGVtIHR5cGUsIHdoaWNoIGluIHR1cm4gaGFzIGEgbGlzdCBTVCBhcyBtZW1iZXIgCgkJICAgICogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhpcyBoZXJlIGFzIHdlbGwsIHNpbmNlIHRoaXMgY2hlY2sgCgkJICAgICogd2FzIG5vdCB5ZXQgcGVyZm9ybWVkLgoJCSAgICAqLwoKCQl9CgkJYW5jZXN0b3IgPSBhbmNlc3Rvci0+YmFzZVR5cGU7CgkgICAgfSAgIAoJICAgIG1lbWJlciA9IG1lbWJlci0+bmV4dDsKCX0KICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgojaWYgMCAvKiBOb3QgeWV0IHVzZWQgY29kZSBmb3IgQ1Qgc2NoZW1hIHZhbGlkYXRpb24gKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ1NpbXBsZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSAgICBjb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCSAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICBpbnQgZmlyZUVycm9ycykKewogICAgaW50IHJldDsKICAgIC8qCiAgICAqIDMuMTQuNCBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIFZhbGlkYXRpb24gUnVsZXMKICAgICogVmFsaWRhdGlvbiBSdWxlOiBTdHJpbmcgVmFsaWQKICAgICovCiAgICAvKgogICAgKiAxIEl0IGlzIHNjaGVtYS12YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhhdCBkZWZpbml0aW9uIGFzIGRlZmluZWQgCiAgICAqIGJ5IERhdGF0eXBlIFZhbGlkIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgCglmaXJlRXJyb3JzLCAxLCAxLCAxKTsKICAgIHJldHVybiAocmV0KTsKICAgIC8qCiAgICAqIDIuMSBJZiBUaGUgZGVmaW5pdGlvbiBpcyBFTlRJVFkgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRZIGdpdmVuIAogICAgKiB0aGUgZW1wdHkgc2V0LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoU2ltcGxlKSAopzMuMTQuNiksIHRoZW4KICAgICogdGhlIHN0cmluZyBtdXN0IGJlIGEgt2RlY2xhcmVkIGVudGl0eSBuYW1lty4KICAgICovCiAgICAvKgogICAgKiAyLjIgSWYgVGhlIGRlZmluaXRpb24gaXMgRU5USVRJRVMgb3IgaXMgdmFsaWRseSBkZXJpdmVkIGZyb20gRU5USVRJRVMgCiAgICAqIGdpdmVuIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSwgCiAgICAqIHRoZW4gZXZlcnkgd2hpdGVzcGFjZS1kZWxpbWl0ZWQgc3Vic3RyaW5nIG9mIHRoZSBzdHJpbmcgbXVzdCBiZSBhILdkZWNsYXJlZCAKICAgICogZW50aXR5IG5hbWW3LgogICAgKi8KICAgIC8qCiAgICAqIDIuMyBvdGhlcndpc2Ugbm8gZnVydGhlciBjb25kaXRpb24gYXBwbGllcy4KICAgICovCgogICAgcmV0dXJuICgwKTsKfQojZW5kaWYKCgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CiAgICAgICAgdmN0eHQtPnBjdHh0ID14bWxTY2hlbWFOZXdQYXJzZXJDdHh0VXNlRGljdCgiKiIsIHZjdHh0LT5zY2hlbWEtPmRpY3QpOwoJLyogdmN0eHQtPnBjdHh0ID0geG1sU2NoZW1hTmV3UGFyc2VyQ3R4dCgiKiIpOyAqLwoJaWYgKHZjdHh0LT5wY3R4dCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycih2Y3R4dCwgTlVMTCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNyZWF0ZVBDdHh0T25WQ3R4dCwgIgoJCSJmYWlsZWQgdG8gY3JlYXRlIGEgdGVtcC4gcGFyc2VyIGNvbnRleHQuXG4iLAoJCU5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyogVE9ETzogUGFzcyB1c2VyIGRhdGEuICovCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnModmN0eHQtPnBjdHh0LCB2Y3R4dC0+ZXJyb3IsIHZjdHh0LT53YXJuaW5nLCBOVUxMKTsJCiAgICB9CiAgICByZXR1cm4gKDApOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCWN0eHQtPnZjdHh0ID0geG1sU2NoZW1hTmV3VmFsaWRDdHh0KE5VTEwpOwoJaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDcmVhdGVQQ3R4dE9uVkN0eHQsICIKCQkiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKiBUT0RPOiBQYXNzIHVzZXIgZGF0YS4gKi8KCXhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKGN0eHQtPnZjdHh0LCBjdHh0LT5lcnJvciwgY3R4dC0+d2FybmluZywgTlVMTCk7CQogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKiBAdmFsdWU6IHRoZSBkZWZhdWx0IHZhbHVlCiAqIEB2YWw6IHRoZSBwcmVjb21wdXRlZCB2YWx1ZSB0byBiZSByZXR1cm5lZAogKiBAbm9kZTogYW4gb3B0aW9uYWwgbm9kZSAodGhlIGhvbGRlciBvZiB0aGUgdmFsdWUpCiAqCiAqIENoZWNrcyB0aGUgImNvcy12YWxpZC1kZWZhdWx0IiBjb25zdHJhaW50cy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBjb25zdHJhaW50cyBhcmUgc2F0aXNmaWVkLAogKiBpZiBub3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBhbmQgLTEgb24gaW50ZXJuYWwKICogZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHBjdHh0LAoJCQkgICAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgICAgIHhtbE5vZGVQdHIgbm9kZSkKeyAgIAogICAgaW50IHJldCA9IDA7CgogICAgLyoKICAgICogY29zLXZhbGlkLWRlZmF1bHQ6CiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogRWxlbWVudCBEZWZhdWx0IFZhbGlkIChJbW1lZGlhdGUpCiAgICAqIEZvciBhIHN0cmluZyB0byBiZSBhIHZhbGlkIGRlZmF1bHQgd2l0aCByZXNwZWN0IHRvIGEgdHlwZSAKICAgICogZGVmaW5pdGlvbiB0aGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICAvKgogICAgKiBOT1RFOiBUaGlzIGhhcyB0byB3b3JrIHdpdGhvdXQgYSBnaXZlbiBub2RlICh0aGUgaG9sZGVyIG9mIHRoZQogICAgKiB2YWx1ZSksIHNpbmNlIGl0IHNob3VsZCB3b3JrIG9uIHRoZSBjb21wb25lbnQsIGkuZS4gYW4gdW5kZXJseWluZwogICAgKiBET00gbXVzdCBub3QgYmUgbWFuZGF0b3J5LgogICAgKi8gICAgIAogICAgaWYgKChwY3R4dCA9PSBOVUxMKSB8fCAodmN0eHQgPT0gTlVMTCkpIHsKCXhtbFNjaGVtYVBFcnIocGN0eHQsIG5vZGUsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdCwgIgoJICAgICJiYWQgYXJndW1lbnRzOiB0aGUgcGFyc2VyIGFuZC9vciB2YWxpZGF0aW9uIGNvbnRleHQgaXMgIgoJICAgICJtaXNzaW5nLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwkKICAgIH0gICAgICAgCiAgICBpZiBJU19DT01QTEVYX1RZUEUodHlwZSkgewoJLyoKCSogQ29tcGxleCB0eXBlLgoJKgoJKiAyLjEgaXRzIHtjb250ZW50IHR5cGV9IG11c3QgYmUgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG9yIG1peGVkLgoJKi8KCS8qIAoJKiBUT0RPOiBBZGp1c3QgdGhpcyB3aGVuIHRoZSBjb250ZW50IHR5cGUgd2lsbCBiZSBjb21wdXRlZCAKCSogY29ycmVjdGx5LiAKCSovCglpZiAoKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEUpICYmCgkgICAgKHR5cGUtPmNvbnRlbnRUeXBlICE9IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykgJiYKCSAgICAodHlwZS0+Y29udGVudFR5cGUgIT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSkgewoJICAgIHhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKHBjdHh0LCAKCQlYTUxfU0NIRU1BUF9DT1NfVkFMSURfREVGQVVMVF8yXzEsCgkJTlVMTCwgTlVMTCwgbm9kZSwKCQl0eXBlLCBOVUxMLCBOVUxMLAoJCSJJZiB0aGUgdHlwZSBvZiBhIGNvbnN0cmFpbnQgdmFsdWUgaXMgY29tcGxleCwgaXRzIGNvbnRlbnQgIgoJCSJ0eXBlIG11c3QgYmUgbWl4ZWQgb3IgYSBzaW1wbGUgdHlwZSIsCgkJTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFQX0NPU19WQUxJRF9ERUZBVUxUXzJfMSk7Cgl9CglpZiAodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkgICAgLyoKCSAgICAqIDIuMi4yIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBtaXhlZCwgdGhlbiB0aGUge2NvbnRlbnQgdHlwZX0ncyAKCSAgICAqIHBhcnRpY2xlIG11c3QgYmUgt2VtcHRpYWJsZbcgYXMgZGVmaW5lZCBieSBQYXJ0aWNsZSBFbXB0aWFibGUgCgkgICAgKiAopzMuOS42KS4KCSAgICAqLwoJICAgIAoJICAgIC8qCgkgICAgKiBVUkdFTlQgVE9ETzogSW1wbGVtZW50IHRoaXMuCgkgICAgKi8KCSAgICByZXR1cm4gKDApOwoJfQogICAgfQkKICAgIC8qCiAgICAqIDEgSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIHN0cmluZyAKICAgICogbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcgCiAgICAqIFZhbGlkICinMy4xNC40KS4KICAgICoKICAgICogQU5ECiAgICAqCiAgICAqIDIuMi4xIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIHRoZW4gdGhlIAogICAgKiBzdHJpbmcgbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gCiAgICAqIGFzIGRlZmluZWQgYnkgU3RyaW5nIFZhbGlkICinMy4xNC40KS4KICAgICovICAgIAogICAgdmN0eHQtPm5vZGUgPSBub2RlOwogICAgdmN0eHQtPmN1ciA9IE5VTEw7CiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh2Y3R4dCwgdHlwZSwgdmFsdWUsIDEsIDEsIDEsIDApOwogICAgLyogcmV0ID0geG1sU2NoZW1hQ2hlY2tDVkNTaW1wbGVUeXBlKHZjdHh0LCBlbGVtRGVjbC0+dmFsdWUsIHR5cGVEZWYsIDApOyAqLyAgIAogICAgaWYgKHJldCA8IDApIHsKCXhtbFNjaGVtYVBFcnIocGN0eHQsIG5vZGUsCgkvKiBOT1ROSUNFOiBlcnJvciBjb2RlOiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCBkdXJpbmcKCSogc2NoZW1hIGNvbnN0cnVjdGlvbiBhbmQgeHNpOnR5cGUgdmFsaWRhdGlvbi4KCSovCglYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tDT1NWYWxpZERlZmF1bHQsICIKCSJ3aGlsZSB2YWxpZGF0aW5nIGEgdmFsdWUgY29uc3RhaW50IHZhbHVlLlxuIiwKCU5VTEwsIE5VTEwpOwoKICAgIH0gICAgIAkgICAgCiAgICByZXR1cm4gKHJldCk7Cn0KCiNpZiAwIC8qIE5vdCB5ZXQgdXNlZCBjb2RlIGZvciBDVCBzY2hlbWEgdmFsaWRhdGlvbiAqLwovKioKICogeG1sU2NoZW1hR2V0U1RDb250ZW50T2ZDVDoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqCiAqCiAqIFJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgc2ltcGxlIHR5cGUgZm9yIHRoZSBjb250ZW50IG9mCiAqIHRoZSBjb21wbGV4IHR5cGUuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRTVENvbnRlbnRPZkNUKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9yaWcgPSB0eXBlLCBhbnlUeXBlOwoKICAgIGFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIHdoaWxlICgodHlwZSAhPSBOVUxMKSAmJiAodHlwZSAhPSBhbnlUeXBlKSAmJiAKCSh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSkgewoJaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkKCSAgICByZXR1cm4odHlwZSk7Cgl0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CiAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCglYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCU5VTEwsIG9yaWcsIE5VTEwsCgkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldFNUQ29udGVudFR5cGVPZkNULCAiCgkibm8gc2ltcGxlIHR5cGUgZm9yIHRoZSBjb250ZW50IG9mIGNvbXBsZXggdHlwZSAnJXMnIGNvdWxkIGJlICIKCSJjb21wdXRlZCIsIG9yaWctPm5hbWUpOwogICAgcmV0dXJuIChOVUxMKTsKfQoKCgoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICoKICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgY29uc3RyYWludHMgYXJlIHNhdGlzZmllZCwgYSBwb3NpdGl2ZQogKiBlcnJvciBjb2RlIGlmIG5vdCBhbmQgLTEgaWYgYW4gaW50ZXJuYWwgZXJyb3Igb2NjdXJlZC4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tDT1NDVEV4dGVuZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKICAgIC8qIAogICAgKiAxIElmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24sIAogICAgKiB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQ09TQ1RFeHRlbmRzLCAiCgkgICAgInRoZSBjb21wbGV4IHR5cGUgJyVzJyBoYXMgbm8gYmFzZSB0eXBlIiwgdHlwZS0+bmFtZSk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChiYXNlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7CgkvKgoJKiAxLjEgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgCgkqIGNvbnRhaW4gZXh0ZW5zaW9uLgoJKi8KCWlmIChiYXNlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfRVhURU5TSU9OKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSwKCQlOVUxMLCB0eXBlLCBOVUxMLAoJCSJUaGUgJ2ZpbmFsJyBvZiB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24gIgoJCSJjb250YWlucyBleHRlbnNpb24iLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMSk7Cgl9CgkvKgoJKiAxLjIgSXRzIHthdHRyaWJ1dGUgdXNlc30gbXVzdCBiZSBhIHN1YnNldCBvZiB0aGUge2F0dHJpYnV0ZSB1c2VzfSAKCSogb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZiwgdGhhdCBpcywgZm9yIGV2ZXJ5IGF0dHJpYnV0ZSAKCSogdXNlIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LCB0aGVyZSAKCSogbXVzdCBiZSBhbiBhdHRyaWJ1dGUgdXNlIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG9mIHRoZSBjb21wbGV4IAoJKiB0eXBlIGRlZmluaXRpb24gaXRzZWxmIHdob3NlIHthdHRyaWJ1dGUgZGVjbGFyYXRpb259IGhhcyB0aGUgc2FtZSAKCSoge25hbWV9LCB7dGFyZ2V0IG5hbWVzcGFjZX0gYW5kIHt0eXBlIGRlZmluaXRpb259IGFzIGl0cyBhdHRyaWJ1dGUgCgkqIGRlY2xhcmF0aW9uCgkqCgkqIE5PVEU6IFRoaXMgd2lsbCBiZSBhbHJlYWR5IHNhdGlzZmllZCBieSB0aGUgd2F5IHRoZSBhdHRyaWJ1dGUgdXNlcwoJKiBhcmUgZXh0ZW5kZWQgaW4geG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOyB0aHVzIHRoaXMgY2hlY2sKCSogaXMgbm90IG5lZWRlZC4KCSovCgoJLyoKCSogMS4zIElmIGl0IGhhcyBhbiB7YXR0cmlidXRlIHdpbGRjYXJkfSwgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIAoJKiBtdXN0IGFsc28gaGF2ZSBvbmUsIGFuZCB0aGUgYmFzZSB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIAoJKiB3aWxkY2FyZH0ncyB7bmFtZXNwYWNlIGNvbnN0cmFpbnR9IG11c3QgYmUgYSBzdWJzZXQgb2YgdGhlIGNvbXBsZXggCgkqIHR5cGUgZGVmaW5pdGlvbidzIHthdHRyaWJ1dGUgd2lsZGNhcmR9J3Mge25hbWVzcGFjZSBjb25zdHJhaW50fSwgCgkqIGFzIGRlZmluZWQgYnkgV2lsZGNhcmQgU3Vic2V0ICinMy4xMC42KS4KCSoKCSogVGhpcyBpcyBhbHJlYWR5IGNoZWNrZWQgaW4geG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uOyB0aHVzIAoJKiB0aGlzIGNoZWNrIGlzIG5vdCBuZWVkZWQuCgkqLwoJCgkvKgoJKiAxLjQgT25lIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKgoJKiAxLjQuMSBUaGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gYW5kIHRoZSAKCSoge2NvbnRlbnQgdHlwZX0gb2YgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGl0c2VsZiBtdXN0IGJlIHRoZSBzYW1lIAoJKiBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCgkqLwoKCgkKICAgIH0gZWxzZSB7CgkvKgoJKiAyIElmIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIGEgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbiwgCgkqIHRoZW4gYWxsIG9mIHRoZSBmb2xsb3dpbmcgbXVzdCBiZSB0cnVlOgoJKi8KCS8qCgkqIDIuMSBUaGUge2NvbnRlbnQgdHlwZX0gbXVzdCBiZSB0aGUgc2FtZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLgoJKi8KCS8qCgkqIDIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIAoJKiBleHRlbnNpb24KCSovCiAgICB9Cgp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrU1JDQ1QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UsIGNvbnRlbnQ7CiAgICBpbnQgT0sgPSAwOwoKICAgIC8qCiAgICAqIFRPRE86IEFkanVzdCB0aGUgZXJyb3IgY29kZXMgaGVyZSwgYXMgSSB1c2VkCiAgICAqIFhNTF9TQ0hFTUFQX1NSQ19DVF8xIG9ubHkgeWV0LgogICAgKi8KICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiAKICAgICogQ29tcGxleCBUeXBlIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sKICAgICovCiAgICBiYXNlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCBOVUxMLCB0eXBlLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tTUkNDVCwgJyVzJywgbm8gYmFzZSB0eXBlIiwgCgkgICAgdHlwZS0+bmFtZSk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIAogICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKCWlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSB7CgkgICAgaWYgSVNfQ09NUExFWF9UWVBFKGJhc2UpIHsKCQkvKgoJCSogMSBJZiB0aGUgPGNvbXBsZXhDb250ZW50PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZSB0eXBlIGRlZmluaXRpb24KCQkqILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdIAoJCSogbXVzdCBiZSBhIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uOwoJCSovCgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9TUkNfQ1RfMSwKCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkgICAgIlRoZSBiYXNlIHR5cGUgaXMgbm90IGEgY29tcGxleCB0eXBlIiwgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkgICAgfQoJfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpIHsKCgkgICAgaWYgSVNfU0lNUExFX1RZUEUoYmFzZSkgewoJCWlmICh0eXBlLT5mbGFncyAmIAoJCSAgICBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CgkJICAgIC8qIAoJCSAgICAqIDIuMS4zIG9ubHkgaWYgdGhlIDxleHRlbnNpb24+IGFsdGVybmF0aXZlIGlzIGFsc28gCgkJICAgICogY2hvc2VuLCBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24uCgkJICAgICovCgkJICAgIC8qIFRPRE86IENoYW5nZSBlcnJvciBjb2RlIHRvIC4uLl9TUkNfQ1RfMl8xXzMuICovCgkJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCU5VTEwsIHR5cGUsIE5VTEwsCgkJCSJBIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbm5vdCByZXN0cmljdCAiCgkJCSJhbiBvdGhlciBzaW1wbGUgdHlwZSIsCgkJCU5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQl9CgkJT0sgPSAxOwoKCSAgICB9IGVsc2UgeyAvKiBpZiBJU19TSU1QTEVfVFlQRShiYXNlKSAqLwoJCWlmIChiYXNlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkgewoJCSAgICAvKgoJCSAgICAqIDIuMS4yIG9ubHkgaWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgYWxzbyAKCQkgICAgKiBjaG9zZW4sIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0gCgkJICAgICogaXMgbWl4ZWQgYW5kIGEgcGFydGljbGUgZW1wdHlhYmxlLgoJCSAgICAqLwkKCQkgICAgLyoKCQkgICAgKiBGSVhNRSBUT0RPOiBDaGVjayBmb3IgKmVtcGlhYmxlIHBhcnRpY2xlKiBpcyBtaXNzaW5nLiAKCQkgICAgKi8KCQkgICAgaWYgKCh0eXBlLT5mbGFncyAmIAoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSA9PSAwKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJBIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbm5vdCAiCgkJCSAgICAiZXh0ZW5kIGFuIG90aGVyIGNvbXBsZXggdHlwZSB3aGljaCBoYXMgYSAiCgkJCSAgICAiY29udGVudCB0eXBlIG9mOiAnbWl4ZWQnIGFuZCBlbXB0aWFibGUgcGFydGljbGUiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogTk9URTogVGhpcyB3aWxsIGJlIGZpcmVkIGFzIHdlbGwsIGlmIHRoZSBiYXNlIHR5cGUKCQkgICAgKiBpcyAqJ2FueVR5cGUnKi4KCQkgICAgKiBOT1RFOiB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgd2lsbCBiZSB0aGUgCgkJICAgICogPHJlc3RyaWN0aW9uPiBpdGVtLgoJCSAgICAqLwoJCSAgICBpZiAodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpIHsKCQkJLyogWWVzLCB0aGlzIGlzIHBhcmFub2lkIHByb2dyYW1taW5nLiAqLwoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCAKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDQ1QsICIKCQkJICAgICInJXMnLCA8c2ltcGxlQ29udGVudD4gaGFzIG5vIDxyZXN0cmljdGlvbj4iLCAKCQkJICAgIHR5cGUtPm5hbWUpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCSAgICAvKgoJCSAgICAqIDIuMiBJZiBjbGF1c2UgMi4xLjIgYWJvdmUgaXMgc2F0aXNmaWVkLCB0aGVuIHRoZXJlIAoJCSAgICAqIG11c3QgYmUgYSA8c2ltcGxlVHlwZT4gYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgCgkJICAgICogPHJlc3RyaWN0aW9uPi4KCQkgICAgKi8KICAgIAkJICAgIGlmICh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPnR5cGUgIT0KCQkJWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgewoJCQkvKiBUT0RPOiBDaGFuZ2UgZXJyb3IgY29kZSB0byAuLi5fU1JDX0NUXzJfMi4gKi8KCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgPHNpbXBsZVR5cGU+IGlzIGV4cGVjdGVkIGFtb25nIHRoZSBjaGlsZHJlbiAiCgkJCSAgICAib2YgPHJlc3RyaWN0aW9uPiIsIE5VTEwpOwoJCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19DVF8xKTsKCQkgICAgfSAKCQkgICAgT0sgPSAxOwoJCX0gZWxzZSB7IC8qIGlmIChiYXNlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRCkqLwoJCSAgICAvKgoJCSAgICAqIDIuMS4xIGEgY29tcGxleCB0eXBlIGRlZmluaXRpb24gd2hvc2Uge2NvbnRlbnQgdHlwZX0gaXMgYSAKCQkgICAgKiBzaW1wbGUgdHlwZSBkZWZpbml0aW9uOwoJCSAgICAqLwoJCSAgICBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX1NSQ19DVF8xLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJBIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbm5vdCAiCgkJCSAgICAiYmUgZGVyaXZlZCBmcm9tIHRoZSBjb21wbGV4IHR5cGUgJyVzJyIsIAoJCQkgICAgYmFzZS0+bmFtZSk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfU1JDX0NUXzEpOwoJCSAgICB9CgkJICAgIGNvbnRlbnQgPSBiYXNlLT5jb250ZW50VHlwZURlZjsKCQkgICAgaWYgKGNvbnRlbnQgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLCAKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDQ1QsICIKCQkJICAgICInJXMnLCBiYXNlIHR5cGUgaGFzIG5vIGNvbnRlbnQgdHlwZSIsIAoJCQkgICAgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIGlmIChjb250ZW50LT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfU1JDX0NUXzEsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkEgY29tcGxleCB0eXBlIChzaW1wbGUgY29udGVudCkgY2Fubm90ICIKCQkJICAgICJiZSBkZXJpdmVkIGZyb20gdGhlIGNvbXBsZXggdHlwZSAnJXMnIiwgCgkJCSAgICBiYXNlLT5uYW1lKTsKCQkJcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfQ1RfMSk7CgkJICAgIH0KCQl9CgkgICAgfSAKCX0gCSAgICAJCiAgICB9CiAgICAvKgogICAgKiBUT0RPOiAzIFRoZSBjb3JyZXNwb25kaW5nIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uIGNvbXBvbmVudCBtdXN0IAogICAgKiBzYXRpc2Z5IHRoZSBjb25kaXRpb25zIHNldCBvdXQgaW4gQ29uc3RyYWludHMgb24gQ29tcGxleCBUeXBlIAogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy40LjYpOwogICAgKgogICAgKiBUT0RPOiA0IElmIGNsYXVzZSAyLjIuMSBvciBjbGF1c2UgMi4yLjIgaW4gdGhlIGNvcnJlc3BvbmRlbmNlIHNwZWNpZmljYXRpb24gCiAgICAqIGFib3ZlIGZvciB7YXR0cmlidXRlIHdpbGRjYXJkfSBpcyBzYXRpc2ZpZWQsIHRoZSBpbnRlbnNpb25hbCAKICAgICogaW50ZXJzZWN0aW9uIG11c3QgYmUgZXhwcmVzc2libGUsIGFzIGRlZmluZWQgaW4gQXR0cmlidXRlIFdpbGRjYXJkIAogICAgKiBJbnRlcnNlY3Rpb24gKKczLjEwLjYpLgogICAgKi8KCn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hR3JvdXBEZWZGaXh1cDoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyBtb2RlbCBncm91cCBkZWZpbml0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUdyb3VwRGVmRml4dXAoeG1sU2NoZW1hVHlwZVB0ciBncm91cCwKCQkgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKeyAgICAKICAgIGdyb3VwLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgIGlmICgoZ3JvdXAtPnJlZiAhPSBOVUxMKSAmJiAoZ3JvdXAtPnN1YnR5cGVzID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGdyb3VwRGVmOwoJLyoKCSogUmVzb2x2ZSB0aGUgcmVmZXJlbmNlLgoJKi8KCWdyb3VwRGVmID0geG1sU2NoZW1hR2V0R3JvdXAoY3R4dC0+c2NoZW1hLCBncm91cC0+cmVmLAoJICAgIGdyb3VwLT5yZWZOcyk7CglpZiAoZ3JvdXBEZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwgCgkJTlVMTCwgZ3JvdXAsIE5VTEwsCgkJInJlZiIsIGdyb3VwLT5yZWYsIGdyb3VwLT5yZWZOcywgCgkJWE1MX1NDSEVNQV9UWVBFX0dST1VQLCBOVUxMKTsKCSAgICByZXR1cm47Cgl9Cglncm91cC0+c3VidHlwZXMgPSBncm91cERlZjsKICAgIH0JCQp9CgojaWYgMCAvKiBFbmFibGUgd2hlbiB0aGUgY29udGVudCB0eXBlIHdpbGwgYmUgY29tcHV0ZWQuICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ29tcHV0ZUNvbnRlbnRUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UsIHJlcyA9IE5VTEw7CgogICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJICAgICJ0aGUgY29tcGxleCB0eXBlICclcycgaGFzIG5vIGJhc2UgdHlwZSIsIHR5cGUtPm5hbWUpOwoJcmV0dXJuICgtMSk7CiAgICB9ICAgCiAgICBpZiAoSVNfQU5ZVFlQRShiYXNlKSB8fCAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gCgkgICAgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkpIHsKCXhtbFNjaGVtYVR5cGVQdHIgc3RhcnQ7CgkvKgoJKiBFZmZlY3RpdmUgJ21peGVkJy4KCSovCglpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQoJICAgICB0eXBlLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKCS8qCgkqIEVmZmVjdGl2ZSBjb250ZW50LgoJKi8KCWlmIChJU19BTllUWVBFKGJhc2UpKSAKCSAgICBzdGFydCA9IHR5cGU7CgllbHNlCgkgICAgc3RhcnQgPSB0eXBlLT5zdWJ0eXBlczsKCSAKICAgIH0gZWxzZSB7IC8qIGlmIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQgKi8KCXhtbFNjaGVtYVR5cGVQdHIgYmFzZUNvbnRlbnRJdGVtOwoKCS8qCgkqIENvbXBsZXggdHlwZSB3aXRoIHNpbXBsZSBjb250ZW50LgoJKi8KCWlmIElTX0NPTVBMRVhfVFlQRShiYXNlKSB7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewkKCQkvKgoJCSogU3VtbWFyeTogYSBjb21wbGV4IHR5cGUgKHNpbXBsZSBjb250ZW50KSBjYW4gKnJlc3RyaWN0KgoJCSogYSBjb21wbGV4IHR5cGUgd2l0aCB0aGUgZm9sbG93aW5nIGNvbnRlbnQgdHlwZToKCQkqIDEuICdtaXhlZCcgYW5kIGFuIGVtcHRpYWJsZSBwYXJ0aWNsZQoJCSogMi4gc2ltcGxlIHR5cGUKCQkqLwoJCWlmIChiYXNlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQpIHsKCQkgICAgLyoKCQkgICAgKiAyIGlmIHRoZSB7Y29udGVudCB0eXBlfSBvZiB0aGUgYmFzZSB0eXBlIGlzIG1peGVkIGFuZCBhIAoJCSAgICAqIHBhcnRpY2xlIHdoaWNoIGlzILdlbXB0aWFibGW3LCAKCQkgICAgKiBbLi4uXSAKCQkgICAgKiB0aGVuIHN0YXJ0aW5nIGZyb20gdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gCgkJICAgICogY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIAoJCSAgICAqIG9mIDxyZXN0cmljdGlvbj4gKCoqd2hpY2ggbXVzdCBiZSBwcmVzZW50KiopCgkJICAgICoKCQkgICAgKiBGSVhNRSBUT0RPOiBIYW5kbGUgImVtcHRpYWJsZSBwYXJ0aWNsZSIuCgkJICAgICovCgkJICAgIHJlcyA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlczsKCQkgICAgaWYgKHJlcyA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQkgICAgTlVMTCwgdHlwZSwgTlVMTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0Q29udGVudFR5cGUsICIKCQkJICAgICJDVCAnJXMnIChyZXN0cmljdGluZyk6IDxzaW1wbGVDb250ZW50PiBoYXMgbm8gIgoJCQkgICAgIjxyZXN0cmljdGlvbj4iLAoJCQkgICAgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgoJCSAgICByZXMtPnN1YnR5cGVzOwoJCSAgICBpZiAocmVzID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICBOVUxMLCB0eXBlLCBOVUxMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkgICAgIkNUICclcycgKHJlc3RyaWN0aW5nKTogPHJlc3RyaWN0aW9uPiBoYXMgbm8gIgoJCQkgICAgIm1hbmRhdG9yeSA8c2ltcGxlVHlwZT4iLAoJCQkgICAgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgYmFzZUNvbnRlbnRJdGVtID0gYmFzZS0+Y29udGVudFR5cGVEZWY7CgkJICAgIGlmIChiYXNlQ29udGVudEl0ZW0gPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgIE5VTEwsIHR5cGUsIE5VTEwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSAgICAiQ1QgJyVzJyAocmVzdHJpY3RpbmcpLCB0aGUgYmFzZSB0eXBlIGhhcyBubyAiCgkJCSAgICAiY29udGVudCB0eXBlIiwgdHlwZS0+bmFtZSk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIGlmIElTX1NJTVBMRV9UWVBFKGJhc2VDb250ZW50SXRlbSkgewoJCQkvKgoJCQkqIDEgSWYgdGhlIGJhc2UgdHlwZSBpcyBhIGNvbXBsZXggdHlwZSB3aG9zZSBvd24gCgkJICAgIAkqIHtjb250ZW50IHR5cGV9IGlzIGEgc2ltcGxlIHR5cGUgYW5kIHRoZSA8cmVzdHJpY3Rpb24+IAoJCQkqIGFsdGVybmF0aXZlIGlzIGNob3NlbgoJCQkqLwoJCQkvKiB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgd2lsbCBiZSB0aGUgcmVzdHJpY3Rpb24gaXRlbS4qLwoJCQlyZXMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXM7CgkJCWlmIChyZXMgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCQkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFHZXRDb250ZW50VHlwZSwgIgoJCQkJIkNUICclcycgKHJlc3RyaWN0aW5nKTogPHNpbXBsZVR5cGU+IGhhcyBubyAiCgkJCQkiPHJlc3RyaWN0aW9uPiIsIHR5cGUtPm5hbWUpOwoJCQkgICAgcmV0dXJuICgtMSk7CgkJCX0KCQkJLyoKCQkJKiAxLjEgdGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgCgkJCSogPHNpbXBsZVR5cGU+IGFtb25nIHRoZSBbY2hpbGRyZW5dIG9mIDxyZXN0cmljdGlvbj5pZiAKCQkJKiB0aGVyZSBpcyBvbmU7CgkJCSovCgkJCXJlcyA9IHJlcy0+c3VidHlwZXM7CgkJCWlmIChyZXMgPT0gTlVMTCkgewoJCQkgICAgLyoKCQkJICAgICogMS4yIG90aGVyd2lzZSB0aGUge2NvbnRlbnQgdHlwZX0gCgkJCSAgICAqIG9mIHRoZSBiYXNlIHR5cGUgLgoJCQkgICAgKi8KCQkJICAgIHJlcyA9IGJhc2VDb250ZW50SXRlbTsKCQkJfQoJCSAgICB9CgkJfQoJCS8qCgkJKiBTUEVDSUFMIFRPRE86IElmICpyZXN0cmljdGluZyogdGhlIHNwZWMgd2FudHMgdXMgdG8gCgkJKiBjcmVhdGUgYW4gKmFkZGl0aW9uYWwqIHNpbXBsZSB0eXBlIHdoaWNoIHJlc3RyaWN0cyB0aGUgCgkJKiBsb2NhdGVkIHNpbXBsZSB0eXBlOyB3ZSB3b24ndCBkbyB0aGlzIHlldCwgYW5kIGxvb2sgaG93IAoJCSogZmFyIHdlIGdldCB3aXRoIGl0LgoJCSovCgkgICAgfSBlbHNlIHsgLyogaWYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTiAqLwoJCS8qCgkJKiBTdW1tYXJ5OiBhIGNvbXBsZXggdHlwZSAoc2ltcGxlIGNvbnRlbnQpIGNhbiAqZXh0ZW5kKgoJCSogb25seSBhIGNvbXBsZXggYmFzZSB3aXRoIGEgc2ltcGxlIHR5cGUgYXMgY29udGVudC4KCQkqLwkJCgkJLyoKCQkqIDMgSWYgdGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIAoJCSogdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdIGlzIGEgY29tcGxleCB0eXBlIAoJCSogZGVmaW5pdGlvbiAod2hvc2Ugb3duIHtjb250ZW50IHR5cGV9ICptdXN0IGJlKiBhIHNpbXBsZSAKCQkqIHR5cGUgZGVmaW5pdGlvbiwgc2VlIGJlbG93KSBhbmQgdGhlICo8ZXh0ZW5zaW9uPiogCgkJKiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoYXQgCgkJKiBjb21wbGV4IHR5cGUgZGVmaW5pdGlvbjsKCQkqLwoJCXJlcyA9IGJhc2UtPmNvbnRlbnRUeXBlRGVmOwoJCWlmIChyZXMgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSJDVCAnJXMnIChleHRlbmRpbmcpLCB0aGUgYmFzZSB0eXBlIGhhcyBubyBjb250ZW50ICIKCQkJInR5cGUiLCB0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkJaWYgKCEgSVNfU0lNUExFX1RZUEUocmVzKSkgewoJCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCVhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCQlOVUxMLCB0eXBlLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJCSJDVCAnJXMnIChleHRlbmRpbmcpLCB0aGUgY29udGVudCB0eXBlIG9mIHRoZSAiCgkJCSJiYXNlIGlzIG5vdCBhIHNpbXBsZSB0eXBlIiwgdHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJICAgIH0JICAgIAkKCX0gZWxzZSAvKiBpZiBJU19DT01QTEVYX1RZUEUoYmFzZSkgKi8KCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTikgewoJICAgIC8qCgkgICAgKiA0IG90aGVyd2lzZSAodGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSAKCSAgICAqILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdIGlzIGEgc2ltcGxlIHR5cGUgCgkgICAgKiBkZWZpbml0aW9uIGFuZCB0aGUgPGV4dGVuc2lvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuKSwgCgkgICAgKiB0aGVuIHRoYXQgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbi4KCSAgICAqLwoJICAgIHJlcyA9IGJhc2U7Cgl9CQoJdHlwZS0+Y29udGVudFR5cGVEZWYgPSByZXM7CglpZiAocmVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJTlVMTCwgdHlwZSwgTlVMTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUdldENvbnRlbnRUeXBlLCAiCgkJIiclcycsIHRoZSBjb250ZW50IHR5cGUgY291bGQgbm90IGJlIGRldGVybWluZWQiLCAKCQl0eXBlLT5uYW1lKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCiAgICB9CiAgICAKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFUeXBlRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIGl0ZW0sCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGN0eHRUeXBlOwoKICAgIGlmIChpdGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgLyoKICAgICogRG8gbm90IGFsbG93IHRoZSBmb2xsb3dpbmcgdHlwZXMgdG8gYmUgdHlwZWZpeGVkLCBwcmlvciB0bwogICAgKiB0aGUgY29ycmVzcG9uZGluZyBzaW1wbGUvY29tcGxleCB0eXBlcy4KICAgICovCiAgICBpZiAoY3R4dC0+Y3R4dFR5cGUgPT0gTlVMTCkgewoJc3dpdGNoIChpdGVtLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VOSU9OOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoJICAgIAoJCXJldHVybjsKCSAgICBkZWZhdWx0OgoJICAgICAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IGl0ZW0tPm5hbWU7CiAgICBpZiAoaXRlbS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKICAgICAgICBzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ6ewkJICAgIAoJCSAgICBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkgewoJCQlpZiAoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LAoJCQkJTlVMTCk7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPQoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZTsgKi8KCQkgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjp7CgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IE5VTEw7CgoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmxhZ3MgfD0gCgkJCVhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfUkVTVFJJQ1RJT047CgkJICAgIGlmIChpdGVtLT5iYXNlVHlwZSAhPSBOVUxMKQoJCQliYXNlID0gaXRlbS0+YmFzZVR5cGU7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaXRlbS0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIGl0ZW0tPmJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmJhc2VOcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLCAKCQkJCU5VTEwsIE5VTEwsIAoJCQkJKHhtbE5vZGVQdHIpIHhtbFNjaGVtYUdldFByb3BOb2RlKGl0ZW0tPm5vZGUsICJiYXNlIiksCgkJCQkiYmFzZSIsIGl0ZW0tPmJhc2UsIGl0ZW0tPmJhc2VOcywKCQkJCVhNTF9TQ0hFTUFfVFlQRV9CQVNJQywgInR5cGUgZGVmaW5pdGlvbiIpOwkJCSAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZSwgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0JCQkKICAgICAgICAgICAgICAgICAgICB9CQoJCSAgICBjdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoJCSAgICBpZiAoY3R4dC0+Y3R4dFR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVgpIHsKCQkJLyoKCQkJKiBDb21wbGV4VHlwZSByZXN0cmljdGlvbi4KCQkJKi8JCQkKCQkJLyoKCQkJKiBDb250ZW50IHR5cGUuCgkJCSovCgkJCWlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQkgICAgLyogMS4xLjEgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIGlmICgoaXRlbS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpICYmCgkJCSAgICAoKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMKQoJCQkgICAgfHwgKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCSAgICBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpKSkKCQkJICAgIC8qIDEuMS4yICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkJZWxzZSBpZiAoKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQoJCQkgICAgJiYgKGl0ZW0tPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCQkJICAgIC8qIDEuMS4zICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkJZWxzZSB7CgkJCSAgICAvKiAxLjIgYW5kIDIuWCBhcmUgYXBwbGllZCBhdCB0aGUgb3RoZXIgbGF5ZXIgKi8KCQkJICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0KCQkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkJfQoJCSAgICB9IGVsc2UgewkKCQkJLyoKCQkJKiBTaW1wbGVUeXBlIHJlc3RyaWN0aW9uLgoJCQkqLwoJCQkvKiBUT0RPOiBOb3RoaW5nPyAqLwoJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjp7CgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IE5VTEw7CgkJICAgIHhtbFNjaGVtYUNvbnRlbnRUeXBlIGV4cGxpY2l0Q29udGVudFR5cGU7CgkJICAgIAoJCSAgICAvKgoJCSAgICAqIEFuIGV4dGVuc2lvbiBkb2VzIGV4aXN0IG9uIGEgY29tcGxleFR5cGUgb25seS4KCQkgICAgKi8KCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZsYWdzIHw9IAoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTjsKCQkgICAgaWYgKGl0ZW0tPnJlY3Vyc2UpIHsKCQkJLyogVE9ETzogVGhlIHdvcmQgInJlY3Vyc2l2ZSIgc2hvdWxkIGJlIGNoYW5nZWQgdG8gImNpcmN1bGFyIiBoZXJlLiAqLwoJCQl4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsCgkJCSAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJICAgIE5VTEwsIGl0ZW0sIGl0ZW0tPm5vZGUsCQoJCQkgICAgIlRoaXMgaXRlbSBpcyBjaXJjdWxhciIsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CgkJICAgIH0KCQkgICAgaWYgKGl0ZW0tPmJhc2UgIT0gTlVMTCkgeyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBiYXNlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBpdGVtLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5iYXNlTnMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwgCgkJCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwgCgkJCQlOVUxMLCBpdGVtLCBpdGVtLT5ub2RlLAoJCQkJImJhc2UiLCBpdGVtLT5iYXNlLCBpdGVtLT5iYXNlTnMsCgkJCQlYTUxfU0NIRU1BX1RZUEVfQkFTSUMsICJ0eXBlIGRlZmluaXRpb24iKTsJCQkJICAgCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFzZS0+Y29udGVudFR5cGUgPT0gCgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCQkgICAgaXRlbS0+cmVjdXJzZSA9IDE7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZSwgY3R4dCwgTlVMTCk7CgkJCSAgICBpdGVtLT5yZWN1cnNlID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkvKgoJCQkqIFRoZSB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCAKCQkJKiB2YWx1Zbcgb2YgdGhlIGJhc2UgW2F0dHJpYnV0ZV0KCQkJKi8KCQkJY3R4dC0+Y3R4dFR5cGUtPmJhc2VUeXBlID0gYmFzZTsKCQkJLyoKCQkJKiBUT0RPOiBUaGlzIG9uZSBpcyBzdGlsbCBuZWVkZWQgZm9yIGNvbXB1dGF0aW9uIG9mCgkJCSogdGhlIGNvbnRlbnQgbW9kZWwgYnkgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsLgoJCQkqIFRyeSB0byBnZXQgcmlkIG9mIGl0LgoJCQkqLwoJCQlpdGVtLT5iYXNlVHlwZSA9IGJhc2U7CQkJCiAgICAgICAgICAgICAgICAgICAgfQoJCSAgICBpZiAoKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJCShpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKQogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlRml4dXAoaXRlbS0+c3VidHlwZXMsIGN0eHQsIE5VTEwpOwkgICAgCgkJICAgIAoJCSAgICBleHBsaWNpdENvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCSAgICBpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkKCQkJLyogMS4xLjEgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgZWxzZSBpZiAoKGl0ZW0tPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSAmJgoJCQkoKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCVhNTF9TQ0hFTUFfVFlQRV9BTEwpCgkJCXx8IChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpKSkKCQkJLyogMS4xLjIgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgZWxzZSBpZiAoKGl0ZW0tPnN1YnR5cGVzLT50eXBlID09CgkJCVhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0UpCgkJCSYmIChpdGVtLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkpCgkJCS8qIDEuMS4zICovCgkJCWV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgkJICAgIGlmIChiYXNlICE9IE5VTEwpIHsKCQkJLyogSXQgd2lsbCBiZSByZXBvcnRlZCBsYXRlciwgaWYgdGhlIGJhc2UgaXMgbWlzc2luZy4gKi8JCQkgICAgCgkJCWlmIChleHBsaWNpdENvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWSkgewoJCQkgICAgLyogMi4xICovCgkJCSAgICBpdGVtLT5jb250ZW50VHlwZSA9IGJhc2UtPmNvbnRlbnRUeXBlOwoJCQl9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkJICAgIC8qIDIuMiBpbWJpdGFibGUgISAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPQoJCQkJWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCQl9IGVsc2UgewoJCQkgICAgLyogMi4zIGltYml0YWJsZSBwYXJlaWwgISAqLwoJCQkgICAgaXRlbS0+Y29udGVudFR5cGUgPQoJCQkJWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwoJCQl9CgkJICAgIH0JCSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDp7CgkJICAgIGN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CgkJICAgIGN0eHQtPmN0eHRUeXBlID0gaXRlbTsKCQkgICAgLyoKCQkgICAgKiBTdGFydCB3aXRoIGFuIGVtcHR5IGNvbnRlbnQtdHlwZSB0eXBlLgoJCSAgICAqLwoJCSAgICBpZiAoaXRlbS0+c3VidHlwZXMgPT0gTlVMTCkKCQkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CgoJCSAgICBpZiAoKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHx8IAoJCQkoKGl0ZW0tPnN1YnR5cGVzLT50eXBlICE9IAoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpICYmIAoJCQkoaXRlbS0+c3VidHlwZXMtPnR5cGUgIT0gCgkJCVhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpKSkgewoJCQkvKiAKCQkJKiBUaGlzIGNhc2UgaXMgdW5kZXJzdG9vZCBhcyBzaG9ydGhhbmQgZm9yIGNvbXBsZXggCgkJCSogY29udGVudCByZXN0cmljdGluZyB0aGUgdXItdHlwZSBkZWZpbml0aW9uLCBhbmQgCgkJCSogdGhlIGRldGFpbHMgb2YgdGhlIG1hcHBpbmdzIHNob3VsZCBiZSBtb2RpZmllZCBhcyAKCQkJKiBuZWNlc3NhcnkuCgkJCSovCQkJCgkJCWl0ZW0tPmJhc2VUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CgkJCWl0ZW0tPmZsYWdzIHw9IAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTjsKCQkJLyoKCQkJKiBBc3N1bWUgdGhhdCB3ZSBpbmhlcml0IHRoZSBjb250ZW50LXR5cGUgdHlwZSAKCQkJKiBmcm9tICdhbnlUeXBlJywgd2hpY2ggaXMgJ21peGVkJyBhbmQgYSBwYXJ0aWNsZQoJCQkqIGVtcHRpYWJsZS4KCQkJKi8KCQkJaXRlbS0+Y29udGVudFR5cGUgPSBpdGVtLT5iYXNlVHlwZS0+Y29udGVudFR5cGU7CgkJICAgIH0KCQkgICAgLyoKCQkgICAgKiBGaXh1cCB0aGUgc3ViIGNvbXBvbmVudHMuCgkJICAgICovCgkJICAgIGlmICgoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCQkJKGl0ZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PQoJCQlYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpIHsJCQkgICAgCgkJCXhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CgkJICAgIH0JCgkJICAgIGlmIChpdGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpIHsKCQkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CQkJCgkJICAgIH0gZWxzZSBpZiAoaXRlbS0+c3VidHlwZXMgIT0gTlVMTCkgewoJCQkvKgoJCQkqIFVzZSB0aGUgY29udGVudC10eXBlIHR5cGUgb2YgdGhlIG1vZGVsIGdyb3VwcwoJCQkqIGRlZmluZWQsIGlmICdtaXhlZCcgaXMgbm90IHNldC4gSWYgJ21peGVkJyBpcyBzZXQKCQkJKiBpdCB3aWxsIGV4cGFuZCB0aGUgY29udGVudC10eXBlIGJ5IGFsbG93aW5nIGNoYXJhY3RlcgoJCQkqIGNvbnRlbnQgdG8gYXBwZWFyLgoJCQkqLwoJCQlpdGVtLT5jb250ZW50VHlwZSA9CgkJCSAgICBpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CgkJICAgIH0KCgkJICAgIC8qCgkJICAgICogU29tZSBvcHRpbWl6YXRpb24gZm9yIHZhbGlkYXRpb246CgkJICAgICogSWYgdGhlcmUgYXJlIG5vIGZhY2V0cyBiZXNpZGUgdGhlICJ3aGl0ZXNwYWNlIiBmYWNldCwKCQkgICAgKiB0aGVuIGEgdmFsdWUgbmVlZHMgbm90IHRvIGNoZWNrZWQgYWdhaW5zdCBhZ2FpbnN0IGEKCQkgICAgKiBmYWNldCwgdGh1cyBubyBjb21wdXRlZCB2YWx1ZSBpcyBuZWVkZWQuCgkJICAgICogVE9ETyBVUkdFTlQ6IFRoaXMgaXMganVzdCBhIHdvcmthcm91bmQsIHdlIG5lZWQgdG8KCQkgICAgKiBpbnRyb2R1Y2UgdGhlIGNvcnJlY3QgdXNhZ2Ugb2YgY29udGVudFR5cGUgdG8gc3RvcmUgdGhlCgkJICAgICogZmFjZXRzIGluIQoJCSAgICAqLwoJCSAgICBpZiAoKGl0ZW0tPmJhc2VUeXBlICE9IE5VTEwpICYmCgkJICAgICAgICAoaXRlbS0+YmFzZVR5cGUtPmZsYWdzICYKCQkJIFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFKSkKCQkJaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7CgkJICAgIGVsc2UgewoJCQl4bWxTY2hlbWFGYWNldExpbmtQdHIgY3VyOwoKCQkJZm9yIChjdXIgPSBpdGVtLT5mYWNldFNldDsgY3VyICE9IE5VTEw7CgkJCSAgICBjdXIgPSBjdXItPm5leHQpIHsKCQkJICAgIGlmIChjdXItPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQkJaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7CgkJCQlicmVhazsKCQkJICAgIH0KCQkJfQoJCSAgICB9CQoKCQkgICAgeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uKGN0eHQsIGl0ZW0pOwoJCSAgICB4bWxTY2hlbWFDaGVja0RlZmF1bHRzKGl0ZW0sIGN0eHQsIGl0ZW0tPm5hbWUpOwoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IGN0eHRUeXBlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6ewogICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPnN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJLyogCgkJCSAqIFJlbW92ZWQgZHVlIHRvIGltcGxlbWVudGF0aW9uIG9mIHRoZSBidWlsZCBvZiBhdHRyaWJ1dGUgdXNlcy4gCgkJCSAqLwoJCQkvKgoJCQlpZiAoaXRlbS0+YXR0cmlidXRlcyA9PSBOVUxMKQoJCQkgICAgaXRlbS0+YXR0cmlidXRlcyA9CgkJCSAgICAgICAgaXRlbS0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7CgkJCSovCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKCQkvKgoJCSogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBTY2hlbWEgQ29tcG9uZW50CgkJKgoJCSovCgkJY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsJCQoJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlpZiAoaXRlbS0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IAoJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IGl0ZW07CgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CgkJfQoJCS8qIEZpeHVwIGJhc2UgdHlwZSAqLwkJCgkJaWYgKChpdGVtLT5iYXNlVHlwZSAhPSBOVUxMKSAmJiAKCQkgICAgKGl0ZW0tPmJhc2VUeXBlLT5jb250ZW50VHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpIHsKCQkgICAgLyogT1BUSU1JWkU6IEFjdHVhbGx5IHRoaXMgb25lIHdpbGwgbmV2ZXIgYnkgaGl0LCBzaW5jZQoJCSAgICAqIHRoZSBiYXNlIHR5cGUgaXMgYWxyZWFkeSB0eXBlLWZpeGVkIGluIDxyZXN0cmljdGlvbj4uCgkJICAgICovCgkJICAgIGN0eHQtPmN0eHRUeXBlID0gaXRlbTsKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKGl0ZW0tPmJhc2VUeXBlLCBjdHh0LCBOVUxMKTsKCQl9CgkJLyogQmFzZSB0eXBlOiAKCQkqIDIgSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgCgkJKiB0aGVuIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuCgkJKi8KCQlpZiAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9UWVBFX0xJU1QpIHsKCQkgICAgaXRlbS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CQkgICAgCgkJfSBlbHNlIGlmIChpdGVtLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCSAgICBYTUxfU0NIRU1BX1RZUEVfVU5JT04pIHsKCQkgICAgaXRlbS0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OOwoJCX0gZWxzZSBpZiAoaXRlbS0+c3VidHlwZXMtPnR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB7CgkJICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldCwgY3VyLCBsYXN0ID0gTlVMTDsKCQkgICAgCQkgICAgCSAgICAJCSAgIAoJCSAgICAvKiAKCQkgICAgKiBWYXJpZXR5CgkJICAgICogSWYgdGhlIDxyZXN0cmljdGlvbj4gYWx0ZXJuYXRpdmUgaXMgY2hvc2VuLCB0aGVuIHRoZSAKCQkgICAgKiB7dmFyaWV0eX0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCgkJICAgICovCQoJCSAgICBpZiAoaXRlbS0+YmFzZVR5cGUgIT0gTlVMTCkgewoJCQlpZiAoaXRlbS0+YmFzZVR5cGUtPmZsYWdzICYgCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQzsKCQkJZWxzZSBpZiAoaXRlbS0+YmFzZVR5cGUtPmZsYWdzICYgCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkKCQkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUOwoJCQllbHNlIGlmIChpdGVtLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikKCQkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTjsJCSAgICAJCSAgICAJCSAgIAoJCQkvKgoJCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgUmVzdHJpY3Rpb24gCgkJCSogKEZhY2V0cykKCQkJKiBOT1RFOiBTYXRpc2ZhY3Rpb24gb2YgMSBhbmQgMiBhcmlzZSBmcm9tIHRoZSBmaXh1cCAKCQkJKiBhcHBsaWVkIGJlZm9yZWhhbmQuCgkJCSoJCQkgICAgCgkJCSogMyBUaGUge2ZhY2V0c30gb2YgUiBhcmUgdGhlIHVuaW9uIG9mIFMgYW5kIHRoZSB7ZmFjZXRzfSAKCQkJKiBvZiBCLCBlbGltaW5hdGluZyBkdXBsaWNhdGVzLiBUbyBlbGltaW5hdGUgZHVwbGljYXRlcywgCgkJCSogd2hlbiBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgb2NjdXJzIGluIGJvdGggUyBhbmQgdGhlIAoJCQkqIHtmYWNldHN9IG9mIEIsIHRoZSBvbmUgaW4gdGhlIHtmYWNldHN9IG9mIEIgaXMgbm90IAoJCQkqIGluY2x1ZGVkLCB3aXRoIHRoZSBleGNlcHRpb24gb2YgZW51bWVyYXRpb24gYW5kIHBhdHRlcm4gCgkJCSogZmFjZXRzLCBmb3Igd2hpY2ggbXVsdGlwbGUgb2NjdXJyZW5jZXMgd2l0aCBkaXN0aW5jdCB2YWx1ZXMgCgkJCSogYXJlIGFsbG93ZWQuCgkJCSovCgkJCWlmIChpdGVtLT5iYXNlVHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJCQkgICAgbGFzdCA9IGl0ZW0tPmZhY2V0U2V0OwoJCQkgICAgaWYgKGxhc3QgIT0gTlVMTCkKCQkJCXdoaWxlIChsYXN0LT5uZXh0ICE9IE5VTEwpCgkJCQkgICAgbGFzdCA9IGxhc3QtPm5leHQ7CgkJCSAgICBjdXIgPSBpdGVtLT5iYXNlVHlwZS0+ZmFjZXRTZXQ7CgkJCSAgICBmb3IgKDsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJCQkJLyogCgkJCQkqIEJhc2UgcGF0dGVybnMgd29uJ3QgYmUgYWRkIGhlcmU6CgkJCQkqIHRoZXkgYXJlIE9SZWQgaW4gYSB0eXBlIGFuZAoJCQkJKiBBTkRlZCBpbiBkZXJpdmVkIHR5cGVzLiBUaGlzIHdpbGwKCQkJCSogaGFwcGVkIGF0IHZhbGlkYXRpb24gbGV2ZWwgYnkKCQkJCSogd2Fsa2luZyB0aGUgYmFzZSBheGlzIG9mIHRoZSB0eXBlLgoJCQkJKi8KCQkJCWlmIChjdXItPmZhY2V0LT50eXBlID09IAoJCQkJICAgIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgCgkJCQkgICAgY29udGludWU7CgkJCQlmYWNldCA9IE5VTEw7CgkJCQlpZiAoKGl0ZW0tPmZhY2V0U2V0ICE9IE5VTEwpICYmCgkJCQkgICAgLyogUkVNT1ZFRDogYSBjaGVjayBmb3IKCQkJCSAgICAqIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTiB3YXMgYWxyZWFkeQoJCQkJICAgICogcGVyZm9ybWVkIGFib3ZlLgoJCQkJCgkJCQkgICAgKiAoY3VyLT5mYWNldC0+dHlwZSAhPSAKCQkJCSAgICAqIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgJiYKCQkJCSAgICAqLwoJCQkJICAoY3VyLT5mYWNldC0+dHlwZSAhPSAKCQkJCSAgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTikpIHsJCQkJCgkJCQkgICAgZmFjZXQgPSBpdGVtLT5mYWNldFNldDsKCQkJCSAgICBkbyB7CgkJCQkJaWYgKGN1ci0+ZmFjZXQtPnR5cGUgPT0gCgkJCQkJICAgIGZhY2V0LT5mYWNldC0+dHlwZSkgCgkJCQkJICAgIGJyZWFrOwoJCQkJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJCQkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJCQl9CgkJCQlpZiAoZmFjZXQgPT0gTlVMTCkgewoJCQkJICAgIGZhY2V0ID0gKHhtbFNjaGVtYUZhY2V0TGlua1B0cikgCgkJCQkJeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldExpbmspKTsKCQkJCSAgICBpZiAoZmFjZXQgPT0gTlVMTCkgewoJCQkJCXhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCQkJICAgICJmaXhpbmcgc2ltcGxlVHlwZSIsIE5VTEwpOwoJCQkJCXJldHVybjsKCQkJCSAgICB9CgkJCQkgICAgLyoKCQkJCSAgICAqIFRoZSBmYWNldHMgYXJlIG5vdCBjb3BpZWQgYnV0IHJlZmVyZW5jZWQKCQkJCSAgICAqIHZpYSB0aGUgZmFjZXQgbGluay4KCQkJCSAgICAqLwoJCQkJICAgIGZhY2V0LT5mYWNldCA9IGN1ci0+ZmFjZXQ7CgkJCQkgICAgZmFjZXQtPm5leHQgPSBOVUxMOwoJCQkJICAgIGlmIChsYXN0ID09IE5VTEwpCgkJCQkJaXRlbS0+ZmFjZXRTZXQgPSBmYWNldDsJCSAgICAKCQkJCSAgICBlbHNlIAoJCQkJCWxhc3QtPm5leHQgPSBmYWNldDsKCQkJCSAgICBsYXN0ID0gZmFjZXQ7CQkJCQoJCQkJfQkJCQkgICAgCgkJCSAgICB9CgkJCX0KCQkJLyoKCQkJKiBTb21lIG9wdGltaXphdGlvbiBmb3IgdmFsaWRhdGlvbjoKCQkJKiBJZiB0aGVyZSBhcmUgbm8gZmFjZXRzIGJlc2lkZSB0aGUgIndoaXRlc3BhY2UiIGZhY2V0LAoJCQkqIHRoZW4gYSB2YWx1ZSBuZWVkcyBub3QgdG8gY2hlY2tlZCBhZ2FpbnN0IGFnYWluc3QgYQoJCQkqIGZhY2V0LCB0aHVzIG5vIGNvbXB1dGVkIHZhbHVlIGlzIG5lZWRlZC4KCQkJKi8KCQkJaWYgKGl0ZW0tPmJhc2VUeXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFKQoJCQkgICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GQUNFVFNORUVEVkFMVUU7CgkJCWVsc2UgewoJCQkgICAgZm9yIChjdXIgPSBpdGVtLT5mYWNldFNldDsgY3VyICE9IE5VTEw7CgkJCSAgICBjdXIgPSBjdXItPm5leHQpIHsKCQkJCWlmIChjdXItPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRSkgewoJCQkJICAgIGl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRkFDRVRTTkVFRFZBTFVFOwoJCQkJICAgIGJyZWFrOwoJCQkJfQoJCQkgICAgfQoJCQl9CgkJICAgIH0KCQl9CQoJCS8qCgkJKiBDaGVjayBjb25zdHJhaW50cy4KCQkqLwoJCXhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZShjdHh0LCBpdGVtKTsKCQl4bWxTY2hlbWFDaGVja0RlZmF1bHRzKGl0ZW0sIGN0eHQsIGl0ZW0tPm5hbWUpOwoJCWN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOiAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgICAgIGl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTOwogICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfR1JPVVA6CgkJLyoKCQkqIFRPRE86IEhhbmRsaW5nIHdhcyBtb3ZlZCB0byB4bWxTY2hlbWFHcm91cERlZkZpeHVwLgoJCSovCgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0xJU1Q6IAoJCXhtbFNjaGVtYVBhcnNlTGlzdFJlZkZpeHVwKGl0ZW0sIGN0eHQpOwoJCWl0ZW0tPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CQkKCQl4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2soaXRlbSwgY3R4dCk7CgkJaXRlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9GQUNFVDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYRVhDTFVTSVZFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9GUkFDVElPTkRJR0lUUzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0U6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgICAgICBpdGVtLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJaWYgKGl0ZW0tPnN1YnR5cGVzICE9IE5VTEwpCgkJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChpdGVtLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9JRENfVU5JUVVFOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVk6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRjoKCQlicmVhazsKICAgICAgICB9CiAgICB9CiNpZmRlZiBERUJVR19UWVBFCiAgICBpZiAoaXRlbS0+bm9kZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJUeXBlIG9mICVzIDogJXM6JWQgOiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPm5vZGUtPmRvYy0+VVJMLAogICAgICAgICAgICAgICAgICAgICAgICB4bWxHZXRMaW5lTm8oaXRlbS0+bm9kZSkpOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIlR5cGUgb2YgJXMgOiIsIG5hbWUpOwogICAgfQogICAgc3dpdGNoIChpdGVtLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJzaW1wbGVcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbGVtZW50c1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAidW5rbm93biAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbXB0eVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgkvKiBSZW1vdmVkLCBzaW5jZSBub3QgdXNlZC4gKi8KCS8qCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWQgb3IgZWxlbXNcbiIpOwogICAgICAgICAgICBicmVhazsKCSovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0OgogKiBAZmFjZXQ6ICB0aGUgZmFjZXQKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKgogKiBSZXR1cm5zIDAgaWYgb2theSBvciAtMSBpbiBjYWUgb2YgZXJyb3IKICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBub25OZWdhdGl2ZUludGVnZXJUeXBlID0gTlVMTDsKICAgIGludCByZXQgPSAwLCByZXVzZVZhbEN0eHQgPSAwOwoKICAgIGlmICgoZmFjZXQgPT0gTlVMTCkgfHwgKHR5cGVEZWNsID09IE5VTEwpKQogICAgICAgIHJldHVybigtMSk7CiAgICAvKiAKICAgICogVE9ETzogd2lsbCB0aGUgcGFyc2VyIGNvbnRleHQgYmUgZ2l2ZW4gaWYgdXNlZCBmcm9tCiAgICAqIHRoZSByZWxheE5HIG1vZHVsZT8KICAgICovCgogICAgaWYgKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPT0gTlVMTCkgewogICAgICAgIG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUgPQogICAgICAgICAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19OTklOVEVHRVIpOwogICAgfQogICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkVYQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CgljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT046IHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBPa2F5IHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBhdCB0aGF0IHBvaW50LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQ7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKCQkvKiA0LjMuNS41IENvbnN0cmFpbnRzIG9uIGVudW1lcmF0aW9uIFNjaGVtYSBDb21wb25lbnRzCgkJKiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IGVudW1lcmF0aW9uIHZhbGlkIHJlc3RyaWN0aW9uCgkJKiBJdCBpcyBhbiC3ZXJyb3K3IGlmIGFueSBtZW1iZXIgb2Yge3ZhbHVlfSBpcyBub3QgaW4gdGhlIAoJCSogt3ZhbHVlIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259LiAKCQkqCgkJKiBtaW5JbmNsdXNpdmUsIG1heEluY2x1c2l2ZSwgbWluRXhjbHVzaXZlLCBtYXhFeGNsdXNpdmU6CgkJKiBUaGUgdmFsdWUgt211c3S3IGJlIGluIHRoZSAKCQkqILd2YWx1ZSBzcGFjZbcgb2YgdGhlILdiYXNlIHR5cGW3LiAKCQkqLwoJCS8qCgkJKiBUaGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIHRvIGRlbGl2ZXIgYSBjb21waWxlZCB2YWx1ZQoJCSogb24gdGhlIGZhY2V0LiBJbiBYTUwgU2NoZW1hcyB0aGUgdHlwZSBob2xkaW5nIGEgZmFjZXQsIAoJCSogY2Fubm90IGJlIGEgYnVpbHQtaW4gdHlwZS4gVGh1cyB0byBlbnN1cmUgdGhhdCBvdGhlciBBUEkKCQkqIGNhbGxzIChyZWxheG5nKSBkbyB3b3JrLCBpZiB0aGUgZ2l2ZW4gdHlwZSBpcyBhIGJ1aWx0LWluIAoJCSogdHlwZSwgd2Ugd2lsbCBhc3N1bWUgdGhhdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZSAqaXMKCQkqIGFscmVhZHkqIHRoZSBiYXNlIHR5cGUuCQkKCQkqLwoJCWlmICh0eXBlRGVjbC0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCQkgICAgYmFzZSA9IHR5cGVEZWNsLT5iYXNlVHlwZTsKCQkgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJICAgICJ0aGUgdHlwZSAnJXMnIGhhcyBubyBiYXNlIHR5cGUuXG4iLAoJCQkgICAgdHlwZURlY2wtPm5hbWUsIE5VTEwpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQkJCgkJfSBlbHNlCgkJICAgIGJhc2UgPSB0eXBlRGVjbDsKCQkvKgoJCSogVGhpcyBhdm9pZHMgcGVyc2V2ZXJhdGl2ZSBjcmVhdGlvbiBvZiB0aGUgCgkJKiB2YWxpZGF0aW9uIGNvbnRleHQgaWYgYSBwYXJzZXIgY29udGV4dCBpcwoJCSogdXNlZC4KCQkqLwoJCWlmIChjdHh0ICE9IE5VTEwpIHsKCQkgICAgcmV1c2VWYWxDdHh0ID0gMTsKCQkgICAgaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCQkJaWYgKHhtbFNjaGVtYUNyZWF0ZVZDdHh0T25QQ3R4dChjdHh0KSA9PSAtMSkKCQkJICAgIHJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIHZjdHh0ID0gY3R4dC0+dmN0eHQ7CgkJfSBlbHNlIHsKCQkgICAgdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CgkJICAgIGlmICh2Y3R4dCA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIgoJCQkgICAgImNyZWF0aW5nIGEgbmV3IHZhbGlkYXRpb24gY29udGV4dC5cbiIsCgkJCSAgICBOVUxMLCBOVUxMKTsKCQkJcmV0dXJuICgtMSk7CQoJCSAgICB9CgkJfQoJICAgICAgICAgICAgICAgIAoJCXZjdHh0LT5ub2RlID0gZmFjZXQtPm5vZGU7CgkJdmN0eHQtPmN1ciA9IE5VTEw7CgkJLyoKCQkqIE5PVEU6IFRoaXMgY2FsbCBkb2VzIG5vdCBjaGVjayB0aGUgY29udGVudCBub2RlcywgCgkJKiBzaW5jZSB0aGV5IGFyZSBub3QgYXZhaWxhYmxlOgoJCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldCAKCQkqIGRlZmluaXRpb24sICpub3QqIHRoZSBhdHRyaWJ1dGUgaG9sZGluZyB0aGUgKnZhbHVlKiAKCQkqIG9mIHRoZSBmYWNldC4KCQkqLwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCBiYXNlLCAKCQkgICAgZmFjZXQtPnZhbHVlLCAwLCAxLCAxLCAwKTsKCQlmYWNldC0+dmFsID0gdmN0eHQtPnZhbHVlOwoJCXZjdHh0LT52YWx1ZSA9IE5VTEw7CQkKICAgICAgICAgICAgICAgIGlmIChyZXQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgLyogZXJyb3IgY29kZSAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfRkFDRVQsIAoJCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnJXMnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUsIAoJCQkgICAgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLCAKCQkJICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQlYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQkJTlVMTCwgTlVMTCwgTlVMTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSJmYWlsZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlICclcycgbmFtZSBvZiB0aGUgIgoJCQkiZmFjZXQgJyVzJyBhZ2FpbnN0IHRoZSBiYXNlIHR5cGUgJyVzJy5cbiIsCgkJCWZhY2V0LT52YWx1ZSwgCgkJCXhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCQkJYmFzZS0+bmFtZSwgTlVMTCwgTlVMTCk7IAoJCSAgICByZXQgPSAtMTsKCQl9ICAgCgkJaWYgKHJldXNlVmFsQ3R4dCA9PSAwKQoJCSAgICB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CiAgICAgICAgICAgIGZhY2V0LT5yZWdleHAgPSB4bWxSZWdleHBDb21waWxlKGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgIGlmIChmYWNldC0+cmVnZXhwID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9SRUdFWFBfSU5WQUxJRCwKCQkgICAgIlR5cGUgZGVmaW5pdGlvbiAnJXMnOiBUaGUgdmFsdWUgJyVzJyBvZiB0aGUgIgoJCSAgICAiZmFjZXQgJ3BhdHRlcm4nIGlzIG5vdCB2YWxpZC5cbiIsCgkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOnsKICAgICAgICAgICAgICAgIGludCB0bXA7CgogICAgICAgICAgICAgICAgdG1wID0KICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldC0+dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKGZhY2V0LT52YWwpKTsKICAgICAgICAgICAgICAgIGlmICh0bXAgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIC8qIGVycm9yIGNvZGUgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgZmFjZXQtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0ZBQ0VUX1ZBTFVFLAoJCQkgICAgTlVMTCwgTlVMTCwgTlVMTCwKCQkJICAgICJUeXBlIGRlZmluaXRpb24gJyVzJzogVGhlIHZhbHVlICclcycgb2YgdGhlICIKCQkJICAgICJmYWNldCAnJXMnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUsIAoJCQkgICAgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTp7CiAgICAgICAgICAgICAgICBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicHJlc2VydmUiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInJlcGxhY2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUkVQTEFDRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAiY29sbGFwc2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfV0hJVEVfU1BBQ0UsCgkJCSAgICAiVHlwZSBkZWZpbml0aW9uICclcyc6IFRoZSB2YWx1ZSAnJXMnIG9mIHRoZSAiCgkJCSAgICAiZmFjZXQgJ3doaXRlU3BhY2UnIGlzIG5vdCB2YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tEZWZhdWx0czoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIENoZWNrcyB0aGUgZGVmYXVsdCB2YWx1ZXMgdHlwZXMsIGVzcGVjaWFsbHkgZm9yIGZhY2V0cyAKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRGVmYXVsdHMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKQp7CiAgICBpZiAobmFtZSA9PSBOVUxMKQogICAgICAgIG5hbWUgPSB0eXBlRGVjbC0+bmFtZTsgCiAgICAvKgogICAgKiBOT1RFOiBJdCBpcyBpbnRlbmRlZCB0byB1c2UgdGhlIGZhY2V0cyBsaXN0LCBpbnN0ZWFkCiAgICAqIG9mIGZhY2V0U2V0LgogICAgKi8KICAgIGlmICh0eXBlRGVjbC0+ZmFjZXRzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0ID0gdHlwZURlY2wtPmZhY2V0czsKCQoJLyoKCSogVGVtcG9yYXJpbHkgYXNzaWduIHRoZSAic2NoZW1hIiB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CgkqIG9mIHRoZSBwYXJzZXIgY29udGV4dC4gVGhpcyBpcyBuZWVkZWQgZm9yIE5PVEFUSU9OIHZhbGlkYXRpb24uCgkqLwoJaWYgKGN0eHQtPnZjdHh0ID09IE5VTEwpIHsKCSAgICBpZiAoeG1sU2NoZW1hQ3JlYXRlVkN0eHRPblBDdHh0KGN0eHQpID09IC0xKQoJCXJldHVybjsKCX0KCWN0eHQtPnZjdHh0LT5zY2hlbWEgPSBjdHh0LT5zY2hlbWE7CgoJd2hpbGUgKGZhY2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFDaGVja0ZhY2V0KGZhY2V0LCB0eXBlRGVjbCwgY3R4dCwgbmFtZSk7CgkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCX0KCgljdHh0LT52Y3R4dC0+c2NoZW1hID0gTlVMTDsKICAgIH0gICAgCn0KCi8qKgogKiB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZjoKICogQGN0eHRHcjogdGhlIHNlYXJjaGVkIG1vZGVsIGdyb3VwCiAqIEBsaXN0OiB0aGUgbGlzdCBvZiBtb2RlbCBncm91cHMgdG8gYmUgcHJvY2Vzc2VkCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIGNpcmN1bGFyIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gcmVmZXJlbmNlLCBvdGhlcndpc2UgTlVMTC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldENpcmNNb2RlbEdyRGVmUmVmKHhtbFNjaGVtYVR5cGVQdHIgY3R4dEdyRGVmLAoJCQkgIHhtbFNjaGVtYVR5cGVQdHIgZ3IpCnsgICAgCiAgICB4bWxTY2hlbWFUeXBlUHRyIGNpcmMgPSBOVUxMOwogICAgaW50IG1hcmtlZDsKICAgIC8qCiAgICAqIFdlIHdpbGwgc2VhcmNoIGZvciBhbiBtb2RlbCBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBtb2RlbCBncm91cCBkZWZpbml0aW9uLgogICAgKi8gICAgICAgIAogICAgd2hpbGUgKGdyICE9IE5VTEwpIHsKCWlmICgoKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgfHwKCSAgICAgKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BTEwpIHx8CgkgICAgIChnci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpIHx8CgkgICAgIChnci0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKSkgJiYKCSAgICAoZ3ItPnN1YnR5cGVzICE9IE5VTEwpKSB7CQkgCgkgICAgbWFya2VkID0gMDsKCSAgICBpZiAoKGdyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9HUk9VUCkgJiYKCQkoZ3ItPnJlZiAhPSBOVUxMKSkgewoJCWlmIChnci0+c3VidHlwZXMgPT0gY3R4dEdyRGVmKQoJCSAgICByZXR1cm4gKGdyKTsKCQllbHNlIGlmIChnci0+c3VidHlwZXMtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEKSB7CgkJICAgIGdyID0gZ3ItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogTWFyayB0byBhdm9pZCBpbmZpbml0ZSByZWN1cnNpb24gb24KCQkgICAgKiBjaXJjdWxhciByZWZlcmVuY2VzIG5vdCB5ZXQgZXhhbWluZWQuCgkJICAgICovCgkJICAgIGdyLT5zdWJ0eXBlcy0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9NQVJLRUQ7CgkJICAgIG1hcmtlZCA9IDE7CgkJfSAKCQlpZiAoZ3ItPnN1YnR5cGVzLT5zdWJ0eXBlcyAhPSBOVUxMKQoJCSAgICBjaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoY3R4dEdyRGVmLCAKCQkJZ3ItPnN1YnR5cGVzLT5zdWJ0eXBlcyk7CgkJICAgIC8qCgkJICAgICogVW5tYXJrIHRoZSB2aXNpdGVkIG1vZGVsIGdyb3VwIGRlZmluaXRpb24uCgkJKi8KCQlpZiAobWFya2VkKQoJCSAgICBnci0+c3VidHlwZXMtPmZsYWdzIF49IFhNTF9TQ0hFTUFTX1RZUEVfTUFSS0VEOwoJCWlmIChjaXJjICE9IE5VTEwpCgkJICAgIHJldHVybiAoY2lyYyk7CgkgICAgfSBlbHNlIHsKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY01vZGVsR3JEZWZSZWYoY3R4dEdyRGVmLCAKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIGdyLT5zdWJ0eXBlcyk7CgkJaWYgKGNpcmMgIT0gTlVMTCkKCQkgICAgcmV0dXJuIChjaXJjKTsKCSAgICB9CgoJfQoJZ3IgPSBnci0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXI6CiAqIGF0dHJHcjogIHRoZSBtb2RlbCBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIHRvIG1vZGVsIGdyb3VwIGRlZmluaXRpb25zLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyKHhtbFNjaGVtYVR5cGVQdHIgbW9kZWxHckRlZiwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAgIAogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBNb2RlbCBHcm91cCBDb3JyZWN0CiAgICAqIDIgQ2lyY3VsYXIgZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCB3aXRoaW4gdGhlIHtwYXJ0aWNsZXN9IAogICAgKiBvZiBhIGdyb3VwIHRoZXJlIG11c3Qgbm90IGJlIGF0IGFueSBkZXB0aCBhIHBhcnRpY2xlIHdob3NlIHt0ZXJtfSAKICAgICogaXMgdGhlIGdyb3VwIGl0c2VsZi4KICAgICovCiAgICAvKgogICAgKiBOT1RFOiAiZ3ItPnN1YnR5cGVzIiBob2xkcyB0aGUgcmVmZXJlbmNlZCBncm91cC4KICAgICovCiAgICBpZiAoKG1vZGVsR3JEZWYtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0dST1VQKSB8fCAKCSgobW9kZWxHckRlZi0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkgPT0gMCkgfHwKCShtb2RlbEdyRGVmLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCXJldHVybjsKICAgIGVsc2UgewoJeG1sU2NoZW1hVHlwZVB0ciBjaXJjOwoKCWNpcmMgPSB4bWxTY2hlbWFHZXRDaXJjTW9kZWxHckRlZlJlZihtb2RlbEdyRGVmLCBtb2RlbEdyRGVmLT5zdWJ0eXBlcyk7CglpZiAoY2lyYyAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFRPRE86IFJlcG9ydCB0aGUgcmVmZXJlbmNlZCBhdHRyIGdyb3VwIGFzIFFOYW1lLgoJICAgICovCgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFQX01HX1BST1BTX0NPUlJFQ1RfMiwKCQlOVUxMLCBOVUxMLCBjaXJjLT5ub2RlLAoJCSJDaXJjdWxhciByZWZlcmVuY2UgdG8gdGhlIG1vZGVsIGdyb3VwIGRlZmluaXRpb24gJyVzJyAiCgkJImRlZmluZWQiLCBtb2RlbEdyRGVmLT5uYW1lKTsKCSAgICAvKgoJICAgICogTk9URTogV2Ugd2lsbCBjdXQgdGhlIHJlZmVyZW5jZSB0byBhdm9pZCBmdXJ0aGVyCgkgICAgKiBjb25mdXNpb24gb2YgdGhlIHByb2Nlc3Nvci4KCSAgICAqIFRPRE86IFNQRUM6IERvZXMgdGhlIHNwZWMgZGVmaW5lIGhvdyB0byBwcm9jZXNzIGhlcmU/CgkgICAgKi8KCSAgICBjaXJjLT5zdWJ0eXBlcyA9IE5VTEw7Cgl9CiAgICB9Cn0KCgovKioKICogeG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZjoKICogQGN0eHRHcjogdGhlIHNlYXJjaGVkIGF0dHJpYnV0ZSBncm91cAogKiBAYXR0cjogdGhlIGN1cnJlbnQgYXR0cmlidXRlIGxpc3QgdG8gYmUgcHJvY2Vzc2VkCiAqCiAqIFRoaXMgb25lIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgYnkKICogeG1sU2NoZW1hQ2hlY2tTUkNBdHRyaWJ1dGVHcm91cENpcmN1bGFyIG9ubHkuCiAqCiAqIFJldHVybnMgdGhlIGNpcmN1bGFyIGF0dHJpYnV0ZSBncm91IHJlZmVyZW5jZSwgb3RoZXJ3aXNlIE5VTEwuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZih4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjdHh0R3IsCgkJCSAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsgICAgCiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBjaXJjID0gTlVMTCwgZ3I7CiAgICBpbnQgbWFya2VkOwogICAgLyoKICAgICogV2Ugd2lsbCBzZWFyY2ggZm9yIGFuIGF0dHJpYnV0ZSBncm91cCByZWZlcmVuY2Ugd2hpY2gKICAgICogcmVmZXJlbmNlcyB0aGUgY29udGV4dCBhdHRyaWJ1dGUgZ3JvdXAuCiAgICAqLyAgICAJCiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgltYXJrZWQgPSAwOwoJaWYgKGF0dHItPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgZ3IgPSAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGF0dHI7CgkgICAgaWYgKGdyLT5yZWZJdGVtICE9IE5VTEwpICB7CgkJaWYgKGdyLT5yZWZJdGVtID09IGN0eHRHcikKCQkgICAgcmV0dXJuIChncik7CgkJZWxzZSBpZiAoZ3ItPnJlZkl0ZW0tPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQpIHsKCQkgICAgYXR0ciA9IGF0dHItPm5leHQ7CgkJICAgIGNvbnRpbnVlOwoJCX0gZWxzZSB7CgkJICAgIC8qCgkJICAgICogTWFyayBhcyB2aXNpdGVkIHRvIGF2b2lkIGluZmluaXRlIHJlY3Vyc2lvbiBvbgoJCSAgICAqIGNpcmN1bGFyIHJlZmVyZW5jZXMgbm90IHlldCBleGFtaW5lZC4KCQkgICAgKi8KCQkgICAgZ3ItPnJlZkl0ZW0tPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkJICAgIG1hcmtlZCA9IDE7CgkJfQoJICAgIH0KCSAgICBpZiAoZ3ItPmF0dHJpYnV0ZXMgIT0gTlVMTCkKCQljaXJjID0geG1sU2NoZW1hR2V0Q2lyY0F0dHJHclJlZihjdHh0R3IsIGdyLT5hdHRyaWJ1dGVzKTsKCSAgICAvKgoJICAgICogVW5tYXJrIHRoZSB2aXNpdGVkIGdyb3VwJ3MgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChtYXJrZWQpCgkJZ3ItPnJlZkl0ZW0tPmZsYWdzIF49IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9NQVJLRUQ7CgkgICAgaWYgKGNpcmMgIT0gTlVMTCkKCQlyZXR1cm4gKGNpcmMpOwoJfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgkJCQkKLyoqCiAqIHhtbFNjaGVtYUNoZWNrU1JDQXR0cmlidXRlR3JvdXBDaXJjdWxhcjoKICogYXR0ckdyOiAgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUKICoKICogQ2hlY2tzIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIG9mIGF0dHJpYnV0ZSBncm91cHMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZUdyb3VwQ2lyY3VsYXIoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgYXR0ckdyLAoJCQkJCXhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkJY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKeyAgICAKICAgIC8qCiAgICAqIFNjaGVtYSBSZXByZXNlbnRhdGlvbiBDb25zdHJhaW50OiAKICAgICogQXR0cmlidXRlIEdyb3VwIERlZmluaXRpb24gUmVwcmVzZW50YXRpb24gT0sKICAgICogMyBDaXJjdWxhciBncm91cCByZWZlcmVuY2UgaXMgZGlzYWxsb3dlZCBvdXRzaWRlIDxyZWRlZmluZT4uIAogICAgKiBUaGF0IGlzLCB1bmxlc3MgdGhpcyBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0ncyBwYXJlbnQgaXMgCiAgICAqIDxyZWRlZmluZT4sIHRoZW4gYW1vbmcgdGhlIFtjaGlsZHJlbl0sIGlmIGFueSwgdGhlcmUgbXVzdCAKICAgICogbm90IGJlIGFuIDxhdHRyaWJ1dGVHcm91cD4gd2l0aCByZWYgW2F0dHJpYnV0ZV0gd2hpY2ggcmVzb2x2ZXMgCiAgICAqIHRvIHRoZSBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGlzIDxhdHRyaWJ1dGVHcm91cD4uIEluZGlyZWN0IAogICAgKiBjaXJjdWxhcml0eSBpcyBhbHNvIHJ1bGVkIG91dC4gVGhhdCBpcywgd2hlbiBRTmFtZSByZXNvbHV0aW9uIAogICAgKiAoU2NoZW1hIERvY3VtZW50KSAopzMuMTUuMykgaXMgYXBwbGllZCB0byBhILdRTmFtZbcgYXJpc2luZyBmcm9tIAogICAgKiBhbnkgPGF0dHJpYnV0ZUdyb3VwPnMgd2l0aCBhIHJlZiBbYXR0cmlidXRlXSBhbW9uZyB0aGUgW2NoaWxkcmVuXSwgCiAgICAqIGl0IG11c3Qgbm90IGJlIHRoZSBjYXNlIHRoYXQgYSC3UU5hbWW3IGlzIGVuY291bnRlcmVkIGF0IGFueSBkZXB0aCAKICAgICogd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgPGF0dHJpYnV0ZUdyb3VwPi4KICAgICovCiAgICAvKgogICAgKiBPbmx5IGdsb2JhbCBjb21wb25lbnRzIGNhbiBiZSByZWZlcmVuY2VkLgogICAgKi8KICAgIGlmICgoKGF0dHJHci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSA9PSAwKSB8fCAKCShhdHRyR3ItPmF0dHJpYnV0ZXMgPT0gTlVMTCkpCglyZXR1cm47CiAgICBlbHNlIHsKCXhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGNpcmM7CgoJY2lyYyA9IHhtbFNjaGVtYUdldENpcmNBdHRyR3JSZWYoYXR0ckdyLCBhdHRyR3ItPmF0dHJpYnV0ZXMpOwoJaWYgKGNpcmMgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBUT0RPOiBSZXBvcnQgdGhlIHJlZmVyZW5jZWQgYXR0ciBncm91cCBhcyBRTmFtZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfQVRUUklCVVRFX0dST1VQXzMsCgkJTlVMTCwgTlVMTCwgY2lyYy0+bm9kZSwKCQkiQ2lyY3VsYXIgcmVmZXJlbmNlIHRvIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgJyVzJyAiCgkJImRlZmluZWQiLCBhdHRyR3ItPm5hbWUpOwoJICAgIC8qCgkgICAgKiBOT1RFOiBXZSB3aWxsIGN1dCB0aGUgcmVmZXJlbmNlIHRvIGF2b2lkIGZ1cnRoZXIKCSAgICAqIGNvbmZ1c2lvbiBvZiB0aGUgcHJvY2Vzc29yLgoJICAgICogQkFEU1BFQzogVGhlIHNwZWMgc2hvdWxkIGRlZmluZSBob3cgdG8gcHJvY2VzcyBpbiB0aGlzIGNhc2UuCgkgICAgKi8KCSAgICBjaXJjLT5hdHRyaWJ1dGVzID0gTlVMTDsKCSAgICBjaXJjLT5yZWZJdGVtID0gTlVMTDsKCX0KICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJHcnBGaXh1cDoKICogQGF0dHJncnBEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJHcnBGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyZ3JwLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0cmdycC0+bmFtZTsKICAgIGlmIChhdHRyZ3JwLT5hdHRyaWJ1dGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJncnAtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmVmOwoKICAgICAgICByZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChjdHh0LT5zY2hlbWEsIGF0dHJncnAtPnJlZiwgCgkgICAgYXR0cmdycC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBSZXNDb21wQXR0ckVycihjdHh0LCAKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgYXR0cmdycCwgYXR0cmdycC0+bm9kZSwKCQkicmVmIiwgYXR0cmdycC0+cmVmLCBhdHRyZ3JwLT5yZWZOcywgCgkJWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCWF0dHJncnAtPnJlZkl0ZW0gPSByZWY7CgkvKgoJKiBDaGVjayBmb3Igc2VsZiByZWZlcmVuY2UhCgkqLwogICAgICAgIHhtbFNjaGVtYUF0dHJHcnBGaXh1cChyZWYsIGN0eHQsIE5VTEwpOwogICAgICAgIGF0dHJncnAtPmF0dHJpYnV0ZXMgPSByZWYtPmF0dHJpYnV0ZXM7CglhdHRyZ3JwLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHJlZi0+YXR0cmlidXRlV2lsZGNhcmQ7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFBdHRyQ2hlY2tWYWxDb25zdHI6CiAqIEBpdGVtOiAgYW4gc2NoZW1hIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbi91c2UKICogQGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogCiAqIFZhbGlkYXRlcyB0aGUgdmFsdWUgY29uc3RyYWludHMgb2YgYW4gYXR0cmlidXRlIGRlY2xhcmF0aW9uL3VzZS4KICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0cih4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgaXRlbSwKCQkJICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CgogICAgLyoKICAgICogYS1wcm9wcy1jb3JyZWN0CiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogQXR0cmlidXRlIERlY2xhcmF0aW9uIFByb3BlcnRpZXMgQ29ycmVjdAogICAgKgogICAgKiAyIGlmIHRoZXJlIGlzIGEge3ZhbHVlIGNvbnN0cmFpbnR9LCB0aGUgY2Fub25pY2FsIGxleGljYWwgCiAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGl0cyB2YWx1ZSBtdXN0IGJlILd2YWxpZLcgd2l0aCByZXNwZWN0IAogICAgKiB0byB0aGUge3R5cGUgZGVmaW5pdGlvbn0gYXMgZGVmaW5lZCBpbiBTdHJpbmcgVmFsaWQgKKczLjE0LjQpLiAKICAgICovCgogICAgaWYgKGl0ZW0tPmRlZlZhbHVlICE9IE5VTEwpIHsKCWludCByZXQ7Cgl4bWxOb2RlUHRyIG5vZGU7Cgl4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CgoJaWYgKGl0ZW0tPnN1YnR5cGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGl0ZW0tPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0F0dHJWYWxDb25zdHIsICIKCQkidHlwZSBpcyBtaXNzaW5nLi4uIHNraXBwaW5nIHZhbGlkYXRpb24gb2YgIgoJCSJ2YWx1ZSBjb25zdHJhaW50IiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuOwoJfQoKCS8qCgkqIFRPRE86IFRyeSB0byBhdm9pZCBjcmVhdGluZyBhIG5ldyBjb250ZXh0LgoJKiBUT0RPOiBUaGlzIGFsbCBpcyBub3QgdmVyeSBwZXJmb3JtYW50LgoJKi8KCXR5cGUgPSBpdGVtLT5zdWJ0eXBlczsKCS8qCgkqIEVuc3VyZSB0aGVyZSdzIHZhbGlkYXRpb24gY29udGV4dC4KCSovCglpZiAoY3R4dC0+dmN0eHQgPT0gTlVMTCkgewoJICAgIGlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIGl0ZW0tPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrQXR0clZhbENvbnN0ciwgIgoJCSAgICAiY3JlYXRpbmcgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQkgICAgTlVMTCwgTlVMTCk7CgkJcmV0dXJuOwoJICAgIH0KCX0KCglpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0ZJWEVEKQoJICAgIG5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChpdGVtLT5ub2RlLCBCQURfQ0FTVCAiZml4ZWQiKTsKCWVsc2UKCSAgICBub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoaXRlbS0+bm9kZSwgQkFEX0NBU1QgImRlZmF1bHQiKTsKCWN0eHQtPnZjdHh0LT5ub2RlID0gbm9kZTsKCWN0eHQtPnZjdHh0LT5jdXIgPSBOVUxMOwoJLyoKCSogTk9URTogVGhpcyBjYWxsIGRvZXMgbm90IGNoZWNrIHRoZSBjb250ZW50IG5vZGVzLCAKCSogc2luY2UgdGhleSBhcmUgbm90IGF2YWlsYWJsZToKCSogZmFjZXQtPm5vZGUgaXMganVzdCB0aGUgbm9kZSBob2xkaW5nIHRoZSBmYWNldCAKCSogZGVmaW5pdGlvbiwgKm5vdCogdGhlIGF0dHJpYnV0ZSBob2xkaW5nIHRoZSAqdmFsdWUqIAoJKiBvZiB0aGUgZmFjZXQuCgkqLwoJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dC0+dmN0eHQsIHR5cGUsIAoJICAgIGl0ZW0tPmRlZlZhbHVlLCAwLCAxLCAxLCAwKTsKCWlmIChyZXQgPT0gMCkgewoJICAgIC8qCgkgICAgKiBTdG9yZSB0aGUgY29tcHV0ZWQgdmFsdWUuCgkgICAgKi8KICAgIAkgICAgaXRlbS0+ZGVmVmFsID0gY3R4dC0+dmN0eHQtPnZhbHVlOwoJICAgIGN0eHQtPnZjdHh0LT52YWx1ZSA9IE5VTEw7CQoJfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkgICAgaWYgKGN0eHQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYVBTaW1wbGVUeXBlRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BUF9BX1BST1BTX0NPUlJFQ1RfMiwgCgkJICAgIE5VTEwsIE5VTEwsIG5vZGUsIAoJCSAgICB0eXBlLCBOVUxMLCBpdGVtLT5kZWZWYWx1ZSwKCQkgICAgTlVMTCwgTlVMTCwgTlVMTCk7CgkgICAgfQoJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LCBYTUxfU0NIRU1BUF9JTlRFUk5BTCwKCQlOVUxMLCBOVUxMLCBub2RlLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXR0ckNoZWNrVmFsQ29uc3RyLCAiCgkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiB0aGUgIgoJCSJhdHRyaWJ1dGUgZGVjbC91c2UgYWdhaW5zdCB0aGUgdHlwZSAnJXMnIiwKCQl0eXBlLT5uYW1lKTsgCSAgICAKCX0JICAgCQogICAgfSAgICAKfQoKI2lmIDAgLyogTm90IHVzZWQgeWV0LiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrRWxlbVByb3BzQ29ycmVjdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCSAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVkZWNsKQp7CiAgICAvKgogICAgKiBUT0RPOiAxIFRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiBtdXN0IGJlIGFzIAogICAgKiBkZXNjcmliZWQgaW4gdGhlIHByb3BlcnR5IHRhYmxlYXUgaW4gVGhlIEVsZW1lbnQgRGVjbGFyYXRpb24gU2NoZW1hIAogICAgKiBDb21wb25lbnQgKKczLjMuMSksIG1vZHVsbyB0aGUgaW1wYWN0IG9mIE1pc3NpbmcgU3ViLWNvbXBvbmVudHMgKKc1LjMpLgogICAgKi8KICAgIC8qCiAgICAqIDIgSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKICAgICogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlIAogICAgKiBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4KICAgICoKICAgICogTk9URTogVGhpcyBpcyBkb25lIGluIHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ci4KICAgICovCiAgICAvKgogICAgKiAzIElmIHRoZXJlIGlzIGEgbm9uLbdhYnNlbnS3IHtzdWJzdGl0dXRpb24gZ3JvdXAgYWZmaWxpYXRpb259LCAKICAgICogdGhlbiB7c2NvcGV9IG11c3QgYmUgZ2xvYmFsLgogICAgKgogICAgKiBOT1RFOiBUaGlzIGlzIGRvbmUgaW4geG1sU2NoZW1hUGFyc2VFbGVtZW50LgogICAgKiBUT0RPOiBNb3ZlIGl0IHRvIHRoaXMgbGF5ZXIgaGVyZS4KICAgICovCiAgICAvKgogICAgKiBUT0RPOiA0IElmIHRoZXJlIGlzIGEge3N1YnN0aXR1dGlvbiBncm91cCBhZmZpbGlhdGlvbn0sIHRoZSB7dHlwZSBkZWZpbml0aW9ufSAKICAgICogb2YgdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24gbXVzdCBiZSB2YWxpZGx5IGRlcml2ZWQgZnJvbSB0aGUge3R5cGUgCiAgICAqIGRlZmluaXRpb259IG9mIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSwgZ2l2ZW4gdGhlIHZhbHVlIAogICAgKiBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCBleGNsdXNpb25zfSBvZiB0aGUge3N1YnN0aXR1dGlvbiBncm91cCAKICAgICogYWZmaWxpYXRpb259LCBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAoQ29tcGxleCkgKKczLjQuNikgCiAgICAqIChpZiB0aGUge3R5cGUgZGVmaW5pdGlvbn0gaXMgY29tcGxleCkgb3IgYXMgZGVmaW5lZCBpbiAKICAgICogVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KSAoaWYgdGhlIHt0eXBlIGRlZmluaXRpb259IGlzIAogICAgKiBzaW1wbGUpLiAKICAgICovCiAgICAvKgogICAgKiBUT0RPOiA1IElmIHRoZSB7dHlwZSBkZWZpbml0aW9ufSBvciB7dHlwZSBkZWZpbml0aW9ufSdzIHtjb250ZW50IHR5cGV9IAogICAgKiBpcyBvciBpcyBkZXJpdmVkIGZyb20gSUQgdGhlbiB0aGVyZSBtdXN0IG5vdCBiZSBhIHt2YWx1ZSBjb25zdHJhaW50fS4KICAgICogTm90ZTogVGhlIHVzZSBvZiBJRCBhcyBhIHR5cGUgZGVmaW5pdGlvbiBmb3IgZWxlbWVudHMgZ29lcyBiZXlvbmQgCiAgICAqIFhNTCAxLjAsIGFuZCBzaG91bGQgYmUgYXZvaWRlZCBpZiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBpcyBkZXNpcmVkCiAgICAqLwogICAgLyoKICAgICogVE9ETzogNiBDaXJjdWxhciBzdWJzdGl0dXRpb24gZ3JvdXBzIGFyZSBkaXNhbGxvd2VkLiBUaGF0IGlzLCBpdCBtdXN0IG5vdCAKICAgICogYmUgcG9zc2libGUgdG8gcmV0dXJuIHRvIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24gYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgCiAgICAqIHRoZSB7c3Vic3RpdHV0aW9uIGdyb3VwIGFmZmlsaWF0aW9ufSBwcm9wZXJ0eS4KICAgICovCn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyOgogKiBAaXRlbTogIGFuIHNjaGVtYSBlbGVtZW50IGRlY2xhcmF0aW9uL3BhcnRpY2xlCiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlCiAqIAogKiBWYWxpZGF0ZXMgdGhlIHZhbHVlIGNvbnN0cmFpbnRzIG9mIGFuIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqCiAqIEZpeGVzIGZpbmlzaCBkb2luZyB0aGUgY29tcHV0YXRpb25zIG9uIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0cih4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wsCgkJCSAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCkKeyAgIAogICAgaWYgKGRlY2wtPnZhbHVlICE9IE5VTEwpIHsKCWludCByZXQ7Cgl4bWxOb2RlUHRyIG5vZGUgPSBOVUxMOwoJeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCS8qCgkqIDIgSWYgdGhlcmUgaXMgYSB7dmFsdWUgY29uc3RyYWludH0sIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgaXRzIHZhbHVlIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIHt0eXBlIAoJKiBkZWZpbml0aW9ufSBhcyBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4KCSovICAgIAoJaWYgKGRlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGRlY2wtPm5vZGUsCgkJWE1MX1NDSEVNQVBfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0VsZW1WYWxDb25zdHIsICIKCQkidHlwZSBpcyBtaXNzaW5nLi4uIHNraXBwaW5nIHZhbGlkYXRpb24gb2YgIgoJCSJ0aGUgdmFsdWUgY29uc3RyYWludCIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybjsKCX0KCS8qCgkqIEVuc3VyZSB0aGVyZSdzIGEgdmFsaWRhdGlvbiBjb250ZXh0LgoJKi8KCWlmICh4bWxTY2hlbWFDcmVhdGVWQ3R4dE9uUEN0eHQoY3R4dCkgPT0gLTEpCgkgICAgcmV0dXJuOwoKCXR5cGUgPSBkZWNsLT5zdWJ0eXBlczsKCglpZiAoZGVjbC0+bm9kZSAhPSBOVUxMKSB7CgkgICAgaWYgKGRlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkKCQlub2RlID0gKHhtbE5vZGVQdHIpIHhtbEhhc1Byb3AoZGVjbC0+bm9kZSwgQkFEX0NBU1QgImZpeGVkIik7CgkgICAgZWxzZQoJCW5vZGUgPSAoeG1sTm9kZVB0cikgeG1sSGFzUHJvcChkZWNsLT5ub2RlLCBCQURfQ0FTVCAiZGVmYXVsdCIpOwoJfQoJY3R4dC0+dmN0eHQtPm5vZGUgPSBub2RlOwoJY3R4dC0+dmN0eHQtPmN1ciA9IE5VTEw7CglyZXQgPSB4bWxTY2hlbWFDaGVja0NPU1ZhbGlkRGVmYXVsdChjdHh0LCBjdHh0LT52Y3R4dCwgdHlwZSwgZGVjbC0+dmFsdWUsIAoJICAgIG5vZGUpOwoJaWYgKHJldCA9PSAwKSB7CgkgICAgLyoKCSAgICAqIENvbnN1bWUgdGhlIGNvbXB1dGVkIHZhbHVlLgoJICAgICovCiAgICAJICAgIGRlY2wtPmRlZlZhbCA9IGN0eHQtPnZjdHh0LT52YWx1ZTsKICAJICAgIGN0eHQtPnZjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9IGVsc2UgaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFQQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFQX0lOVEVSTkFMLAoJCU5VTEwsIE5VTEwsIG5vZGUsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFFbGVtQ2hlY2tWYWxDb25zdHIsICIKCQkiZmFpbGVkIHRvIHZhbGlkYXRlIHRoZSB2YWx1ZSBjb25zdHJhaW50IG9mIHRoZSAiCgkJImVsZW1lbnQgZGVjbGFyYXRpb24gJyVzJyIsCgkJZGVjbC0+bmFtZSk7IAkgICAgCgl9CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hQXR0ckZpeHVwOgogKiBAaXRlbTogIGFuIHNjaGVtYSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlLgogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSAKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gYXR0cmlidXRlIGRlY2xhcmF0aW9ucy91c2VzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBpdGVtLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgICAvKiAKICAgICogVE9ETzogSWYgaW5jbHVkaW5nIHRoaXMgaXMgZG9uZSB0d2ljZSAoISkgZm9yIGV2ZXJ5IGF0dHJpYnV0ZS4KICAgICogICAgICAgLT4gSG1tLCBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIGRvbmUuCiAgICAqLwogICAgLyoKICAgICogVGhlIHNpbXBsZSB0eXBlIGRlZmluaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+IGVsZW1lbnQgCiAgICAqIGluZm9ybWF0aW9uIGl0ZW0gaW4gdGhlIFtjaGlsZHJlbl0sIGlmIHByZXNlbnQsIG90aGVyd2lzZSB0aGUgc2ltcGxlIAogICAgKiB0eXBlIGRlZmluaXRpb24gt3Jlc29sdmVktyB0byBieSB0aGUgt2FjdHVhbCB2YWx1Zbcgb2YgdGhlIHR5cGUgCiAgICAqIFthdHRyaWJ1dGVdLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlILdzaW1wbGUgdXItdHlwZSBkZWZpbml0aW9uty4KICAgICovCiAgICBpZiAoaXRlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0lOVEVSTkFMX1JFU09MVkVEKQoJcmV0dXJuOwogICAgaXRlbS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfQVRUUl9JTlRFUk5BTF9SRVNPTFZFRDsKICAgIGlmIChpdGVtLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChpdGVtLT50eXBlTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgaXRlbS0+dHlwZU5hbWUsCgkgICAgaXRlbS0+dHlwZU5zKTsKCWlmICgodHlwZSA9PSBOVUxMKSB8fCAoISBJU19TSU1QTEVfVFlQRSh0eXBlKSkpIHsKCSAgICB4bWxTY2hlbWFQUmVzQ29tcEF0dHJFcnIoY3R4dCwKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQlOVUxMLCAoeG1sU2NoZW1hVHlwZVB0cikgaXRlbSwgaXRlbS0+bm9kZSwKCQkidHlwZSIsIGl0ZW0tPnR5cGVOYW1lLCBpdGVtLT50eXBlTnMsIAoJCVhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUsIE5VTEwpOwoJfSBlbHNlCgkgICAgaXRlbS0+c3VidHlwZXMgPSB0eXBlOwoJCiAgICB9IGVsc2UgaWYgKGl0ZW0tPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGRlY2w7CgoJLyoKCSogV2UgaGF2ZSBhbiBhdHRyaWJ1dGUgdXNlIGhlcmU7IGFzc2lnbiB0aGUgcmVmZXJlbmNlZCAKCSogYXR0cmlidXRlIGRlY2xhcmF0aW9uLgoJKi8KCS8qCgkqIFRPRE86IEV2YWx1YXRlLCB3aGF0IGVycm9ycyBjb3VsZCBvY2N1ciBpZiB0aGUgZGVjbGFyYXRpb24gaXMgbm90CgkqIGZvdW5kLiBJdCBtaWdodCBiZSBwb3NzaWJsZSB0aGF0IHRoZSAidHlwZWZpeHVwIiBtaWdodCBjcmFzaCBpZgoJKiBubyByZWYgZGVjbGFyYXRpb24gd2FzIGZvdW5kLgoJKi8KCWRlY2wgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGUoY3R4dC0+c2NoZW1hLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zKTsKICAgICAgICBpZiAoZGVjbCA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsCgkgICAgCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpdGVtLCBpdGVtLT5ub2RlLAoJCSJyZWYiLCBpdGVtLT5yZWYsIGl0ZW0tPnJlZk5zLCAKCQlYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCWl0ZW0tPnJlZkRlY2wgPSBkZWNsOwogICAgICAgIHhtbFNjaGVtYUF0dHJGaXh1cChkZWNsLCBjdHh0LCBOVUxMKTsKCQogICAgICAgIGl0ZW0tPnN1YnR5cGVzID0gZGVjbC0+c3VidHlwZXM7CgkvKgoJKiBBdHRyaWJ1dGUgVXNlIENvcnJlY3QKCSogYXUtcHJvcHMtY29ycmVjdC4yOiBJZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0gaGFzIGEgZml4ZWQgCgkqIHt2YWx1ZSBjb25zdHJhaW50fSwgdGhlbiBpZiB0aGUgYXR0cmlidXRlIHVzZSBpdHNlbGYgaGFzIGEgCgkqIHt2YWx1ZSBjb25zdHJhaW50fSwgaXQgbXVzdCBhbHNvIGJlIGZpeGVkIGFuZCBpdHMgdmFsdWUgbXVzdCBtYXRjaCAKCSogdGhhdCBvZiB0aGUge2F0dHJpYnV0ZSBkZWNsYXJhdGlvbn0ncyB7dmFsdWUgY29uc3RyYWludH0uCgkqLwoJaWYgKChkZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJfRklYRUQpICYmIAoJICAgIChpdGVtLT5kZWZWYWx1ZSAhPSBOVUxMKSkgewoJICAgIGlmICgoKGl0ZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9GSVhFRCkgPT0gMCkgfHwKCQkoIXhtbFN0ckVxdWFsKGl0ZW0tPmRlZlZhbHVlLCBkZWNsLT5kZWZWYWx1ZSkpKSB7CgkJeG1sU2NoZW1hUEN1c3RvbUVycihjdHh0LAoJCSAgICBYTUxfU0NIRU1BUF9BVV9QUk9QU19DT1JSRUNUXzIsIAoJCSAgICBOVUxMLCBOVUxMLCBpdGVtLT5ub2RlLCAKCQkgICAgIlRoZSB2YWx1ZSBjb25zdHJhaW50IG11c3QgYmUgZml4ZWQgIgoJCSAgICAiYW5kIG1hdGNoIHRoZSByZWZlcmVuY2VkIGF0dHJpYnV0ZSAiCgkJICAgICJkZWNsYXJhdGlvbnMncyB2YWx1ZSBjb25zdHJhaW50ICclcyciLAoJCSAgICBkZWNsLT5kZWZWYWx1ZSk7CgkgICAgfQoJICAgIC8qCgkgICAgKiBGVVRVUkU6IE9uZSBzaG91bGQgY2hhbmdlIHRoZSB2YWx1ZXMgb2YgdGhlIGF0dHIuIHVzZQoJICAgICogaWYgZXZlciB2YWxpZGF0aW9uIHNob3VsZCBiZSBhdHRlbXB0ZWQgZXZlbiBpZiB0aGUKCSAgICAqIHNjaGVtYSBpdHNlbGYgd2FzIG5vdCBmdWxseSB2YWxpZC4KCSAgICAqLwoJfQogICAgfSBlbHNlIHsKCWl0ZW0tPnN1YnR5cGVzID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7ICAgICAgICAKICAgIH0JCn0KCi8qKgogKiB4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmOgogKiBAaWRjOiAgdGhlIGlkZW50aXR5LWNvbnN0cmFpbnQgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogUmVzb2x2ZSBrZXlSZWYgcmVmZXJlbmNlcyB0byBrZXkvdW5pcXVlIElEQ3MuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFSZXNvbHZlSURDS2V5UmVmKHhtbFNjaGVtYUlEQ1B0ciBpZGMsCgkJCSAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VEKQp7ICAKICAgIGlmIChpZGMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGlkYy0+cmVmLT5uYW1lICE9IE5VTEwpIHsgCQoJaWRjLT5yZWYtPml0ZW0gPSAoeG1sU2NoZW1hQmFzaWNJdGVtUHRyKSB4bWxIYXNoTG9va3VwMigKCSAgICBjdHh0LT5zY2hlbWEtPmlkY0RlZiwgCgkgICAgaWRjLT5yZWYtPm5hbWUsIAoJICAgIGlkYy0+cmVmLT50YXJnZXROYW1lc3BhY2UpOwogICAgICAgIGlmIChpZGMtPnJlZi0+aXRlbSA9PSBOVUxMKSB7CgkgICAgLyogCgkgICAgKiBUT0RPOiBJdCBpcyBhY3R1YWxseSBub3QgYW4gZXJyb3IgdG8gZmFpbCB0byByZXNvbHZlLgoJICAgICovCgkgICAgeG1sU2NoZW1hUFJlc0NvbXBBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCU5VTEwsICh4bWxTY2hlbWFUeXBlUHRyKSBpZGMsIGlkYy0+bm9kZSwKCQkicmVmZXIiLCBpZGMtPnJlZi0+bmFtZSwgCgkJaWRjLT5yZWYtPnRhcmdldE5hbWVzcGFjZSwgCgkJWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47Cgl9ICAgICAgICAKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBwYXJzZSBhIHNjaGVtYSBkZWZpbml0aW9uIHJlc291cmNlIGFuZCBidWlsZCBhbiBpbnRlcm5hbAogKiBYTUwgU2hlbWEgc3RydXR1cmUgd2hpY2ggY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgaW5zdGFuY2VzLgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICB4bWxTY2hlbWFQdHIgcmV0ID0gTlVMTDsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CiAgICBpbnQgcHJlc2VydmUgPSAwOwoKICAgIC8qCiAgICAqIFRoaXMgb25lIGlzIHVzZWQgaWYgdGhlIHNjaGVtYSB0byBiZSBwYXJzZWQgd2FzIHNwZWNpZmllZCB2aWEgCiAgICAqIHRoZSBBUEk7IGkuZS4gbm90IGF1dG9tYXRpY2FsbHkgYnkgdGhlIHZhbGlkYXRlZCBpbnN0YW5jZSBkb2N1bWVudC4KICAgICovCgogICAgeG1sU2NoZW1hSW5pdFR5cGVzKCk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGN0eHQtPmNvdW50ZXIgPSAwOwogICAgY3R4dC0+Y29udGFpbmVyID0gTlVMTDsKCiAgICAvKgogICAgICogRmlyc3Qgc3RlcCBpcyB0byBwYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgaW50byBhbiBET00vSW5mb3NldAogICAgICovCiAgICBpZiAoY3R4dC0+VVJMICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkRmlsZSgoY29uc3QgY2hhciAqKSBjdHh0LT5VUkwsIE5VTEwsIAoJICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgbG9hZCAnJXMnLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5VUkwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoY3R4dC0+YnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkTWVtb3J5KGN0eHQtPmJ1ZmZlciwgY3R4dC0+c2l6ZSwgTlVMTCwgTlVMTCwKCSAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX1BBUlNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlLlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgZG9jLT5VUkwgPSB4bWxTdHJkdXAoQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiKTsKICAgICAgICBjdHh0LT5VUkwgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIEJBRF9DQVNUICJpbl9tZW1vcnlfYnVmZmVyIiwgLTEpOwogICAgfSBlbHNlIGlmIChjdHh0LT5kb2MgIT0gTlVMTCkgewogICAgICAgIGRvYyA9IGN0eHQtPmRvYzsKCXByZXNlcnZlID0gMTsKICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9USElOR19UT19QQVJTRSwKCQkgICAgICAieG1sU2NoZW1hUGFyc2U6IGNvdWxkIG5vdCBwYXJzZS5cbiIsCgkJICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICAvKgogICAgICogVGhlbiBleHRyYWN0IHRoZSByb290IGFuZCBTY2hlbWEgcGFyc2UgaXQKICAgICAqLwogICAgcm9vdCA9IHhtbERvY0dldFJvb3RFbGVtZW50KGRvYyk7CiAgICBpZiAocm9vdCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfTk9ST09ULAoJCSAgICAgICJUaGUgc2NoZW1hIGhhcyBubyBkb2N1bWVudCBlbGVtZW50LlxuIiwgTlVMTCwgTlVMTCk7CglpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFJlbW92ZSBhbGwgdGhlIGJsYW5rIHRleHQgbm9kZXMKICAgICAqLwogICAgeG1sU2NoZW1hQ2xlYW51cERvYyhjdHh0LCByb290KTsKCiAgICAvKgogICAgICogVGhlbiBkbyB0aGUgcGFyc2luZyBmb3IgZ29vZAogICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFQYXJzZVNjaGVtYShjdHh0LCByb290KTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmICghcHJlc2VydmUpIHsKCSAgICB4bWxGcmVlRG9jKGRvYyk7Cgl9CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+ZG9jID0gZG9jOwogICAgcmV0LT5wcmVzZXJ2ZSA9IHByZXNlcnZlOwogICAgY3R4dC0+c2NoZW1hID0gcmV0OwogICAgY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwogICAgY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyRml4dXAsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCBhdHRyaWJ1dGVzIGdyb3VwIGRlY2xhcmF0aW9ucwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF0dHJHcnBGaXh1cCwKICAgICAgICAgICAgICAgIGN0eHQpOwoKICAgIC8qCiAgICAqIFJlc29sdmUgaWRlbnRpdHktY29uc3RyYWludCBrZXlSZWZzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+aWRjRGVmLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYVJlc29sdmVJRENLZXlSZWYsIGN0eHQpOwoKICAgIC8qCiAgICAqIENoZWNrIGF0dHJpYnV0ZSBncm91cHMgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMuCiAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyZ3JwRGVjbCwgKHhtbEhhc2hTY2FubmVyKSAKCXhtbFNjaGVtYUNoZWNrQXR0cmlidXRlR3JvdXBDaXJjdWxhciwgY3R4dCk7CgogICAgLyoKICAgICogVGhlbiBmaXh1cCBhbGwgbW9kZWwgZ3JvdXAgZGVmaW5pdGlvbnMuCiAgICAqLyAgICAKICAgIHhtbEhhc2hTY2FuKHJldC0+Z3JvdXBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUdyb3VwRGVmRml4dXAsIGN0eHQpOwogICAgCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgdHlwZXMgcHJvcGVydGllcwogICAgICovICAgIAogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFUeXBlRml4dXAsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeCByZWZlcmVuY2VzIG9mIGVsZW1lbnQgZGVjbGFyYXRpb247IGFwcGx5IGNvbnN0cmFpbnRzLgogICAgICovICAgIAogICAgeG1sSGFzaFNjYW5GdWxsKHJldC0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkgeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjaywgY3R4dCk7CgogICAgIC8qCiAgICAqIENoZWNrIG1vZGVsIGdyb3VwcyBkZWZuaXRpb25zIGZvciBjaXJjdWxhciByZWZlcmVuY2VzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+Z3JvdXBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIAoJeG1sU2NoZW1hQ2hlY2tHcm91cERlZkNpcmN1bGFyLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBidWlsZCB0aGUgY29udGVudCBtb2RlbCBmb3IgYWxsIGNvbXBsZXggdHlwZXMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwKICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGNoZWNrIHRoZSBkZWZhdWx0cyBwYXJ0IG9mIHRoZSB0eXBlIGxpa2UgZmFjZXRzIHZhbHVlcwogICAgICovCiAgICAvKiBPTEQ6IHhtbEhhc2hTY2FuKHJldC0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cywgY3R4dCk7ICovCgogICAgLyoKICAgICogVmFsaWRhdGUgdGhlIHZhbHVlIGNvbnN0cmFpbnQgb2YgYXR0cmlidXRlIGRlY2xhcmF0aW9ucy91c2VzLgogICAgKi8KICAgIHhtbEhhc2hTY2FuKHJldC0+YXR0ckRlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyLCBjdHh0KTsKCiAgICAvKgogICAgKiBWYWxpZGF0ZSB0aGUgdmFsdWUgY29uc3RyYWludCBvZiBlbGVtZW50IGRlY2xhcmF0aW9ucy4KICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmVsZW1EZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrRWxlbVZhbENvbnN0ciwgY3R4dCk7CgoKICAgIGlmIChjdHh0LT5uYmVycm9ycyAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZShyZXQpOwogICAgICAgIHJldCA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlcnI6ICB0aGUgZXJyb3IgY2FsbGJhY2sKICogQHdhcm46ICB0aGUgd2FybmluZyBjYWxsYmFjawogKiBAY3R4OiAgY29udGV4dHVhbCBkYXRhIGZvciB0aGUgY2FsbGJhY2tzCiAqCiAqIFNldCB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zIHVzZWQgdG8gaGFuZGxlIGVycm9ycyBmb3IgYSB2YWxpZGF0aW9uIGNvbnRleHQKICovCnZvaWQKeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFBhcnNlckVycm9yczoKICogQGN0eHQ6ICBhIFhNbC1TY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGVycjogdGhlIGVycm9yIGNhbGxiYWNrIHJlc3VsdAogKiBAd2FybjogdGhlIHdhcm5pbmcgY2FsbGJhY2sgcmVzdWx0CiAqIEBjdHg6IGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcyByZXN1bHQKICoKICogR2V0IHRoZSBjYWxsYmFjayBpbmZvcm1hdGlvbiB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgcGFyc2VyIGNvbnRleHQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGZhaWx1cmUsIDAgb3RoZXJ3aXNlCiAqLwppbnQgCnhtbFNjaGVtYUdldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlFcnJvckZ1bmMgKiBlcnIsCgkJCQkJCQkgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyAqIHdhcm4sIHZvaWQgKipjdHgpCnsKCWlmIChjdHh0ID09IE5VTEwpCgkJcmV0dXJuKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4oMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKEJBRF9DQVNUICJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuIChCQURfQ0FTVCAidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoQkFEX0NBU1QgImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKEJBRF9DQVNUICJJbnRlcm5hbCBFcnJvciIpOwp9CgpzdGF0aWMgaW50CnhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBhbmM7CgogICAgLyogCiAgICAqIFRoZSBub3JtYWxpemF0aW9uIHR5cGUgY2FuIGJlIGNoYW5nZWQgb25seSBmb3IgdHlwZXMgd2hpY2ggYXJlIGRlcml2ZWQgCiAgICAqIGZyb20geHNkOnN0cmluZy4KICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX0ZBQ0VUX1BSRVNFUlZFKTsKCWVsc2UgaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX05PUk1TVFJJTkcpCgkgICAgcmV0dXJuKFhNTF9TQ0hFTUFTX0ZBQ0VUX1JFUExBQ0UpOwoJZWxzZSBpZiAodHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkKCSAgICAvKgoJICAgICogTm90ZSB0aGF0IHdlIGFzc3VtZSBhIHdoaXRlc3BhY2Ugb2YgcHJlc2VydmUgZm9yIGFueVNpbXBsZVR5cGUuCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkUpOwoJZWxzZSB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3IAoJICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0byAKCSAgICAqIGNvbGxhcHNlCgkgICAgKi8KCSAgICByZXR1cm4oWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0UpOwoJfQkJICAgCSAgICAKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJLyoKCSogRm9yIGxpc3QgdHlwZXMgdGhlIGZhY2V0ICJ3aGl0ZVNwYWNlIiBpcyBmaXhlZCB0byAiY29sbGFwc2UiLiAKCSovCglyZXR1cm4gKFhNTF9TQ0hFTUFTX0ZBQ0VUX0NPTExBUFNFKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXJldHVybiAoWE1MX1NDSEVNQVNfRkFDRVRfVU5LTk9XTik7CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYVR5cGVQdHIgYW55U1Q7Cgl4bWxTY2hlbWFGYWNldExpbmtQdHIgbGluOwoKCS8qCgkqIEF0b21pYyB0eXBlcy4KCSovCglhbnlTVCA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJYW5jID0gdHlwZS0+YmFzZVR5cGU7CglkbyB7CgkgICAgLyoKCSAgICAqIEZvciBhbGwgt2F0b21pY7cgZGF0YXR5cGVzIG90aGVyIHRoYW4gc3RyaW5nIChhbmQgdHlwZXMgt2Rlcml2ZWS3IAoJICAgICogYnkgt3Jlc3RyaWN0aW9utyBmcm9tIGl0KSB0aGUgdmFsdWUgb2Ygd2hpdGVTcGFjZSBpcyBmaXhlZCB0byAKCSAgICAqIGNvbGxhcHNlCgkgICAgKi8KCSAgICBpZiAoKGFuYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkJKGFuYy0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfU1RSSU5HKSkgewoJCQoJCWxpbiA9IHR5cGUtPmZhY2V0U2V0OwoJCWRvIHsKCQkgICAgaWYgKGxpbi0+ZmFjZXQtPnR5cGUgPT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSB7CgkJCXJldHVybihsaW4tPmZhY2V0LT53aGl0ZXNwYWNlKTsKCQkJYnJlYWs7CgkJICAgIH0KCQkgICAgbGluID0gbGluLT5uZXh0OwoJCX0gd2hpbGUgKGxpbiAhPSBOVUxMKTsJCgkJYnJlYWs7CgkgICAgfQoJICAgIGFuYyA9IGFuYy0+YmFzZVR5cGU7Cgl9IHdoaWxlIChhbmMgIT0gYW55U1QpOwoJcmV0dXJuIChYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSk7CiAgICB9ICAKICAgIHJldHVybiAoLTEpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBob2xkaW5nIHRoZSBmYWNldHMKICogQGZhY2V0czogIHRoZSBsaXN0IG9mIGZhY2V0cyB0byBjaGVjawogKiBAdmFsdWU6ICB0aGUgbGV4aWNhbCByZXByIG9mIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKiBAdmFsOiAgdGhlIHByZWNvbXB1dGVkIHZhbHVlCiAqIEBmaXJlRXJyb3JzOiAgaWYgMCwgb25seSBpbnRlcm5hbCBlcnJvcnMgd2lsbCBiZSBmaXJlZDsKICoJCSBvdGhlcndpc2UgYWxsIGVycm9ycyB3aWxsIGJlIGZpcmVkLgogKgogKiBDaGVjayBhIHZhbHVlIGFnYWluc3QgYWxsIGZhY2V0IGNvbmRpdGlvbnMKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQl4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQljb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCQl1bnNpZ25lZCBsb25nIGxlbmd0aCwKCQkJCWludCBmaXJlRXJyb3JzKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbFNjaGVtYVR5cGVQdHIgIGJpVHlwZTsgLyogVGhlIGJ1aWxkLWluIHR5cGUuICovCiAgICB4bWxTY2hlbWFUeXBlUHRyIHRtcFR5cGU7CiAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rOwogICAgaW50IHJldEZhY2V0OwogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB1bnNpZ25lZCBsb25nIGxlbiA9IDA7CgojaWZkZWYgREVCVUdfVU5JT05fVkFMSURBVElPTgogICAgcHJpbnRmKCJGYWNldHMgb2YgdHlwZTogJyVzJ1xuIiwgKGNvbnN0IGNoYXIgKikgdHlwZS0+bmFtZSk7CiAgICBwcmludGYoIiAgZmlyZUVycm9yczogJWRcbiIsIGZpcmVFcnJvcnMpOwojZW5kaWYKICAgICAgICAKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyoKICAgICogTk9URTogRG8gbm90IGp1bXAgYXdheSwgaWYgdGhlIGZhY2V0U2V0IG9mIHRoZSBnaXZlbiB0eXBlIGlzCiAgICAqIGVtcHR5OiB1bnRpbCBub3csICJwYXR0ZXJuIiBmYWNldHMgb2YgdGhlICpiYXNlIHR5cGVzKiBuZWVkIHRvCiAgICAqIGJlIGNoZWNrZWQgYXMgd2VsbC4KICAgICovCiAgICBiaVR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIHdoaWxlICgoYmlUeXBlICE9IE5VTEwpICYmIChiaVR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSkKCWJpVHlwZSA9IGJpVHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmlUeXBlID09IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCQkgICAgCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLCAiCgkgICAgInRoZSBiYXNlIHR5cGUgYXhpcyBvZiB0aGUgZ2l2ZW4gdHlwZSAnJXMnIGRvZXMgbm90IHJlc29sdmUgdG8gIgoJICAgICJhIGJ1aWx0LWluIHR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwkKCXJldHVybiAoLTEpOwogICAgfSAgICAKICAgIAogICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCWZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OwoJd2hpbGUgKGZhY2V0TGluayAhPSBOVUxMKSB7CgkgICAgZmFjZXQgPSBmYWNldExpbmstPmZhY2V0OwoJICAgIC8qCgkgICAgKiBTa2lwIHRoZSBwYXR0ZXJuICJ3aGl0ZVNwYWNlIjogaXQgaXMgdXNlZCB0byAKCSAgICAqIGZvcm1hdCB0aGUgY2hhcmFjdGVyIGNvbnRlbnQgYmVmb3JlaGFuZC4KCSAgICAqLwkgICAgCgkgICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQkgICAgYnJlYWs7CgkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6IAoJCSAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgewoJCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUxpc3RTaW1wbGVUeXBlRmFjZXQoZmFjZXQsCgkJCSAgICB2YWx1ZSwgbGVuZ3RoLCAwKTsKCQkJbGVuID0gbGVuZ3RoOwoJCSAgICB9IGVsc2UKCQkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMZW5ndGhGYWNldChiaVR5cGUsIGZhY2V0LAoJCQkgICAgdmFsdWUsIGN0eHQtPnZhbHVlLCAmbGVuKTsKCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldChiaVR5cGUsIGZhY2V0LCB2YWx1ZSwgCgkJCWN0eHQtPnZhbHVlKTsKCSAgICB9CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXQgb2YgdHlwZSAnJXMnLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkJYnJlYWs7CgkgICAgfSBlbHNlIGlmICgocmV0ID4gMCkgJiYgKGZpcmVFcnJvcnMpKSB7CgkJeG1sU2NoZW1hVkZhY2V0RXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIGxlbiwKCQkgICAgdHlwZSwgZmFjZXQsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0KCgkgICAgZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0OwoJfQoJaWYgKHJldCA+PSAwKSB7CgkgICAgLyoKCSAgICAqIFByb2Nlc3MgZW51bWVyYXRpb25zLgoJICAgICovCgkgICAgcmV0RmFjZXQgPSAwOwoJICAgIGZhY2V0TGluayA9IHR5cGUtPmZhY2V0U2V0OwoJICAgIHdoaWxlIChmYWNldExpbmsgIT0gTlVMTCkgewoJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlID09IFhNTF9TQ0hFTUFfRkFDRVRfRU5VTUVSQVRJT04pIHsKCQkgICAgcmV0RmFjZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0KGJpVHlwZSwgZmFjZXRMaW5rLT5mYWNldCwgCgkJCXZhbHVlLCBjdHh0LT52YWx1ZSk7CQkKCQkgICAgaWYgKHJldEZhY2V0IDw9IDApCgkJCWJyZWFrOwoJCX0KCQlmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQ7CgkgICAgfQoJICAgIGlmIChyZXRGYWNldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQ7CgkJaWYgKGZpcmVFcnJvcnMpCgkJICAgIHhtbFNjaGVtYVZGYWNldEVycihjdHh0LCByZXQsIG5vZGUsCgkJCXZhbHVlLCAwLCB0eXBlLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldEZhY2V0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldCBvZiB0eXBlICclcycuXG4iLAoJCSAgICBCQURfQ0FTVCAiZW51bWVyYXRpb24iLCBOVUxMKTsKCQkgICAgcmV0ID0gLTE7CQkKCSAgICB9CQkKCX0KICAgIH0KICAgIGlmIChyZXQgPj0gMCkgewoJLyoKCSogUHJvY2VzcyBwYXR0ZXJzLiBQYXR0ZXJuIGZhY2V0cyBhcmUgT1JlZCBhdCB0eXBlIGxldmVsIAoJKiBhbmQgQU5EZWQgaWYgZGVyaXZlZC4gV2FsayB0aGUgYmFzZSB0eXBlIGF4aXMuCgkqLwoJdG1wVHlwZSA9IHR5cGU7CglmYWNldCA9IE5VTEw7CglkbyB7CgkgICAgcmV0RmFjZXQgPSAwOwoJICAgIGZvciAoZmFjZXRMaW5rID0gdG1wVHlwZS0+ZmFjZXRTZXQ7IGZhY2V0TGluayAhPSBOVUxMOyAKCQlmYWNldExpbmsgPSBmYWNldExpbmstPm5leHQpIHsKCQlpZiAoZmFjZXRMaW5rLT5mYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pCgkJICAgIGNvbnRpbnVlOwoJCXJldEZhY2V0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldChiaVR5cGUsIGZhY2V0TGluay0+ZmFjZXQsIAoJCSAgICB2YWx1ZSwgY3R4dC0+dmFsdWUpOwoJCWlmIChyZXRGYWNldCA9PSAwKSAKCQkgICAgYnJlYWs7CgkJZWxzZSBpZiAocmV0RmFjZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbCwgIgoJCQkidmFsaWRhdGluZyAncGF0dGVybicgZmFjZXQgJyVzJyBvZiB0eXBlICclcycuXG4iLAoJCQlmYWNldExpbmstPmZhY2V0LT52YWx1ZSwgdG1wVHlwZS0+bmFtZSk7CgkJICAgIHJldCA9IC0xOwoJCSAgICBicmVhazsKCQl9IGVsc2UKCQkgICAgLyogU2F2ZSB0aGUgbGFzdCBub24tdmFsaWRhdGluZyBmYWNldC4gKi8KCQkgICAgZmFjZXQgPSBmYWNldExpbmstPmZhY2V0OwoJICAgIH0KCSAgICBpZiAocmV0RmFjZXQgIT0gMCkKCQlicmVhazsJCSAgICAKCSAgICB0bXBUeXBlID0gdG1wVHlwZS0+YmFzZVR5cGU7Cgl9IHdoaWxlICgodG1wVHlwZSAhPSBOVUxMKSAmJiAodG1wVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKTsKCWlmIChyZXRGYWNldCA+IDApIHsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfUEFUVEVSTl9WQUxJRDsKCSAgICBpZiAoZmlyZUVycm9ycykgewoJCXhtbFNjaGVtYVZGYWNldEVycihjdHh0LCByZXQsIG5vZGUsIHZhbHVlLCAwLCB0eXBlLCBmYWNldCwgCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoJICAgIH0KCX0KICAgIH0JICAgIAogICAKICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNpbXBsZSB0eXBlIHZhbGlkYXRpb24JCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURPTSBWYWxpZGF0aW9uIGNvZGUJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBlbGVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpOwpzdGF0aWMgaW50IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJCSAgaW50IGlzTmlsLAoJCQkJCSAgaW50IHZhbFNpbXBsZUNvbnRlbnQpOwoKc3RhdGljIHZvaWQgeG1sU2NoZW1hQmVnaW5FbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCk7CnN0YXRpYyBpbnQgeG1sU2NoZW1hRW5kRWxlbWVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpOwoKI2lmZGVmIEVMRU1fSU5GT19FTkFCTEVECi8qKgogKiB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvOgogKiBAdmN0eHQ6IHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIENyZWF0ZXMvcmV1c2VzIGFuZCBpbml0aWFsaXplcyB0aGUgZWxlbWVudCBpbmZvIGl0ZW0gZm9yIAogKiB0aGUgY3VycmVjdCB0cmVlIGRlcHRoLgogKgogKiBSZXR1cm5zIHRoZSBlbGVtZW50IGluZm8gaXRlbSBvciBOVUxMIG9uIEFQSSBvciBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgeG1sU2NoZW1hTm9kZUluZm9QdHIKeG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgaW50IGRlcHRoKQp7CiAgICB4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbmZvID0gTlVMTDsKICAgIAogICAgaWYgKGRlcHRoID4gdmN0eHQtPnNpemVFbGVtSW5mb3MpIHsKCXhtbFNjaGVtYVZFcnIodmN0eHQsIE5VTEwsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hR2V0RnJlc2hFbGVtSW5mbywgIgoJICAgICJhbiBpbmNvbnNpc3RlbnQgZGVwdGggZW5jb3VudGVyZWQuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICh2Y3R4dC0+ZWxlbUluZm9zID09IE5VTEwpIHsJCgl2Y3R4dC0+ZWxlbUluZm9zID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyICopIAoJICAgIHhtbE1hbGxvYygxMCAqIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJhbGxvY2F0aW5nIHRoZSBlbGVtZW50IGluZm8gYXJyYXkiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJbWVtc2V0KHZjdHh0LT5lbGVtSW5mb3MsIDAsIDEwICogc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSk7Cgl2Y3R4dC0+c2l6ZUVsZW1JbmZvcyA9IDEwOwogICAgfSBlbHNlIGlmICh2Y3R4dC0+c2l6ZUVsZW1JbmZvcyA9PSB2Y3R4dC0+ZGVwdGgpIHsKCWludCBpID0gdmN0eHQtPnNpemVFbGVtSW5mb3M7CgoJdmN0eHQtPnNpemVFbGVtSW5mb3MgKj0gMjsKCXZjdHh0LT5lbGVtSW5mb3MgPSAoeG1sU2NoZW1hTm9kZUluZm9QdHIgKikgCgkgICAgeG1sUmVhbGxvYyh2Y3R4dC0+ZWxlbUluZm9zLCB2Y3R4dC0+c2l6ZUVsZW1JbmZvcyAqIAoJICAgIHNpemVvZih4bWxTY2hlbWFOb2RlSW5mb1B0cikpOwoJaWYgKHZjdHh0LT5lbGVtSW5mb3MgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJyZS1hbGxvY2F0aW5nIHRoZSBlbGVtZW50IGluZm8gYXJyYXkiLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwoJfQoJLyoKCSogV2UgbmVlZCB0aGUgbmV3IG1lbW9yeSB0byBiZSBOVUxMZWQuCgkqIFRPRE86IFVzZSBtZW1zZXQgaW5zdGVhZD8KCSovCglmb3IgKDsgaSA8IHZjdHh0LT5zaXplRWxlbUluZm9zOyBpKyspCgkgICAgdmN0eHQtPmVsZW1JbmZvc1tpXSA9IE5VTEw7CiAgICB9IGVsc2UKCWluZm8gPSB2Y3R4dC0+ZWxlbUluZm9zW2RlcHRoXTsKCiAgICBpZiAoaW5mbyA9PSBOVUxMKSB7CglpbmZvID0gKHhtbFNjaGVtYU5vZGVJbmZvUHRyKSAKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CglpZiAoaW5mbyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgYW4gZWxlbWVudCBpbmZvIiwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0JCgl2Y3R4dC0+ZWxlbUluZm9zW2RlcHRoXSA9IGluZm87CiAgICB9CiAgICBtZW1zZXQoaW5mbywgMCwgc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CiAgICBpbmZvLT5kZXB0aCA9IGRlcHRoOwogIAogICAgcmV0dXJuIChpbmZvKTsKfQojZW5kaWYgLyogRUxFTV9JTkZPX0VOQUJMRUQgKi8KCgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJTdGF0ZXM6CiAqIEBzdGF0ZTogIGEgbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqIEZyZWUgdGhlIGdpdmVuIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyh4bWxTY2hlbWFBdHRyU3RhdGVQdHIgc3RhdGUpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CiAgICB3aGlsZSAoc3RhdGUgIT0gTlVMTCkgewoJdG1wID0gc3RhdGU7CglzdGF0ZSA9IHN0YXRlLT5uZXh0OwkKCXhtbEZyZWUodG1wKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGF0dHJzOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZXMKICoKICogUmVnaXN0ZXIgdGhlIGxpc3Qgb2YgYXR0cmlidXRlcyBhcyB0aGUgc2V0IHRvIGJlIHZhbGlkYXRlZCBvbiB0aGF0IGVsZW1lbnQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbEF0dHJQdHIgYXR0cnMpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgogICAgY3R4dC0+YXR0ciA9IE5VTEw7CiAgICBjdHh0LT5hdHRyVG9wID0gTlVMTDsKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRycy0+bnMgIT0gTlVMTCkgJiYKICAgICAgICAgICAgKHhtbFN0ckVxdWFsKGF0dHJzLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpKSB7CiAgICAgICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCXRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpCgkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCWlmICh0bXAgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXRtcC0+YXR0ciA9IGF0dHJzOwoJdG1wLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTjsKCXRtcC0+bmV4dCA9IE5VTEw7Cgl0bXAtPmRlY2wgPSBOVUxMOwoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgCiAgICAgICAgICAgIGN0eHQtPmF0dHIgPSB0bXA7CgllbHNlCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHRtcDsKCWN0eHQtPmF0dHJUb3AgPSB0bXA7CiAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCiNpZiAwIC8qIEN1cnJlbnRseSBub3QgdXNlZCAqLwovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDaGVja05vZGVMaXN0CiAqIEBub2RlbGlzdDogdGhlIGxpc3Qgb2Ygbm9kZXMKICoKICogQ2hlY2sgdGhlIG5vZGUgbGlzdCBpcyBvbmx5IG1hZGUgb2YgdGV4dCBub2RlcyBhbmQgZW50aXRpZXMgcG9pbnRpbmcKICogdG8gdGV4dCBub2RlcwogKgogKiBSZXR1cm5zIDEgaWYgdHJ1ZSwgMCBpZiBmYWxzZSBhbmQgLTEgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoeG1sTm9kZVB0ciBub2RlbGlzdCkKewogICAgd2hpbGUgKG5vZGVsaXN0ICE9IE5VTEwpIHsKICAgICAgICBpZiAobm9kZWxpc3QtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgewogICAgICAgICAgICBUT0RPICAgICAgICAgICAgICAgIC8qIGltcGxlbWVudCByZWN1cnNpb24gaW4gdGhlIGVudGl0eSBjb250ZW50ICovCiAgICAgICAgfQogICAgICAgIGlmICgobm9kZWxpc3QtPnR5cGUgIT0gWE1MX1RFWFRfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DT01NRU5UX05PREUpICYmCiAgICAgICAgICAgIChub2RlbGlzdC0+dHlwZSAhPSBYTUxfUElfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIHJldHVybiAoMCk7CiAgICAgICAgfQogICAgICAgIG5vZGVsaXN0ID0gbm9kZWxpc3QtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDEpOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQKeG1sU2NoZW1hUG9zdFNjaGVtYUFzc2VtYmxlRml4dXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0KQp7CiAgICBpbnQgaSwgbmJJdGVtczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgaXRlbSwgKml0ZW1zOwoKCiAgICAvKgogICAgKiBEdXJpbmcgdGhlIEFzc2VtYmxlIG9mIHRoZSBzY2hlbWEgY3R4dC0+Y3VySXRlbXMgaGFzCiAgICAqIGJlZW4gZmlsbGVkIHdpdGggdGhlIHJlbGV2YW50IG5ldyBpdGVtcy4gRml4IHRob3NlIHVwLgogICAgKi8KICAgIG5iSXRlbXMgPSBjdHh0LT5hc3NlbWJsZS0+bmJJdGVtczsKICAgIGl0ZW1zID0gKHhtbFNjaGVtYVR5cGVQdHIgKikgY3R4dC0+YXNzZW1ibGUtPml0ZW1zOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hQXR0ckZpeHVwKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hUmVmRml4dXBDYWxsYmFjaygoeG1sU2NoZW1hRWxlbWVudFB0cikgaXRlbSwgY3R4dCwgCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQOgoJCXhtbFNjaGVtYUF0dHJHcnBGaXh1cCgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIAoJCSAgICBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQl4bWxTY2hlbWFHcm91cERlZkZpeHVwKGl0ZW0sIGN0eHQsIE5VTEwpOyAgICAgICAgICAgIAoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBDaXJjdWxhcml0eSBjaGVja3MuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9HUk9VUDoKCQl4bWxTY2hlbWFDaGVja0dyb3VwRGVmQ2lyY3VsYXIoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVA6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVHcm91cENpcmN1bGFyKAoJCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAvKgogICAgKiBGaXh1cCBmb3IgYWxsIG90aGVyIGl0ZW0uIAogICAgKiBUT0RPOiBIbW0sIG5vdCBzdXJlIGlmIHN0YXJ0aW5nIGZyb20gY29tcGxleC9zaW1wbGUgdHlwZXMsCiAgICAqIGFsbCBzdWJzZXF1ZW50IGl0ZW1zIHdpbGwgYmUgcmVhY2hlZC4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsJICAgIAogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFUeXBlRml4dXAoaXRlbSwgY3R4dCwgTlVMTCk7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlicmVhazsKCX0KICAgIH0KICAgIC8qCiAgICAqIENoZWNrIGZhY2V0IHZhbHVlcy4gTm90ZSB0aGF0IGZhY2V0cyBhcmUKICAgICogaG9sZCBieSBzaW1wbGUgdHlwZSBjb21wb25lbnRzIG9ubHkgKGFuZAogICAgKiBieSBjb21wbGV4IHR5cGVzIGluIHRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uKS4KICAgICovCiAgICAvKiBPTEQ6IAogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKCQl4bWxTY2hlbWFDaGVja0RlZmF1bHRzKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9CiAgICAqLwogICAgLyoKICAgICogQnVpbGQgdGhlIGNvbnRlbnQgbW9kZWwgZm9yIGNvbXBsZXggdHlwZXMuCiAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IG5iSXRlbXM7IGkrKykgewoJaXRlbSA9IGl0ZW1zW2ldOwoJc3dpdGNoIChpdGVtLT50eXBlKSB7CSAgICAKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgoJCXhtbFNjaGVtYUJ1aWxkQ29udGVudE1vZGVsKGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJYnJlYWs7Cgl9CiAgICB9IAogICAgLyoKICAgICogVmFsaWRhdGUgdmFsdWUgY29udHJhaW50IHZhbHVlcy4KICAgICovCiAgICBmb3IgKGkgPSAwOyBpIDwgbmJJdGVtczsgaSsrKSB7CglpdGVtID0gaXRlbXNbaV07Cglzd2l0Y2ggKGl0ZW0tPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEU6CgkJeG1sU2NoZW1hQ2hlY2tBdHRyVmFsQ29uc3RyKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIGl0ZW0sIGN0eHQsIE5VTEwpOwoJCWJyZWFrOwoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6CgkJeG1sU2NoZW1hQ2hlY2tFbGVtVmFsQ29uc3RyKCh4bWxTY2hlbWFFbGVtZW50UHRyKSBpdGVtLCBjdHh0LCBOVUxMKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQogICAgfQp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uOgogKiBAcGN0eHQ6ICBhIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogdGhlIGV4aXN0aW5nIHNjaGVtYQogKiBAbm9kZTogdGhlIG5vZGUgdGhhdCBmaXJlZCB0aGUgYXNzZW1ibGluZwogKiBAbnNOYW1lOiB0aGUgbmFtZXNwYWNlIG5hbWUgb2YgdGhlIG5ldyBzY2hlbWEKICogQGxvY2F0aW9uOiB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeUxvY2F0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAoJCQkgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbnNOYW1lLAoJCQkgICAgY29uc3QgeG1sQ2hhciAqbG9jYXRpb24pCnsKICAgIGNvbnN0IHhtbENoYXIgKnRhcmdldE5zLCAqb2xkdG5zOyAKICAgIHhtbERvY1B0ciBkb2MsIG9sZGRvYzsKICAgIGludCBvbGRmbGFncywgcmV0ID0gMDsKICAgIHhtbE5vZGVQdHIgZG9jRWxlbTsKICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgcGN0eHQ7CgogICAgLyoKICAgICogVGhpcyBzaG91bGQgYmUgdXNlZDoKICAgICogMS4gb24gPGltcG9ydD4ocykKICAgICogMi4gaWYgcmVxdWVzdGVkIGJ5IHRoZSB2YWxpZGF0ZWQgaW5zdGFuY2UgCiAgICAqIDMuIGlmIHJlcXVlc3RlZCB2aWEgdGhlIEFQSQogICAgKi8KICAgIGlmICgodmN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogQ3JlYXRlIGEgdGVtcG9yYXJ5IHBhcnNlciBjb250ZXh0LgogICAgKi8KICAgIGlmICgodmN0eHQtPnBjdHh0ID09IE5VTEwpICYmCgkoeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KHZjdHh0KSA9PSAtMSkpIHsKCXhtbFNjaGVtYVZFcnIodmN0eHQsIG5vZGUsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24sICIKCSAgICAiZmFpbGVkIHRvIGNyZWF0ZSBhIHRlbXAuIHBhcnNlciBjb250ZXh0LlxuIiwgCgkgICAgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsJCQogICAgfSAgICAgICAgICAgIAogICAgcGN0eHQgPSB2Y3R4dC0+cGN0eHQ7CiAgICAvKgogICAgKiBTZXQgdGhlIGNvdW50ZXIgdG8gcHJvZHVjZSB1bmlxdWUgbmFtZXMgZm9yIGFub255bW91cyBpdGVtcy4KICAgICovCiAgICBwY3R4dC0+Y291bnRlciA9IHNjaGVtYS0+Y291bnRlcjsgICAgCiAgICAvKgogICAgKiBBY3F1aXJlIHRoZSBzY2hlbWEgZG9jdW1lbnQuCiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hQWNxdWlyZVNjaGVtYURvYyhwY3R4dCwgc2NoZW1hLCBub2RlLAoJbnNOYW1lLCBsb2NhdGlvbiwgJmRvYywgJnRhcmdldE5zLCAwKTsKICAgIGlmIChyZXQgIT0gMCkgewoJaWYgKGRvYyAhPSBOVUxMKQoJICAgIHhtbEZyZWVEb2MoZG9jKTsKICAgIH0gZWxzZSBpZiAoZG9jICE9IE5VTEwpIHsKCWRvY0VsZW0gPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwoJLyoKCSogQ3JlYXRlIG5ldyBhc3NlbWJsZSBpbmZvLgoJKi8KCWlmIChwY3R4dC0+YXNzZW1ibGUgPT0gTlVMTCkgewoJICAgIHBjdHh0LT5hc3NlbWJsZSA9IHhtbFNjaGVtYU5ld0Fzc2VtYmxlKCk7CgkgICAgaWYgKHBjdHh0LT5hc3NlbWJsZSA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJICAgICJNZW1vcnkgZXJyb3I6IHhtbFNjaGVtYUFzc2VtYmxlQnlMb2NhdGlvbiwgIgoJCSAgICAiYWxsb2NhdGluZyBhc3NlbWJsZSBpbmZvIiwgTlVMTCk7CgkJeG1sRnJlZURvYyhkb2MpOwoJCXJldHVybiAoLTEpOwoJICAgIH0KCX0KCS8qCgkqIFNhdmUgYW5kIHJlc2V0IHRoZSBjb250ZXh0ICYgc2NoZW1hLgoJKi8KCW9sZGZsYWdzID0gc2NoZW1hLT5mbGFnczsKCW9sZHRucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJb2xkZG9jID0gc2NoZW1hLT5kb2M7CgkKCXhtbFNjaGVtYUNsZWFyU2NoZW1hRGVmYXVsdHMoc2NoZW1hKTsKCXNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0gdGFyZ2V0TnM7CgkvKiBzY2hlbWEtPm5iQ3VySXRlbXMgPSAwOyAqLwoJcGN0eHQtPnNjaGVtYSA9IHNjaGVtYTsKCXBjdHh0LT5jdHh0VHlwZSA9IE5VTEw7CglwY3R4dC0+cGFyZW50SXRlbSA9IE5VTEw7CgkKCXhtbFNjaGVtYVBhcnNlU2NoZW1hRGVmYXVsdHMocGN0eHQsIHNjaGVtYSwgZG9jRWxlbSk7CQkKCXhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwocGN0eHQsIHNjaGVtYSwgZG9jRWxlbS0+Y2hpbGRyZW4pOwoJeG1sU2NoZW1hUG9zdFNjaGVtYUFzc2VtYmxlRml4dXAocGN0eHQpOwoJLyoKCSogU2V0IHRoZSBjb3VudGVyIG9mIGl0ZW1zLgoJKi8KCXNjaGVtYS0+Y291bnRlciA9IHBjdHh0LT5jb3VudGVyOwoJLyoKCSogRnJlZSB0aGUgbGlzdCBvZiBhc3NlbWJsZWQgY29tcG9uZW50cy4KCSovCglwY3R4dC0+YXNzZW1ibGUtPm5iSXRlbXMgPSAwOwoJLyoKCSogUmVzdG9yZSB0aGUgY29udGV4dCAmIHNjaGVtYS4KCSovCglzY2hlbWEtPmZsYWdzID0gb2xkZmxhZ3M7CglzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSA9IG9sZHRuczsKCXNjaGVtYS0+ZG9jID0gb2xkZG9jOwoJcmV0ID0gcGN0eHQtPmVycjsKICAgIH0gICAgICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHI6CiAqIEB2Y3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAeHNpQXR0cjogYW4geHNpIGF0dHJpYnV0ZQogKiBAbm9OYW1lc3BhY2U6IHdoZXRoZXIgYSBzY2hlbWEgd2l0aCBubyB0YXJnZXQgbmFtZXNwYWNlIGlzIGV4cHRlY3RlZAogKgogKiBFeHBhbmRzIGFuIGV4aXN0aW5nIHNjaGVtYSBieSBhbiBhZGRpdGlvbmFsIHNjaGVtYSB1c2luZwogKiB0aGUgeHNpOnNjaGVtYUxvY2F0aW9uIG9yIHhzaTpub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZQogKiBvZiBhbiBpbnN0YW5jZS4gSWYgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gaXMgdXNlZCwgQG5vTmFtZXNwYWNlCiAqIG11c3QgYmUgc2V0IHRvIDEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgbmV3IHNjaGVtYSBpcyBjb3JyZWN0LCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJIHhtbEF0dHJQdHIgeHNpQXR0ciwKCQkJIGludCBub05hbWVzcGFjZSkKewogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpjdXIsICplbmQ7CiAgICBjb25zdCB4bWxDaGFyICpuc25hbWUgPSBOVUxMLCAqbG9jYXRpb247CiAgICBpbnQgY291bnQgPSAwOwogICAgaW50IHJldCA9IDA7CiAgICAKICAgIGlmICh4c2lBdHRyID09IE5VTEwpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIodmN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCSAgICBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUF0dHIsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBQYXJzZSB0aGUgdmFsdWU7IHdlIHdpbGwgYXNzdW1lIGFuIGV2ZW4gbnVtYmVyIG9mIHZhbHVlcwogICAgKiB0byBiZSBnaXZlbiAodGhpcyBpcyBob3cgWGVyY2VzIGFuZCBYU1Ygd29yaykuCiAgICAqLwogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgeHNpQXR0cik7ICAgIAogICAgY3VyID0gdmFsdWU7CiAgICBkbyB7CQoJaWYgKG5vTmFtZXNwYWNlICE9IDEpIHsKCSAgICAvKgoJICAgICogR2V0IHRoZSBuYW1lc3BhY2UgbmFtZS4KCSAgICAqLwoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgY291bnQrKzsKCSAgICBuc25hbWUgPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsJCQoJICAgIGN1ciA9IGVuZDsKCX0KCS8qCgkqIEdldCB0aGUgVVJJLgoJKi8KCXdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCSAgICBjdXIrKzsKCWVuZCA9IGN1cjsKCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJICAgIGVuZCsrOwoJaWYgKGVuZCA9PSBjdXIpCgkgICAgYnJlYWs7Cgljb3VudCsrOwoJbG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKHZjdHh0LT5zY2hlbWEtPmRpY3QsIGN1ciwgZW5kIC0gY3VyKTsKCWN1ciA9IGVuZDsJCglyZXQgPSB4bWxTY2hlbWFBc3NlbWJsZUJ5TG9jYXRpb24odmN0eHQsIHZjdHh0LT5zY2hlbWEsIAoJICAgIHhzaUF0dHItPnBhcmVudCwgbnNuYW1lLCBsb2NhdGlvbik7CglpZiAocmV0ID09IC0xKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJKHhtbE5vZGVQdHIpIHhzaUF0dHIsIE5VTEwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFBc3NlbWJsZUJ5WFNJQXR0ciwgIgoJCSJhc3NlbWJsaW5nIHNjaGVtYXRhIiwgTlVMTCk7CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSh2YWx1ZSk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9IHdoaWxlICgqY3VyICE9IDApOwogICAgaWYgKHZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKHZhbHVlKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtOgogKiBAdmN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06IGFuIGVsZW1lbnQgbm9kZSBwb3NzaWJseSBob2xkaW5nIHhzaSBhdHRyaWJ1dGVzCiAqIEBub05hbWVzcGFjZTogd2hldGhlciBhIHNjaGVtYSB3aXRoIG5vIHRhcmdldCBuYW1lc3BhY2UgaXMgZXhwdGVjdGVkCiAqCiAqIEFzc2VtYmxlcyBhbiBleGlzdGluZyBzY2hlbWEgYnkgYW4gYWRkaXRpb25hbCBzY2hlbWEgdXNpbmcKICogdGhlIHhzaTpzY2hlbWFMb2NhdGlvbiBvciB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiBhdHRyaWJ1dGVzCiAqIG9mIHRoZSBnaXZlbiBAZWxlbS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBuZXcgc2NoZW1hIGlzIGNvcnJlY3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAgCgkJCSB4bWxOb2RlUHRyIGVsZW0pCnsgICAgCiAgICBpbnQgcmV0ID0gMCwgcmV0TnMgPSAwOwogICAgeG1sQXR0clB0ciBhdHRyOwoKICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgInNjaGVtYUxvY2F0aW9uIiwgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CglyZXROcyA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHZjdHh0LCBhdHRyLCAwKTsKCWlmIChyZXROcyA9PSAtMSkKCSAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lBdHRyKHZjdHh0LCBhdHRyLCAxKTsKCWlmIChyZXQgPT0gLTEpCgkgICAgcmV0dXJuICgtMSk7CiAgICB9CiAgICBpZiAocmV0TnMgIT0gMCkKCXJldHVybiAocmV0TnMpOwogICAgZWxzZQoJcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5hbWU6ICB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudCBkZXRlY3RlZCAobWlnaHQgYmUgTlVMTCkKICogQHR5cGU6ICB0aGUgdHlwZQogKgogKiBBIHRyYW5zaXRpb24gaGFzIGJlZW4gbWFkZSBpbiB0aGUgYXV0b21hdGEgYXNzb2NpYXRlZCB0byBhbiBlbGVtZW50CiAqIGNvbnRlbnQgbW9kZWwKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2soeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUgQVRUUklCVVRFX1VOVVNFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIHhtbE5vZGVQdHIgb2xkbm9kZSA9IGN0eHQtPm5vZGU7CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2s6ICVzLCAlcywgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgbmFtZSwgdHlwZS0+bmFtZSwgbm9kZS0+bmFtZSk7CiNlbmRpZgogICAgLyoKICAgICogQHR5cGUtPnR5cGUgd2lsbCBiZSBYTUxfU0NIRU1BX1RZUEVfQU5ZIG9yIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5ULgogICAgKi8KICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgY3R4dC0+bm9kZSA9IG5vZGU7ICAgIAogICAgY3R4dC0+Y3VyID0gbm9kZS0+Y2hpbGRyZW47CgojaWZkZWYgRUxFTV9JTkZPX0VOQUJMRUQKICAgIHhtbFNjaGVtYUJlZ2luRWxlbWVudChjdHh0KTsKI2VuZGlmCgogICAgLyoKICAgICogQXNzZW1ibGUgbmV3IHNjaGVtYXRhIHVzaW5nIHhzaS4KICAgICovCiAgICBpZiAoY3R4dC0+eHNpQXNzZW1ibGUpIHsKCWludCByZXQ7CgoJcmV0ID0geG1sU2NoZW1hQXNzZW1ibGVCeVhTSUVsZW0oY3R4dCwgY3R4dC0+bm9kZSk7CglpZiAocmV0ID09IC0xKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQljdHh0LT5ub2RlLCBOVUxMLCAJCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQsICIKCQkiYXNzZW1ibGluZyBzY2hlbWEgYnkgeHNpIiwgTlVMTCk7CgkgICAgZ290byBsZWF2ZTsKCX0KCS8qCgkqIE5PVEU6IFdlIHdvbid0IHJlYWN0IG9uIHNjaGVtYSBwYXJzZXIgZXJyb3JzIGhlcmUuCgkqIFRPRE86IEJ1dCBhIHdhcm5pbmcgd291bGQgYmUgbmljZS4KCSovCiAgICB9ICAgIAogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOiB7CgkgICAgLyoKCSAgICAqIE5PVEU6IFRoZSBidWlsZCBvZiB0aGUgY29udGVudCBtb2RlbCAKCSAgICAqICh4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwpIGVuc3VyZXMgdGhhdCB0aGUgZWxlbWVudCAKCSAgICAqIGRlY2xhcmF0aW9uIChhbmQgbm90IGEgcmVmZXJlbmNlIHRvIGl0KSB3aWxsIGJlIGdpdmVuLgoJICAgICovCgkgICAgaWYgKCgoeG1sU2NoZW1hRWxlbWVudFB0cikgY3R4dC0+dHlwZSktPnJlZiAhPSBOVUxMKSB7CgkJLyoKCQkqIFRoaXMgaXMgcGFyYW5vaWQgY29kaW5nIDstKS4uLiBpdCBzaG91bGQgbm90CgkJKiBoYXBwZW4gaGVyZSBhbnkgbW9yZS4KCQkqLwoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkgICAgbm9kZSwgTlVMTCwJCQkJCQkKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCAiCgkJICAgICJlbGVtZW50IGRlY2xhcmF0aW9uICdyZWZlcmVuY2UnIGVuY291bnRlcmVkLCAiCgkJICAgICJidXQgYW4gZWxlbWVudCBkZWNsYXJhdGlvbiB3YXMgZXhwZWN0ZWQiLCAKCQkgICAgTlVMTCk7CgkJZ290byBsZWF2ZTsKCSAgICB9CgkgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbihjdHh0LCAKCQkoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZSk7CgkgICAgYnJlYWs7Cgl9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgoJICAgIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQoY3R4dCwgdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwoJZGVmYXVsdDogCgkgICAgYnJlYWs7CiAgICB9CmxlYXZlOgoKI2lmZGVmIEVMRU1fSU5GT19FTkFCTEVECiAgICB4bWxTY2hlbWFFbmRFbGVtZW50KGN0eHQpOwojZW5kaWYKICAgIGN0eHQtPnR5cGUgPSBvbGR0eXBlOwogICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7Cn0gIAoKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZU5vdGF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwgCgkJCSAgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCSAgeG1sU2NoZW1hVmFsUHRyICp2YWwsCgkJCSAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpbnQgcmV0OwogICAgICAgIAogICAgcmV0ID0geG1sVmFsaWRhdGVRTmFtZSh2YWx1ZSwgMSk7CiAgICBpZiAocmV0ICE9IDApCglyZXR1cm4gKHJldCk7CgogICAgewoJeG1sQ2hhciAqdXJpID0gTlVMTDsKCXhtbENoYXIgKmxvY2FsID0gTlVMTDsKCXhtbENoYXIgKnByZWZpeDsKCQoJbG9jYWwgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CglpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxOc1B0ciBuczsKCgkgICAgLyoKCSAgICAqIFRPRE86IE1ha2UgdGhpcyBzdHJlYW1hYmxlLgoJICAgICovCgkgICAgaWYgKChub2RlID09IE5VTEwpIHx8IChub2RlLT5kb2MgPT0gTlVMTCkpIHsKICAgIAkJeG1sRnJlZShwcmVmaXgpOwoJCXhtbEZyZWUobG9jYWwpOwoJCXJldHVybiAoMyk7CgkgICAgfQoJICAgIAoJICAgIG5zID0geG1sU2VhcmNoTnMobm9kZS0+ZG9jLCBub2RlLCBwcmVmaXgpOwoJICAgIGlmIChucyA9PSBOVUxMKSB7CgkJeG1sRnJlZShwcmVmaXgpOwoJCXhtbEZyZWUobG9jYWwpOwoJCXJldHVybiAoMSk7CgkgICAgfQoJfQkKCWlmIChwcmVmaXggIT0gTlVMTCkgewoJICAgIGlmICh4bWxIYXNoTG9va3VwMih2Y3R4dC0+c2NoZW1hLT5ub3RhRGVjbCwgbG9jYWwsIHVyaSkgPT0gTlVMTCkKCQlyZXQgPSAxOwoJfSBlbHNlIGlmICh4bWxIYXNoTG9va3VwMih2Y3R4dC0+c2NoZW1hLT5ub3RhRGVjbCwgdmFsdWUsCgkgICAgTlVMTCkgPT0gTlVMTCkKCSAgICByZXQgPSAxOwoKCWlmICgocmV0ID09IDApICYmICh2YWwgIT0gTlVMTCkpIHsKCSAgICBpZiAocHJlZml4ICE9IE5VTEwpIHsKCQkoKnZhbCkgPSB4bWxTY2hlbWFOZXdOT1RBVElPTlZhbHVlKEJBRF9DQVNUIGxvY2FsLAoJCSAgICBCQURfQ0FTVCB4bWxTdHJkdXAodXJpKSk7CgkJbG9jYWwgPSBOVUxMOwoJICAgIH0gZWxzZSAKCQkoKnZhbCkgPSB4bWxTY2hlbWFOZXdOT1RBVElPTlZhbHVlKEJBRF9DQVNUIHhtbFN0cmR1cCh2YWx1ZSksCgkJTlVMTCk7CgkgICAgaWYgKCp2YWwgPT0gTlVMTCkKCQlyZXQgPSAtMTsKCX0KCWlmIChsb2NhbCAhPSBOVUxMKQoJICAgIHhtbEZyZWUobG9jYWwpOwogICAgfQoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdmFsdWU6IHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQKICogQGZpcmVFcnJvcnM6IHNoYWxsIGVycm9ycyBiZSByZXBvcnRlZD8KICogQGFwcGx5RmFjZXRzOiBzaGFsbCBmYWNldHMgYmUgYXBwbGllZD8KICogQG5vcm1hbGl6ZTogc2hhbGwgdGhlIHZhbHVlIGJlIG5vcm1hbGl6ZWQ/CiAqIEBjaGVja05vZGVzOiBzaGFsbCB0aGUgY29udGVudCBub2RlcyBiZSBjaGVja2VkPwogKgogKiBWYWxpZGF0ZXMgYSB2YWx1ZSBieSB0aGUgZ2l2ZW4gdHlwZSAodXNlciBkZXJpdmVkIG9yIGJ1aWx0LWluKS4KICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAoJCQkJIGNvbnN0IHhtbENoYXIgKnZhbHVlLAkJCQkgCgkJCQkgaW50IGZpcmVFcnJvcnMsCQkJCSAKCQkJCSBpbnQgYXBwbHlGYWNldHMsCgkJCQkgaW50IG5vcm1hbGl6ZSwKCQkJCSBpbnQgY2hlY2tOb2RlcykKewogICAgeG1sTm9kZVB0ciBub2RlOwogICAgaW50IHJldCA9IDA7ICAKICAgIHhtbENoYXIgKm5vcm1WYWx1ZSA9IE5VTEw7CiAgICBpbnQgd3RzcDsgICAgICAgCiAKICAgIG5vZGUgPSBjdHh0LT5ub2RlOwogICAgLyogU2F2ZSB0aGUgY3VycmVudCB3aGl0ZXNwYWNlIG5vcm1hbGl6YXRpb24gdHlwZS4gKi8KICAgIHd0c3AgPSBjdHh0LT52YWx1ZVdTOwogICAgLyoKICAgICogTm9ybWFsaXplIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAobm9ybWFsaXplICYmIAoJKGN0eHQtPnZhbHVlV1MgIT0gWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0UpKSB7CglpbnQgbm9ybSA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKHR5cGUpOwoJCglpZiAoKG5vcm0gIT0gLTEpICYmIChub3JtID4gY3R4dC0+dmFsdWVXUykpIHsKCSAgICBpZiAobm9ybSA9PSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSkKCQlub3JtVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZyh2YWx1ZSk7CgkgICAgZWxzZQoJCW5vcm1WYWx1ZSA9IHhtbFNjaGVtYVdoaXRlU3BhY2VSZXBsYWNlKHZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZVdTID0gbm9ybTsKCSAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgkJdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBub3JtVmFsdWU7Cgl9CQkKICAgIH0gICAgCiAgICAvKgogICAgKiBUaGUgbm9kZXMgb2YgYSBjb250ZW50IG11c3QgYmUgY2hlY2tlZCBvbmx5IG9uY2UsCiAgICAqIHRoaXMgaXMgbm90IHdvcmtpbmcgc2luY2UgbGlzdCB0eXBlcyB3aWxsIGZpcmUgdGhpcwogICAgKiBtdWx0aXBsZSB0aW1lcy4KICAgICovCiAgICBpZiAoKGNoZWNrTm9kZXMgPT0gMSkgJiYgKGN0eHQtPmN1ciAhPSBOVUxMKSkgewoJeG1sTm9kZVB0ciBjdXIgPSBjdHh0LT5jdXI7CgoJZG8gewoJICAgIHN3aXRjaCAoY3VyLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfVEVYVF9OT0RFOgoJICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKCSAgICBjYXNlIFhNTF9QSV9OT0RFOgoJICAgIGNhc2UgWE1MX0NPTU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKCSAgICBjYXNlIFhNTF9YSU5DTFVERV9FTkQ6CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfRU5USVRZX1JFRl9OT0RFOgoJICAgIGNhc2UgWE1MX0VOVElUWV9OT0RFOgoJCS8qIFRPRE86IFNjb3VyIHRoZSBlbnRpdGllcyBmb3IgaWxsZWdhbCBub2Rlcy4gKi8KCQlUT0RPIGJyZWFrOwoJICAgIGNhc2UgWE1MX0VMRU1FTlRfTk9ERTogewoJICAgIC8qIE5PVEU6IENoYW5nZWQgdG8gYW4gaW50ZXJuYWwgZXJyb3IsIHNpbmNlIHRoZSAKCSAgICAqIGV4aXN0ZW5jZSBvZiBhbiBlbGVtZW50IG5vZGUgd2lsbCBiZSBhbHJlYWR5IGNoZWNrZWQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5U2ltcGxlVHlwZSBhbmQgaW4KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5Q29tcGxleFR5cGUuCgkJKi8KCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgLyogWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLCAqLwoJCSAgICBub2RlLCB0eXBlLAoJCSAgICAiRWxlbWVudCAnJXMnIGZvdW5kIGluIHNpbXBsZSB0eXBlIGNvbnRlbnQiLCAKCQkgICAgY3VyLT5uYW1lKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFWX0lOVEVSTkFMKTsKCQkJCSAgIH0KCSAgICBjYXNlIFhNTF9BVFRSSUJVVEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX1RZUEVfTk9ERToKCSAgICBjYXNlIFhNTF9ET0NVTUVOVF9GUkFHX05PREU6CgkgICAgY2FzZSBYTUxfTk9UQVRJT05fTk9ERToKCSAgICBjYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CgkgICAgY2FzZSBYTUxfRFREX05PREU6CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9ERUNMOgoJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9ERUNMOgoJICAgIGNhc2UgWE1MX0VOVElUWV9ERUNMOgoJICAgIGNhc2UgWE1MX05BTUVTUEFDRV9ERUNMOgojaWZkZWYgTElCWE1MX0RPQ0JfRU5BQkxFRAoJICAgIGNhc2UgWE1MX0RPQ0JfRE9DVU1FTlRfTk9ERTogCiNlbmRpZgkJICAgIAkJICAgIAkJICAgIAoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAvKiBYTUxfU0NIRU1BU19FUlJfSU5WQUxJREVMRU0sICovCgkJICAgIG5vZGUsIE5VTEwsCgkJICAgICJOb2RlIG9mIHVuZXhwZWN0ZWQgdHlwZSBmb3VuZCBpbiBzaW1wbGUgdHlwZSBjb250ZW50IiwKCQkgICAgTlVMTCk7CgkJcmV0dXJuIChYTUxfU0NIRU1BVl9JTlRFUk5BTCk7CgkgICAgfQoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJeG1sU2NoZW1hVHlwZVB0ciBiYXNlLCBhbnlUeXBlOwoKCWFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCgliYXNlID0gdHlwZS0+YmFzZVR5cGU7Cgl3aGlsZSAoKGJhc2UgIT0gTlVMTCkgJiYgCgkgICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgJiYKCSAgICAoYmFzZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpICYmCgkgICAgKGJhc2UgIT0gYW55VHlwZSkpIHsKCSAgICBiYXNlID0gYmFzZS0+YmFzZVR5cGU7Cgl9CglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCBiYXNlLCB2YWx1ZSwgMSwgMCwgMSwgMCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGNvbXBsZXggdHlwZSAnJXMnXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfSBlbHNlIGlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgLyogCgkgICAgKiBDaGVjayBmYWNldHMuCgkgICAgKi8JICAgIAoJICAgIC8qCgkgICAgKiBUaGlzIGlzIHNvbWVob3cgbm90IG5pY2UsIHNpbmNlIGlmIGFuIGVycm9yIG9jY3VycwoJICAgICogdGhlIHJlcG9ydGVkIHR5cGUgd2lsbCBiZSB0aGUgY29tcGxleCB0eXBlOyB0aGUgc3BlYwoJICAgICogd2FudHMgYSBzaW1wbGUgdHlwZSB0byBiZSBjcmVhdGVkIG9uIHRoZSBjb21wbGV4IHR5cGUKCSAgICAqIGlmIGl0IGhhcyBhIHNpbXBsZSBjb250ZW50LiBGb3Igbm93IHdlIGhhdmUgdG8gbGl2ZSB3aXRoCgkgICAgKiBpdC4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgY29tcGxleCB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJICAgIH0JCgl9CQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoKCWlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CgkvKgoJKiBTVFJFQU0tUkVBRC1DSElMRFJFTi4KCSovCSAgICAJCQoJaWYgKCh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19OT1RBVElPTikgJiYKCSAgICAoY3R4dC0+c2NoZW1hICE9IE5VTEwpKSB7CgkgICAgLyoKCSAgICAqIE5PVEFUSU9OcyBuZWVkIHRvIGJlIHByb2Nlc3NlZCBoZXJlLCBzaW5jZSB0aGV5IG5lZWQKCSAgICAqIHRvIGxvb2t1cCBpbiB0aGUgaGFzaHRhYmxlIG9mIE5PVEFUSU9OIGRlY2xhcmF0aW9ucy4KCSAgICAqLwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlTm90YXRpb24oY3R4dCwgdmFsdWUsICYoY3R4dC0+dmFsdWUpLCBub2RlKTsgCgl9IGVsc2UKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxQcmVkZWZUeXBlTm9kZU5vTm9ybSh0eXBlLCB2YWx1ZSwgJihjdHh0LT52YWx1ZSksIG5vZGUpOwoJaWYgKHJldCA+IDApIHsJICAgIAoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSAKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgZWxzZQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsJICAgIAoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwoJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgYnVpbHQtaW4gdHlwZSAnJXMnXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAoKGN0eHQtPnZhbHVlID09IE5VTEwpICYmIAoJICAgICh0eXBlLT5idWlsdEluVHlwZSA9PSBYTUxfU0NIRU1BU19TVFJJTkcpICYmCgkgICAgKGN0eHQtPm5vZGVJbmZvICE9IE5VTEwpICYmCgkgICAgKGN0eHQtPm5vZGVJbmZvLT5mbGFncyAmIFhNTF9TQ0hFTUFfRUxFTV9JTkZPX1ZBTFVFX05FRURFRCkpIHsKI2lmZGVmIElEQ19WQUxVRV9TVVBQT1JUCgkgICAgeG1sQ2hhciAqdmFsZHVwOwoJICAgIC8qCgkgICAgKiBDcmVhdGUgYSBwcmVjb21wdXRlZCBzdHJpbmcgdmFsdWUgZm9yICJzdHJpbmciIGFzIHdlbGwgaWYKCSAgICAqIHJlcXVlc3RlZC4KCSAgICAqLwoJICAgIHZhbGR1cCA9IHhtbFN0cmR1cCh2YWx1ZSk7CgkgICAgY3R4dC0+dmFsdWUgPSB4bWxTY2hlbWFOZXdTdHJpbmdWYWx1ZShYTUxfU0NIRU1BU19TVFJJTkcsCgkJQkFEX0NBU1QgdmFsZHVwKTsKCSAgICBpZiAoKHZhbGR1cCAhPSBOVUxMKSAmJiAoY3R4dC0+dmFsdWUgPT0gTlVMTCkpCgkJeG1sRnJlZSh2YWxkdXApOwojZW5kaWYKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSB7ICAgICAgICAKCS8qIDEuMi4xIGlmIHt2YXJpZXR5fSBpcyC3YXRvbWljtyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IAoJKiBhIGxpdGVyYWwgaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259IAoJKi8JCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLT5iYXNlVHlwZSwgdmFsdWUsIDAsIDAsIDAsIDApOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBhdG9taWMgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewkgICAgCgkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xOwoJICAgIGlmIChmaXJlRXJyb3JzKQoJCXhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgbm9kZSwgdmFsdWUsIHR5cGUpOwkKCX0gZWxzZSBpZiAoKGFwcGx5RmFjZXRzKSAmJiAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICAvKiAKCSAgICAqIENoZWNrIGZhY2V0cy4KCSAgICAqLwkgICAgCSAgICAJICAgIAoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgdHlwZSwgCgkJdmFsdWUsIDAsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgYXRvbWljIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCQkvKgoJCSBEaXNhYmxlZCwgc2luY2UgdGhlIGZhY2V0IHZhbGlkYXRpb24gYWxyZWFkeSByZXBvcnRzIGVycm9ycy4KCQlpZiAoZmlyZUVycm9ycykgCgkJICAgIHhtbFNjaGVtYVZTaW1wbGVUeXBlRXJyKGN0eHQsIHJldCwgY3R4dC0+Y3VyLCB2YWx1ZSwgdHlwZSk7CgkJKi8KCSAgICB9CQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CiAgICAgICAgCgl4bWxTY2hlbWFUeXBlUHRyIHRtcFR5cGU7Cgljb25zdCB4bWxDaGFyICpjdXIsICplbmQ7Cgl4bWxDaGFyICp0bXA7Cgl1bnNpZ25lZCBsb25nIGxlbiA9IDA7CgoJLyogMS4yLjIgaWYge3ZhcmlldHl9IGlzILdsaXN0tyB0aGVuIHRoZSBzdHJpbmcgbXVzdCBiZSBhIHNlcXVlbmNlIAoJKiBvZiB3aGl0ZSBzcGFjZSBzZXBhcmF0ZWQgdG9rZW5zLCBlYWNoIG9mIHdoaWNoILdtYXRjaLdlcyBhIGxpdGVyYWwgCgkqIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2Yge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSAKCSovCgkKCWlmICh2YWx1ZSA9PSBOVUxMKQoJICAgIHZhbHVlID0gQkFEX0NBU1QgIiI7Cgl0bXBUeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKTsJCgljdXIgPSB2YWx1ZTsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIGxlbisrOwoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHRtcFR5cGUsIHRtcCwgMCwgMSwgMCwgMCk7CgkgICAgeG1sRnJlZSh0bXApOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBhbiBpdGVtIG9mIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CQoJCWJyZWFrOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CgkJYnJlYWs7CgkgICAgfQkKCSAgICBjdXIgPSBlbmQ7Cgl9IHdoaWxlICgqY3VyICE9IDApOwoJLyogCgkqIENoZWNrIGZhY2V0cy4KCSovCglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAoKHJldCA9PSAwKSAmJiAoYXBwbHlGYWNldHMpKSB7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCB0eXBlLCAKCQl2YWx1ZSwgbGVuLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIGxpc3Qgc2ltcGxlIHR5cGUgJyVzJ1xuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlIGlmIChyZXQgPiAwKSB7CgkJcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yOwoJCS8qCgkJIERpc2FibGVkLCBzaW5jZSB0aGUgZmFjZXQgdmFsaWRhdGlvbiBhbHJlYWR5IHJlcG9ydHMgZXJyb3JzLgoJCWlmIChmaXJlRXJyb3JzKSAKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBjdHh0LT5jdXIsIHZhbHVlLCB0eXBlKTsKCQkqLwoJICAgIH0JIAkgICAKCSAgIAoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyTGluazsKCgkvKgoJKiBUT0RPOiBGb3IgYWxsIGRhdGF0eXBlcyC3ZGVyaXZlZLcgYnkgt3VuaW9utyAgd2hpdGVTcGFjZSBkb2VzIAoJKiBub3QgYXBwbHkgZGlyZWN0bHk7IGhvd2V2ZXIsIHRoZSBub3JtYWxpemF0aW9uIGJlaGF2aW9yIG9mILd1bmlvbrcgCgkqIHR5cGVzIGlzIGNvbnRyb2xsZWQgYnkgdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlIAoJKiC3bWVtYmVyVHlwZXO3IGFnYWluc3Qgd2hpY2ggdGhlILd1bmlvbrcgaXMgc3VjY2Vzc2Z1bGx5IHZhbGlkYXRlZC4gCgkqCgkqIFRoaXMgbWVhbnMgdGhhdCB0aGUgdmFsdWUgaXMgbm9ybWFsaXplZCBieSB0aGUgZmlyc3QgdmFsaWRhdGluZwoJKiBtZW1iZXIgdHlwZSwgdGhlbiB0aGUgZmFjZXRzIG9mIHRoZSB1bmlvbiB0eXBlIGFyZSBhcHBsaWVkLiBUaGlzCgkqIG5lZWRzIGNoYW5naW5nIG9mIHRoZSB2YWx1ZSEKCSovCQoJCgkvKgoJKiAxLjIuMyBpZiB7dmFyaWV0eX0gaXMgt3VuaW9utyB0aGVuIHRoZSBzdHJpbmcgbXVzdCC3bWF0Y2i3IGEgCgkqIGxpdGVyYWwgaW4gdGhlILdsZXhpY2FsIHNwYWNltyBvZiBhdCBsZWFzdCBvbmUgbWVtYmVyIG9mIAoJKiB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IAoJKi8KI2lmZGVmIERFQlVHX1VOSU9OX1ZBTElEQVRJT04KCXByaW50ZigiVW5pb24gU1QgICAgIDogJyVzJ1xuIiwgKGNvbnN0IGNoYXIgKikgdHlwZS0+bmFtZSk7CglwcmludGYoIiAgZmlyZUVycm9ycyA6ICVkXG4iLCBmaXJlRXJyb3JzKTsKCXByaW50ZigiICBhcHBseUZhY2V0czogJWRcbiIsIGFwcGx5RmFjZXRzKTsKI2VuZGlmCgltZW1iZXJMaW5rID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZSk7CglpZiAobWVtYmVyTGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInVuaW9uIHNpbXBsZSB0eXBlICclcycgaGFzIG5vIG1lbWJlciB0eXBlc1xuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXQgPSAtMTsKCX0gCglpZiAocmV0ID09IDApIHsKCSAgICB3aGlsZSAobWVtYmVyTGluayAhPSBOVUxMKSB7CgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgbWVtYmVyTGluay0+dHlwZSwgCgkJICAgIHZhbHVlLCAwLCAxLCAxLCAwKTsKCQlpZiAoKHJldCA8PSAwKSB8fCAocmV0ID09IDApKQoJCSAgICBicmVhazsJICAgIAoJCW1lbWJlckxpbmsgPSBtZW1iZXJMaW5rLT5uZXh0OwoJICAgIH0gICAgIAoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBtZW1iZXJzIG9mIHVuaW9uIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCQlpZiAoZmlyZUVycm9ycykKCQkgICAgeG1sU2NoZW1hVlNpbXBsZVR5cGVFcnIoY3R4dCwgcmV0LCBub2RlLCB2YWx1ZSwgdHlwZSk7CgkgICAgfQoJfQoJLyoKCSogQXBwbHkgZmFjZXRzIChwYXR0ZXJuLCBlbnVtZXJhdGlvbikuCQoJKi8KCWlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgaW50IG13czsKCSAgICAvKgoJICAgICogVGhlIG5vcm1hbGl6YXRpb24gYmVoYXZpb3Igb2Ygt3VuaW9utyB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IAoJICAgICogdGhlIHZhbHVlIG9mIHdoaXRlU3BhY2Ugb24gdGhhdCBvbmUgb2YgdGhlILdtZW1iZXJUeXBlc7cgCgkgICAgKiBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuIAoJICAgICovCQkgICAgCgkgICAgaWYgKG5vcm1WYWx1ZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidGhlIHZhbHVlIHdhcyBhbHJlYWR5IG5vcm1hbGl6ZWQgZm9yIHRoZSB1bmlvbiBzaW1wbGUgIgoJCSAgICAidHlwZSAnJXMnLlxuIiwgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgfQoJICAgIG13cyA9IHhtbFNjaGVtYUdldFdoaXRlU3BhY2VGYWNldFZhbHVlKG1lbWJlckxpbmstPnR5cGUpOwoJICAgIGlmIChtd3MgPiBjdHh0LT52YWx1ZVdTKSB7CgkJaWYgKG13cyA9PSBYTUxfU0NIRU1BU19GQUNFVF9DT0xMQVBTRSkKCQkgICAgbm9ybVZhbHVlID0geG1sU2NoZW1hQ29sbGFwc2VTdHJpbmcodmFsdWUpOwoJCWVsc2UKCQkgICAgbm9ybVZhbHVlID0geG1sU2NoZW1hV2hpdGVTcGFjZVJlcGxhY2UodmFsdWUpOwoJCWlmIChub3JtVmFsdWUgIT0gTlVMTCkKCQkgICAgdmFsdWUgPSAoY29uc3QgeG1sQ2hhciAqKSBub3JtVmFsdWU7CgkgICAgfQoKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIHR5cGUsIAoJCXZhbHVlLCAwLCBmaXJlRXJyb3JzKTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgZmFjZXRzIG9mIHVuaW9uIHNpbXBsZSB0eXBlICclcydcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZSBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCQkvKgoJCWlmIChmaXJlRXJyb3JzKQoJCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LCByZXQsIGN0eHQtPmN1ciwgdmFsdWUsIHR5cGUpOwoJCSovCgkgICAgfQkKCX0KICAgIH0gICAgICAgICAgIAogICAgY3R4dC0+dmFsdWVXUyA9IHd0c3A7CiAgICBpZiAobm9ybVZhbHVlICE9IE5VTEwpCgl4bWxGcmVlKG5vcm1WYWx1ZSk7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSBlbGVtZW50IG5vZGUgdG8gYmUgdmFsaWRhdGVkLgogKgogKiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIAoJCQkJICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgIGludCBpc05pbCwKCQkJCSAgICAgaW50IHZhbFNpbXBsZUNvbnRlbnQpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgb2xkdHlwZTsKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIHhtbE5vZGVQdHIgY3VyOwogICAgaW50IHJldCA9IDAsIHJldHZhbCA9IDA7CiAgICAgICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlTaW1wbGVUeXBlLCAiCgkgICAgImJhZCBhcmd1bWVudHMiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsgICAgCiAgICB9CgogICAgb2xkdHlwZSA9IGN0eHQtPnR5cGU7CiAgICBub2RlID0gY3R4dC0+bm9kZTsKICAgIC8qIAogICAgKiBjdmMtdHlwZTogMy4xLjIgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCAKICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgogICAgKi8gICAKICAgIC8qCiAgICAqIFNUUkVBTTogQ2hpbGQgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBjdXIgPSBub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJLyoKCSogVE9ETzogRW50aXRpZXMsIHdpbGwgdGhleSBwcm9kdWNlIGVsZW1lbnRzIGFzIHdlbGw/CgkqLwoJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8yLAoJCW5vZGUsIHR5cGUsCQkKCQkiTm8gZWxlbWVudCBjb250ZW50IGFsbG93ZWQiLCBOVUxMKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMjsKCX0KCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIAogICAgLyoKICAgICogY3ZjLXR5cGUgMy4xLjE6CiAgICAqCiAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIG11c3QgYmUgZW1wdHksIGV4Y2VwdGluZyB0aG9zZSB3aG9zZSBuYW1lc3BhY2UgbmFtZSAKICAgICogaXMgaWRlbnRpY2FsIHRvIGh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIGFuZCB3aG9zZSBsb2NhbCAKICAgICogbmFtZSBpcyBvbmUgb2YgdHlwZSwgbmlsLCBzY2hlbWFMb2NhdGlvbiBvciBub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uLgogICAgKi8gICAKICAgIC8qCiAgICAqIFNUUkVBTTogQXR0cmlidXRlIG5vZGVzIGFyZSBwcm9jZXNzZWQuCiAgICAqLwogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRyLT5ucyA9PSBOVUxMKSB8fAogICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgfHwKICAgICAgICAgICAgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5pbCIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hTG9jYXRpb24iKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwKICAgICAgICAgICAgICAoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24iKSkpKSB7CgkgICAgeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCVhNTF9TQ0hFTUFWX0NWQ19UWVBFXzNfMV8xLCBhdHRyKTsKCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMTsKICAgICAgICB9CglhdHRyID0gYXR0ci0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIFRoaXMgd2lsbCBza2lwIHZhbGlkYXRpb24gaWYgdGhlIHR5cGUgaXMgJ2FueVNpbXBsZVR5cGUnIGFuZAogICAgKiBpZiB0aGUgdmFsdWUgd2FzIGFscmVhZHkgdmFsaWRhdGVkIChlLmcuIGRlZmF1bHQgdmFsdWVzKS4KICAgICovCiAgICBpZiAoKCEgaXNOaWwpICYmIAoJKHZhbFNpbXBsZUNvbnRlbnQgPT0gMSkgJiYKCSgodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHx8CgkgKHR5cGUtPmJ1aWx0SW5UeXBlICE9IFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSkgewoJeG1sQ2hhciAqdmFsdWU7CgoJdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKCS8qCgkqIE5PVEU6IFRoaXMgY2FsbCB3aWxsIG5vdCBjaGVjayB0aGUgY29udGVudCBub2Rlcywgc2luY2UKCSogdGhpcyBzaG91bGQgYmUgY2hlY2tlZCBoZXJlIGFscmVhZHkuCgkqLwoJcmV0dmFsID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUoY3R4dCwgdHlwZSwgdmFsdWUsIAoJICAgIDEsIDEsIDEsIDApOwoJaWYgKHZhbHVlICE9IE5VTEwpCgkgICAgeG1sRnJlZSh2YWx1ZSk7CglpZiAocmV0dmFsICE9IDApCgkgICAgcmV0ID0gcmV0dmFsOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmU6CiAqIEB2YWx1ZTogdGhlIGxleGljYWwgcmVwcmVzYW50YXRpb24gb2YgdGhlIFFOYW1lIHZhbHVlCiAqIEBub2RlOiB0aGUgbm9kZSB0byBzZWFyY2ggZm9yIHRoZSBjb3JyZXNwb25kaW5nIG5hbWVzcGFjZSBkZWNsYXJhdGlvbgogKiBAbnNOYW1lOiB0aGUgcmVzdWx0aW5nIG5hbWVzcGFjZSBuYW1lIGlmIGZvdW5kCiAqCiAqIENoZWNrcyB0aGF0IGEgdmFsdWUgY29uZm9ybXMgdG8gdGhlIGxleGljYWwgc3BhY2Ugb2YgdGhlIHR5cGUgUU5hbWU7CiAqIGlmIHZhbGlkLCB0aGUgY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgbmFtZSBpcyBzZWFyY2hlZCBhbmQgcmV0dXJlZCAKICogYXMgYSBjb3B5IGluIEBuc05hbWUuIFRoZSBsb2NhbCBuYW1lIGlzIHJldHVybmVkIGluIEBsb2NhbE5hbWUgYXMKICogYSBjb3B5LgogKgogKiBSZXR1cm5zIDAgaWYgdmFsaWQsIDEgaWYgbm90IHZhbGlkIGJ5IHR5cGUsIDIgaWYgbm8gY29ycmVzcG9uZGluZyAKICogbmFtZXNwYWNlIGRlY2xhcmF0aW9uIHdhcyBmb3VuZCBpbiBzY29wZTsgLTEgaW4gY2FzZSBvZiBhbiBpbnRlcm5hbCBvciAKICogQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmUoY29uc3QgeG1sQ2hhciAqdmFsdWUsIHhtbE5vZGVQdHIgbm9kZSwKCQkJeG1sQ2hhciAqKm5zTmFtZSwgeG1sQ2hhciAqKmxvY2FsTmFtZSkKewogICAgaW50IHJldDsKICAgIHhtbENoYXIgKmxvY2FsID0gTlVMTDsKCiAgICBpZiAoKG5zTmFtZSA9PSBOVUxMKSB8fCAobG9jYWxOYW1lID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQoJcmV0dXJuICgtMSk7ICAKICAgICpuc05hbWUgPSBOVUxMOyAgIAogICAgKmxvY2FsTmFtZSA9IE5VTEw7CiAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKICAgIGlmIChyZXQgPT0gMCkgewoJeG1sQ2hhciAqcHJlZml4OwoJeG1sTnNQdHIgbnM7CgkKCS8qCgkqIE5PVEU6IHhtbFNwbGl0UU5hbWUyIHdpbGwgcmV0dXJuIGEgZHVwbGljYXRlZAoJKiBzdHJpbmcuCgkqLwoJbG9jYWwgPSB4bWxTcGxpdFFOYW1lMih2YWx1ZSwgJnByZWZpeCk7CglpZiAobG9jYWwgPT0gTlVMTCkKCSAgICBsb2NhbCA9IHhtbFN0cmR1cCh2YWx1ZSk7CglucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKCS8qCiAgICAgICAgKiBBIG5hbWVzcGFjZSBuZWVkIG5vdCB0byBiZSBmb3VuZCBpZiB0aGUgcHJlZml4IGlzIE5VTEwuCgkqLwoJaWYgKG5zICE9IE5VTEwpIHsKCSAgICAvKgoJICAgICogVE9ETzogSXMgaXQgbmVjZXNzYXJ5IHRvIGR1cGxpY2F0ZSB0aGUgVVJJIGhlcmU/CgkgICAgKi8KCSAgICAqbnNOYW1lID0geG1sU3RyZHVwKG5zLT5ocmVmKTsKCX0gZWxzZSBpZiAocHJlZml4ICE9IE5VTEwpIHsKCSAgICB4bWxGcmVlKHByZWZpeCk7IAoJICAgIGlmIChsb2NhbCAhPSBOVUxMKQoJCXhtbEZyZWUobG9jYWwpOwoJICAgIHJldHVybiAoMik7Cgl9CQkKCSpsb2NhbE5hbWUgPSBsb2NhbDsKCWlmIChwcmVmaXggIT0gTlVMTCkKCSAgICB4bWxGcmVlKHByZWZpeCk7ICAgIAogICAgfSBlbHNlCglyZXR1cm4gKDEpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hSGFzRWxlbUNvbnRlbnQ6IAogKiBAbm9kZTogIHRoZSBub2RlCiAqCiAqIFNjb3VycyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gbm9kZSBmb3IgZWxlbWVudAogKiBub2Rlcy4KICoKICogUmV0dXJucyAxIGlmIGFuIGVsZW1lbnQgbm9kZSBpcyBmb3VuZCwKICogMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUhhc0VsZW1Db250ZW50KHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKG5vZGUgPT0gTlVMTCkKCXJldHVybiAoMCk7CiAgICBub2RlID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAobm9kZSAhPSBOVUxMKSB7CglpZiAobm9kZS0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKQoJICAgIHJldHVybiAoMSk7Cglub2RlID0gbm9kZS0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KLyoqCiAqIHhtbFNjaGVtYUhhc0VsZW1PckNoYXJDb250ZW50OiAKICogQG5vZGU6ICB0aGUgbm9kZQogKgogKiBTY291cnMgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIG5vZGUgZm9yIGVsZW1lbnQKICogYW5kIGNoYXJhY3RlciBub2Rlcy4KICoKICogUmV0dXJucyAxIGlmIGFuIGVsZW1lbnQgb3IgY2hhcmFjdGVyIG5vZGUgaXMgZm91bmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFIYXNFbGVtT3JDaGFyQ29udGVudCh4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGlmIChub2RlID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgbm9kZSA9IG5vZGUtPmNoaWxkcmVuOwogICAgd2hpbGUgKG5vZGUgIT0gTlVMTCkgewoJc3dpdGNoIChub2RlLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfRUxFTUVOVF9OT0RFOgkKCSAgICAvKiAKCSAgICAqIFRPRE86IEFzayBEYW5pZWwgaWYgdGhlc2UgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkgICAgKi8KCSAgICBjYXNlIFhNTF9URVhUX05PREU6CgkgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgoJICAgIC8qCgkgICAgKiBUT0RPOiBIb3cgWE1MX0VOVElUWV9OT0RFcyBldmFsdWF0ZWQ/CgkgICAgKi8KCSAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CgkgICAgY2FzZSBYTUxfRU5USVRZX05PREU6CgkJcmV0dXJuICgxKTsKCQlicmVhazsKCSAgICBkZWZhdWx0OgoJCWJyZWFrOwoJfQoJbm9kZSA9IG5vZGUtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogIElkZW50aXR5LWNvbnN0cmFpbnRzIChJREMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaWZkZWYgSURDX0VOQUJMRUQKCi8qKgogKiB4bWxTY2hlbWFBdWdtZW50SURDOgogKiBAaWRjRGVmOiB0aGUgSURDIGRlZmluaXRpb24KICoKICogQ3JlYXRlcyBhbiBhdWdtZW50ZWQgSURDIGRlZmluaXRpb24gaXRlbS4KICoKICogUmV0dXJucyB0aGUgaXRlbSwgb3IgTlVMTCBvbiBpbnRlcm5hbCBlcnJvcnMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFBdWdtZW50SURDKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYsCgkJICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgeG1sU2NoZW1hSURDQXVnUHRyIGFpZGM7CgogICAgYWlkYyA9ICh4bWxTY2hlbWFJRENBdWdQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSURDQXVnKSk7CiAgICBpZiAoYWlkYyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCSAgICAieG1sU2NoZW1hQXVnbWVudElEQzogYWxsb2NhdGluZyBhbiBhdWdtZW50ZWQgSURDIGRlZmluaXRpb24iLAoJICAgIE5VTEwpOwoJcmV0dXJuOwogICAgfQogICAgYWlkYy0+YnViYmxlRGVwdGggPSAtMTsKICAgIGFpZGMtPmRlZiA9IGlkY0RlZjsKICAgIGFpZGMtPm5leHQgPSBOVUxMOwogICAgaWYgKHZjdHh0LT5haWRjcyA9PSBOVUxMKQoJdmN0eHQtPmFpZGNzID0gYWlkYzsKICAgIGVsc2UgewoJYWlkYy0+bmV4dCA9IHZjdHh0LT5haWRjczsKCXZjdHh0LT5haWRjcyA9IGFpZGM7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENOZXdCaW5kaW5nOgogKiBAaWRjRGVmOiB0aGUgSURDIGRlZmluaXRpb24gb2YgdGhpcyBiaW5kaW5nCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURDIGJpbmRpbmcuCiAqCiAqIFJldHVybnMgdGhlIG5ldyBiaW5kaW5nIGluIGNhc2Ugb2Ygc3VjY2VlZGVkLCBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cgp4bWxTY2hlbWFJRENOZXdCaW5kaW5nKHhtbFNjaGVtYUlEQ1B0ciBpZGNEZWYpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIpIHhtbE1hbGxvYygKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmcpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCSAgICAiYWxsb2NhdGluZyBhIFBTVkkgSURDIGJpbmRpbmcgaXRlbSIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDQmluZGluZykpOwogICAgcmV0LT5kZWZpbml0aW9uID0gaWRjRGVmOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hSURDU3RvcmVOb2RlVGFibGVJdGVtOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpdGVtOiB0aGUgSURDIG5vZGUgdGFibGUgaXRlbQogKgogKiBUaGUgdmFsaWRhdGlvbiBjb250ZXh0IGlzIHVzZWQgdG8gc3RvcmUgYW4gSURDIG5vZGUgdGFibGUgaXRlbXMuCiAqIFRoZXkgYXJlIHN0b3JlZCB0byBhdm9pZCBjb3B5aW5nIHRoZW0gaWYgSURDIG5vZGUtdGFibGVzIGFyZSBtZXJnZWQKICogd2l0aCBjb3JyZXNwb25kaW5nIHBhcmVudCBJREMgbm9kZS10YWJsZXMgKGJ1YmJsaW5nKS4KICoKICogUmV0dXJucyAwIGlmIHN1Y2NlZWRlZCwgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJRENTdG9yZU5vZGVUYWJsZUl0ZW0oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAKCQkJICAgICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIGl0ZW0pCnsKICAgIC8qCiAgICAqIEFkZCB0byBnb2JhbCBsaXN0LgogICAgKi8gICAgCiAgICBpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsJCQkKCXZjdHh0LT5pZGNOb2RlcyA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCSAgICB4bWxNYWxsb2MoMjAgKiBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpKTsKCWlmICh2Y3R4dC0+aWRjTm9kZXMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkodmN0eHQsIAoJCSJhbGxvY2F0aW5nIHRoZSBJREMgbm9kZSB0YWJsZSBpdGVtIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCXZjdHh0LT5zaXplSWRjTm9kZXMgPSAyMDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVJZGNOb2RlcyA8PSB2Y3R4dC0+bmJJZGNOb2RlcykgewoJdmN0eHQtPnNpemVJZGNOb2RlcyAqPSAyOwoJdmN0eHQtPmlkY05vZGVzID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJICAgIHhtbFJlYWxsb2ModmN0eHQtPmlkY05vZGVzLCB2Y3R4dC0+c2l6ZUlkY05vZGVzICogCgkgICAgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CglpZiAodmN0eHQtPmlkY05vZGVzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkicmUtYWxsb2NhdGluZyB0aGUgSURDIG5vZGUgdGFibGUgaXRlbSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9CiAgICB2Y3R4dC0+aWRjTm9kZXNbdmN0eHQtPm5iSWRjTm9kZXMrK10gPSBpdGVtOwogICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENTdG9yZUtleToKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAaXRlbTogdGhlIElEQyBrZXkKICoKICogVGhlIHZhbGlkYXRpb24gY29udGV4dCBpcyB1c2VkIHRvIHN0b3JlIGFuIElEQyBrZXkuCiAqCiAqIFJldHVybnMgMCBpZiBzdWNjZWVkZWQsIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDU3RvcmVLZXkoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0LCAKCQkgICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5KQp7CiAgICAvKgogICAgKiBBZGQgdG8gZ29iYWwgbGlzdC4KICAgICovICAgIAogICAgaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCXZjdHh0LT5pZGNLZXlzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKikgCgkgICAgeG1sTWFsbG9jKDQwICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENLZXlQdHIpKTsKCWlmICh2Y3R4dC0+aWRjS2V5cyA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeSh2Y3R4dCwgCgkJImFsbG9jYXRpbmcgdGhlIElEQyBrZXkgc3RvcmFnZSBsaXN0IiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9Cgl2Y3R4dC0+c2l6ZUlkY0tleXMgPSA0MDsKICAgIH0gZWxzZSBpZiAodmN0eHQtPnNpemVJZGNLZXlzIDw9IHZjdHh0LT5uYklkY0tleXMpIHsKCXZjdHh0LT5zaXplSWRjS2V5cyAqPSAyOwoJdmN0eHQtPmlkY0tleXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSAKCSAgICB4bWxSZWFsbG9jKHZjdHh0LT5pZGNLZXlzLCB2Y3R4dC0+c2l6ZUlkY0tleXMgKiAKCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJaWYgKHZjdHh0LT5pZGNLZXlzID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkicmUtYWxsb2NhdGluZyB0aGUgSURDIGtleSBzdG9yYWdlIGxpc3QiLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIHZjdHh0LT5pZGNLZXlzW3ZjdHh0LT5uYklkY0tleXMrK10gPSBrZXk7CiAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FwcGVuZE5vZGVUYWJsZUl0ZW06CiAqIEBiaW5kOiB0aGUgSURDIGJpbmRpbmcKICogQG50SXRlbTogdGhlIG5vZGUtdGFibGUgaXRlbQogKgogKiBBcHBlbmRzIHRoZSBJREMgbm9kZS10YWJsZSBpdGVtIHRvIHRoZSBiaW5kaW5nLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludCAKeG1sU2NoZW1hSURDQXBwZW5kTm9kZVRhYmxlSXRlbSh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kLAoJCQkJeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbnRJdGVtKQp7CiAgICBpZiAoYmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCWJpbmQtPnNpemVOb2RlcyA9IDEwOwoJYmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJICAgIHhtbE1hbGxvYygxMCAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKGJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CQogICAgfSBlbHNlIGlmIChiaW5kLT5zaXplTm9kZXMgPD0gYmluZC0+bmJOb2RlcykgewoJYmluZC0+c2l6ZU5vZGVzICo9IDI7CgliaW5kLT5ub2RlVGFibGUgPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgKikgCgkgICAgeG1sUmVhbGxvYyhiaW5kLT5ub2RlVGFibGUsIGJpbmQtPnNpemVOb2RlcyAqIAoJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJaWYgKGJpbmQtPm5vZGVUYWJsZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVyck1lbW9yeShOVUxMLCAKCQkicmUtYWxsb2NhdGluZyBhbiBhcnJheSBvZiBJREMgbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJICAgIHJldHVybigtMSk7Cgl9CiAgICB9CiAgICBiaW5kLT5ub2RlVGFibGVbYmluZC0+bmJOb2RlcysrXSA9IG50SXRlbTsKICAgIHJldHVybigwKTsgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmc6IAogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBtYXRjaGVyOiB0aGUgSURDIG1hdGNoZXIKICoKICogTG9va3MgdXAgYW4gUFNWSSBJREMgYmluZGluZywgZm9yIHRoZSBJREMgZGVmaW5pdGlvbiBhbmQgCiAqIG9mIHRoZSBnaXZlbiBtYXRjaGVyLiBJZiBub25lIGZvdW5kLCBhIG5ldyBvbmUgaXMgY3JlYXRlZAogKiBhbmQgYWRkZWQgdG8gdGhlIElEQyB0YWJsZS4KICoKICogUmV0dXJucyBhbiBJREMgYmluZGluZyBvciBOVUxMIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0cgp4bWxTY2hlbWFJRENBcXVpcmVCaW5kaW5nKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXIpCnsKICAgIHhtbFNjaGVtYU5vZGVJbmZvUHRyIGluZm87CgogICAgaW5mbyA9IHZjdHh0LT5lbGVtSW5mb3NbbWF0Y2hlci0+ZGVwdGhdOwoKICAgIGlmIChpbmZvLT5pZGNUYWJsZSA9PSBOVUxMKSB7CglpbmZvLT5pZGNUYWJsZSA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcobWF0Y2hlci0+YWlkYy0+ZGVmKTsKCWlmIChpbmZvLT5pZGNUYWJsZSA9PSBOVUxMKQoJICAgIHJldHVybiAoTlVMTCk7CglyZXR1cm4oaW5mby0+aWRjVGFibGUpOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQgPSBOVUxMOwoJCgliaW5kID0gaW5mby0+aWRjVGFibGU7CglkbyB7CgkgICAgaWYgKGJpbmQtPmRlZmluaXRpb24gPT0gbWF0Y2hlci0+YWlkYy0+ZGVmKQoJCXJldHVybihiaW5kKTsKCSAgICBpZiAoYmluZC0+bmV4dCA9PSBOVUxMKSB7CgkJYmluZC0+bmV4dCA9IHhtbFNjaGVtYUlEQ05ld0JpbmRpbmcobWF0Y2hlci0+YWlkYy0+ZGVmKTsKCQlpZiAoYmluZC0+bmV4dCA9PSBOVUxMKQoJCSAgICByZXR1cm4gKE5VTEwpOwoJCXJldHVybihiaW5kLT5uZXh0KTsKCSAgICB9CgkgICAgYmluZCA9IGJpbmQtPm5leHQ7Cgl9IHdoaWxlIChiaW5kICE9IE5VTEwpOwkKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlS2V5OiAKICogQGtleTogdGhlIElEQyBrZXkKICoKICogRnJlZXMgYW4gSURDIGtleSB0b2dldGhlciB3aXRoIGl0cyBjb21waWxlZCB2YWx1ZS4KICovCnN0YXRpYyB2b2lkIAp4bWxTY2hlbWFJRENGcmVlS2V5KHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5KQp7CiAgICBpZiAoa2V5LT5jb21wVmFsdWUgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVWYWx1ZShrZXktPmNvbXBWYWx1ZSk7CiAgICB4bWxGcmVlKGtleSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJRENGcmVlQmluZGluZzoKICoKICogRnJlZXMgYW4gSURDIGJpbmRpbmcuIE5vdGUgdGhhdCB0aGUgbm9kZSB0YWJsZS1pdGVtcwogKiBhcmUgbm90IGZyZWVkLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcoeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgYmluZCkKewogICAgaWYgKGJpbmQtPm5vZGVUYWJsZSAhPSBOVUxMKSB7CglpZiAoYmluZC0+ZGVmaW5pdGlvbi0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIGludCBpOwoJICAgIC8qCgkgICAgKiBOb2RlLXRhYmxlIGl0ZW1zIGZvciBrZXlyZWZzIGFyZSBub3Qgc3RvcmVkIGdsb2JhbGx5CgkgICAgKiB0byB0aGUgdmFsaWRhdGlvbiBjb250ZXh0LCBzaW5jZSB0aGV5IGFyZSBub3QgYnViYmxlZC4KCSAgICAqIFdlIG5lZWQgdG8gZnJlZSB0aGVtIGhlcmUuCgkgICAgKi8KCSAgICBmb3IgKGkgPSAwOyBpIDwgYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJeG1sRnJlZShiaW5kLT5ub2RlVGFibGVbaV0tPmtleXMpOwoJCXhtbEZyZWUoYmluZC0+bm9kZVRhYmxlW2ldKTsKCSAgICB9Cgl9Cgl4bWxGcmVlKGJpbmQtPm5vZGVUYWJsZSk7CiAgICB9CiAgICB4bWxGcmVlKGJpbmQpOwp9CgovKioKICogeG1sU2NoZW1hSURDRnJlZUlEQ1RhYmxlOgogKiBAYmluZDogdGhlIGZpcnN0IElEQyBiaW5kaW5nIGluIHRoZSBsaXN0CiAqCiAqIEZyZWVzIGFuIElEQyB0YWJsZSwgaS5lLiBhbGwgdGhlIElEQyBiaW5kaW5ncyBpbiB0aGUgbGlzdC4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUlEQ0ZyZWVJRENUYWJsZSh4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kKQp7CiAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBwcmV2OwoKICAgIHdoaWxlIChiaW5kICE9IE5VTEwpIHsKCXByZXYgPSBiaW5kOwkJICAgIAoJYmluZCA9IGJpbmQtPm5leHQ7Cgl4bWxTY2hlbWFJRENGcmVlQmluZGluZyhwcmV2KTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdDoKICogQG1hdGNoZXI6IHRoZSBmaXJzdCBJREMgbWF0Y2hlciBpbiB0aGUgbGlzdAogKgogKiBGcmVlcyBhIGxpc3Qgb2YgSURDIG1hdGNoZXJzLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hSURDRnJlZU1hdGNoZXJMaXN0KHhtbFNjaGVtYUlEQ01hdGNoZXJQdHIgbWF0Y2hlcikKewogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBuZXh0OwoKICAgIHdoaWxlIChtYXRjaGVyICE9IE5VTEwpIHsKCW5leHQgPSBtYXRjaGVyLT5uZXh0OwoJaWYgKG1hdGNoZXItPmtleVNlcXMgIT0gTlVMTCkgewoJICAgIGludCBpOwoJICAgIGZvciAoaSA9IDA7IGkgPCBtYXRjaGVyLT5zaXplS2V5U2VxczsgaSsrKQoJCWlmIChtYXRjaGVyLT5rZXlTZXFzW2ldICE9IE5VTEwpCgkJICAgIHhtbEZyZWUobWF0Y2hlci0+a2V5U2Vxc1tpXSk7CgkgICAgeG1sRnJlZShtYXRjaGVyLT5rZXlTZXFzKTsKCX0KCXhtbEZyZWUobWF0Y2hlcik7CgltYXRjaGVyID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUFyZVZhbHVlc0VxdWFsOgogKiBAdGE6IHRoZSBmaXJzdCB0eXBlCiAqIEBhOiB0aGUgZmlyc3QgdmFsdWUKICogQHRiOiB0aGUgc2Vjb25kIHR5cGUKICogQGI6IHRoZSBzZWNvbmQgdmFsdWUKICoKICogQ29tcGFyZXMgdHdvIHZhbHVlcy4KICoKICogUmV0dXJucyAxIGlmIHRoZXkgYXJlIGVxdWFsLCAwIGlmIG5vdCBhbmQgLTEgb24gaW50ZXJuYWwgZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCXhtbFNjaGVtYVR5cGVQdHIgdGEsCgkJCXhtbFNjaGVtYVZhbFB0ciBhLAoJCQl4bWxTY2hlbWFUeXBlUHRyIHRiLAoJCQl4bWxTY2hlbWFWYWxQdHIgYikgCnsgICAgICAgCiAgICAvKiBTYW1lIHVzZXIgZGVyaXZlZC9idWlsdC1pbiBkZXJpdmVkL2J1aWx0LWluIHByaW1pdGl2ZSB0eXBlcy4gKi8KICAgIGlmICh0YSA9PSB0YikKCWdvdG8gY29tcGFyZVZhbHVlOwogICAgCiAgICAvKgogICAgKiBOb3RlIHRoYXQgY29tcGFyaXNvbiB3aXRoIGFueVNpbXBsZVR5cGVzIHdpdGggYmUgc3VwcG9ydGVkIGZvcgogICAgKiBzdHJpbmcgYmFzZWQgdHlwZXMgYXMgd2VsbC4KICAgICovCiNpZiAwICAgIAogICAgaWYgKCh0YS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkgfHwKCSh0Yi0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpCglyZXR1cm4oMCk7CiNlbmRpZgogICAgCiAgICAvKgogICAgKiA0LjIuMSBlcXVhbCAoZGF0YS10eXBlcykKICAgICoKICAgICogdGhlILd2YWx1ZSBzcGFjZbdzIG9mIGFsbCC3cHJpbWl0aXZltyBkYXRhdHlwZXMgYXJlIGRpc2pvaW50IAogICAgKiAodGhleSBkbyBub3Qgc2hhcmUgYW55IHZhbHVlcykgCiAgICAqLwogICAgaWYgKCh0YS0+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+bmJIaXN0b3J5ID09IDApCgkgICAgZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoKCW1hdGNoRGVwdGggPSBzdG8tPmhpc3Rvcnlbc3RvLT5uYkhpc3RvcnkgLTFdOwoKCS8qCgkqIE9ubHkgbWF0Y2hlcyBhdCB0aGUgY3VycmVudCBkZXB0aCBhcmUgb2YgaW50ZXJlc3QuCgkqLwoJaWYgKG1hdGNoRGVwdGggIT0gZGVwdGgpIHsKCSAgICBzdG8gPSBzdG8tPm5leHQ7CgkgICAgY29udGludWU7Cgl9CQoJaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfRklFTEQpIHsKCSAgICBpZiAoISBJU19TSU1QTEVfVFlQRSh0eXBlKSkgewoJCS8qCgkJKiBOb3QgcXVhbGlmaWVkIGlmIHRoZSBmaWVsZCByZXNvbHZlcyB0byBhIG5vZGUgb2Ygbm9uCgkJKiBzaW1wbGUgdHlwZS4KCQkqLwkKCQl4bWxTY2hlbWFTdHJlYW1WQ3VzdG9tRXJyKHZjdHh0LAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfSURDLAoJCSAgICB2Y3R4dC0+bm9kZUluZm8sIAoJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgc3RvLT5tYXRjaGVyLT5haWRjLT5kZWYsCgkJICAgICJUaGUgZmllbGQgJyVzJyBkb2VzIGV2YWx1YXRlIHRvIGEgbm9kZSBvZiAiCgkJICAgICJub24tc2ltcGxlIHR5cGUiLCBzdG8tPnNlbC0+eHBhdGgsIE5VTEwpOwoJCQoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0KCSAgICBpZiAoKGtleSA9PSBOVUxMKSAmJiAodmN0eHQtPm5vZGVJbmZvLT52YWx1ZSA9PSBOVUxMKSkgewoJCS8qCgkJKiBGYWlsZWQgdG8gcHJvdmlkZSB0aGUgbm9ybWFsaXplZCB2YWx1ZTsgbWFieQoJCSogdGhlIHZhbHVlIHdhcyBpbnZhbGlkLgoJCSovCgkJeG1sU2NoZW1hU3RyZWFtVkN1c3RvbUVycih2Y3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJICAgIHZjdHh0LT5ub2RlSW5mbywKCQkgICAgKHhtbFNjaGVtYVR5cGVQdHIpIHN0by0+bWF0Y2hlci0+YWlkYy0+ZGVmLAoJCSAgICAiV2FybmluZzogTm8gcHJlY29tcHV0ZWQgdmFsdWUgYXZhaWxhYmxlLCB0aGUgdmFsdWUgIgoJCSAgICAid2FzIGVpdGhlciBpbnZhbGlkIG9yIHNvbWV0aGluZyBzdHJhbmdlIGhhcHBlbmQiLAoJCSAgICBOVUxMLCBOVUxMKTsKCQkvKgoJCXhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlSW5mby0+bm9kZSwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVhQYXRoUHJvY2Vzc0hpc3RvcnksICIKCQkgICAgImNvbXB1dGVkIHZhbHVlIG5vdCBhdmFpbGFibGUuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCQkqLwoJCXN0by0+bmJIaXN0b3J5LS07CgkJZ290byBkZXJlZ2lzdGVyX2NoZWNrOwoJICAgIH0gZWxzZSB7CgkJeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyID0gc3RvLT5tYXRjaGVyOwoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgKmtleVNlcTsKCQlpbnQgcG9zLCBpZHg7CgkJCgkJLyoKCQkqIFRoZSBrZXkgd2lsbCBiZSBhbmNob3JlZCBvbiB0aGUgbWF0Y2hlcidzIGxpc3Qgb2YKCQkqIGtleS1zZXF1ZW5jZXMuIFRoZSBwb3NpdGlvbiBpbiB0aGlzIGxpc3QgaXMgZGV0ZXJtaW5lZAoJCSogYnkgdGhlIHRhcmdldCBub2RlJ3MgZGVwdGggcmVsYXRpdmUgdG8gdGhlIG1hdGNoZXIncwoJCSogZGVwdGggb2YgY3JlYXRpb24gKGkuZS4gdGhlIGRlcHRoIG9mIHRoZSBzY29wZSBlbGVtZW50KS4KCQkqLwkJICAgIAoJCXBvcyA9IHN0by0+ZGVwdGggLSBtYXRjaGVyLT5kZXB0aDsKCQlpZHggPSBzdG8tPnNlbC0+aW5kZXg7CgkJCgkJLyoKCQkqIENyZWF0ZS9ncm93IHRoZSBhcnJheSBvZiBrZXktc2VxdWVuY2VzLgoJCSovCgkJaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCSAgICBpZiAocG9zID4gOSkgCgkJCW1hdGNoZXItPnNpemVLZXlTZXFzID0gcG9zICogMjsKCQkgICAgZWxzZQoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyA9IDEwOwoJCSAgICBtYXRjaGVyLT5rZXlTZXFzID0gKHhtbFNjaGVtYVBTVklJRENLZXlQdHIgKiopIAoJCQl4bWxNYWxsb2MobWF0Y2hlci0+c2l6ZUtleVNlcXMgKgoJCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKSk7CQkJCgkJICAgIGlmIChtYXRjaGVyLT5rZXlTZXFzID09IE5VTEwpIHsJCQoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhbiBhcnJheSBvZiBrZXktc2VxdWVuY2VzIiwKCQkJICAgIE5VTEwpOwoJCQlyZXR1cm4oLTEpOwoJCSAgICB9CgkJICAgIG1lbXNldChtYXRjaGVyLT5rZXlTZXFzLCAwLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQl9IGVsc2UgaWYgKHBvcyA+PSBtYXRjaGVyLT5zaXplS2V5U2VxcykgewkKCQkgICAgaW50IGkgPSBtYXRjaGVyLT5zaXplS2V5U2VxczsKCQkgICAgCgkJICAgIG1hdGNoZXItPnNpemVLZXlTZXFzICo9IDI7CgkJICAgIG1hdGNoZXItPmtleVNlcXMgPSAoeG1sU2NoZW1hUFNWSUlEQ0tleVB0ciAqKikKCQkJeG1sUmVhbGxvYyhtYXRjaGVyLT5rZXlTZXFzLAoJCQltYXRjaGVyLT5zaXplS2V5U2VxcyAqCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopKTsKCQkgICAgaWYgKG1hdGNoZXItPmtleVNlcXMgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAicmVhbGxvY2F0aW5nIGFuIGFycmF5IG9mIGtleS1zZXF1ZW5jZXMiLAoJCQkgICAgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CgkJICAgIC8qCgkJICAgICogVGhlIGFycmF5IG5lZWRzIHRvIGJlIE5VTExlZC4KCQkgICAgKiBUT0RPOiBVc2UgbWVtc2V0PwoJCSAgICAqLwoJCSAgICBmb3IgKDsgaSA8IG1hdGNoZXItPnNpemVLZXlTZXFzOyBpKyspIAoJCQltYXRjaGVyLT5rZXlTZXFzW2ldID0gTlVMTDsJCQkKCQl9CgkJCgkJLyoKCQkqIEdldC9jcmVhdGUgdGhlIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9IG1hdGNoZXItPmtleVNlcXNbcG9zXTsJCSAgICAKCQlpZiAoa2V5U2VxID09IE5VTEwpIHsJCgkJICAgIGdvdG8gY3JlYXRlX3NlcXVlbmNlOwoJCX0gZWxzZSB7CgkJICAgIGlmIChrZXlTZXFbaWR4XSAhPSBOVUxMKSB7CgkJCS8qCgkJCSogY3ZjLWlkZW50aXR5LWNvbnN0cmFpbnQ6CgkJCSogMyBGb3IgZWFjaCBub2RlIGluIHRoZSC3dGFyZ2V0IG5vZGUgc2V0tyBhbGwKCQkJKiBvZiB0aGUge2ZpZWxkc30sIHdpdGggdGhhdCBub2RlIGFzIHRoZSBjb250ZXh0CgkJCSogbm9kZSwgZXZhbHVhdGUgdG8gZWl0aGVyIGFuIGVtcHR5IG5vZGUtc2V0IG9yCgkJCSogYSBub2RlLXNldCB3aXRoIGV4YWN0bHkgb25lIG1lbWJlciwgd2hpY2ggbXVzdAoJCQkqIGhhdmUgYSBzaW1wbGUgdHlwZS4KCQkJKiAKCQkJKiBUaGUga2V5IHdhcyBhbHJlYWR5IHNldDsgcmVwb3J0IGFuIGVycm9yLgoJCQkqLwoJCQl4bWxTY2hlbWFTdHJlYW1WQ3VzdG9tRXJyKHZjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJCSAgICB2Y3R4dC0+bm9kZUluZm8sCgkJCSAgICAoeG1sU2NoZW1hVHlwZVB0cikgbWF0Y2hlci0+YWlkYy0+ZGVmLAoJCQkgICAgIlRoZSBmaWVsZCAnJXMnIGV2YWx1YXRlcyB0byBhIG5vZGUtc2V0ICIKCQkJICAgICJ3aXRoIG1vcmUgdGhhbiBvbmUgbWVtYmVyIiwKCQkJICAgIHN0by0+c2VsLT54cGF0aCwgTlVMTCk7CgkJCXN0by0+bmJIaXN0b3J5LS07CgkJCWdvdG8gZGVyZWdpc3Rlcl9jaGVjazsKCQkgICAgfSBlbHNlIHsKCQkJZ290byBjcmVhdGVfa2V5OwoJCSAgICB9CgkJfQoJCQpjcmVhdGVfc2VxdWVuY2U6CgkJLyoKCQkqIENyZWF0ZSBhIGtleS1zZXF1ZW5jZS4KCQkqLwoJCWtleVNlcSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICopIHhtbE1hbGxvYygKCQkgICAgbWF0Y2hlci0+YWlkYy0+ZGVmLT5uYkZpZWxkcyAqIAoJCSAgICBzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ0tleVB0cikpOwoJCWlmIChrZXlTZXEgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCQkiYWxsb2NhdGluZyBhbiBJREMga2V5LXNlcXVlbmNlIiwgTlVMTCk7CgkJICAgIHJldHVybigtMSk7CQkJCgkJfQkKCQltZW1zZXQoa2V5U2VxLCAwLCBtYXRjaGVyLT5haWRjLT5kZWYtPm5iRmllbGRzICogCgkJICAgIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSk7CgkJbWF0Y2hlci0+a2V5U2Vxc1twb3NdID0ga2V5U2VxOwpjcmVhdGVfa2V5OgoJCS8qCgkJKiBDcmVhdGVkIGEga2V5IG9uY2UgcGVyIG5vZGUgb25seS4KCQkqLyAgCgkJaWYgKGtleSA9PSBOVUxMKSB7CgkJICAgIGtleSA9ICh4bWxTY2hlbWFQU1ZJSURDS2V5UHRyKSB4bWxNYWxsb2MoCgkJCXNpemVvZih4bWxTY2hlbWFQU1ZJSURDS2V5KSk7CgkJICAgIGlmIChrZXkgPT0gTlVMTCkgewoJCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsCgkJCSAgICAiYWxsb2NhdGluZyBhIElEQyBrZXkiLCBOVUxMKTsKCQkJeG1sRnJlZShrZXlTZXEpOwoJCQltYXRjaGVyLT5rZXlTZXFzW3Bvc10gPSBOVUxMOwoJCQlyZXR1cm4oLTEpOwkJCQoJCSAgICB9CgkJICAgIC8qCgkJICAgICogQ29uc3VtZSB0aGUgY29tcGlsZWQgdmFsdWUuCgkJICAgICovCgkJICAgIGtleS0+dHlwZSA9IHR5cGU7CgkJICAgIGtleS0+Y29tcFZhbHVlID0gdmN0eHQtPm5vZGVJbmZvLT52YWx1ZTsKCQkgICAgdmN0eHQtPm5vZGVJbmZvLT52YWx1ZSA9IE5VTEw7CgkJICAgIC8qCgkJICAgICogU3RvcmUgdGhlIGtleSBpbiBhIGdsb2JhbCBsaXN0LgoJCSAgICAqLwoJCSAgICBpZiAoeG1sU2NoZW1hSURDU3RvcmVLZXkodmN0eHQsIGtleSkgPT0gLTEpIHsKCQkJeG1sU2NoZW1hSURDRnJlZUtleShrZXkpOwoJCQlyZXR1cm4gKC0xKTsKCQkgICAgfQoJCX0KCQlrZXlTZXFbaWR4XSA9IGtleTsJCSAgICAKCSAgICB9Cgl9IGVsc2UgaWYgKHN0by0+dHlwZSA9PSBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpIHsKCQkKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICoqa2V5U2VxID0gTlVMTDsKCSAgICB4bWxTY2hlbWFQU1ZJSURDQmluZGluZ1B0ciBiaW5kOwoJICAgIHhtbFNjaGVtYVBTVklJRENOb2RlUHRyIG50SXRlbTsKCSAgICB4bWxTY2hlbWFJRENNYXRjaGVyUHRyIG1hdGNoZXI7CgkgICAgeG1sU2NoZW1hSURDUHRyIGlkYzsKCSAgICBpbnQgcG9zLCBpLCBqLCBuYktleXM7CgkgICAgLyoKCSAgICAqIEhlcmUgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIHNjZW5hcmlvOgoJICAgICogQW4gSURDICdzZWxlY3Rvcicgc3RhdGUgb2JqZWN0IHJlc29sdmVkIHRvIGEgdGFyZ2V0IG5vZGUsCgkgICAgKiBkdXJpbmcgdGhlIHRpbWUgdGhpcyB0YXJnZXQgbm9kZSB3YXMgaW4gdGhlIAoJICAgICogYW5jZXN0b3Itb3Itc2VsZiBheGlzLCB0aGUgJ2ZpZWxkJyBzdGF0ZSBvYmplY3QocykgbG9va2VkIAoJICAgICogb3V0IGZvciBtYXRjaGluZyBub2RlcyB0byBjcmVhdGUgYSBrZXktc2VxdWVuY2UgZm9yIHRoaXMgCgkgICAgKiB0YXJnZXQgbm9kZS4gTm93IHdlIGFyZSBiYWNrIHRvIHRoaXMgdGFyZ2V0IG5vZGUgYW5kIG5lZWQKCSAgICAqIHRvIHB1dCB0aGUga2V5LXNlcXVlbmNlLCB0b2dldGhlciB3aXRoIHRoZSB0YXJnZXQgbm9kZSAKCSAgICAqIGl0c2VsZiwgaW50byB0aGUgbm9kZS10YWJsZSBvZiB0aGUgY29ycmVzcG9uZGluZyBJREMgCgkgICAgKiBiaW5kaW5nLgoJICAgICovCgkgICAgbWF0Y2hlciA9IHN0by0+bWF0Y2hlcjsKCSAgICBpZGMgPSBtYXRjaGVyLT5haWRjLT5kZWY7CgkgICAgbmJLZXlzID0gaWRjLT5uYkZpZWxkczsKCSAgICBwb3MgPSBkZXB0aCAtIG1hdGNoZXItPmRlcHRoOwkJCgkgICAgLyoKCSAgICAqIENoZWNrIGlmIHRoZSBtYXRjaGVyIGhhcyBhbnkga2V5LXNlcXVlbmNlcyBhdCBhbGwsIHBsdXMKCSAgICAqIGlmIGl0IGhhcyBhIGtleS1zZXF1ZW5jZSBmb3IgdGhlIGN1cnJlbnQgdGFyZ2V0IG5vZGUuCgkgICAgKi8JCQoJICAgIGlmICgobWF0Y2hlci0+a2V5U2VxcyA9PSBOVUxMKSB8fAoJCShtYXRjaGVyLT5zaXplS2V5U2VxcyA8PSBwb3MpKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBrZXlTZXEgPSAmKG1hdGNoZXItPmtleVNlcXNbcG9zXSk7CQkKCSAgICBpZiAoKmtleVNlcSA9PSBOVUxMKSB7CgkJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkKCQkgICAgZ290byBzZWxlY3Rvcl9rZXlfZXJyb3I7CgkJZWxzZQoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJICAgIH0KCSAgICAKCSAgICBmb3IgKGkgPSAwOyBpIDwgbmJLZXlzOyBpKyspIHsKCQlpZiAoKCprZXlTZXEpW2ldID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgKiBOb3QgcXVhbGlmaWVkLCBpZiBub3QgYWxsIGZpZWxkcyBkaWQgcmVzb2x2ZS4KCQkgICAgKi8KCQkgICAgaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWSkgewoJCQkvKgoJCQkqIEFsbCBmaWVsZHMgb2YgYSAia2V5IiBJREMgbXVzdCByZXNvbHZlLgoJCQkqLwoJCQlnb3RvIHNlbGVjdG9yX2tleV9lcnJvcjsKCQkgICAgfQkJICAgIAoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEFsbCBmaWVsZHMgZGlkIHJlc29sdmUuCgkgICAgKi8KCSAgICAKCSAgICAvKgoJICAgICogNC4xIElmIHRoZSB7aWRlbnRpdHktY29uc3RyYWludCBjYXRlZ29yeX0gaXMgdW5pcXVlKC9rZXkpLAoJICAgICogdGhlbiBubyB0d28gbWVtYmVycyBvZiB0aGUgt3F1YWxpZmllZCBub2RlIHNldLcgaGF2ZQoJICAgICogt2tleS1zZXF1ZW5jZXO3IHdob3NlIG1lbWJlcnMgYXJlIHBhaXJ3aXNlIGVxdWFsLCBhcwoJICAgICogZGVmaW5lZCBieSBFcXVhbCBpbiBbWE1MIFNjaGVtYXM6IERhdGF0eXBlc10uCgkgICAgKgoJICAgICogR2V0IHRoZSBJREMgYmluZGluZyBmcm9tIHRoZSBtYXRjaGVyIGFuZCBjaGVjayBmb3IKCSAgICAqIGR1cGxpY2F0ZSBrZXktc2VxdWVuY2VzLgoJICAgICovCgkgICAgYmluZCA9IHhtbFNjaGVtYUlEQ0FxdWlyZUJpbmRpbmcodmN0eHQsIG1hdGNoZXIpOwoJICAgIGlmICgoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSAmJiAKCQkoYmluZC0+bmJOb2RlcyAhPSAwKSkgewoJCXhtbFNjaGVtYVBTVklJRENLZXlQdHIgY2tleSwgYmtleSwgKmJrZXlTZXE7CgkJCgkJaSA9IDA7CgkJcmVzID0gMDsKCQkvKgoJCSogQ29tcGFyZSB0aGUga2V5LXNlcXVlbmNlcywga2V5IGJ5IGtleS4KCQkqLwoJCWRvIHsKCQkgICAgYmtleVNlcSA9IGJpbmQtPm5vZGVUYWJsZVtpXS0+a2V5czsJCSAgICAKCQkgICAgZm9yIChqID0gMDsgaiA8IG5iS2V5czsgaisrKSB7CgkJCWNrZXkgPSAoKmtleVNlcSlbal07CgkJCWJrZXkgPSBia2V5U2VxW2pdOwkJCQkJCQkKCQkJcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwodmN0eHQsIGNrZXktPnR5cGUsCgkJCSAgICBja2V5LT5jb21wVmFsdWUsIGJrZXktPnR5cGUsIGJrZXktPmNvbXBWYWx1ZSk7CgkJCWlmIChyZXMgPT0gLTEpIHsKCQkJICAgIHJldHVybiAoLTEpOwoJCQl9IGVsc2UgaWYgKHJlcyA9PSAwKQoJCQkgICAgYnJlYWs7CgkJICAgIH0KCQkgICAgaWYgKHJlcyA9PSAxKSB7CgkJCS8qCgkJCSogRHVwbGljYXRlIGZvdW5kLgoJCQkqLwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBpKys7CgkJfSB3aGlsZSAoaSA8IGJpbmQtPm5iTm9kZXMpOwoJCWlmIChpICE9IGJpbmQtPm5iTm9kZXMpIHsKCQkgICAgLyogICAKCQkgICAgKiBUT0RPOiBUcnkgdG8gcmVwb3J0IHRoZSBrZXktc2VxdWVuY2UuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVN0cmVhbVZDdXN0b21FcnIodmN0eHQsIAoJCQlYTUxfU0NIRU1BVl9DVkNfSURDLAoJCQl2Y3R4dC0+bm9kZUluZm8sCgkJCSh4bWxTY2hlbWFUeXBlUHRyKSBpZGMsCgkJCSJEdXBsaWNhdGUga2V5LXNlcXVlbmNlIGZvdW5kIiwgTlVMTCwgTlVMTCk7CgkJICAgIAoJCSAgICBnb3RvIHNlbGVjdG9yX2xlYXZlOwoJCX0KCSAgICB9CgkgICAgLyoKCSAgICAqIEFkZCBhIG5vZGUtdGFibGUgaXRlbSB0byB0aGUgSURDIGJpbmRpbmcuCgkgICAgKi8KCSAgICBudEl0ZW0gPSAoeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIpIHhtbE1hbGxvYygKCQlzaXplb2YoeG1sU2NoZW1hUFNWSUlEQ05vZGUpKTsKCSAgICBpZiAobnRJdGVtID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsIAoJCSAgICAiYWxsb2NhdGluZyBhbiBJREMgbm9kZS10YWJsZSBpdGVtIiwgTlVMTCk7CgkJeG1sRnJlZSgqa2V5U2VxKTsKCQkqa2V5U2VxID0gTlVMTDsKCQlyZXR1cm4oLTEpOwoJICAgIH0JCgkgICAgbWVtc2V0KG50SXRlbSwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlKSk7CQkKCSAgICAKCSAgICAvKiAKCSAgICAqIFN0b3JlIHRoZSBub2RlLXRhYmxlIGl0ZW0gb24gZ2xvYmFsIGxpc3QuCgkgICAgKi8KCSAgICBpZiAoaWRjLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkJaWYgKHhtbFNjaGVtYUlEQ1N0b3JlTm9kZVRhYmxlSXRlbSh2Y3R4dCwgbnRJdGVtKSA9PSAtMSkgewoJCSAgICB4bWxGcmVlKG50SXRlbSk7CgkJICAgIHhtbEZyZWUoKmtleVNlcSk7CgkJICAgICprZXlTZXEgPSBOVUxMOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkgICAgfQoJICAgIC8qCgkgICAgKiBJbml0IHRoZSBub2RlLXRhYmxlIGl0ZW0uIENvbnN1bWUgdGhlIGtleS1zZXF1ZW5jZS4KCSAgICAqLwoJICAgIG50SXRlbS0+bm9kZSA9IHZjdHh0LT5ub2RlOwoJICAgIG50SXRlbS0+a2V5cyA9ICprZXlTZXE7CgkgICAgKmtleVNlcSA9IE5VTEw7CgkgICAgaWYgKHhtbFNjaGVtYUlEQ0FwcGVuZE5vZGVUYWJsZUl0ZW0oYmluZCwgbnRJdGVtKSA9PSAtMSkgewkJICAgIAoJCWlmIChpZGMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0lEQ19LRVlSRUYpIHsKCQkgICAgLyogCgkJICAgICogRnJlZSB0aGUgaXRlbSwgc2luY2Uga2V5cmVmIGl0ZW1zIHdvbid0IGJlCgkJICAgICogcHV0IG9uIGEgZ2xvYmFsIGxpc3QuCgkJICAgICovCgkJICAgIHhtbEZyZWUobnRJdGVtLT5rZXlzKTsKCQkgICAgeG1sRnJlZShudEl0ZW0pOwoJCX0KCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgCgkgICAgZ290byBzZWxlY3Rvcl9sZWF2ZTsKc2VsZWN0b3Jfa2V5X2Vycm9yOgoJICAgIC8qCgkgICAgKiA0LjIuMSAoS0VZKSBUaGUgt3RhcmdldCBub2RlIHNldLcgYW5kIHRoZSAKCSAgICAqILdxdWFsaWZpZWQgbm9kZSBzZXS3IGFyZSBlcXVhbCwgdGhhdCBpcywgZXZlcnkgCgkgICAgKiBtZW1iZXIgb2YgdGhlILd0YXJnZXQgbm9kZSBzZXS3IGlzIGFsc28gYSBtZW1iZXIKCSAgICAqIG9mIHRoZSC3cXVhbGlmaWVkIG5vZGUgc2V0tyBhbmQgdmljZSB2ZXJzYS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVN0cmVhbVZDdXN0b21FcnIodmN0eHQsIAoJCVhNTF9TQ0hFTUFWX0NWQ19JREMsCgkJdmN0eHQtPm5vZGVJbmZvLCAKCQkoeG1sU2NoZW1hVHlwZVB0cikgaWRjLAoJCSJBbGwgJ2tleScgZmllbGRzIG11c3QgZXZhbHVhdGUgdG8gYSBub2RlIiwKCQlOVUxMLCBOVUxMKTsKc2VsZWN0b3JfbGVhdmU6CgkgICAgLyoKCSAgICAqIEZyZWUgdGhlIGtleS1zZXF1ZW5jZSBpZiBub3QgYWRkZWQgdG8gdGhlIElEQyB0YWJsZS4KCSAgICAqLwoJICAgIGlmICgoa2V5U2VxICE9IE5VTEwpICYmICgqa2V5U2VxICE9IE5VTEwpKSB7CgkJeG1sRnJlZSgqa2V5U2VxKTsKCQkqa2V5U2VxID0gTlVMTDsKCSAgICB9Cgl9IC8qIGlmIHNlbGVjdG9yICovCgkKCXN0by0+bmJIaXN0b3J5LS07CgpkZXJlZ2lzdGVyX2NoZWNrOgoJLyoKCSogRGVyZWdpc3RlciBzdGF0ZSBvYmplY3RzIGlmIHRoZXkgcmVhY2ggdGhlIGRlcHRoIG9mIGNyZWF0aW9uLgoJKi8KCWlmICgoc3RvLT5uYkhpc3RvcnkgPT0gMCkgJiYgKHN0by0+ZGVwdGggPT0gZGVwdGgpKSB7CiNpZiBERUJVR19JREMKCSAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICBTVE8gcG9wICclcydcbiIsCgkJc3RvLT5zZWwtPnhwYXRoKTsKI2VuZGlmCgkgICAgaWYgKHZjdHh0LT54cGF0aFN0YXRlcyAhPSBzdG8pIHsKCQl4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSwgIgoJCSAgICAiVGhlIHN0YXRlIG9iamVjdCB0byBiZSByZW1vdmVkIGlzIG5vdCB0aGUgZmlyc3QgIgoJCSAgICAiaW4gdGhlIGxpc3QuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCSAgICB9CgkgICAgbmV4dHN0byA9IHN0by0+bmV4dDsKCSAgICAvKgoJICAgICogVW5saW5rIGZyb20gdGhlIGxpc3Qgb2YgYWN0aXZlIFhQYXRoIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZXMgPSBzdG8tPm5leHQ7CgkgICAgc3RvLT5uZXh0ID0gdmN0eHQtPnhwYXRoU3RhdGVQb29sOwoJICAgIC8qCgkgICAgKiBMaW5rIGl0IHRvIHRoZSBwb29sIG9mIHJldXNhYmxlIHN0YXRlIG9iamVjdHMuCgkgICAgKi8KCSAgICB2Y3R4dC0+eHBhdGhTdGF0ZVBvb2wgPSBzdG87CSAgICAKCSAgICBzdG8gPSBuZXh0c3RvOwoJfSBlbHNlCgkgICAgc3RvID0gc3RvLT5uZXh0OwogICAgfSAvKiB3aGlsZSAoc3RvICE9IE5VTEwpICovCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVyczoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbURlY2w6IHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uCiAqCiAqIENyZWF0ZXMgaGVscGVyIG9iamVjdHMgdG8gZXZhbHVhdGUgSURDIHNlbGVjdG9ycy9maWVsZHMKICogc3VjY2Vzc2l2ZWx5LgogKgogKiBSZXR1cm5zIDAgaWYgT0sgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVycyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJCSAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgeG1sU2NoZW1hSURDTWF0Y2hlclB0ciBtYXRjaGVyLCBsYXN0ID0gTlVMTDsKICAgIHhtbFNjaGVtYUlEQ1B0ciBpZGMsIHJlZklkYzsKICAgIHhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjOwogICAgICAgIAogICAgaWRjID0gKHhtbFNjaGVtYUlEQ1B0cikgZWxlbURlY2wtPmlkY3M7CiAgICBpZiAoaWRjID09IE5VTEwpCglyZXR1cm4gKDApOwogICAgCiNpZiBERUJVR19JREMKICAgIHsKCXhtbENoYXIgKnN0ciA9IE5VTEw7Cgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgCgkgICAgIklEQzogUkVHSVNURVIgb24gJXMsIGRlcHRoICVkXG4iLAoJICAgIChjaGFyICopIHhtbFNjaGVtYUZvcm1hdE5zVXJpTG9jYWwoJnN0ciwgdmN0eHQtPm5vZGVJbmZvLT5uYW1lc3BhY2VOYW1lLAoJCXZjdHh0LT5ub2RlSW5mby0+bG9jYWxOYW1lKSwgdmN0eHQtPmRlcHRoKTsKCUZSRUVfQU5EX05VTEwoc3RyKQogICAgfQojZW5kaWYKICAgIGlmICh2Y3R4dC0+bm9kZUluZm8tPmlkY01hdGNoZXJzICE9IE5VTEwpIHsKCXhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVyczogIgoJICAgICJUaGUgY2hhaW4gb2YgSURDIG1hdGNoZXJzIGlzIGV4cGVjdGVkIHRvIGJlIGVtcHR5LlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgZG8gewoJaWYgKGlkYy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfSURDX0tFWVJFRikgewoJICAgIC8qCgkgICAgKiBTaW5jZSBJRENzIGJ1YmJsZXMgYXJlIGV4cGVuc2l2ZSB3ZSBuZWVkIHRvIGtub3cgdGhlCgkgICAgKiBkZXB0aCBhdCB3aGljaCB0aGUgYnViYmxlcyBzaG91bGQgc3RvcDsgdGhpcyB3aWxsIGJlCgkgICAgKiB0aGUgZGVwdGggb2YgdGhlIHRvcC1tb3N0IGtleXJlZiBJREMuIElmIG5vIGtleXJlZgoJICAgICogcmVmZXJlbmNlcyBhIGtleS91bmlxdWUgSURDLCB0aGUgYnViYmxlRGVwdGggd2lsbAoJICAgICogYmUgLTEsIGluZGljYXRpbmcgdGhhdCBubyBidWJibGVzIGFyZSBuZWVkZWQuCgkgICAgKi8KCSAgICByZWZJZGMgPSAoeG1sU2NoZW1hSURDUHRyKSBpZGMtPnJlZi0+aXRlbTsKCSAgICBpZiAocmVmSWRjICE9IE5VTEwpIHsKCQkvKgoJCSogTG9va3VwIHRoZSBhdWdtZW50ZWQgSURDLgoJCSovCgkJYWlkYyA9IHZjdHh0LT5haWRjczsKCQl3aGlsZSAoYWlkYyAhPSBOVUxMKSB7CgkJICAgIGlmIChhaWRjLT5kZWYgPT0gcmVmSWRjKQoJCQlicmVhazsKCQkgICAgYWlkYyA9IGFpZGMtPm5leHQ7CgkJfQoJCWlmIChhaWRjID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hVkVycih2Y3R4dCwgdmN0eHQtPm5vZGUsCgkJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnM6ICIKCQkJIkNvdWxkIG5vdCBmaW5kIGFuIGF1Z21lbnRlZCBJREMgaXRlbSBmb3IgYW4gSURDICIKCQkJImRlZmluaXRpb24uXG4iLAoJCQlOVUxMLCBOVUxMKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQkJCgkJaWYgKChhaWRjLT5idWJibGVEZXB0aCA9PSAtMSkgfHwKCQkgICAgKHZjdHh0LT5kZXB0aCA8IGFpZGMtPmJ1YmJsZURlcHRoKSkKCQkgICAgYWlkYy0+YnViYmxlRGVwdGggPSB2Y3R4dC0+ZGVwdGg7CgkgICAgfQoJfQoJLyoKCSogTG9va3VwIHRoZSBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIHRoZSBJREMgZGVmaW5pdGlvbi4KCSovCglhaWRjID0gdmN0eHQtPmFpZGNzOwoJd2hpbGUgKGFpZGMgIT0gTlVMTCkgewoJICAgIGlmIChhaWRjLT5kZWYgPT0gaWRjKQoJCWJyZWFrOwoJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJfQoJaWYgKGFpZGMgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnIodmN0eHQsIHZjdHh0LT5ub2RlLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hSURDUmVnaXN0ZXJNYXRjaGVyczogIgoJCSJDb3VsZCBub3QgZmluZCBhbiBhdWdtZW50ZWQgSURDIGl0ZW0gZm9yIGFuIElEQyBkZWZpbml0aW9uLlxuIiwKCQlOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKC0xKTsKCX0KCS8qCgkqIENyZWF0ZSBhbiBJREMgbWF0Y2hlciBmb3IgZXZlcnkgSURDIGRlZmluaXRpb24uCgkqLwoJbWF0Y2hlciA9ICh4bWxTY2hlbWFJRENNYXRjaGVyUHRyKSAKCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUlEQ01hdGNoZXIpKTsKCWlmIChtYXRjaGVyID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KHZjdHh0LCAKCQkiYWxsb2NhdGluZyBhbiBJREMgbWF0Y2hlciIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbWVtc2V0KG1hdGNoZXIsIDAsIHNpemVvZih4bWxTY2hlbWFJRENNYXRjaGVyKSk7CglpZiAobGFzdCA9PSBOVUxMKQoJICAgIHZjdHh0LT5ub2RlSW5mby0+aWRjTWF0Y2hlcnMgPSBtYXRjaGVyOwoJZWxzZQoJICAgIGxhc3QtPm5leHQgPSBtYXRjaGVyOwoJbGFzdCA9IG1hdGNoZXI7CgoJbWF0Y2hlci0+dHlwZSA9IElEQ19NQVRDSEVSOwoJbWF0Y2hlci0+ZGVwdGggPSB2Y3R4dC0+ZGVwdGg7CQoJbWF0Y2hlci0+YWlkYyA9IGFpZGM7CiNpZiBERUJVR19JREMJCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIklEQzogICByZWdpc3RlciBtYXRjaGVyXG4iKTsKI2VuZGlmIAoJLyoKCSogSW5pdCB0aGUgYXV0b21hdG9uIHN0YXRlIG9iamVjdC4gCgkqLwoJaWYgKHhtbFNjaGVtYUlEQ0FkZFN0YXRlT2JqZWN0KHZjdHh0LCBtYXRjaGVyLCAKCSAgICBpZGMtPnNlbGVjdG9yLCBYUEFUSF9TVEFURV9PQkpfVFlQRV9JRENfU0VMRUNUT1IpID09IC0xKQoJICAgIHJldHVybiAoLTEpOwoKCWlkYyA9IGlkYy0+bmV4dDsKICAgIH0gd2hpbGUgKGlkYyAhPSBOVUxMKTsKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFCdWJibGVJRENOb2RlVGFibGVzOiAKICogQGRlcHRoOiB0aGUgY3VycmVudCB0cmVlIGRlcHRoCiAqCiAqIE1lcmdlcyBJREMgYmluZGluZ3Mgb2YgYW4gZWxlbWVudCBhdCBAZGVwdGggaW50byB0aGUgY29ycmVzcG9uZGluZyBJREMgCiAqIGJpbmRpbmdzIG9mIGl0cyBwYXJlbnQgZWxlbWVudC4gSWYgYSBkdXBsaWNhdGUgbm90ZS10YWJsZSBlbnRyeSBpcyBmb3VuZCwgCiAqIGJvdGgsIHRoZSBwYXJlbnQgbm9kZS10YWJsZSBlbnRyeSBhbmQgY2hpbGQgZW50cnkgYXJlIGRpc2NhcmRlZCBmcm9tIHRoZSAKICogbm9kZS10YWJsZSBvZiB0aGUgcGFyZW50LgogKgogKiBSZXR1cm5zIDAgaWYgT0sgYW5kIC0xIG9uIGludGVybmFsIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIGJpbmQ7IC8qIElEQyBiaW5kaW5ncyBvZiB0aGUgY3VycmVudCBub2RlLiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ0JpbmRpbmdQdHIgKnBhclRhYmxlLCBwYXJCaW5kID0gTlVMTCwgbGFzdFBhckJpbmQgPSBOVUxMOyAvKiBwYXJlbnQgSURDIGJpbmRpbmdzLiAqLwogICAgeG1sU2NoZW1hUFNWSUlEQ05vZGVQdHIgbm9kZSwgcGFyTm9kZSA9IE5VTEw7IC8qIG5vZGUtdGFibGUgZW50cmllcy4gKi8KICAgIHhtbFNjaGVtYVBTVklJRENLZXlQdHIga2V5LCBwYXJLZXk7IC8qIGtleXMgb2YgaW4gYSBrZXktc2VxdWVuY2UuICovCiAgICB4bWxTY2hlbWFJRENBdWdQdHIgYWlkYzsKICAgIGludCBpLCBqLCBrLCByZXQgPSAwLCBvbGROdW0sIG5ld0R1cGxzID0gMDsKICAgIGludCBkdXBsVG9wOwoKICAgIC8qCiAgICAqIFRoZSBub2RlIHRhYmxlIGhhcyB0aGUgZm9sbG93aW5nIHNlY3Rpb25zOgogICAgKgogICAgKiAgTyAtLT4gb2xkIG5vZGUtdGFibGUgZW50cmllcyAoZmlyc3QpCiAgICAqICBPIAogICAgKiAgKyAtLT4gbmV3IG5vZGUtdGFibGUgZW50cmllcwogICAgKiAgKyAKICAgICogICUgLS0+IG5ldyBkdXBsaWNhdGUgbm9kZS10YWJsZSBlbnRyaWVzICAgIAogICAgKiAgJSAKICAgICogICMgLS0+IG9sZCBkdXBsaWNhdGUgbm9kZS10YWJsZSBlbnRyaWVzICAgIAogICAgKiAgIyAobGFzdCkKICAgICoKICAgICovCiAgICBiaW5kID0gdmN0eHQtPm5vZGVJbmZvLT5pZGNUYWJsZTsgICAgICAgIAogICAgaWYgKGJpbmQgPT0gTlVMTCkgewoJLyogRmluZSwgbm8gdGFibGUsIG5vIGJ1YmJsZXMuICovCglyZXR1cm4gKDApOwogICAgfQogICAgCiAgICBwYXJUYWJsZSA9ICYodmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGggLTFdLT5pZGNUYWJsZSk7CiAgICAvKgogICAgKiBXYWxrIGFsbCBiaW5kaW5nczsgY3JlYXRlIG5ldyBvciBhZGQgdG8gZXhpc3RpbmcgYmluZGluZ3MuCiAgICAqIFJlbW92ZSBkdXBsaWNhdGUga2V5LXNlcXVlbmNlcy4KICAgICovCnN0YXJ0X2JpbmRpbmc6CiAgICB3aGlsZSAoYmluZCAhPSBOVUxMKSB7CgkvKgoJKiBTa2lwIGtleXJlZiBJRENzLgoJKi8KCWlmIChiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgYmluZCA9IGJpbmQtPm5leHQ7CgkgICAgY29udGludWU7Cgl9CgkvKgoJKiBDaGVjayBpZiB0aGUga2V5L3VuaXF1ZSBJREMgdGFibGUgbmVlZHMgdG8gYmUgYnViYmxlZC4KCSovCglhaWRjID0gdmN0eHQtPmFpZGNzOwoJZG8gewoJICAgIGlmIChhaWRjLT5kZWYgPT0gYmluZC0+ZGVmaW5pdGlvbikgewoJCWlmIChhaWRjLT5idWJibGVEZXB0aCA+PSB2Y3R4dC0+ZGVwdGgpIHsKCQkgICAgYmluZCA9IGJpbmQtPm5leHQ7CgkJICAgIGdvdG8gc3RhcnRfYmluZGluZzsKCQl9CgkJYnJlYWs7CgkgICAgfQoJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJfSB3aGlsZSAoYWlkYyAhPSBOVUxMKTsKCglpZiAocGFyVGFibGUgIT0gTlVMTCkKCSAgICBwYXJCaW5kID0gKnBhclRhYmxlOwoJd2hpbGUgKHBhckJpbmQgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiBTZWFyY2ggYSBtYXRjaGluZyBwYXJlbnQgYmluZGluZyBmb3IgdGhlCgkgICAgKiBJREMgZGVmaW5pdGlvbi4KCSAgICAqLwoJICAgIGlmIChwYXJCaW5kLT5kZWZpbml0aW9uID09IGJpbmQtPmRlZmluaXRpb24pIHsKCgkJLyoKCQkqIENvbXBhcmUgZXZlcnkgbm9kZS10YWJsZSBlbnRyeSBvZiB0aGUgY2hpbGQgbm9kZSwgCgkJKiBpLmUuIHRoZSBrZXktc2VxdWVuY2Ugd2l0aGluLCAuLi4KCQkqLwoJCW9sZE51bSA9IHBhckJpbmQtPm5iTm9kZXM7IC8qIFNraXAgbmV3bHkgYWRkZWQgaXRlbXMuICovCgkJZHVwbFRvcCA9IG9sZE51bSArIHBhckJpbmQtPm5iRHVwbHM7CgoJCWZvciAoaSA9IDA7IGkgPCBiaW5kLT5uYk5vZGVzOyBpKyspIHsKCQkgICAgbm9kZSA9IGJpbmQtPm5vZGVUYWJsZVtpXTsKCQkgICAgaWYgKG5vZGUgPT0gTlVMTCkKCQkJY29udGludWU7CgkJICAgIC8qCgkJICAgICogLi4ud2l0aCBldmVyeSBrZXktc2VxdWVuY2Ugb2YgdGhlIHBhcmVudCBub2RlLCBhbHJlYWR5CgkJICAgICogZXZhbHVhdGVkIHRvIGJlIGEgZHVwbGljYXRlIGtleS1zZXF1ZW5jZS4KCQkgICAgKi8KCQkgICAgaWYgKHBhckJpbmQtPm5iRHVwbHMgIT0gMCkgewoJCQlqID0gYmluZC0+bmJOb2RlcyArIG5ld0R1cGxzOyAKCQkJd2hpbGUgKGogPCBkdXBsVG9wKSB7CgkJCSAgICBwYXJOb2RlID0gcGFyQmluZC0+bm9kZVRhYmxlW2pdOwoJCQkgICAgZm9yIChrID0gMDsgayA8IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOyBrKyspIHsKCQkJCWtleSA9IG5vZGUtPmtleXNba107CgkJCQlwYXJLZXkgPSBwYXJOb2RlLT5rZXlzW2tdOwoJCQkJcmV0ID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwodmN0eHQsIGtleS0+dHlwZSwgCgkJCQkgICAga2V5LT5jb21wVmFsdWUsCgkJCQkgICAgcGFyS2V5LT50eXBlLCBwYXJLZXktPmNvbXBWYWx1ZSk7CgkJCQlpZiAocmV0ID09IC0xKSB7CgkJCQkgICAgLyogVE9ETzogSW50ZXJuYWwgZXJyb3IgKi8KCQkJCSAgICByZXR1cm4oLTEpOwoJCQkJfSBlbHNlIGlmIChyZXQgPT0gMCkKCQkJCSAgICBicmVhazsKCgkJCSAgICB9CgkJCSAgICBpZiAocmV0ID09IDEpCgkJCQkvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCQlicmVhazsKCQkJICAgIGorKzsKCQkJfQoJCQlpZiAoaiAhPSBkdXBsVG9wKSB7CgkJCSAgICAvKiBEdXBsaWNhdGUgZm91bmQuICovCgkJCSAgICBjb250aW51ZTsKCQkJfQoJCSAgICB9CQkgICAgCgkJICAgIC8qCgkJICAgICogLi4uIGFuZCB3aXRoIGV2ZXJ5IGtleS1zZXF1ZW5jZSBvZiB0aGUgcGFyZW50IG5vZGUuCgkJICAgICovCQkgICAgCQkgICAgCgkJICAgIGogPSAwOwoJCSAgICB3aGlsZSAoaiA8IG9sZE51bSkgewoJCQlwYXJOb2RlID0gcGFyQmluZC0+bm9kZVRhYmxlW2pdOwoJCQkvKgoJCQkqIENvbXBhcmUga2V5IGJ5IGtleS4gCgkJCSovCgkJCWZvciAoayA9IDA7IGsgPCBwYXJCaW5kLT5kZWZpbml0aW9uLT5uYkZpZWxkczsgaysrKSB7CgkJCSAgICBrZXkgPSBub2RlLT5rZXlzW2tdOwoJCQkgICAgcGFyS2V5ID0gcGFyTm9kZS0+a2V5c1trXTsJCQkKCgkJCSAgICByZXQgPSB4bWxTY2hlbWFBcmVWYWx1ZXNFcXVhbCh2Y3R4dCwga2V5LT50eXBlLCAKCQkJCWtleS0+Y29tcFZhbHVlLAoJCQkJcGFyS2V5LT50eXBlLCBwYXJLZXktPmNvbXBWYWx1ZSk7CgkJCSAgICBpZiAocmV0ID09IC0xKSB7CgkJCQkvKiBUT0RPOiBJbnRlcm5hbCBlcnJvciAqLwoJCQkgICAgfSBlbHNlIGlmIChyZXQgPT0gMCkKCQkJCWJyZWFrOwoKCQkJfQoJCQlpZiAocmV0ID09IDEpCgkJCSAgICAvKgoJCQkgICAgKiBUaGUga2V5LXNlcXVlbmNlcyBhcmUgZXF1YWwuCgkJCSAgICAqLwoJCQkgICAgYnJlYWs7CgkJCWorKzsKCQkgICAgfQoJCSAgICBpZiAoaiAhPSBvbGROdW0pIHsKCQkJLyoKCQkJKiBIYW5kbGUgZHVwbGljYXRlcy4KCQkJKi8KCQkJbmV3RHVwbHMrKzsKCQkJb2xkTnVtLS07CgkJCXBhckJpbmQtPm5iTm9kZXMtLTsKCQkJLyoKCQkJKiBNb3ZlIGxhc3Qgb2xkIGl0ZW0gdG8gcG9zIG9mIGR1cGxpY2F0ZS4KCQkJKi8KCQkJcGFyQmluZC0+bm9kZVRhYmxlW2pdID0gCgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGVbb2xkTnVtXTsKCQkJCgkJCWlmIChwYXJCaW5kLT5uYk5vZGVzICE9IG9sZE51bSkgewoJCQkgICAgLyoKCQkJICAgICogSWYgbmV3IGl0ZW1zIGV4aXN0LCBtb3ZlIGxhc3QgbmV3IGl0ZW0gdG8gCgkJCSAgICAqIGxhc3Qgb2Ygb2xkIGl0ZW1zLgoJCQkgICAgKi8KCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZVtvbGROdW1dID0gCgkJCQlwYXJCaW5kLT5ub2RlVGFibGVbcGFyQmluZC0+bmJOb2Rlc107CgkJCX0KCQkJLyoKCQkJKiBNb3ZlIGR1cGxpY2F0ZSB0byBsYXN0IHBvcyBvZiBuZXcvb2xkIGl0ZW1zLgoJCQkqLwoJCQlwYXJCaW5kLT5ub2RlVGFibGVbcGFyQmluZC0+bmJOb2Rlc10gPSBwYXJOb2RlOwkJCQoJCQkKCQkgICAgfSBlbHNlIHsKCQkJLyoKCQkJKiBBZGQgdGhlIG5vZGUtdGFibGUgZW50cnkgKG5vZGUgYW5kIGtleS1zZXF1ZW5jZSkgb2YgCgkJCSogdGhlIGNoaWxkIG5vZGUgdG8gdGhlIG5vZGUgdGFibGUgb2YgdGhlIHBhcmVudCBub2RlLgoJCQkqLwoJCQlpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsJCQkKCQkJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQkJCXhtbE1hbGxvYygxICogc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgImFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJcmV0dXJuKC0xKTsKCQkJICAgIH0KCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcyA9IDE7CgkJCX0gZWxzZSBpZiAoZHVwbFRvcCA+PSBwYXJCaW5kLT5zaXplTm9kZXMpIHsKCQkJICAgIHBhckJpbmQtPnNpemVOb2RlcysrOwoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlID0gKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyICopIAoJCQkJeG1sUmVhbGxvYyhwYXJCaW5kLT5ub2RlVGFibGUsIHBhckJpbmQtPnNpemVOb2RlcyAqIAoJCQkJc2l6ZW9mKHhtbFNjaGVtYVBTVklJRENOb2RlUHRyKSk7CgkJCSAgICBpZiAocGFyQmluZC0+bm9kZVRhYmxlID09IE5VTEwpIHsKCQkJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJCQkgICAgInJlLWFsbG9jYXRpbmcgSURDIGxpc3Qgb2Ygbm9kZS10YWJsZSBpdGVtcyIsIE5VTEwpOwoJCQkJcmV0dXJuKC0xKTsKCQkJICAgIH0KCQkJfQoJCQkKCQkJLyoKCQkJKiBNb3ZlIGZpcnN0IG9sZCBkdXBsaWNhdGUgdG8gbGFzdCBwb3NpdGlvbgoJCQkqIG9mIG9sZCBkdXBsaWNhdGVzICsxLgoJCQkqLwoJCQlpZiAocGFyQmluZC0+bmJEdXBscyAhPSAwKSB7CgkJCSAgICBwYXJCaW5kLT5ub2RlVGFibGVbZHVwbFRvcF0gPQoJCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXMgKyBuZXdEdXBsc107CgkJCX0KCQkJLyoKCQkJKiBNb3ZlIGZpcnN0IG5ldyBkdXBsaWNhdGUgdG8gbGFzdCBwb3NpdGlvbiBvZgoJCQkqIG5ldyBkdXBsaWNhdGVzICsxLgoJCQkqLwoJCQlpZiAobmV3RHVwbHMgIT0gMCkgewoJCQkgICAgcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXMgKyBuZXdEdXBsc10gPQoJCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdOwoJCQl9CgkJCS8qCgkJCSogQXBwZW5kIHRoZSBuZXcgbm9kZS10YWJsZSBlbnRyeSB0byB0aGUgJ25ldyBub2RlLXRhYmxlCgkJCSogZW50cmllcycgc2VjdGlvbi4KCQkJKi8KCQkJcGFyQmluZC0+bm9kZVRhYmxlW3BhckJpbmQtPm5iTm9kZXNdID0gbm9kZTsKCQkJcGFyQmluZC0+bmJOb2RlcysrOwoJCQlkdXBsVG9wKys7CgkJICAgIH0KCQl9CgkJcGFyQmluZC0+bmJEdXBscyArPSBuZXdEdXBsczsKCQlicmVhazsKCSAgICB9CgkgICAgaWYgKHBhckJpbmQtPm5leHQgPT0gTlVMTCkKCQlsYXN0UGFyQmluZCA9IHBhckJpbmQ7CgkgICAgcGFyQmluZCA9IHBhckJpbmQtPm5leHQ7Cgl9CglpZiAocGFyQmluZCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIE5vIGJpbmRpbmcgZm9yIHRoZSBJREMgd2FzIGZvdW5kOiBjcmVhdGUgYSBuZXcgb25lIGFuZAoJICAgICogY29weSBhbGwgbm9kZS10YWJsZXMuCgkgICAgKi8KCSAgICBwYXJCaW5kID0geG1sU2NoZW1hSURDTmV3QmluZGluZyhiaW5kLT5kZWZpbml0aW9uKTsKCSAgICBpZiAocGFyQmluZCA9PSBOVUxMKQoJCXJldHVybigtMSk7CgoJICAgIHBhckJpbmQtPm5vZGVUYWJsZSA9ICh4bWxTY2hlbWFQU1ZJSURDTm9kZVB0ciAqKSAKCQl4bWxNYWxsb2MoYmluZC0+bmJOb2RlcyAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJICAgIGlmIChwYXJCaW5kLT5ub2RlVGFibGUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVZFcnJNZW1vcnkoTlVMTCwgCgkJICAgICJhbGxvY2F0aW5nIGFuIGFycmF5IG9mIElEQyBub2RlLXRhYmxlIGl0ZW1zIiwgTlVMTCk7CgkJeG1sU2NoZW1hSURDRnJlZUJpbmRpbmcocGFyQmluZCk7CgkJcmV0dXJuKC0xKTsKCSAgICB9CgkgICAgcGFyQmluZC0+c2l6ZU5vZGVzID0gYmluZC0+bmJOb2RlczsKCSAgICBwYXJCaW5kLT5uYk5vZGVzID0gYmluZC0+bmJOb2RlczsKCSAgICBtZW1jcHkocGFyQmluZC0+bm9kZVRhYmxlLCBiaW5kLT5ub2RlVGFibGUsCgkJYmluZC0+bmJOb2RlcyAqIHNpemVvZih4bWxTY2hlbWFQU1ZJSURDTm9kZVB0cikpOwoJICAgIGlmICgqcGFyVGFibGUgPT0gTlVMTCkKCQkqcGFyVGFibGUgPSBwYXJCaW5kOwoJICAgIGVsc2UKCQlsYXN0UGFyQmluZC0+bmV4dCA9IHBhckJpbmQ7Cgl9CgliaW5kID0gYmluZC0+bmV4dDsKICAgIH0gIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrQ1ZDSURDS2V5UmVmOgogKiBAdmN0eHQ6IHRoZSBXWFMgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtRGVjbDogdGhlIGVsZW1lbnQgZGVjbGFyYXRpb24KICoKICogQ2hlY2sgdGhlIGN2Yy1pZGMta2V5cmVmIGNvbnN0cmFpbnRzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQpCnsKICAgIHhtbFNjaGVtYVBTVklJRENCaW5kaW5nUHRyIHJlZmJpbmQsIGJpbmQ7CgogICAgcmVmYmluZCA9IHZjdHh0LT5ub2RlSW5mby0+aWRjVGFibGU7CiAgICAvKgogICAgKiBGaW5kIGEga2V5cmVmLgogICAgKi8KICAgIHdoaWxlIChyZWZiaW5kICE9IE5VTEwpIHsKCWlmIChyZWZiaW5kLT5kZWZpbml0aW9uLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9JRENfS0VZUkVGKSB7CgkgICAgaW50IGksIGosIGssIHJlczsKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyICpyZWZLZXlzLCAqa2V5czsKCSAgICB4bWxTY2hlbWFQU1ZJSURDS2V5UHRyIHJlZktleSwga2V5OwoKCSAgICAvKgoJICAgICogRmluZCB0aGUgcmVmZXJyZWQga2V5L3VuaXF1ZS4KCSAgICAqLwoJICAgIGJpbmQgPSB2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlOwoJICAgIGRvIHsKCQlpZiAoKHhtbFNjaGVtYUlEQ1B0cikgcmVmYmluZC0+ZGVmaW5pdGlvbi0+cmVmLT5pdGVtID09IAoJCSAgICBiaW5kLT5kZWZpbml0aW9uKQoJCSAgICBicmVhazsKCQliaW5kID0gYmluZC0+bmV4dDsKCSAgICB9IHdoaWxlIChiaW5kICE9IE5VTEwpOwoKCSAgICAvKgoJICAgICogU2VhcmNoIGZvciBhIG1hdGNoaW5nIGtleS1zZXF1ZW5jZXMuCgkgICAgKi8KCSAgICBmb3IgKGkgPSAwOyBpIDwgcmVmYmluZC0+bmJOb2RlczsgaSsrKSB7CgkJcmVzID0gMDsKCQlpZiAoYmluZCAhPSBOVUxMKSB7CQkgICAgCgkJICAgIHJlZktleXMgPSByZWZiaW5kLT5ub2RlVGFibGVbaV0tPmtleXM7CgkJICAgIGZvciAoaiA9IDA7IGogPCBiaW5kLT5uYk5vZGVzOyBqKyspIHsKCQkJa2V5cyA9IGJpbmQtPm5vZGVUYWJsZVtqXS0+a2V5czsKCQkJZm9yIChrID0gMDsgayA8IGJpbmQtPmRlZmluaXRpb24tPm5iRmllbGRzOyBrKyspIHsKCQkJICAgIHJlZktleSA9IHJlZktleXNba107CgkJCSAgICBrZXkgPSBrZXlzW2tdOwoJCQkgICAgcmVzID0geG1sU2NoZW1hQXJlVmFsdWVzRXF1YWwodmN0eHQsCgkJCQlrZXktPnR5cGUsIGtleS0+Y29tcFZhbHVlLAoJCQkJcmVmS2V5LT50eXBlLCByZWZLZXktPmNvbXBWYWx1ZSk7CgkJCSAgICBpZiAocmVzID09IDApCgkJCQlicmVhazsKCQkJICAgIGVsc2UgaWYgKHJlcyA9PSAtMSkgewoJCQkJcmV0dXJuICgtMSk7CgkJCSAgICB9CgkJCX0KCQkJaWYgKHJlcyA9PSAxKSB7CgkJCSAgICAvKgoJCQkgICAgKiBNYXRjaCBmb3VuZC4KCQkJICAgICovCgkJCSAgICBicmVhazsKCQkJfQoJCSAgICB9CgkJfQoJCWlmIChyZXMgPT0gMCkgewoJCSAgICAvKiBUT0RPOiBSZXBvcnQgdGhlIGtleS1zZXF1ZW5jZS4gKi8KCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycih2Y3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0lEQywKCQkJcmVmYmluZC0+bm9kZVRhYmxlW2ldLT5ub2RlLCAKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIHJlZmJpbmQtPmRlZmluaXRpb24sCgkJCSJObyBtYXRjaGluZyBrZXktc2VxdWVuY2UgZm91bmQiLCBOVUxMKTsKCQl9CgkgICAgfQoJfQoJcmVmYmluZCA9IHJlZmJpbmQtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gKDApOwp9CiNlbmRpZiAvKiBJRENfRU5BQkxFRCAqLwoKI2lmZGVmIEVMRU1fSU5GT19FTkFCTEVECi8qKgogKiB4bWxTY2hlbWFCZWdpbkVsZW1lbnQ6CiAqIEB2Y3R4dDogdGhlIFdYUyB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogSnVzdCBhIHRlbXBvcmFyeSB3b3JrYXJvdW5kIHRvIHNpbXVsYXRlIHN0cmVhbWluZyB2YWxpZGF0aW9uCiAqIGEgYml0LgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQmVnaW5FbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCkKewogICAgdmN0eHQtPmRlcHRoKys7CiAgICB2Y3R4dC0+bm9kZUluZm8gPSB4bWxTY2hlbWFHZXRGcmVzaEVsZW1JbmZvKHZjdHh0LCB2Y3R4dC0+ZGVwdGgpOwogICAgdmN0eHQtPm5vZGVJbmZvLT5ub2RlID0gdmN0eHQtPm5vZGU7CiAgICB2Y3R4dC0+bm9kZUluZm8tPmxvY2FsTmFtZSA9IHZjdHh0LT5ub2RlLT5uYW1lOwogICAgaWYgKHZjdHh0LT5ub2RlLT5ucyAhPSBOVUxMKQoJdmN0eHQtPm5vZGVJbmZvLT5uYW1lc3BhY2VOYW1lID0gdmN0eHQtPm5vZGUtPm5zLT5ocmVmOwogICAgZWxzZSAKCXZjdHh0LT5ub2RlSW5mby0+bmFtZXNwYWNlTmFtZSA9IE5VTEw7ICAgIAp9CgovKioKICogeG1sU2NoZW1hRW5kRWxlbWVudDoKICogQHZjdHh0OiB0aGUgV1hTIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBKdXN0IGEgdGVtcG9yYXJ5IHdvcmthcm91bmQgdG8gc2ltdWxhdGUgc3RyZWFtaW5nIHZhbGlkYXRpb24KICogYSBiaXQuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUVuZEVsZW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIHZjdHh0KQp7CiAgICBpZiAodmN0eHQtPmRlcHRoIDwgMCkgewoJLyogVE9ETzogcmFpc2UgZXJyb3I/ICovCgl2Y3R4dC0+ZGVwdGgtLTsKCXJldHVybiAoMCk7CiAgICB9CiNpZmRlZiBJRENfRU5BQkxFRAogICAgLyoKICAgICogRXZhbHVhdGUgdGhlIGhpc3Rvcnkgb2YgY2hhbmdlcyBvZiBhY3RpdmUgc3RhdGUgb2JqZWN0cy4KICAgICovCiAgICBpZiAoeG1sU2NoZW1hWFBhdGhQcm9jZXNzSGlzdG9yeSh2Y3R4dCwgdmN0eHQtPmRlcHRoKSA9PSAtMSkKCXJldHVybiAoLTEpOwoKICAgIGlmICh2Y3R4dC0+bm9kZUluZm8tPnZhbHVlICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+bm9kZUluZm8tPnZhbHVlKTsKCXZjdHh0LT5ub2RlSW5mby0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgLyoKICAgICogVE9ETzogNiBUaGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gZWFjaCBvZiAKICAgICogdGhlIHtpZGVudGl0eS1jb25zdHJhaW50IGRlZmluaXRpb25zfSBhcyBwZXIgSWRlbnRpdHktY29uc3RyYWludCAKICAgICogU2F0aXNmaWVkICinMy4xMS40KS4KICAgICovCiAgICAvKgogICAgKiBWYWxpZGF0ZSBJREMga2V5cmVmcy4KICAgICovCiAgICB4bWxTY2hlbWFDaGVja0NWQ0lEQ0tleVJlZih2Y3R4dCk7CiNlbmRpZgogICAgCiAgICAvKgogICAgKiBNZXJnZS9mcmVlIHRoZSBJREMgdGFibGUuCiAgICAqLwogICAgaWYgKHZjdHh0LT5ub2RlSW5mby0+aWRjVGFibGUgIT0gTlVMTCkgewojaWZkZWYgSURDX0VOQUJMRUQKI2lmZGVmIERFQlVHX0lEQwoJeG1sU2NoZW1hRGVidWdEdW1wSURDVGFibGUoc3Rkb3V0LAoJICAgIHZjdHh0LT5ub2RlSW5mby0+bmFtZXNwYWNlTmFtZSwKCSAgICB2Y3R4dC0+bm9kZUluZm8tPmxvY2FsTmFtZSwKCSAgICB2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlKTsKI2VuZGlmCglpZiAodmN0eHQtPmRlcHRoID4gMCkgewoJICAgIC8qCgkgICAgKiBNZXJnZSB0aGUgSURDIG5vZGUgdGFibGUgd2l0aCB0aGUgdGFibGUgb2YgdGhlIHBhcmVudCBub2RlLgoJICAgICovCgkgICAgeG1sU2NoZW1hQnViYmxlSURDTm9kZVRhYmxlcyh2Y3R4dCk7CSAgICAKCX0KCS8qCgkqIFRPRE86IERvbid0IGZyZWUgdGhlIFBTVkkgSURDIHRhYmxlcyBpZiB0aGV5IGFyZQoJKiByZXF1ZXN0ZWQgZm9yIHRoZSBQU1ZJLgoJKi8KCXhtbFNjaGVtYUlEQ0ZyZWVJRENUYWJsZSh2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlKTsKI2VuZGlmCgl2Y3R4dC0+bm9kZUluZm8tPmlkY1RhYmxlID0gTlVMTDsKICAgIH0KCiAgICAvKgogICAgKiBDbGVhbnVwIElEQyBtYXRjaGVycy4KICAgICovCiNpZmRlZiBJRENfRU5BQkxFRAogICAgaWYgKHZjdHh0LT5ub2RlSW5mby0+aWRjTWF0Y2hlcnMgIT0gTlVMTCkgewkKCXhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdCh2Y3R4dC0+bm9kZUluZm8tPmlkY01hdGNoZXJzKTsKCXZjdHh0LT5ub2RlSW5mby0+aWRjTWF0Y2hlcnMgPSBOVUxMOwogICAgfQojZW5kaWYKCiAgICAvKgogICAgKiBTa2lwIGZ1cnRoZXIgcHJvY2Vzc2luZyBpZiB3ZSBhcmUgb24gdGhlIHZhbGlkYXRpb24gcm9vdC4KICAgICovCiAgICBpZiAodmN0eHQtPmRlcHRoID09IDApIHsKCXZjdHh0LT5kZXB0aC0tOwoJcmV0dXJuICgwKTsKICAgIH0KCiAgICAvKgogICAgKiBSZXNldCB0aGUgYnViYmxlRGVwdGggaWYgbmVlZGVkLgogICAgKi8KI2lmZGVmIElEQ19FTkFCTEVECiAgICBpZiAodmN0eHQtPmFpZGNzICE9IE5VTEwpIHsKCXhtbFNjaGVtYUlEQ0F1Z1B0ciBhaWRjID0gdmN0eHQtPmFpZGNzOwoJZG8gewoJICAgIGlmIChhaWRjLT5idWJibGVEZXB0aCA9PSB2Y3R4dC0+ZGVwdGgpIHsKCQkvKgoJCSogQSBidWJibGVEZXB0aCBvZiBhIGtleS91bmlxdWUgSURDIG1hdGNoZXMgdGhlIGN1cnJlbnQKCQkqIGRlcHRoLCB0aGlzIG1lYW5zIHRoYXQgd2UgYXJlIGxlYXZpbmcgdGhlIHNjb3BlIG9mIHRoZQoJCSogdG9wLW1vc3Qga2V5cmVmIElEQy4KCQkqLwoJCWFpZGMtPmJ1YmJsZURlcHRoID0gLTE7CgkgICAgfQoJICAgIGFpZGMgPSBhaWRjLT5uZXh0OwoJfSB3aGlsZSAoYWlkYyAhPSBOVUxMKTsKICAgIH0KI2VuZGlmCiAgICB2Y3R4dC0+ZGVwdGgtLTsKICAgIC8qCiAgICAqIENsZWFyIHRoZSBjdXJyZW50IGVsZW1JbmZvLgogICAgKi8KICAgIGlmICh2Y3R4dC0+bm9kZUluZm8tPnZhbHVlICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZyZWVWYWx1ZSh2Y3R4dC0+bm9kZUluZm8tPnZhbHVlKTsKCXZjdHh0LT5ub2RlSW5mby0+dmFsdWUgPSBOVUxMOwogICAgfQogICAgdmN0eHQtPm5vZGVJbmZvID0gdmN0eHQtPmVsZW1JbmZvc1t2Y3R4dC0+ZGVwdGhdOwogICAgdmN0eHQtPm5vZGUgPSB2Y3R4dC0+bm9kZUluZm8tPm5vZGU7CgogICAgcmV0dXJuICgwKTsKfQoKI2VuZGlmIC8qIEVMRU1fSU5GT19FTkFCTEVEICovCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgdHlwZS4KICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKEVsZW1lbnQpCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAoJCQkJICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCkKewogICAgeG1sTm9kZVB0ciBlbGVtOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGFjdHVhbFR5cGUgPSBOVUxMOwogICAgeG1sQXR0clB0ciBhdHRyOwogICAgeG1sQ2hhciAqYXR0clZhbHVlOyAKICAgIGludCBuaWxsZWQgPSAwLCBlbGVtSGFzQ29udGVudCA9IC0xOwoKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZEludGVybmFsLCAKICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlIGFuZCB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQuCiAgICAqIE5vdGUgdGhhdCBAZWxlbURlY2wgd2lsbCBiZSB0aGUgZGVjbGFyYXRpb24gYW5kIG5ldmVyIHRoZQogICAgKiByZWZlcmVuY2UgdG8gYSBkZWNsYXJhdGlvbi4KICAgICovCgogICAgaWYgKGN0eHQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgTlVMTCwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkgICAgImJhZCBhcmd1bWVudHMuXG4iLAoJICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGVsZW0gPSBjdHh0LT5ub2RlOyAgIAoKICAgIC8qCiAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDEKICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LAoJICAgIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwgCgkgICAgZWxlbSwgTlVMTCwKCSAgICAiTm8gbWF0Y2hpbmcgZGVjbGFyYXRpb24gYXZhaWxhYmxlIiwgTlVMTCk7CgkvKiAKCSogRXZhbHVhdGUgSURDcyBldmVuIGlmIGFuIGVycm9yIG9jY3VyZWQuCgkqLwojaWZkZWYgSURDX0VOQUJMRUQKCWlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsIFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJICAgIHJldHVybiAoLTEpOwojZW5kaWYKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAyCiAgICAqLwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHsKCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzIsCgkgICAgZWxlbSwgTlVMTCwgCgkgICAgIlRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGlzIGFic3RyYWN0IiwgTlVMTCk7CgkvKiAKCSogRXZhbHVhdGUgSURDcyBldmVuIGlmIGFuIGVycm9yIG9jY3VyZWQuCgkqLwojaWZkZWYgSURDX0VOQUJMRUQKCWlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsIFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJICAgIHJldHVybiAoLTEpOwojZW5kaWYKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAgCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiAzCiAgICAqIEhhbmRsZSAneHNpOm5pbCcuCiAgICAqLwogICAgCiAgICBhdHRyID0geG1sSGFzTnNQcm9wKGVsZW0sIEJBRF9DQVNUICJuaWwiLCB4bWxTY2hlbWFJbnN0YW5jZU5zKTsKICAgIGlmIChhdHRyICE9IE5VTEwpIHsKCWF0dHJWYWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KCh4bWxOb2RlUHRyKSBhdHRyKTsJCgljdHh0LT5ub2RlID0gKHhtbE5vZGVQdHIpIGF0dHI7CgljdHh0LT5jdXIgPSBhdHRyLT5jaGlsZHJlbjsJCglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCAKCSAgICB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19CT09MRUFOKSwKCSAgICBCQURfQ0FTVCBhdHRyVmFsdWUsIDEsIDEsIDEsIDEpOwoJY3R4dC0+bm9kZSA9IGVsZW07CgljdHh0LT50eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsOwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCSh4bWxOb2RlUHRyKSBhdHRyLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJInZhbGlkYXRpbmcgdGhlIGF0dHJpYnV0ZSAneHNpOm5pbCciLCBOVUxMKTsKCSAgICBpZiAoYXR0clZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZShhdHRyVmFsdWUpOwoJICAgIHJldHVybiAoLTEpOwoJfSAKCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgPT0gMCkgewoJICAgIC8qIAoJICAgICogY3ZjLWVsdCAoMy4zLjQpIDogMy4xIAoJICAgICovCgkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQlYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMSwgCgkJZWxlbSwgTlVMTCwKCQkiVGhlIGVsZW1lbnQgaXMgbm90ICduaWxsYWJsZSciLCBOVUxMKTsJCgl9IGVsc2UgewkJICAgIAoJICAgIGlmICh4bWxTdHJFcXVhbChCQURfQ0FTVCBhdHRyVmFsdWUsIEJBRF9DQVNUICJ0cnVlIikgfHwKCQl4bWxTdHJFcXVhbChCQURfQ0FTVCBhdHRyVmFsdWUsIEJBRF9DQVNUICIxIikpIHsJCQoJCXJldCA9IDA7CgkJLyogCgkJKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjIuMSAKCQkqLwoJCWVsZW1IYXNDb250ZW50ID0geG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSk7CgkJaWYgKGVsZW1IYXNDb250ZW50ID09IDEpIHsKCQkgICAgeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMSwgCgkJCS8qIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwgKi8KCQkJZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCQkiVGhlICduaWxsZWQnIGVsZW1lbnQgbXVzdCBoYXZlIG5vIGNoYXJhY3RlciBvciAiCgkJCSJlbGVtZW50IGNvbnRlbnQiLCBOVUxMKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0VMVF8zXzJfMTsKCQl9CgkJLyogCgkJKiBjdmMtZWx0ICgzLjMuNCkgOiAzLjIuMiAKCQkqLwoJCWlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9GSVhFRCkgJiYKCQkgICAgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewoJCSAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0NWQ19FTFRfM18yXzIsIAoJCQkvKiBYTUxfU0NIRU1BU19FUlJfSEFWRURFRkFVTFQsICovCgkJCWVsZW0sICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkJIlRoZXJlIGlzIGEgZml4ZWQgdmFsdWUgY29uc3RyYWludCBkZWZpbmVkIGZvciAiCgkJCSJ0aGUgJ25pbGxlZCcgZWxlbWVudCIsIE5VTEwpOwkJICAgIAoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRUxUXzNfMl8yOwoJCX0KCQlpZiAocmV0ID09IDApCgkJICAgIG5pbGxlZCA9IDE7CQkKCSAgICB9Cgl9CglpZiAoYXR0clZhbHVlICE9IE5VTEwpCgkgICAgeG1sRnJlZShhdHRyVmFsdWUpOwogICAgfQogICAgCgogICAgYWN0dWFsVHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKICAgIC8qIAogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA0IAogICAgKiBIYW5kbGUgJ3hzaTp0eXBlJy4KICAgICovCiAgICAKICAgIGF0dHIgPSB4bWxIYXNOc1Byb3AoZWxlbSwgQkFEX0NBU1QgInR5cGUiLCAgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CQoJeG1sQ2hhciAqbnNOYW1lID0gTlVMTCwgKmxvY2FsID0gTlVMTDsKCQoJLyoKCSogVE9ETzogV2Ugc2hvdWxkIHJlcG9ydCBhICp3YXJuaW5nKiB0aGF0IHRoZSB0eXBlIHdhcyBvdmVycmlkZW4KCSogYnkgdGhlIGluc3RhbmNlLgoJKi8KCQoJLyogCgkqIGN2Yy1lbHQgKDMuMy40KSA6IDQuMSAKCSovCglhdHRyVmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudCgoeG1sTm9kZVB0cikgYXR0cik7CglyZXQgPSB4bWxTY2hlbWFWYWxRTmFtZUFjcXVpcmUoYXR0clZhbHVlLCBhdHRyLT5wYXJlbnQsCQoJICAgICZuc05hbWUsICZsb2NhbCk7CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJKHhtbE5vZGVQdHIpIGF0dHIsICh4bWxTY2hlbWFUeXBlUHRyKSBlbGVtRGVjbCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24sICIKCQkidmFsaWRhdGluZyB0aGUgYXR0cmlidXRlICd4c2k6dHlwZSciLCBOVUxMKTs7CgkgICAgRlJFRV9BTkRfTlVMTChhdHRyVmFsdWUpCgkJRlJFRV9BTkRfTlVMTChuc05hbWUpCgkJRlJFRV9BTkRfTlVMTChsb2NhbCkKCQlyZXR1cm4gKC0xKTsKCX0gZWxzZSBpZiAocmV0ID09IDEpIHsKCSAgICB4bWxTY2hlbWFWU2ltcGxlVHlwZUVycihjdHh0LAoJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwKCQkoeG1sTm9kZVB0cikgYXR0ciwgYXR0clZhbHVlLCAKCQl4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19RTkFNRSkpOwoJfSBlbHNlIGlmIChyZXQgPT0gMikgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJKHhtbE5vZGVQdHIpIGF0dHIsIAoJCXhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX1FOQU1FKSwKCQkiVGhlIFFOYW1lIHZhbHVlICclcycgaGFzIG5vICIKCQkiY29ycmVzcG9uZGluZyBuYW1lc3BhY2UgZGVjbGFyYXRpb24gaW4gc2NvcGUiLCAKCQlhdHRyVmFsdWUpOwkgICAgCSAgICAKCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIGN2Yy1lbHQgKDMuMy40KSA6IDQuMiAKCSAgICAqLwoJICAgIGFjdHVhbFR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbG9jYWwsIG5zTmFtZSk7CgkgICAgaWYgKGFjdHVhbFR5cGUgPT0gTlVMTCkgewkgIAoJCXhtbENoYXIgKnN0ckEgPSBOVUxMOwoJCQoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF80XzIsCgkJICAgICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpLAoJCSAgICAiVGhlIHZhbHVlICVzIGRvZXMgbm90IHJlc29sdmUgdG8gYSB0eXBlICIKCQkgICAgImRlZmluaXRpb24iLCAKCQkgICAgeG1sU2NoZW1hRm9ybWF0TnNVcmlMb2NhbCgmc3RyQSwgbnNOYW1lLCBsb2NhbCkpOwoJCUZSRUVfQU5EX05VTEwoc3RyQSk7ICAgIAoJICAgIH0gZWxzZSB7CQkKCQkvKgoJCSogVVJHRU5UIFRPRE86IGN2Yy1lbHQgKDMuMy40KSA6IDQuMyAoVHlwZSBEZXJpdmF0aW9uIE9LKQoJCSovCQkKCSAgICB9Cgl9CglGUkVFX0FORF9OVUxMKGF0dHJWYWx1ZSkKCUZSRUVfQU5EX05VTEwobnNOYW1lKQoJRlJFRV9BTkRfTlVMTChsb2NhbCkKICAgIH0JCQogICAgLyogVE9ETzogQ2hhbmdlIHRoZSBoYW5kbGluZyBvZiBtaXNzaW5nIHR5cGVzIGFjY29yZGluZyB0bwogICAgKiB0aGUgc3BlYy4KICAgICovCiAgICBpZiAoYWN0dWFsVHlwZSA9PSBOVUxMKSB7CiAgICAJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKICAgIAkgICAgWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMSwKICAgIAkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50IiwgTlVMTCk7CgkvKiAKCSogRXZhbHVhdGUgSURDcyBldmVuIGlmIGFuIGVycm9yIG9jY3VyZWQuCgkqLwojaWZkZWYgSURDX0VOQUJMRUQKCWlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsIFhNTF9FTEVNRU5UX05PREUpID09IC0xKQoJICAgIHJldHVybiAoLTEpOwojZW5kaWYKICAgIAlyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzEpOwogICAgfQogICAgCiAgICAvKgogICAgKiBSZW1lbWJlciB0aGUgYWN0dWFsLXR5cGUgZGVmaW5pdGlvbi4KICAgICovCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAogICAgY3R4dC0+bm9kZUluZm8tPnR5cGVEZWYgPSBhY3R1YWxUeXBlOwojZW5kaWYKICAgIAogICAgLyoKICAgICogVE9ETzogU2luY2UgdGhpcyBzaG91bGQgYmUgYWxyZWFkeSBjaGVja2VkIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbiwKICAgICogYW5kIHdlIHdhbnQgdG8gZ2V0IHJpZCBvZiB0aGUgWE1MX1NDSEVNQVNfRVJSLi4uIHR5cGVzLCB0aGUgZXJyb3IgY29kZQogICAgKiBoYXMgYmVlbiBjaGFuZ2VkIHRvIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLgogICAgKi8KICAgIC8qCiAgICBpZiAoY2hpbGQgPT0gTlVMTCkgewogICAgICAgIGlmIChkZWNsLT5taW5PY2N1cnMgPiAwKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLCAKCQkiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlc1xuIiwKCQlub2RlLT5uYW1lLCBkZWNsLT5uYW1lKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfSAKICAgICovCiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IG1hdGNoZXMKICAgICAqIFRPRE8sIEZJWE1FOiBDYW4gdGhpcyBzdGlsbCBoYXBwZW4gaGVyZT8gSXNuJ3QgdGhpcyBhbHJlYWR5IGNoZWNrZWQKICAgICAqIGJ5IHRoZSBjb250ZW50IG1vZGVsIGF1dG9tYXRvbj8gICAgICAgICAKICAgIGlmICgheG1sU3RyRXF1YWwoY2hpbGQtPm5hbWUsIGRlY2wtPm5hbWUpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycjMoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIFhNTF9TQ0hFTUFTX0VSUl9XUk9OR0VMRU0sIAoJICAgICJFbGVtZW50ICVzOiBtaXNzaW5nIGNoaWxkICVzIGZvdW5kICVzXG4iLAoJICAgIG5vZGUtPm5hbWUsIGRlY2wtPm5hbWUsIGNoaWxkLT5uYW1lKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAqLyAgICAKICAgIGlmIChlbGVtSGFzQ29udGVudCA9PSAtMSkKCWVsZW1IYXNDb250ZW50ID0geG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSk7CgogICAgLyoKICAgICogSURDOiBSZWdpc3RlciBpZGVudGl0eS1jb25zdHJhaW50IFhQYXRoIG1hdGNoZXJzLgogICAgKi8KI2lmZGVmIElEQ19FTkFCTEVECiAgICBpZiAoZWxlbURlY2wtPmlkY3MgIT0gTlVMTCkKCXhtbFNjaGVtYUlEQ1JlZ2lzdGVyTWF0Y2hlcnMoY3R4dCwgZWxlbURlY2wpOwogICAgLyogCiAgICAqIEV2YWx1YXRlIElEQ3MuCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoY3R4dCwgWE1MX0VMRU1FTlRfTk9ERSkgPT0gLTEpCglyZXR1cm4gKC0xKTsKI2VuZGlmCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1IAogICAgKiBUaGUgYXBwcm9wcmlhdGUgY2FzZSBhbW9uZyB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICAvKgogICAgKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEgCiAgICAqIElmIHRoZSBkZWNsYXJhdGlvbiBoYXMgYSB7dmFsdWUgY29uc3RyYWludH0sIAogICAgKiB0aGUgaXRlbSBoYXMgbmVpdGhlciBlbGVtZW50IG5vciBjaGFyYWN0ZXIgW2NoaWxkcmVuXSBhbmQgCiAgICAqIGNsYXVzZSAzLjIgaGFzIG5vdCBhcHBsaWVkLCB0aGVuIGFsbCBvZiB0aGUgZm9sbG93aW5nIG11c3QgYmUgdHJ1ZToKICAgICovCiAgICBpZiAoKGVsZW1IYXNDb250ZW50ID09IDApICYmIChuaWxsZWQgPT0gMCkgJiYgKGVsZW1EZWNsLT52YWx1ZSAhPSBOVUxMKSkgewoJLyoKCSogY3ZjLWVsdCAoMy4zLjQpIDogNS4xLjEgCgkqIElmIHRoZSC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgaXMgYSC3bG9jYWwgdHlwZSBkZWZpbml0aW9utwoJKiB0aGVuIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9CgkqIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBkZWZhdWx0IGZvciB0aGUgt2FjdHVhbCB0eXBlIGRlZmluaXRpb263IGFzIAoJKiBkZWZpbmVkIGluIEVsZW1lbnQgRGVmYXVsdCBWYWxpZCAoSW1tZWRpYXRlKSAopzMuMy42KS4gCgkqLwoJLyogCgkqIE5PVEU6ICdsb2NhbCcgYWJvdmUgbWVhbnMgdHlwZXMgYXF1aXJlZCBieSB4c2k6dHlwZS4KCSovCglyZXQgPSAwOwoJaWYgKGFjdHVhbFR5cGUgIT0gZWxlbURlY2wtPnN1YnR5cGVzKSB7CgkgICAgeG1sU2NoZW1hQ3JlYXRlUEN0eHRPblZDdHh0KGN0eHQpOwoJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQ09TVmFsaWREZWZhdWx0KGN0eHQtPnBjdHh0LCBjdHh0LCBhY3R1YWxUeXBlLCAKCQllbGVtRGVjbC0+dmFsdWUsIE5VTEwpOwkgICAgCgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAoJCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwgCgkJICAgIGVsZW0sIGFjdHVhbFR5cGUsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlEZWNsYXJhdGlvbiwgIgoJCSAgICAidmFsaWRhdGluZyBhIGRlZmF1bHQgdmFsdWUiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9Cgl9CgkvKgoJKiBjdmMtZWx0ICgzLjMuNCkgOiA1LjEuMiAKCSogVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSB3aXRoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCAKCSogcmVwcmVzZW50YXRpb24gb2YgdGhlIHt2YWx1ZSBjb25zdHJhaW50fSB2YWx1ZSB1c2VkIGFzIGl0cyAKCSogt25vcm1hbGl6ZWQgdmFsdWW3IG11c3QgYmUgt3ZhbGlktyB3aXRoIHJlc3BlY3QgdG8gdGhlIAoJKiC3YWN0dWFsIHR5cGUgZGVmaW5pdGlvbrcgYXMgZGVmaW5lZCBieSBFbGVtZW50IExvY2FsbHkgVmFsaWQgKFR5cGUpCgkqICinMy4zLjQpLgoJKi8KCS8qCiAgICAgICAgKiBEaXNhYmxlIHZhbGlkYXRpb24gb2YgdGhlIHNpbXBsZSBjb250ZW50LCBpZiBpdCB3YXMgYWxyZWFkeQoJKiBkb25lIGFib3ZlLgoJKi8KCWlmIChyZXQgPT0gMCkgewoJICAgIGlmIChhY3R1YWxUeXBlICE9IGVsZW1EZWNsLT5zdWJ0eXBlcykKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGUoY3R4dCwgYWN0dWFsVHlwZSwgMCwgMCk7CgkgICAgZWxzZQoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZShjdHh0LCBhY3R1YWxUeXBlLCAwLCAxKTsKCSAgICBjdHh0LT5ub2RlID0gZWxlbTsKCSAgICBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkgICAgZWxlbSwgYWN0dWFsVHlwZSwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJICAgICJ2YWxpZGF0aW5nIGFnYWluc3QgdGhlIHR5cGUiLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIFBTVkk6IENyZWF0ZSBhIHRleHQgbm9kZSBvbiB0aGUgaW5zdGFuY2UgZWxlbWVudC4KCSAgICAqLwoJICAgIGlmIChjdHh0LT5vcHRpb25zICYgWE1MX1NDSEVNQV9WQUxfVkNfSV9DUkVBVEUpIHsKCQl4bWxOb2RlUHRyIHRleHRDaGlsZDsKCQkKCQl0ZXh0Q2hpbGQgPSB4bWxOZXdUZXh0KGVsZW1EZWNsLT52YWx1ZSk7CgkJaWYgKHRleHRDaGlsZCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLCAKCQkJZWxlbSwgYWN0dWFsVHlwZSwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJCSJjb3VsZCBub3QgY3JlYXRlIGEgZGVmYXVsdCB0ZXh0IG5vZGUgZm9yIHRoZSBpbnN0YW5jZSIsIAoJCQlOVUxMKTsKCQl9IGVsc2UKCQkgICAgeG1sQWRkQ2hpbGQoZWxlbSwgdGV4dENoaWxkKTsJICAgIAoJICAgIH0KCX0KCiAgICB9IGVsc2UgewkKCS8qCgkqIDUuMi4xIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSC3dmFsaWS3IHdpdGggcmVzcGVjdCAKCSogdG8gdGhlILdhY3R1YWwgdHlwZSBkZWZpbml0aW9utyBhcyBkZWZpbmVkIGJ5IEVsZW1lbnQgTG9jYWxseSAKCSogVmFsaWQgKFR5cGUpICinMy4zLjQpLgoJKi8KCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZShjdHh0LCBhY3R1YWxUeXBlLCBuaWxsZWQsIDEpOwoJLyoKCSogQ29uc3VtZSB0aGUgY29tcHV0ZWQgdmFsdWUgZm9yIElEQ3MsIGVjdC4gTm90ZSB0aGF0IGRlZmF1bHQKCSogdmFsdWVzIGFyZSBub3Qgc3VwcG9ydGVkIHlldC4KCSovCiNpZmRlZiBFTEVNX0lORk9fRU5BQkxFRAoJaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICBjdHh0LT5ub2RlSW5mby0+dmFsdWUgPSBjdHh0LT52YWx1ZTsKCSAgICBjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CiNlbmRpZgoJY3R4dC0+bm9kZSA9IGVsZW07CglpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsIAoJCWVsZW0sIGFjdHVhbFR5cGUsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeURlY2xhcmF0aW9uLCAiCgkJImNhbGxpbmcgdmFsaWRhdGlvbiBieSB0eXBlIiwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiA1LjIuMiBJZiB0aGVyZSBpcyBhIGZpeGVkIHt2YWx1ZSBjb25zdHJhaW50fSBhbmQgY2xhdXNlIDMuMiBoYXMgCgkqIG5vdCBhcHBsaWVkLCBhbGwgb2YgdGhlIGZvbGxvd2luZyBtdXN0IGJlIHRydWU6CgkqLwoJaWYgKChlbGVtRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKSAmJiAobmlsbGVkID09IDApKSB7CgkgICAgLyoKCSAgICAqIDUuMi4yLjEgVGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBtdXN0IGhhdmUgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqCgkgICAgKiBUT0RPIFJFRFVOREFOVDogSWYgdGhlIGFjdHVhbCB0eXBlIGV4aXN0cywgdGhlIGFib3ZlIGNhbGwgIHRvIAoJICAgICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlIHdpbGwgYWxyZWFkeSBjaGVjayBmb3IgZWxlbWVudCAKCSAgICAqIG5vZGVzLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUhhc0VsZW1Db250ZW50KGVsZW0pKSB7CgkJeG1sU2NoZW1hVkN1c3RvbUVycihjdHh0LCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0VMVF81XzJfMl8xLCAKCQkgICAgZWxlbSwgKHhtbFNjaGVtYVR5cGVQdHIpIGVsZW1EZWNsLAoJCSAgICAiRWxlbWVudHMgaW4gdGhlIGNvbnRlbnQgYXJlIG5vdCBhbGxvd2VkIGlmIGl0IGlzICIKCQkgICAgImNvbnN0cmFpbmVkIGJ5IGEgZml4ZWQgdmFsdWUiLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCS8qCgkJKiA1LjIuMi4yIFRoZSBhcHByb3ByaWF0ZSBjYXNlIGFtb25nIHRoZSBmb2xsb3dpbmcgbXVzdCAKCQkqIGJlIHRydWU6CgkJKi8KCQkKCQlpZiAoYWN0dWFsVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX01JWEVEKSB7CgkJICAgIHhtbENoYXIgKnZhbHVlOwoJCSAgICAvKgoJCSAgICAqIDUuMi4yLjIuMSBJZiB0aGUge2NvbnRlbnQgdHlwZX0gb2YgdGhlILdhY3R1YWwgdHlwZSAKCQkgICAgKiBkZWZpbml0aW9utyBpcyBtaXhlZCwgdGhlbiB0aGUgKmluaXRpYWwgdmFsdWUqIG9mIHRoZSAKCQkgICAgKiBpdGVtIG11c3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCBsZXhpY2FsIHJlcHJlc2VudGF0aW9uIAoJCSAgICAqIG9mIHRoZSB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUuCgkJICAgICoKCQkgICAgKiAuLi4gdGhlICppbml0aWFsIHZhbHVlKiBvZiBhbiBlbGVtZW50IGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gaXMgdGhlIHN0cmluZyBjb21wb3NlZCBvZiwgaW4gb3JkZXIsIHRoZSAKCQkgICAgKiBbY2hhcmFjdGVyIGNvZGVdIG9mIGVhY2ggY2hhcmFjdGVyIGluZm9ybWF0aW9uIGl0ZW0gaW4gCgkJICAgICogdGhlIFtjaGlsZHJlbl0gb2YgdGhhdCBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0uCgkJICAgICovCgkJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoZWxlbS0+ZG9jLCBlbGVtLT5jaGlsZHJlbiwgMSk7CgkJICAgIGlmICghIHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBlbGVtRGVjbC0+dmFsdWUpKSB7CgkJCS8qIAoJCQkqIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJCSogVE9ETzogSW1wbGVtZW50IHRoZSBjYW5vbmljYWwgc3R1ZmYuCgkJCSovCgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMSwgCgkJCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSAgICAiVGhlIHZhbHVlIGRvZXMgbm90IG1hdGNoIHRoZSBjb25vbmljYWwgIgoJCQkgICAgImxleGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGZpeGVkIGNvbnN0cmFpbnQiLCAKCQkJICAgIE5VTEwpOwoJCSAgICB9CgkJICAgIGlmICh2YWx1ZSAhPSBOVUxMKQoJCQl4bWxGcmVlKHZhbHVlKTsKCQl9IGVsc2UgaWYgKChhY3R1YWxUeXBlLT5jb250ZW50VHlwZSA9PSAKCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgfHwgCgkJICAgIChhY3R1YWxUeXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJICAgIHhtbENoYXIgKnZhbHVlOwoKCQkgICAgLyoKCQkgICAgKiA1LjIuMi4yLjIgSWYgdGhlIHtjb250ZW50IHR5cGV9IG9mIHRoZSC3YWN0dWFsIHR5cGUgCgkJICAgICogZGVmaW5pdGlvbrcgaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCB0aGVuIHRoZSAKCQkgICAgKiAqYWN0dWFsIHZhbHVlKiBvZiB0aGUgaXRlbSBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgCgkJICAgICogbGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUge3ZhbHVlIGNvbnN0cmFpbnR9IHZhbHVlLgoJCSAgICAqLwoJCSAgICAvKgoJCSAgICAqIFRPRE86ICphY3R1YWwgdmFsdWUqIGlzIHRoZSBub3JtYWxpemVkIHZhbHVlLCBpbXBsLiB0aGlzLgoJCSAgICAqIFRPRE86IFJlcG9ydCBpbnZhbGlkICYgZXhwZWN0ZWQgdmFsdWVzIGFzIHdlbGwuCgkJICAgICogVE9ETzogSW1wbGVtZW50IHRoZSBjYW5vbmljYWwgc3R1ZmYuCgkJICAgICogCgkJICAgICovCgkJICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcoZWxlbS0+ZG9jLCBlbGVtLT5jaGlsZHJlbiwgMSk7CgkJICAgIGlmICghIHhtbFN0ckVxdWFsKEJBRF9DQVNUIHZhbHVlLCBlbGVtRGVjbC0+dmFsdWUpKSB7CgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9DVkNfRUxUXzVfMl8yXzJfMiwgCgkJCSAgICBlbGVtLCAoeG1sU2NoZW1hVHlwZVB0cikgZWxlbURlY2wsCgkJCSAgICAiVGhlIG5vcm1hbGl6ZWQgdmFsdWUgZG9lcyBub3QgbWF0Y2ggdGhlIGNhbm9uaWNhbCAiCgkJCSAgICAibGV4aWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZml4ZWQgY29uc3RyYWludCIsIAoJCQkgICAgTlVMTCk7CgkJICAgIH0KCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOwoJCSAgICAKCQl9CgkJLyoKCQkqIFRPRE86IFdoYXQgaWYgdGhlIGNvbnRlbnQgdHlwZSBpcyBub3QgJ21peGVkJyBvciBzaW1wbGU/CgkJKi8KCgkgICAgfQoJICAgIAoJfQogICAgfQogICAgLyoKICAgICogVE9ETzogNyBJZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzIHRoZSC3dmFsaWRhdGlvbiByb290tywgaXQgbXVzdCBiZSAKICAgICogt3ZhbGlktyBwZXIgVmFsaWRhdGlvbiBSb290IFZhbGlkIChJRC9JRFJFRikgKKczLjMuNCkuCiAgICAqLwogICAgICAgICAgICAgICAKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFJlcHJlc2VudHMgdGhlIHJlY3Vyc2l2ZSBwb3J0aW9uIG9mIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmQuIAogKiBOb3QgaW50ZW5kZWQgdG8gYmUgdXNlZCBieSBvdGhlciBmdW5jdGlvbnMuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJCQkgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCAKCQkJCQkgICB4bWxOb2RlUHRyIG5vZGUpCnsgICAgICAgIAogICAgY29uc3QgeG1sQ2hhciAqdXJpOwogICAgaW50IHJldCA9IDA7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwoKICAgIGlmIChjdHh0LT54c2lBc3NlbWJsZSkgewkKCXJldCA9IHhtbFNjaGVtYUFzc2VtYmxlQnlYU0lFbGVtKGN0eHQsIGN0eHQtPm5vZGUpOwoJaWYgKHJldCA9PSAtMSkgewoJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCgkJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJY3R4dC0+bm9kZSwgTlVMTCwgCQoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50LCAiCgkJImFzc2VtYmxpbmcgc2NoZW1hIGJ5IHhzaSIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJLyoKCSogTk9URTogV2Ugd29uJ3QgcmVhY3Qgb24gc2NoZW1hIHBhcnNlciBlcnJvcnMgaGVyZS4KCSogVE9ETzogQnV0IGEgd2FybmluZyB3b3VsZCBiZSBuaWNlLgoJKi8KICAgIH0gICAgCiAgICBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzICE9IFhNTF9TQ0hFTUFTX0FOWV9TS0lQKSB7Cgl4bWxTY2hlbWFFbGVtZW50UHRyIGRlY2wgPSBOVUxMOwoKCWlmIChub2RlLT5ucyAhPSBOVUxMKQoJICAgIGRlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAoJICAgIG5vZGUtPm5hbWUsIG5vZGUtPm5zLT5ocmVmLCBOVUxMKTsKCWVsc2UgCgkgICAgZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsIG5vZGUtPm5hbWUsCgkgICAgTlVMTCwgTlVMTCk7CglpZiAoZGVjbCAhPSBOVUxMKSB7CQkgICAgCgkgICAgY3R4dC0+bm9kZSA9IG5vZGU7CQoJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZGVjbCk7CgkgICAgaWYgKHJldCA8IDApIHsJCQoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBbnlJbnRlcm5hbCwgIgoJCSAgICAidmFsaWRhdGluZyBhbiBlbGVtZW50IGluIHRoZSBjb250ZXh0IG9mIGEgd2lsZGNhcmQuIiwKCQkgICAgTlVMTCwgTlVMTCk7CgkgICAgfQoJICAgIHJldHVybiAocmV0KTsKCX0gZWxzZSBpZiAod2lsZC0+cHJvY2Vzc0NvbnRlbnRzID09IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpIHsKCSAgICAvKiBUT0RPOiBDaGFuZ2UgdG8gcHJvcGVyIGVycm9yIGNvZGUuICovCgkgICAgeG1sU2NoZW1hVldpbGRjYXJkRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0NWQ19FTFRfMSwKCQlub2RlLCB3aWxkLCAiTm8gbWF0Y2hpbmcgZ2xvYmFsIGRlY2xhcmF0aW9uIGF2YWlsYWJsZSIpOwoJICAgIC8qIAoJICAgICogRXZhbHVhdGUgSURDcyBldmVuIGlmIGEgdmFsaWRhdGlvbiBlcnJvciBvY2N1cmVkLgoJICAgICovCiNpZmRlZiBJRENfRU5BQkxFRAoJICAgIGlmICh4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsWE1MX0VMRU1FTlRfTk9ERSkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKI2VuZGlmCgkgICAgcmV0dXJuIChjdHh0LT5lcnIpOwoJfQoJLyogCgkqIEV2YWx1YXRlIElEQ3M7IHdlIG5lZWQgdG8ga25vdyBpZiBhbiBJREMgZmllbGQgcmVzb2x2ZXMgdG8KCSogc3VjaCBhIG5vZGUuIFRoaXMgbm9kZSBoYXMgbm8gdHlwZSBkZWZpbml0aW9uIGFuZCB3aWxsCgkqIGRlZmluaXRlbHkgcmVzdWx0IGluIGFuIElEQyB2YWxpZGF0aW9uIGVycm9yIGlmIGFuIElEQyBmaWVsZAoJKiByZXNvbHZlcy4KCSovCiNpZmRlZiBJRENfRU5BQkxFRAoJaWYgKHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoY3R4dCwgWE1MX0VMRU1FTlRfTk9ERSkgPT0gLTEpCgkgICAgcmV0dXJuKC0xKTsKI2VuZGlmCiAgICB9CiAgICBpZiAobm9kZS0+Y2hpbGRyZW4gIT0gTlVMTCkgewkgICAKCWNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CglkbyB7CgkgICAgaWYgKGNoaWxkLT50eXBlID09IFhNTF9FTEVNRU5UX05PREUpIHsKCQlpZiAoY2hpbGQtPm5zICE9IE5VTEwpCgkJICAgIHVyaSA9IGNoaWxkLT5ucy0+aHJlZjsKCQllbHNlCgkJICAgIHVyaSA9IE5VTEw7CgkJaWYgKHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHdpbGQsIHVyaSkgPT0gMCkgewoJCSAgICAvKiBUT0RPOiBlcnJvciBjb2RlLiAqLwoJCSAgICB4bWxTY2hlbWFWV2lsZGNhcmRFcnIoY3R4dCwgWE1MX1NDSEVNQVZfRUxFTUVOVF9DT05URU5ULAoJCQljaGlsZCwgd2lsZCwgCgkJCSJUaGUgbmFtZXNwYWNlIG9mIHRoZSBlbGVtZW50IGlzIG5vdCBhbGxvd2VkIik7CgkJICAgIHJldHVybiAoY3R4dC0+ZXJyKTsgIAoJCX0KI2lmZGVmIEVMRU1fSU5GT19FTkFCTEVECgkJY3R4dC0+bm9kZSA9IGNoaWxkOwoJCXhtbFNjaGVtYUJlZ2luRWxlbWVudChjdHh0KTsKI2VuZGlmCgkJLyoKCQkqIFJlY3Vyc2Ugb3ZlciB0aGUgY2hpbGRyZW4uCgkJKi8KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkSW50ZXJuYWwoY3R4dCwgCgkJICAgIHdpbGQsIGNoaWxkKTsKCQlpZiAocmV0ID09IC0xKQoJCSAgICByZXR1cm4gKC0xKTsKI2lmZGVmIEVMRU1fSU5GT19FTkFCTEVECgkJaWYgKHhtbFNjaGVtYUVuZEVsZW1lbnQoY3R4dCkgPT0gLTEpCgkJICAgIHJldHVybiAoLTEpOwojZW5kaWYKCQlpZiAocmV0ICE9IDApCgkJICAgIHJldHVybiAocmV0KTsJCQoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSB3aGlsZSAgKGNoaWxkICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudENvbnRCeVdpbGRjYXJkOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlXaWxkY2FyZCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsgICAgICAgCiAgICBpZiAoKHR5cGUgPT0gTlVMTCkgfHwgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0FOWSkgfHwKCShjdHh0LT5ub2RlID09IE5VTEwpKSB7Cgl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsIGN0eHQtPm5vZGUsIE5VTEwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVdpbGRjYXJkLCAiCgkgICAgImJhZCBhcmd1bWVudHMiLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQogICAgcmV0dXJuKHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5V2lsZGNhcmRJbnRlcm5hbChjdHh0LCAKCSAgICB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgY3R4dC0+bm9kZSkpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVBbnlUeXBlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjdXJyZW50IGVsZW1lbnQKICoKICogVGhpcyBvbmUgdmFsaWRhdGVzIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgb2YgdGhlIHR5cGUKICogJ2FueVR5cGUnLiBUaGUgcHJvY2VzcyBjb250ZW50cyBvZiB0aGUgd2lsZGNhcmQgb2YgJ2FueVR5cGUnIGlzICJsYXgiLCAKICogdGh1cyBlbGVtZW50cyBpbiB0aGUgc3VidHJlZSB3aWxsIGJlIHZhbGlkYXRlZCwgaWYgYSBjb3JyZXNwb25kaW5nCiAqIGRlY2xhcmF0aW9uIGluIHRoZSBzY2hlbWEgZXhpc3RzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgYW5kIGl0cyBzdWJ0cmVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGU7CiAgICB4bWxOb2RlUHRyIHRvcCwgY3VyOwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOwogICAgaW50IHNraXBDb250ZW50LCByZXQ7CgogICAgaWYgKCh0eXBlID09IE5VTEwpIHx8IChjdHh0LT5ub2RlID09IE5VTEwpKQoJcmV0dXJuICgtMSk7CgogICAgaWYgKGN0eHQtPm5vZGUtPmNoaWxkcmVuID09IE5VTEwpIAoJcmV0dXJuICgwKTsKCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIHRvcCA9IGN0eHQtPm5vZGU7ICAgICAgICAKICAgIC8qCiAgICAqIFNUUkVBTTogQ2hpbGQgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICBjdXIgPSBjdHh0LT5ub2RlLT5jaGlsZHJlbjsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJc2tpcENvbnRlbnQgPSAwOwoJaWYgKGN1ci0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkgICAgLyoKCSAgICAqIFRoZSBwcm9jZXNzIGNvbnRlbnRzIG9mIHRoZSB3aWxkY2FyZCBpcyAibGF4IiwgdGh1cwoJICAgICogd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgZWxlbWVudCBpZiBhIGRlY2xhcmF0aW9uCgkgICAgKiBleGlzdHMuCgkgICAgKi8JCQoJICAgIGlmIChjdXItPm5zICE9IE5VTEwpCgkJZGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCgkJICAgIGN1ci0+bmFtZSwgY3VyLT5ucy0+aHJlZiwgTlVMTCk7CgkgICAgZWxzZSAKCQlkZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwgY3VyLT5uYW1lLCBOVUxMLCBOVUxMKTsJICAgIAoJICAgIGlmIChkZWNsICE9IE5VTEwpIHsJCSAgICAKCQljdHh0LT5ub2RlID0gY3VyOwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24oY3R4dCwgZGVjbCk7CgkJY3R4dC0+bm9kZSA9IHRvcDsKCQlpZiAocmV0IDwgMCkgewkJCgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3VyLCBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUFueVR5cGVDb250ZW50LCAiCgkJCSJ2YWxpZGF0aW5nIGFuIGVsZW1lbnQgaW4gdGhlIGNvbnRleHQgb2YgYSB3aWxkY2FyZC4iLAoJCQlOVUxMLCBOVUxMKTsKCQkgICAgcmV0dXJuIChyZXQpOwoJCX0gZWxzZSBpZiAocmV0ID4gMCkKCQkgICAgcmV0dXJuIChyZXQpOwoJCXNraXBDb250ZW50ID0gMTsKCSAgICB9Cgl9ICAgCgkvKgoJKiBCcm93c2UgdGhlIGZ1bGwgc3VidHJlZSwgZGVlcCBmaXJzdC4KCSovCiAgICAgICAgaWYgKChza2lwQ29udGVudCA9PSAwKSAmJiAoY3VyLT5jaGlsZHJlbiAhPSBOVUxMKSkgewoJICAgIC8qIGRlZXAgZmlyc3QgKi8KCSAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwoJfSBlbHNlIGlmICgoY3VyICE9IHRvcCkgJiYgKGN1ci0+bmV4dCAhPSBOVUxMKSkgewoJICAgIC8qIHRoZW4gc2libGluZ3MgKi8KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9IGVsc2UgaWYgKGN1ciAhPSB0b3ApIHsKCSAgICAvKiBnbyB1cCB0byBwYXJlbnRzLT5uZXh0IGlmIG5lZWRlZCAqLwoJICAgIHdoaWxlIChjdXIgIT0gdG9wKSB7CgkgICAgICAgIGlmIChjdXItPnBhcmVudCAhPSBOVUxMKQoJCSAgICBjdXIgPSBjdXItPnBhcmVudDsKCQlpZiAoKGN1ciAhPSB0b3ApICYmIChjdXItPm5leHQgIT0gTlVMTCkpIHsKCQkgICAgY3VyID0gY3VyLT5uZXh0OwoJCSAgICBicmVhazsKCQl9CgkJaWYgKGN1ci0+cGFyZW50ID09IE5VTEwpIHsKCQkgICAgY3VyID0gTlVMTDsKCQkgICAgYnJlYWs7CgkJfQoJICAgIH0KCSAgICAvKiBleGl0IGNvbmRpdGlvbiAqLwoJICAgIGlmIChjdXIgPT0gdG9wKSAKCSAgICAgICAgY3VyID0gTlVMTDsKCX0gZWxzZQoJICAgIGJyZWFrOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBjb21wbGV4IHR5cGUgdHlwZQogKiB4bWxzY2hlbWEtMS5odG1sI2N2Yy1jb21wbGV4LXR5cGUKICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICogTm90ZSBvbiByZXBvcnRlZCBlcnJvcnM6IEFsdGhvdWdoIGl0IG1pZ2h0IGJlIG5pY2UgdG8gcmVwb3J0CiAqIHRoZSBuYW1lIG9mIHRoZSBzaW1wbGUvY29tcGxleCB0eXBlLCB1c2VkIHRvIHZhbGlkYXRlIHRoZSBjb250ZW50CiAqIG9mIGEgbm9kZSwgaXQgaXMgcXVpdGUgdW5uZWNlc3Nhcnk6IGZvciBnbG9iYWwgZGVmaW5lZCB0eXBlcwogKiB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBlcXVhbCB0byB0aGUgTkNOYW1lIG9mIHRoZSB0eXBlLAogKiBmb3IgbG9jYWwgZGVmaW5lZCB0eXBlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBvdXRwdXQgdGhlIGludGVybmFsCiAqIGNvbXB1dGVkIG5hbWUgb2YgdGhlIHR5cGUuIFRPRE86IEluc3RlYWQsIG9uZSBzaG91bGQgYXR0YWNoIHRoZSAKICogc3RydWN0IG9mIHRoZSB0eXBlIGludm9sdmVkIHRvIHRoZSBlcnJvciBoYW5kbGVyIC0gdGhpcyBhbGxvd3MKICogdGhlIHJlcG9ydCBvZiBhbnkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBieSB0aGUgdXNlci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlDb21wbGV4VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCQkgICAgICBpbnQgdmFsU2ltcGxlQ29udGVudCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBvbGR0eXBlOyAgICAKICAgIHhtbE5vZGVQdHIgZWxlbSwgY2hpbGQ7CiAgICBpbnQgcmV0ID0gMDsKICAgIGNvbnN0IHhtbENoYXIgKm5zVXJpOyAgICAKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRycyA9IE5VTEwsIGF0dHJUb3AgPSBOVUxMOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkpCglyZXR1cm4gKC0xKTsKCiAgICBvbGR0eXBlID0gY3R4dC0+dHlwZTsKICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgZWxlbSA9IGN0eHQtPm5vZGU7CgogICAgLyoKICAgICogVmVyaWZ5IHRoZSBhdHRyaWJ1dGVzCiAgICAqLwogICAgLyoKICAgICogVE9ETzogVGhpcyAiYXR0clRvcCIgdGhpbmcgaXMgbm90IG5lZWRlZCBhbnkgbW9yZS4KICAgICovICAKICAgIC8qIE5PVEU6IHJlbW92ZWQsIHNpbmNlIGEgY2hlY2sgZm9yIGFic3RyYWN0IGlzCiAgICAqIGRvbmUgaW4gdGhlIGN2Yy10eXBlIGNvbnN0cmFpbnQuCiAgICAqCiAgICAqCiAgICAqIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQUJTVFJBQ1QpIHsKICAgICoJeG1sU2NoZW1hVkNvbXBsZXhUeXBlRXJyKGN0eHQsIAogICAgKgkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8xLAogICAgKgkgICAgZWxlbSwgdHlwZSwgCiAgICAqCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnN0cmFjdCIpOwogICAgKglyZXR1cm4gKFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMSk7CiAgICAqfQogICAgKi8KICAgIAogICAgYXR0cnMgPSBjdHh0LT5hdHRyOyAgICAKICAgIGF0dHJUb3AgPSBjdHh0LT5hdHRyVG9wOyAgIAogICAgLyoKICAgICogU1RSRUFNOiBBdHRyaWJ1dGUgbm9kZXMgYXJlIHByb2Nlc3NlZC4KICAgICovCiAgICB4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoY3R4dCwgZWxlbS0+cHJvcGVydGllcyk7ICAgICAKICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBlbGVtLCB0eXBlKTsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgY3R4dC0+YXR0ciA9IGF0dHJzOyAgICAKICAgIGN0eHQtPmF0dHJUb3AgPSBhdHRyVG9wOyAgICAKCiAgICAvKgogICAgKiBUT0RPOiBUaGlzIG9uZSBjcmVhdGVzIGEgcmVnZXhwIGV2ZW4gaWYgbm8gY29udGVudAogICAgKiBtb2RlbCB3YXMgZGVmaW5lZC4gU29tZWhvdyAtPmNvbnRNb2RlbCBpcyBhbHdheXMgbm90IE5VTEwKICAgICogZm9yIGNvbXBsZXggdHlwZXMsIGV2ZW4gaWYgdGhleSBhcmUgZW1wdHkuCiAgICAqIFRPRE86IENoZWNrIGlmIHRoZSBvYm92ZSBzdGlsbCBvY2N1cnMuCiAgICAqLyAgICAgICAgICAgICAgCiAgICBzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTogewoJICAgIC8qCgkgICAgKiAxIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbXB0eSwgdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiAKCSAgICAqIGl0ZW0gaGFzIG5vIGNoYXJhY3RlciBvciBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSAgICAqLwoJICAgIC8qCgkgICAgKiBUT0RPOiBJcyB0aGUgZW50aXR5IHN0dWZmIGNvcnJlY3Q/CgkgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hSGFzRWxlbU9yQ2hhckNvbnRlbnQoZWxlbSkgPT0gMSkgewkgICAgCSAgICAKCQl4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8xLAoJCSAgICBlbGVtLCB0eXBlLCAKCQkgICAgIkNoYXJhY3RlciBvciBlbGVtZW50IGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkgICAgImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbXB0eSIpOwogICAgICAgICAgICB9CSAKICAgICAgICAgICAgYnJlYWs7Cgl9CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDoKCSAgICBpZiAoKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpICYmIAoJCSh0eXBlLT5iYXNlVHlwZS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZVFlQRSkpIHsKCQkvKgoJCSogVGhlIHR5cGUgaGFzICdhbnlUeXBlJyBhcyBpdHMgYmFzZSBhbmQgbm8gY29udGVudCBtb2RlbAoJCSogaXMgZGVmaW5lZCAtPiB1c2UgJ2FueVR5cGUnIGFzIHRoZSB0eXBlIHRvIHZhbGlkYXRlCgkJKiBhZ2FpbnN0LgoJCSovCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKGN0eHQsIHR5cGUtPmJhc2VUeXBlKTsKCQkvKiBUT0RPOiBIYW5kbGUgLTEuICovCgkJYnJlYWs7CgkgICAgfQoJICAgIC8qIE5vIGJyZWFrIG9uIHB1cnBvc2UuICovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgewoJICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIG9sZHJlZ2V4cCA9IE5VTEw7CgkgICAgeG1sQ2hhciAqdmFsdWVzWzEwXTsKCSAgICBpbnQgdGVybWluYWwsIG5idmFsID0gMTAsIG5ibmVnOwoJICAgIAoJICAgIC8qCgkgICAgKiBDb250ZW50IG1vZGVsIGNoZWNrIGluaXRpYWxpemF0aW9uLgoJICAgICovCgkgICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CQkJCQkKCQlvbGRyZWdleHAgPSBjdHh0LT5yZWdleHA7CgkJY3R4dC0+cmVnZXhwID0geG1sUmVnTmV3RXhlY0N0eHQodHlwZS0+Y29udE1vZGVsLAoJCSAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykKCQkgICAgeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjaywgY3R4dCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiPT09PT4gJXNcbiIsIGVsZW0tPm5hbWUpOwojZW5kaWYKCSAgICB9CgkgICAgLyoKCSAgICAqIFNUUkVBTTogQ2hpbGRyZW4gYXJlIHByb2Nlc3NlZC4KCSAgICAqLwoJICAgIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsJCQoJCWlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkJICAgIGlmIChjaGlsZC0+bnMgIT0gTlVMTCkKCQkJbnNVcmkgPSBjaGlsZC0+bnMtPmhyZWY7CgkJICAgIGVsc2UKCQkJbnNVcmkgPSBOVUxMOwoJCSAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZzIoY3R4dC0+cmVnZXhwLAoJCQljaGlsZC0+bmFtZSwgbnNVcmksIGNoaWxkKTsKCQkgICAgaWYgKGN0eHQtPmVyciA9PSBYTUxfU0NIRU1BVl9JTlRFUk5BTCkKCQkJcmV0dXJuICgtMSk7CgkJICAgIC8qCgkJICAgICogVVJHRU5UIFRPRE86IENvdWxkIHdlIGFuY2hvciBhbiBlcnJvciByZXBvcnQKCQkgICAgKiBoZXJlIHRvIG5vdGlmeSBvZiBpbnZhbGlkIGVsZW1lbnRzPwoJCSAgICAqIFRPRE86IFBlcmhhcHMgaXQgd291bGQgYmUgYmV0dGVyIHRvIHJlcG9ydCAKCQkgICAgKiBvbmx5IHRoZSBmaXJzdCBlcnJvbmVvdXMgZWxlbWVudCBhbmQgdGhlbiBicmVhay4KCQkgICAgKi8KI2lmZGVmIERFQlVHX0FVVE9NQVRBCgkJICAgIGlmIChyZXQgPCAwKQoJCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkJIiAgLS0+ICVzIEVycm9yXG4iLCBjaGlsZC0+bmFtZSk7CgkJICAgIGVsc2UKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlc1xuIiwgY2hpbGQtPm5hbWUpOwojZW5kaWYKCQkgICAgaWYgKHJldCA8IDApIHsKCQkJeG1sUmVnRXhlY0VyckluZm8oY3R4dC0+cmVnZXhwLCBOVUxMLCAmbmJ2YWwsICZuYm5lZywKCQkJICAgICZ2YWx1ZXNbMF0sICZ0ZXJtaW5hbCk7CgkJCXhtbFNjaGVtYVZDb21wbGV4VHlwZUVsZW1FcnIoY3R4dCwgCgkJCSAgICBYTUxfU0NIRU1BVl9FTEVNRU5UX0NPTlRFTlQsCgkJCSAgICBjaGlsZCwgTlVMTC8qIHR5cGUgKi8sIAoJCQkgICAgIlRoaXMgZWxlbWVudCBpcyBub3QgZXhwZWN0ZWQiLAoJCQkgICAgbmJ2YWwsIG5ibmVnLCB2YWx1ZXMpOwoJCQlyZXQgPSAxOwoJCQkvKgoJCQkqIE5vdGUgdGhhdCB0aGlzIHdpbGwgc2tpcCBmdXJ0aGVyIHZhbGlkYXRpb24gb2YgdGhlCgkJCSogY29udGVudC4KCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0KCQl9IGVsc2UgaWYgKCh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFMpICYmIAoJCSAgICAvKiAKCQkgICAgKiBUT0RPOiBBc2sgRGFuaWVsIGlmIHRoaXMgYXJlIGFsbCBjaGFyYWN0ZXIgbm9kZXMuCgkJICAgICovCgkJICAgICgoKGNoaWxkLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICghSVNfQkxBTktfTk9ERShjaGlsZCkpKSB8fAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkgfHwJCSAgICAJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSB8fAkJICAgIAoJCSAgICAgKGNoaWxkLT50eXBlID09IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSkgewkJICAgIAoJCSAgICAvKiAKCQkgICAgKiAyLjMgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVsZW1lbnQtb25seSwgdGhlbiB0aGUgCgkJICAgICogZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBjaGFyYWN0ZXIgaW5mb3JtYXRpb24gCgkJICAgICogaXRlbSBbY2hpbGRyZW5dIG90aGVyIHRoYW4gdGhvc2Ugd2hvc2UgW2NoYXJhY3RlciAKCQkgICAgKiBjb2RlXSBpcyBkZWZpbmVkIGFzIGEgd2hpdGUgc3BhY2UgaW4gW1hNTCAxLjAgKFNlY29uZCAKCQkgICAgKiBFZGl0aW9uKV0uCgkJICAgICovCQkJCgkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzMsCgkJCWVsZW0sIHR5cGUsIAoJCQkiQ2hhcmFjdGVyIGNvbnRlbnQgaXMgbm90IGFsbG93ZWQsICIKCQkJImJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBpcyBlbGVtZW50LW9ubHkiKTsKCQkgICAgcmV0ID0gMTsKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CQkgICAgCgkgICAgfSAgICAKCSAgICAvKgoJICAgICogQ29udGVudCBtb2RlbCBjaGVjayBmaW5hbGl6YXRpb24uCgkgICAgKi8KICAgICAgIAkgICAgaWYgKHR5cGUtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CgkJaWYgKHJldCA9PSAwKSB7CgkJICAgIHhtbFJlZ0V4ZWNOZXh0VmFsdWVzKGN0eHQtPnJlZ2V4cCwgJm5idmFsLCAmbmJuZWcsCgkJCSZ2YWx1ZXNbMF0sICZ0ZXJtaW5hbCk7CgkJICAgIGlmIChuYnZhbCArIG5ibmVnICE9IDApIHsKCQkJLyoKCQkJKiBJZiBhIG5leHQgdmFsdWUgc3RpbGwgZXhpc3RzLCBJIGRvZXMgbm90IGhhdmUgdG8KCQkJKiBtZWFuIHRoYXQgdGhlcmUncyBhbiBlbGVtZW50IG1pc3NpbmcsIHNpbmNlIGl0CgkJCSogbWlnaHQgYmUgYW4gb3B0aW9uYWwgZWxlbWVudC4gU28gZG91YmxlIGNoZWNrIGl0LgoJCQkqLwoJCQlyZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZyhjdHh0LT5yZWdleHAsCgkJCSAgICBOVUxMLCBOVUxMKTsKCQkJaWYgKHJldCA8PSAwKSB7CgkJCSAgICByZXQgPSAxOwogICAgCQkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVsZW1FcnIoY3R4dCwKCQkJCVhNTF9TQ0hFTUFWX0VMRU1FTlRfQ09OVEVOVCwKCQkJCWVsZW0sIHR5cGUsICJNaXNzaW5nIGNoaWxkIGVsZW1lbnQocykiLAoJCQkJbmJ2YWwsIG5ibmVnLCB2YWx1ZXMpOwkJCSAgICAKCQkJfSBlbHNlCgkJCSAgICByZXQgPSAwOwkJCQojaWZkZWYgREVCVUdfQVVUT01BVEEKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSAgICAiPT09PT4gJXMgOiAlZFxuIiwgZWxlbS0+bmFtZSwgcmV0KTsKI2VuZGlmCgkJICAgIH0JCSAgICAKI2lmZGVmIERFQlVHX0NPTlRFTlQKCQkgICAgaWYgKHJldCA9PSAwKQoJCQl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCQkJICAgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgc3VjY2VlZGVkXG4iLAoJCQkgICAgZWxlbS0+bmFtZSk7CiNlbmRpZgoJCX0KCQl4bWxSZWdGcmVlRXhlY0N0eHQoY3R4dC0+cmVnZXhwKTsKCQljdHh0LT5yZWdleHAgPSBvbGRyZWdleHA7CgkgICAgfQoJfQogICAgICAgICAgICBicmVhazsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQzoKCSAgICAvKgoJICAgICogSWYgdGhlIHNpbXBsZSBjb250ZW50IHdhcyBhbHJlYWR5IHZhbGlkYXRlZCAKCSAgICAqIChlLmcuIGEgZGVmYXVsdCB2YWx1ZSksIHRoZSBjb250ZW50IG5lZWQgbm90CgkgICAgKiB0byBiZSB2YWxpZGF0ZWQgYWdhaW4uCgkgICAgKi8KCWlmICh2YWxTaW1wbGVDb250ZW50ID09IDEpIHsKCSAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFdlIGhpdCBhIGNvbXBsZXhUeXBlIHdpdGggYSBzaW1wbGVDb250ZW50IHJlc29sdmluZwoJICAgICogdG8gYSB1c2VyIGRlcml2ZWQgb3IgYnVpbHQtaW4gc2ltcGxlIHR5cGUuCgkgICAgKi8KCSAgICAvKiAKCSAgICAqIDIuMiBJZiB0aGUge2NvbnRlbnQgdHlwZX0gaXMgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCAKCSAgICAqIHRoZW4gdGhlIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gZWxlbWVudCAKCSAgICAqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXSwgYW5kIHRoZSC3bm9ybWFsaXplZCB2YWx1ZbcgCgkgICAgKiBvZiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGlzILd2YWxpZLcgd2l0aCByZXNwZWN0IAoJICAgICogdG8gdGhhdCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGFzIGRlZmluZWQgYnkgU3RyaW5nIAoJICAgICogVmFsaWQgKKczLjE0LjQpLgoJICAgICovCSAgCgkgICAgLyoKCSAgICAqIFNUUkVBTTogQ2hpbGRyZW4gYXJlIHByb2Nlc3NlZC4KCSAgICAqLwoJICAgIGNoaWxkID0gZWxlbS0+Y2hpbGRyZW47CgkgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCQkvKgoJCSogVE9ETzogQ291bGQgdGhlIGVudGl0eSBzdHVmZiBwcm9kdWNlIGVsZW1lbnRzCgkJKiBhcyB3ZWxsPwoJCSovCiAgICAgICAgICAgICAgICBpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCWVsZW0sIHR5cGUsIAoJCQkiRWxlbWVudCBjb250ZW50IGlzIG5vdCBhbGxvd2VkLCBiZWNhdXNlICIKCQkJInRoZSBjb250ZW50IHR5cGUgaXMgYSBzaW1wbGUgdHlwZSIpOwoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMjsKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CQkgICAgCgkgICAgfQkKCSAgICBjdHh0LT5ub2RlID0gZWxlbTsKCSAgICBjdHh0LT5jdXIgPSBlbGVtLT5jaGlsZHJlbjsKCSAgICBpZiAocmV0ID09IDApIHsKCQkvKgoJCSogVmFsaWRhdGUgdGhlIGNoYXJhY3RlciBjb250ZW50IGFnYWluc3QgYSBzaW1wbGUgdHlwZS4KCQkqLwoJCS8qCgkJKiBTVFJFQU06IENoaWxkcmVuIGFyZSBwcm9jZXNzZWQuCgkJKi8KCQlpZiAoZWxlbS0+Y2hpbGRyZW4gPT0gTlVMTCkKCQkgICAgdmFsdWUgPSBOVUxMOwoJCWVsc2UKCQkgICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChlbGVtKTsgCgkJLyoKCQkqIFVSR0VOVCBUT0RPOiBTaG91bGQgZmFjZXRzIGZvciB0aGUgc2ltcGxlIHR5cGUgdmFsaWRhdGlvbiBiZSAKCQkqIGRpc2FibGVkLCBpZiB0aGUgZGVyaXZhdGlvbiBvZiBmYWNldHMgZm9yIGNvbXBsZXggdHlwZXMgCgkJKiBpcyBpbXBsZW1lbnRlZD8KCQkqLwoJCS8qCgkJKiBOT1RFOiBUaGlzIGNhbGwgd29uJ3QgY2hlY2sgdGhlIGNvcnJlY3QgdHlwZXMgb2YgdGhlCgkJKiBjb250ZW50IG5vZGVzLCBzaW5jZSB0aGlzIHNob3VsZCBiZSBkb25lIGhlcmUuCgkJKi8KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0eXBlLCB2YWx1ZSwgMSwgMSwgMSwgMCk7CgkJaWYgKHJldCA+IDApIHsJCgkJICAgIC8qCgkJICAgICogTk9URTogQWx0aG91Z2ggYW4gZXJyb3Igd2lsbCBiZSByZXBvcnRlZCBieSAKCQkgICAgKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgdGhlIHNwZWMgd2FudHMKCQkgICAgKiBhIHNwZWNpZmljIGNvbXBsZXggdHlwZSBlcnJvciB0byBiZSByZXBvcnRlZCAKCQkgICAgKiBhZGRpdGlvbmFsbHkuCgkJICAgICovCgkJICAgIHhtbFNjaGVtYVZDb21wbGV4VHlwZUVycihjdHh0LCAKCQkJWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCWVsZW0sIHR5cGUsICAKCQkJIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSwgIgoJCQkiRWxlbWVudCAnJXMnOiBFcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlICclcycuXG4iLAoJCQllbGVtLT5uYW1lLCB0eXBlLT5uYW1lKTsKCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOyAKCQkgICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CSAgICAKCSAgICBpZiAocmV0ID09IDApIHsKCQkvKiAKCQkqIEFwcGx5IGZhY2V0cyBvZiB0aGUgY29tcGxleFR5cGUuIEJlIHN1cmUgdG8gcGFzcyB0aGUgCgkJKiBidWlsdC1pbiB0eXBlIHRvIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwuCgkJKi8JICAgIAoJCS8qIFVSR0VOVCBUT0RPOiBJIGRvbid0IGtub3cgeWV0IGlmIHRoZSBmYWNldHMgb2YgdGhlIHNpbXBsZSB0eXBlCgkJKiBhcmUgdXNlZCwgb3IgaWYgdGhlIGZhY2V0cywgZGVmaW5lZCBieSB0aGlzIGNvbXBsZXggdHlwZSwKCQkqIGFyZSB0byBiZSB1c2VkIG9ubHkuIFRoaXMgaGVyZSBhcHBsaWVzIGJvdGggZmFjZXQgc2V0cy4KCQkqLwkgICAgCgoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgCgkJICAgIHR5cGUsIHZhbHVlLCAwLCAxKTsKCQlpZiAocmV0ID4gMCkgewoJCSAgICB4bWxTY2hlbWFWQ29tcGxleFR5cGVFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yLAoJCQllbGVtLCB0eXBlLCAKCQkJIlRoZSBjaGFyYWN0ZXIgY29udGVudCBpcyBub3QgdmFsaWQiKTsKCQkgICAgcmV0ID0gWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzI7CgkJfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSwgIgoJCQkiRWxlbWVudCAnJXMnOiBFcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlICclcyc7IGZhaWxlZCB0byAiCgkJCSJhcHBseSBmYWNldHMuXG4iLAoJCQl0eXBlLT5uYW1lLCBOVUxMKTsKCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJCXhtbEZyZWUodmFsdWUpOyAKCQkgICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCSAgICB9CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSh2YWx1ZSk7CgoJfQoJICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRPRE8geG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmltcGxlbWVudGVkIGNvbnRlbnQgdHlwZSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+Y29udGVudFR5cGUpOwogICAgfQogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBsaXN0IG9mIHR5cGUgZGVjbGFyYXRpb25zCiAqCiAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICAgIGludCBpc05pbCwKCQkJICAgICAgIGludCB2YWxTaW1wbGVDb250ZW50KQp7CiAgICBpbnQgcmV0OwoKICAgCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIFhNTF9TQ0hFTUFWX0lOVEVSTkFMLCBOVUxMLCBOVUxMLAoJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlUeXBlLCAiCgkgICAgImJhZCBhcmd1bWVudHMiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsgICAgCiAgICB9ICAgIAkKICAgIC8qIAogICAgKiBUaGlzIG9uZSBpcyBjYWxsZWQgYnkgInhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudEJ5RGVjbGFyYXRpb24iLgogICAgKiBJdCB3aWxsIGZvcndhcmQgdG8gdGhlIHByb3BlciB2YWxpZGF0aW9uIAogICAgKiBwcm9jZWR1cmVzIGZvciB0aGUgZ2l2ZW4gdHlwZS4KICAgICovICAgICAgICAKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgIAl4bWxTY2hlbWFWQ3VzdG9tRXJyKGN0eHQsIAogICAgCSAgICBYTUxfU0NIRU1BVl9DVkNfVFlQRV8xLAogICAgCSAgICBjdHh0LT5ub2RlLCBOVUxMLCAKICAgIAkgICAgIlRoZSB0eXBlIGRlZmluaXRpb24gaXMgYWJzZW50IiwgTlVMTCk7CiAgICAJcmV0dXJuIChYTUxfU0NIRU1BVl9DVkNfVFlQRV8xKTsKICAgIH0KICAgIAogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9BQlNUUkFDVCkgewogICAgCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwgCiAgICAJICAgIFhNTF9TQ0hFTUFWX0NWQ19UWVBFXzIsCiAgICAJICAgIGN0eHQtPm5vZGUsIHR5cGUsIAogICAgCSAgICAiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnN0cmFjdCIsIE5VTEwpOwogICAgCXJldHVybiAoWE1MX1NDSEVNQVZfQ1ZDX1RZUEVfMik7CiAgICB9CgogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CgljYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOgogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeUNvbXBsZXhUeXBlKGN0eHQsIHR5cGUsCgkJdmFsU2ltcGxlQ29udGVudCk7CiAgICAgICAgICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgogICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoY3R4dCwgdHlwZSwKCQlpc05pbCwgdmFsU2ltcGxlQ29udGVudCk7CiAgICAgICAgICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfQkFTSUM6CgkgICAgaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX0FOWVRZUEUpCgkJcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50QnlBbnlUeXBlKGN0eHQsIHR5cGUpOwoJICAgIGVsc2UKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnRCeVNpbXBsZVR5cGUoY3R4dCwgdHlwZSwKCQkgICAgaXNOaWwsIHZhbFNpbXBsZUNvbnRlbnQpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXQgPSAtMTsKCSAgICBicmVhazsKICAgIH0JCiAgICBpZiAocmV0ID09IC0xKQoJcmV0dXJuICgtMSk7CiAgICBlbHNlCglyZXR1cm4gKHJldCk7Cn0KCnN0YXRpYyBpbnQKeG1sU2NoZW1hUG9zdENyZWF0ZVZhbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgdmN0eHQsCgkJICAgICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlLAoJCSAgICAgICB4bWxTY2hlbWFWYWxQdHIgKnZhbCkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBwcmltOwoKICAgIGlmICh2YWwgPT0gTlVMTCkgewoJeG1sU2NoZW1hVkVycih2Y3R4dCwgdmN0eHQtPm5vZGVJbmZvLT5ub2RlLCAKCSAgICBYTUxfU0NIRU1BVl9JTlRFUk5BTCwKCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBvc3RDcmVhdGVWYWwsICIKCSAgICAiYmFkIGFyZ3VtZW50cyIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAvKgogICAgKiBPbmx5IHN0cmluZyBvciBhbnlTaW1wbGVUeXBlIHZhbHVlcyBhcmUgZXhwZWN0ZWQgdG8gYmUgcG9zdC1jcmVhdGVkLgogICAgKi8KICAgIHByaW0gPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHZjdHh0LT5ub2RlSW5mby0+dHlwZURlZik7CiAgICBpZiAoKHByaW0tPmJ1aWx0SW5UeXBlID09IFhNTF9TQ0hFTUFTX1NUUklORykgfHwgCgkocHJpbS0+YnVpbHRJblR5cGUgPT0gWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpCiAgICB7CiNpZiAwCglidWlsdEluID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGVBbmNlc3Rvcih2Y3R4dC0+bm9kZUluZm8tPnR5cGVEZWYpOwojZW5kaWYKCWlmICh2YWx1ZSA9PSBOVUxMKQoJICAgIC8qIFRPRE86IENhbiB0aGlzIGhhcHBlbiBhdCBhbGw/ICovCgkgICAgKnZhbCA9IHhtbFNjaGVtYU5ld1N0cmluZ1ZhbHVlKFhNTF9TQ0hFTUFTX1NUUklORywKCQl4bWxTdHJkdXAoQkFEX0NBU1QgIiIpKTsKCWVsc2UKCSAgICAqdmFsID0geG1sU2NoZW1hTmV3U3RyaW5nVmFsdWUoWE1MX1NDSEVNQVNfU1RSSU5HLCB2YWx1ZSk7CglpZiAoKCp2YWwpID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZUluZm8tPm5vZGUsIAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hUG9zdENyZWF0ZVZhbCwgIgoJCSJmYWlsZWQgdG8gY3JlYXRlIHRoZSB2YWx1ZSIsIE5VTEwsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOyAKCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICB4bWxTY2hlbWFWRXJyKHZjdHh0LCB2Y3R4dC0+bm9kZUluZm8tPm5vZGUsIAoJWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBvc3RDcmVhdGVWYWwsICIKCSJ0aGUgZ2l2ZW4gdHlwZSBpcyBub3Qgc3VwcG9ydGVkIiwgTlVMTCwgTlVMTCk7CiAgICByZXR1cm4gKC0xKTsKfSAgICAKCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dCwKCQkJICAgICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBzdGF0ZSkKewogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpkZWZWYWx1ZTsKICAgIHhtbFNjaGVtYVZhbFB0ciBkZWZWYWw7CiAgICBpbnQgZml4ZWQ7CiAgICBpbnQgcmV0OwoKICAgIGlmICh2Y3R4dC0+YXR0ckluZm8tPnR5cGVEZWYgPT0gTlVMTCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9UWVBFX05PVF9SRVNPTFZFRDsKCXJldHVybiAoWE1MX1NDSEVNQVNfQVRUUl9UWVBFX05PVF9SRVNPTFZFRCk7CiAgICB9CiAgICB2Y3R4dC0+bm9kZSA9IHZjdHh0LT5hdHRySW5mby0+bm9kZTsKICAgIHZjdHh0LT5jdXIgPSB2Y3R4dC0+bm9kZS0+Y2hpbGRyZW47CiAgICAvKiBTVFJFQU0gKi8KICAgIHZhbHVlID0geG1sTm9kZUxpc3RHZXRTdHJpbmcodmN0eHQtPm5vZGUtPmRvYywgdmN0eHQtPmN1ciwgMSk7CiAgICAKICAgIC8qCiAgICAqIE5PVEU6IFRoaXMgY2FsbCBhbHNvIGNoZWNrcyB0aGUgY29udGVudCBub2RlcyBmb3IgY29ycmVjdCB0eXBlLgogICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCB2Y3R4dC0+YXR0ckluZm8tPnR5cGVEZWYsCgl2YWx1ZSwgMSwgMSwgMSwgMSk7CiAgICAJICAgIAogICAgLyoKICAgICogSGFuZGxlICdmaXhlZCcgYXR0cmlidXRlcy4KICAgICovCiAgICBpZiAocmV0ID4gMCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFOwoJLyoKCSogTk9URTogRml4ZWQgdmFsdWUgY29uc3RyYWludHMgd2lsbCBiZSBub3QKCSogYXBwbGllZCBpZiB0aGUgdmFsdWUgd2FzIGludmFsaWQsIGJlY2F1c2U6IAoJKiAxLiBUaGUgdmFsaWRhdGlvbiBwcm9jZXNzIGRvZXMgbm90IHJldHVybiBhIHByZWNvbXB1dGVkIAoJKiAgICB2YWx1ZS4KCSogMi4gQW4gaW52YWxpZCB2YWx1ZSBpbXBsaWVzIGEgdmlvbGF0aW9uIG9mIGEgZml4ZWQgCgkqICAgIHZhbHVlIGNvbnN0cmFpbnQuCgkqLwogICAgfSBlbHNlIGlmIChyZXQgPT0gMCkgewoJc3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJaWYgKHhtbFNjaGVtYUdldEVmZmVjdGl2ZVZhbHVlQ29uc3RyYWludCgKCSAgICAoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB2Y3R4dC0+YXR0ckluZm8tPmRlY2wsIAoJICAgICZmaXhlZCwgJmRlZlZhbHVlLCAmZGVmVmFsKSAmJiAoZml4ZWQgPT0gMSkpIHsKCgkgICAgaW50IHdzID0geG1sU2NoZW1hR2V0V2hpdGVTcGFjZUZhY2V0VmFsdWUoCgkJdmN0eHQtPm5vZGVJbmZvLT50eXBlRGVmKTsJICAgIAoJICAgIC8qCgkgICAgKiBjdmMtYXUgOiBBdHRyaWJ1dGUgTG9jYWxseSBWYWxpZCAoVXNlKQoJICAgICogRm9yIGFuIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpdGVtIHRvIGJlt3ZhbGlktyAKCSAgICAqIHdpdGggcmVzcGVjdCB0byBhbiBhdHRyaWJ1dGUgdXNlIGl0cyC3bm9ybWFsaXplZCAKCSAgICAqIHZhbHVltyBtdXN0IG1hdGNoIHRoZSBjYW5vbmljYWwgbGV4aWNhbCByZXByZXNlbnRhdGlvbgoJICAgICogb2YgdGhlIGF0dHJpYnV0ZSB1c2UncyB7dmFsdWUgY29uc3RyYWludH0gdmFsdWUsIGlmIGl0CgkgICAgKiBpcyBwcmVzZW50IGFuZCBmaXhlZC4KCSAgICAqCgkgICAgKiBUT0RPOiBVc2Ugc29tZWhvdyB0aGUgKm5vcm1hbGl6ZWQqIHZhbHVlIGFuZCB0aGUgKmNhbm9uaWNhbCoKCSAgICAqIGZpeGVkIHZhbHVlLiBUaGlzIGhlcmUgY29tcGFyZXMgdGhlIGNhbm9uaWNhbCB2YWx1ZXMgb2YgYm90aC4KCSAgICAqIFRoZSBub3JtYWxpemVkIHZhbHVlIG9mLCBmb3IgZXhhbXBsZSwgYSBmbG9hdCB0eXBlIGNhbiBkaWZmZXIKCSAgICAqIGZyb20gaXRzIGNhbm9uaWNhbCByZXByZXNlbnRhdGlvbi4gVGhpcyBhbGwgbWVhbnMgdGhhdCBhIGZpeGVkCgkgICAgKiB2YWx1ZSBjYW4gb25seSBiZSBPSywgaWYgaXQncyBwcmVzZW50IGluIHRoZSBjYW5vbmljYWwgZm9ybSBpbgoJICAgICogdGhlIGluc3RhbmNlLgoJICAgICogTk9URTogU2luY2UgdGhlIHZhbHVlIGZvciBzdHJpbmcgYW5kIGFueVNpbXBsZVR5cGUgaXMgbm90IGFsd2F5cwoJICAgICogcHJlY29tcHV0ZWQgZHVyaW5nIHZhbGlkYXRpb24sIHdlIG5lZWQgdG8gZG8gaXQgbm93LgoJICAgICovCgkgICAgaWYgKHZjdHh0LT52YWx1ZSA9PSBOVUxMKSB7CgkJLyoKCQkqIFBvc3QtY3JlYXRlIHRoZSB2YWx1ZS4KCQkqLwoJCWlmICh4bWxTY2hlbWFQb3N0Q3JlYXRlVmFsKHZjdHh0LCB2YWx1ZSwgJih2Y3R4dC0+dmFsdWUpKSA9PSAtMSkgewoJCSAgICByZXQgPSAtMTsKCQkgICAgZ290byBleGl0OwoJCX0KCQl2YWx1ZSA9IE5VTEw7CgkgICAgfQoJICAgIGlmIChkZWZWYWwgPT0gTlVMTCkgewoJCXhtbENoYXIgKnN0cjsKCQkJCQoJCS8qCgkJKiBQb3N0LWNyZWF0ZSB0aGUgZGVmYXVsdC9maXhlZCB2YWx1ZS4KCQkqLwoJCWlmIChkZWZWYWx1ZSA9PSBOVUxMKQoJCSAgICBzdHIgPSB4bWxTdHJkdXAoQkFEX0NBU1QgIiIpOwoJCWVsc2UKCQkgICAgc3RyID0geG1sU3RyZHVwKGRlZlZhbHVlKTsKCQlpZiAoeG1sU2NoZW1hUG9zdENyZWF0ZVZhbCh2Y3R4dCwgc3RyLCAmZGVmVmFsKSA9PSAtMSkgewoJCSAgICByZXQgPSAtMTsKCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJICAgIGdvdG8gZXhpdDsKCQl9CgkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHZjdHh0LT5hdHRySW5mby0+ZGVjbCktPmRlZlZhbCA9IGRlZlZhbDsKCSAgICB9CSAgICAKCSAgICBpZiAoeG1sU2NoZW1hQ29tcGFyZVZhbHVlc1dodHNwKHZjdHh0LT52YWx1ZSwKCQkoeG1sU2NoZW1hV2hpdGVzcGFjZVZhbHVlVHlwZSkgd3MsCgkJZGVmVmFsLAoJCSh4bWxTY2hlbWFXaGl0ZXNwYWNlVmFsdWVUeXBlKSB3cykgIT0gMCkKCSAgICB7CgkJc3RhdGUtPnN0YXRlID0gCVhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9GSVhFRF9WQUxVRTsKCSAgICB9Cgl9CiAgICB9CmV4aXQ6ICAKICAgIGlmICh2YWx1ZSAhPSBOVUxMKSB7Cgl4bWxGcmVlKHZhbHVlKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXhUeXBlIGhvbGRpbmcgdGhlIGF0dHJpYnV0ZSB1c2VzCiAqCiAqIFZhbGlkYXRlIHRoZSBhdHRyaWJ1dGVzIG9mIGFuIGVsZW1lbnQuCiAqCiAqIDEuIEV4aXN0ZW50LCBpbnZhbGlkIGF0dHJpYnV0ZXMgYXJlIHJlcG9ydGVkIGluIHRoZSBmb3JtIAogKiAgICAicHJlZml4OmxvY2FsTmFtZSIuIAogKiAgICBSZWFzb246IHJlYWRhYmlsaXR5IC0gaXQgaXMgZWFzaWVyIHRvIGZpbmQgdGhlIGFjdHVhbCBYTUwgCiAqICAgIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhdHRyaWJ1dGVzIFFOYW1lLgogKiAyLiBNaXNzaW5nIGF0dHJpYnV0ZXMgYXJlIHJlcG9ydGVkIGluIHRoZSBmb3JtIAogKiAgICB7IlVSSSIsICJsb2NhbE5hbWUifS4KICogICAgVGhpcyBpcyBuZWNlc3NhcnksIHNpbmNlIHRoZSB0aGUgcHJlZml4IG5lZWQgbm90IHRvIGJlIGRlY2xhcmVkCiAqICAgIGF0IGFsbCwgYW5kIHRodXMgaXMgbm90IGNvbXB1dGFibGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgZWxlbSwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBjb25zdCB4bWxDaGFyICpuc1VSSTsKICAgIGludCByZXQ7CiAgICB4bWxBdHRyUHRyIGF0dHI7IC8qIEFuIGF0dHJpYnV0ZSBvbiB0aGUgZWxlbWVudC4gKi8KICAgIGNvbnN0IHhtbENoYXIgKmRlZlZhbHVlOwogICAgeG1sU2NoZW1hVmFsUHRyIGRlZlZhbDsKICAgIGludCBmaXhlZDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSA9IE5VTEw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgYXR0ckRlY2w7CiAgICBpbnQgZm91bmQ7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgY3VyU3RhdGUsIHJlcUF0dHJTdGF0ZXMgPSBOVUxMLCByZXFBdHRyU3RhdGVzVG9wID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBkZWZBdHRyU3RhdGVzID0gTlVMTCwgZGVmQXR0clN0YXRlc1RvcCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIG9sZG5vZGU7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KICAgIGludCByZWR1bmRhbnQgPSAwOwojZW5kaWYKCiAgICAgIAogICAgLyoKICAgICogQWxsb3cgYWxsIGF0dHJpYnV0ZXMgaWYgdGhlIHR5cGUgaXMgYW55VHlwZS4KICAgICovCiAgICBpZiAodHlwZSA9PSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKSkKCXJldHVybiAoMCk7CgogICAgb2xkbm9kZSA9IGN0eHQtPm5vZGU7CiAgICBpZiAodHlwZSAhPSBOVUxMKQoJYXR0clVzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CiAgICB3aGlsZSAoYXR0clVzZSAhPSBOVUxMKSB7CiAgICAgICAgZm91bmQgPSAwOyAgICAKCWF0dHJEZWNsID0gYXR0clVzZS0+YXR0cjsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJcHJpbnRmKCJhdHRyIHVzZSAtIG5hbWU6ICVzXG4iLCB4bWxTY2hlbWFHZXRBdHRyTmFtZShhdHRyRGVjbCkpOwoJcHJpbnRmKCJhdHRyIHVzZSAtIHVzZTogJWRcbiIsIGF0dHJEZWNsLT5vY2N1cnMpOwojZW5kaWYKICAgICAgICBmb3IgKGN1clN0YXRlID0gY3R4dC0+YXR0cjsgY3VyU3RhdGUgIT0gTlVMTDsgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dCkgewoKCSAgICBpZiAoY3VyU3RhdGUtPmRlY2wgPT0gYXR0clVzZS0+YXR0cikgewojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkJcmVkdW5kYW50ID0gMTsKI2VuZGlmCgkgICAgfQoJICAgIGF0dHIgPSBjdXJTdGF0ZS0+YXR0cjsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigiYXR0ciAtIG5hbWU6ICVzXG4iLCBhdHRyLT5uYW1lKTsKCSAgICBpZiAoYXR0ci0+bnMgIT0gTlVMTCkKCQlwcmludGYoImF0dHIgLSBuczogJXNcbiIsIGF0dHItPm5zLT5ocmVmKTsKCSAgICBlbHNlCgkJcHJpbnRmKCJhdHRyIC0gbnM6IG5vbmVcbiIpOwojZW5kaWYKCSAgICAvKiBUT0RPOiBDYW4gdGhpcyBldmVyIGhhcHBlbj8gKi8KICAgICAgICAgICAgaWYgKGF0dHIgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAoYXR0ckRlY2wtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIGF0dHJEZWNsLT5yZWYpKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGF0dHJEZWNsLT5yZWZOcyA9PSBOVUxMKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCBhdHRyRGVjbC0+cmVmTnMpKSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJEZWNsLT5yZWZOcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIGF0dHJEZWNsLT5uYW1lKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBoYW5kbGUgdGhlIG5hbWVzcGFjZXMgY2hlY2tzIGhlcmUKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGF0dHItPm5zID09IE5VTEwpIHsKCQkgICAgLyoKCQkgICAgICogYWNjZXB0IGFuIHVucXVhbGlmaWVkIGF0dHJpYnV0ZSBvbmx5IGlmIHRoZSB0YXJnZXQKCQkgICAgICogbmFtZXNwYWNlIG9mIHRoZSBkZWNsYXJhdGlvbiBpcyBhYnNlbnQuCgkJICAgICAqLwoJCSAgICBpZiAoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQoJCQkvKiAKCQkJICogVGhpcyBjaGVjayB3YXMgcmVtb3ZlZCwgc2luY2UgdGhlIHRhcmdldCBuYW1lc3BhY2UKCQkJICogd2FzIGV2YWx1YXRlZCBkdXJpbmcgcGFyc2luZyBhbmQgYWxyZWFkeSB0b29rCgkJCSAqICJhdHRyaWJ1dGVGb3JtRGVmYXVsdCIgaW50byBhY2NvdW50LgoJCQkgKi8KCQkgICAgICAgIC8qICgoYXR0cmlidXRlcy0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX05TREVGQVVMVCkgPT0gMCkpICovCgkJICAgICAgICBjb250aW51ZTsKCQl9IGVsc2UgewoJCSAgICBpZiAoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSA9PSBOVUxMKQoJCSAgICAgICAgY29udGludWU7CgkJICAgIGlmICgheG1sU3RyRXF1YWwoYXR0ckRlY2wtPnRhcmdldE5hbWVzcGFjZSwKCQkgICAgICAgICAgICAgICAgICAgICBhdHRyLT5ucy0+aHJlZikpCgkJCWNvbnRpbnVlOwoJCX0KICAgICAgICAgICAgfQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJmb3VuZFxuIik7CiNlbmRpZgogICAgICAgICAgICBmb3VuZCA9IDE7CSAgICAKCSAgICBjdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwoJICAgIGN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfVkFMSURBVEVfVkFMVUU7CgkgICAgLyoKCSAgICByZXQgPSB4bWxTY2hlbWFDaGVja0F0dHJMb2NhbGx5VmFsaWQoY3R4dCwgYXR0ckRlY2wsIGN1clN0YXRlLCBhdHRyKTsKCSAgICAqLwogICAgICAgIH0KICAgICAgICBpZiAoIWZvdW5kKSB7CgkgICAgaWYgKGF0dHJEZWNsLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpIHsKCQl4bWxTY2hlbWFBdHRyU3RhdGVQdHIgdG1wOwoJCQojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkJcHJpbnRmKCJyZXF1aXJlZCBhdHRyIG5vdCBmb3VuZFxuIik7CiNlbmRpZgoJCS8qCgkJKiBBZGQgYSBuZXcgZHVtbXkgYXR0cmlidXRlIHN0YXRlLgoJCSovCQoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyU3RhdGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIHJlcXVpcmVkIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCQkgICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7CgkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCQl9ICAgICAgICAgICAgCgkJdG1wLT5hdHRyID0gTlVMTDsKCQl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9NSVNTSU5HOwoJCXRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJCgkJaWYgKHJlcUF0dHJTdGF0ZXMgPT0gTlVMTCkgewoJCSAgICByZXFBdHRyU3RhdGVzID0gdG1wOwoJCSAgICByZXFBdHRyU3RhdGVzVG9wID0gdG1wOwoJCX0gZWxzZSB7CgkJICAgIHJlcUF0dHJTdGF0ZXNUb3AtPm5leHQgPSB0bXA7CgkJICAgIHJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CgkJfQoJICAgIH0gZWxzZSBpZiAoKGF0dHJEZWNsLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJICAgICh4bWxTY2hlbWFHZXRFZmZlY3RpdmVWYWx1ZUNvbnN0cmFpbnQoYXR0ckRlY2wsIAoJCQkmZml4ZWQsICZkZWZWYWx1ZSwgJmRlZlZhbCkpKSB7CgkJeG1sU2NoZW1hQXR0clN0YXRlUHRyIHRtcDsKCQkvKgoJCSogSGFuZGxlIG5vbiBleGlzdGVudCBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMuCgkJKi8JCgkJdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgCgkJICAgIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0clN0YXRlKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgCgkJCSJyZWdpc3RlcmluZyBzY2hlbWEgc3BlY2lmaWVkIGF0dHJpYnV0ZXMiLCBOVUxMKTsKCQkgICAgY3R4dC0+bm9kZSA9IG9sZG5vZGU7CgkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCQl9ICAgICAgICAgICAgCgkJdG1wLT5hdHRyID0gTlVMTDsKCQl0bXAtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9ERUZBVUxUOwoJCXRtcC0+ZGVjbCA9IGF0dHJEZWNsOwoJCXRtcC0+dmFsdWUgPSBkZWZWYWx1ZTsKCQl0bXAtPm5leHQgPSBOVUxMOwoJCQoJCWlmIChkZWZBdHRyU3RhdGVzID09IE5VTEwpIHsKCQkgICAgZGVmQXR0clN0YXRlcyA9IHRtcDsKCQkgICAgZGVmQXR0clN0YXRlcyA9IHRtcDsKCQl9IGVsc2UgewoJCSAgICBkZWZBdHRyU3RhdGVzLT5uZXh0ID0gdG1wOwoJCSAgICBkZWZBdHRyU3RhdGVzVG9wID0gdG1wOwoJCX0JCQkJCgkgICAgfQkJCQoJfQogICAgICAgIGF0dHJVc2UgPSBhdHRyVXNlLT5uZXh0OwogICAgfQogICAgLyoKICAgICAqIEFkZCByZXF1aXJlZCBhdHRyaWJ1dGVzIHRvIHRoZSBhdHRyaWJ1dGUgc3RhdGVzIG9mIHRoZSBjb250ZXh0LgogICAgICovCiAgICBpZiAocmVxQXR0clN0YXRlcyAhPSBOVUxMKSB7CglpZiAoY3R4dC0+YXR0ciA9PSBOVUxMKSB7CgkgICAgY3R4dC0+YXR0ciA9IHJlcUF0dHJTdGF0ZXM7Cgl9IGVsc2UgewkJCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHJlcUF0dHJTdGF0ZXM7Cgl9CgljdHh0LT5hdHRyVG9wID0gcmVxQXR0clN0YXRlc1RvcDsKICAgIH0KICAgIC8qCiAgICAqIFByb2Nlc3Mgd2lsZGNhcmRzLgogICAgKi8KICAgIAogICAgaWYgKCh0eXBlICE9IE5VTEwpICYmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkgewkKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBuczsJCglwcmludGYoIm1hdGNoaW5nIHdpbGRjYXJkOiBbJWRdIG9mIGNvbXBsZXhUeXBlOiAlc1xuIiwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIHR5cGUtPm5hbWUpOwoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogbGF4XG4iKTsKCWVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkgICAgWE1MX1NDSEVNQVNfQU5ZX1NUUklDVCkKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc3RyaWN0XG4iKTsKCWVsc2UKCSAgICBwcmludGYoInByb2Nlc3NDb250ZW50czogc2tpcFxuIik7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPmFueSkKCSAgICBwcmludGYoInR5cGU6IGFueVxuIik7CgllbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQgIT0gTlVMTCkgewoJICAgIHByaW50ZigidHlwZTogbmVnYXRlZFxuIik7CgkgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkKCQlwcmludGYoIm5zOiAoYWJzZW50KVxuIik7CgkgICAgZWxzZQoJCXByaW50ZigibnM6ICVzXG4iLCB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQtPnZhbHVlKTsKCX0gZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5zU2V0ICE9IE5VTEwpIHsKCSAgICBwcmludGYoInR5cGU6IHNldFxuIik7CgkgICAgbnMgPSB0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bnNTZXQ7CgkgICAgd2hpbGUgKG5zICE9IE5VTEwpIHsKCQlpZiAobnMtPnZhbHVlID09IE5VTEwpCgkJICAgIHByaW50ZigibnM6IChhYnNlbnQpXG4iKTsKCQllbHNlCgkJICAgIHByaW50ZigibnM6ICVzXG4iLCBucy0+dmFsdWUpOwoJCW5zID0gbnMtPm5leHQ7CgkgICAgfQkgICAgCgl9IGVsc2UKCSAgICBwcmludGYoImVtcHR5XG4iKTsKCgojZW5kaWYJCgljdXJTdGF0ZSA9IGN0eHQtPmF0dHI7Cgl3aGlsZSAoY3VyU3RhdGUgIT0gTlVMTCkgewoJICAgIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKSB7CQkKCQlpZiAoY3VyU3RhdGUtPmF0dHItPm5zICE9IE5VTEwpIAoJCSAgICBuc1VSSSA9IGN1clN0YXRlLT5hdHRyLT5ucy0+aHJlZjsKCQllbHNlCgkJICAgIG5zVVJJID0gTlVMTDsJCQoJCWlmICh4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgCgkJICAgIG5zVVJJKSkgewoJCSAgICAvKgoJCSAgICAqIEhhbmRsZSBwcm9jZXNzQ29udGVudHMuCgkJICAgICovCgkJICAgIGlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cyA9PSAKCQkJWE1MX1NDSEVNQVNfQU5ZX0xBWCkgfHwKCQkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCVhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpKSB7CgkJCQoJCQlhdHRyID0gY3VyU3RhdGUtPmF0dHI7CQkJCQkJCgkJCWF0dHJEZWNsID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgCgkJCSAgICBhdHRyLT5uYW1lLCBuc1VSSSk7CgkJCWN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJCWlmIChhdHRyRGVjbCAhPSBOVUxMKSB7CgkJCSAgICBjdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwoJCQkgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9WQUxJREFURV9WQUxVRTsKCQkJICAgIC8qIFRPRE8KCQkJICAgIHJldCA9IHhtbFNjaGVtYUNoZWNrQXR0ckxvY2FsbHlWYWxpZChjdHh0LCBhdHRyRGVjbCwgY3VyU3RhdGUsIGF0dHIpOwoJCQkgICAgKi8KCQkJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkgewoJCQkgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCQl9IGVsc2UKCQkJICAgIGN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfV0lMRF9OT19ERUNMOwoJCSAgICB9IGVsc2UKCQkJY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCX0KCSAgICB9CgkgICAgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dDsKICAgICAgICB9CiAgICB9ICAgIAogICAgCiAgICBpZiAoY3R4dC0+YXR0ciAhPSBOVUxMKSB7CglpbnQgdmFsdWVOZWVkZWQ7CgoJLyoKCSogVmFsaWRhdGUgdGhlIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUuCgkqLwoJaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwoJICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKCX0KCWN1clN0YXRlID0gY3R4dC0+YXR0cjsKCXdoaWxlICgoY3VyU3RhdGUgIT0gTlVMTCkgJiYgKGN1clN0YXRlICE9IGN0eHQtPmF0dHJUb3AtPm5leHQpKSB7CgkgICAgdmFsdWVOZWVkZWQgPSAwOwoJICAgIHN3aXRjaCAoY3VyU3RhdGUtPnN0YXRlKSB7CgkJY2FzZSBYTUxfU0NIRU1BU19BVFRSX1ZBTElEQVRFX1ZBTFVFOgoKCQkgICAgLyoKCQkgICAgKiBDcmVhdGUgYW4gYXR0cmlidXRlIGluZm8gaWYgbmVlZGVkLgoJCSAgICAqLwoJCSAgICBpZiAoY3R4dC0+YXR0ckluZm8gPT0gTlVMTCkgewoJCQljdHh0LT5hdHRySW5mbyA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgCgkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vZGVJbmZvKSk7CgkJCWlmIChjdHh0LT5hdHRySW5mbyA9PSBOVUxMKSB7CgkJCSAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsIAoJCQkJImFsbG9jYXRpbmcgYW4gYXR0cmlidXRlIGluZm8iLCBOVUxMKTsKCQkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCQkJfQoJCSAgICB9CgkJICAgIC8qCgkJICAgICogSW5pdCB0aGUgYXR0cmlidXRlIGluZm8uCgkJICAgICovCgkJICAgIGN0eHQtPmF0dHJJbmZvLT5mbGFncyA9IDA7CgkJICAgIGN0eHQtPmF0dHJJbmZvLT5ub2RlID0gKHhtbE5vZGVQdHIpIGN1clN0YXRlLT5hdHRyOwoJCSAgICBjdHh0LT5hdHRySW5mby0+ZGVjbCA9ICh4bWxTY2hlbWFUeXBlUHRyKSBjdXJTdGF0ZS0+ZGVjbDsKCQkgICAgY3R4dC0+YXR0ckluZm8tPnZhbHVlID0gTlVMTDsKCQkgICAgaWYgKGN1clN0YXRlLT5kZWNsICE9IE5VTEwpCgkJCWN0eHQtPmF0dHJJbmZvLT50eXBlRGVmID0gY3VyU3RhdGUtPmRlY2wtPnN1YnR5cGVzOwoJCSAgICBlbHNlCgkJCWN0eHQtPmF0dHJJbmZvLT50eXBlRGVmID0gTlVMTDsKCQkgICAgaWYgKGN1clN0YXRlLT5hdHRyLT5ucyAhPSBOVUxMKQoJCQljdHh0LT5hdHRySW5mby0+bmFtZXNwYWNlTmFtZSA9IAoJCQljdXJTdGF0ZS0+YXR0ci0+bnMtPmhyZWY7CgkJICAgIGVsc2UKCQkJY3R4dC0+YXR0ckluZm8tPm5hbWVzcGFjZU5hbWUgPSBOVUxMOwoJCSAgICBjdHh0LT5hdHRySW5mby0+bG9jYWxOYW1lID0gY3VyU3RhdGUtPmF0dHItPm5hbWU7CgkJICAgIAoJCSAgICBjdHh0LT5ub2RlSW5mbyA9IGN0eHQtPmF0dHJJbmZvOwoKI2lmZGVmIElEQ19FTkFCTEVEICAKCQkgICAgLyoKCQkgICAgKiBFdmFsdWF0ZSBJRENzLgoJCSAgICAqLwoJCSAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJCQlyZXQgPSB4bWxTY2hlbWFYUGF0aEV2YWx1YXRlKGN0eHQsCgkJCSAgICBYTUxfQVRUUklCVVRFX05PREUpOwoJCQlpZiAocmV0ID09IC0xKQoJCQkgICAgZ290byBmYXRhbF9leGl0OwoJCSAgICB9CgojZW5kaWYKCQkgICAgcmV0ID0geG1sU2NoZW1hQ2hlY2tBdHRyTG9jYWxseVZhbGlkKGN0eHQsIGN1clN0YXRlKTsKCQkgICAgaWYgKHJldCA9PSAtMSkKCQkJZ290byBmYXRhbF9leGl0OwoJCSAgICBpZiAoKHJldCAhPSAwKSAmJiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkpIHsKCQkJeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKCQkJY3R4dC0+dmFsdWUgPSBOVUxMOwoJCSAgICB9CgkJICAgIC8qIE5vIGJyZWFrIG9uIHB1cnBvc2UuICovCgkJY2FzZSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ6CiNpZmRlZiBJRENfRU5BQkxFRAoJCSAgICBpZiAoY3R4dC0+eHBhdGhTdGF0ZXMgIT0gTlVMTCkgewoJCQkvKgoJCQkqIEV2YWx1YXRlIElEQ3MuCgkJCSovCgkJCWlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkJCSAgICBjdHh0LT5hdHRySW5mby0+dmFsdWUgPSBjdHh0LT52YWx1ZTsKCQkJICAgIGN0eHQtPnZhbHVlID0gTlVMTDsKCQkJfQkJCgkJCWlmICh4bWxTY2hlbWFYUGF0aFByb2Nlc3NIaXN0b3J5KGN0eHQsIGN0eHQtPmRlcHRoICsxKSA9PSAtMSkKCQkJICAgIGdvdG8gZmF0YWxfZXhpdDsKCQkgICAgfQoJCSAgICBicmVhazsKI2VuZGlmCgkJZGVmYXVsdDoKCQkgICAgYnJlYWs7CgkgICAgfQoJICAgIGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQ7Cgl9CgoJLyoKCSogUmVwb3J0IG1pc3NpbmcgYW5kIGlsbGVnYWwgYXR0cmlidXRlcy4KCSovCgljdXJTdGF0ZSA9IGN0eHQtPmF0dHI7Cgl3aGlsZSAoKGN1clN0YXRlICE9IE5VTEwpICYmIChjdXJTdGF0ZSAhPSBjdHh0LT5hdHRyVG9wLT5uZXh0KSkgewoJICAgIGlmIChjdXJTdGF0ZS0+c3RhdGUgIT0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEKSB7CgkJYXR0ciA9IGN1clN0YXRlLT5hdHRyOwoJCWlmIChjdXJTdGF0ZS0+ZGVjbCAhPSBOVUxMKSB7CgkJICAgIGlmIChjdXJTdGF0ZS0+ZGVjbC0+cmVmICE9IE5VTEwpCgkJCWF0dHJEZWNsID0gY3VyU3RhdGUtPmRlY2wtPnJlZkRlY2w7CgkJICAgIGVsc2UgCgkJCWF0dHJEZWNsID0gY3VyU3RhdGUtPmRlY2w7CgkJfSBlbHNlCgkJICAgIGF0dHJEZWNsID0gTlVMTDsKCQlpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORykgewoJCSAgICB4bWxTY2hlbWFWTWlzc2luZ0F0dHJFcnIoY3R4dCwgZWxlbSwgYXR0ckRlY2wpOwoJCX0gZWxzZSBpZiAoY3VyU3RhdGUtPnN0YXRlID09IAoJCSAgICBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEKSB7CgkJICAgIHhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkJWE1MX1NDSEVNQVZfQ1ZDX0FUVFJJQlVURV8yLAoJCQkoeG1sTm9kZVB0cikgYXR0ciwKCQkJKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHJEZWNsLAoJCQkiVGhlIHR5cGUgZGVmaW5pdGlvbiBpcyBhYnNlbnQiLAoJCQlOVUxMKTsKCQl9IGVsc2UgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSAKCQkgICAgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX0ZJWEVEX1ZBTFVFKSB7CQkJCgkJCXhtbFNjaGVtYVZDdXN0b21FcnIoY3R4dCwKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19BVSwgCgkJCSAgICAoeG1sTm9kZVB0cikgYXR0ciwgKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHJEZWNsLAoJCQkgICAgIlRoZSB2YWx1ZSBkb2VzIG5vdCBtYXRjaCB0aGUgZml4ZWQgdmFsdWUgIgoJCQkgICAgImNvbnN0cmFpbnQiLCBOVUxMKTsKCQl9IGVsc2UgaWYgKGN1clN0YXRlLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1dJTERfTk9fREVDTCkgewoJCSAgICB4bWxTY2hlbWFWV2lsZGNhcmRFcnIoY3R4dCwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19XSUxEQ0FSRCwKCQkJKHhtbE5vZGVQdHIpIGF0dHIsCgkJCXR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCQkiTm8gZ2xvYmFsIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBmb3VuZCwgYnV0ICIKCQkJInN0aXB1bGF0ZWQgYnkgdGhlIHN0cmljdCBwcm9jZXNzQ29udGVudHMgb2YgIgoJCQkidGhlIHdpbGRjYXJkIik7CQkJCgkJfSBlbHNlIGlmIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9VTktOT1dOKSB7CgkJICAgIC8qIFRPRE86ICJwcm9oaWJpdGVkIiB3b24ndCBldmVyIGJlIHRvdWNoZWQgaGVyZSEuIAoJCSAgICAgIChjdXJTdGF0ZS0+c3RhdGUgPT0gWE1MX1NDSEVNQVNfQVRUUl9QUk9ISUJJVEVEKSkKCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBUT0RPOiBPbmUgbWlnaHQgcmVwb3J0IGRpZmZlcmVudCBlcnJvciBtZXNzYWdlcyAKCQkgICAgKiBmb3IgdGhlIGZvbGxvd2luZyBlcnJvcnMuCgkJICAgICovCgkJICAgIGlmICgodHlwZSA9PSBOVUxMKSB8fCAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkpIHsKCQkJeG1sU2NoZW1hVklsbGVnYWxBdHRyRXJyKGN0eHQsIAoJCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8zXzJfMSwgYXR0cik7CgkJICAgIH0gZWxzZSB7CgkJCXhtbFNjaGVtYVZJbGxlZ2FsQXR0ckVycihjdHh0LCAKCQkJICAgIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfM18yXzIsIGF0dHIpOwoJCSAgICB9CgkJfQoJICAgIH0JCgkgICAgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dDsKCX0gIAogICAgfSAgICAKICAgIAogICAgLyoKICAgICogQWRkIG1pc3NpbmcgZGVmYXVsdC9maXhlZCBhdHRyaWJ1dGVzLgogICAgKi8KICAgIGlmIChkZWZBdHRyU3RhdGVzICE9IE5VTEwpIHsgICAgCgljdXJTdGF0ZSA9IGRlZkF0dHJTdGF0ZXM7CgkKCXdoaWxlIChjdXJTdGF0ZSAhPSBOVUxMKSB7IAoJICAgIGF0dHJEZWNsID0gY3VyU3RhdGUtPmRlY2w7CgkgICAgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkKCQlhdHRyRGVjbCA9IGF0dHJEZWNsLT5yZWZEZWNsOwoKI2lmZGVmIElEQ19FTkFCTEVEIAoJICAgIC8qCgkgICAgKiBFdmFsdWF0ZSBJRENzIG9uIGRlZmF1bHQgYXR0cmlidXRlcy4KCSAgICAqLwoJICAgIGlmIChjdHh0LT54cGF0aFN0YXRlcyAhPSBOVUxMKSB7CgkJLyoKCQkqIENyZWF0ZSBhbiBhdHRyaWJ1dGUgaW5mbyBpZiBuZWVkZWQuCgkJKi8KCQlpZiAoY3R4dC0+YXR0ckluZm8gPT0gTlVMTCkgewoJCSAgICBjdHh0LT5hdHRySW5mbyA9ICh4bWxTY2hlbWFOb2RlSW5mb1B0cikgCgkJCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hTm9kZUluZm8pKTsKCQkgICAgaWYgKGN0eHQtPmF0dHJJbmZvID09IE5VTEwpIHsKCQkJeG1sU2NoZW1hVkVyck1lbW9yeShjdHh0LCAKCQkJICAgICJhbGxvY2F0aW5nIGFuIGF0dHJpYnV0ZSBpbmZvIiwgTlVMTCk7CgkJCWdvdG8gZmF0YWxfZXhpdDsKCQkgICAgfQoJCSAgICBjdHh0LT5hdHRySW5mby0+dmFsdWUgPSBOVUxMOwoJCX0KCQkvKgoJCSogSW5pdCB0aGUgYXR0cmlidXRlIGluZm8uCgkJKiBUT0RPOiBIbW0sIG1hYnkgYSBiaXQgb3ZlcnNpemVkIHRoaXMgYWxsLgoJCSovCgkJY3R4dC0+YXR0ckluZm8tPmZsYWdzID0gMDsJCQoJCWN0eHQtPmF0dHJJbmZvLT5kZWNsID0gKHhtbFNjaGVtYVR5cGVQdHIpIGF0dHJEZWNsOwoJCWN0eHQtPmF0dHJJbmZvLT5ub2RlID0gTlVMTDsJCQkJCgkJY3R4dC0+YXR0ckluZm8tPnR5cGVEZWYgPSBhdHRyRGVjbC0+c3VidHlwZXM7CgkJY3R4dC0+YXR0ckluZm8tPm5hbWVzcGFjZU5hbWUgPSBhdHRyRGVjbC0+dGFyZ2V0TmFtZXNwYWNlOwoJCWN0eHQtPmF0dHJJbmZvLT5sb2NhbE5hbWUgPSBhdHRyRGVjbC0+bmFtZTsKCgkJY3R4dC0+bm9kZUluZm8gPSBjdHh0LT5hdHRySW5mbzsKCQkJCQkJCQkJICAgIAoJCXJldCA9IHhtbFNjaGVtYVhQYXRoRXZhbHVhdGUoY3R4dCwKCQkgICAgWE1MX0FUVFJJQlVURV9OT0RFKTsKCQlpZiAocmV0ID09IC0xKQoJCSAgICBnb3RvIGZhdGFsX2V4aXQ7CgkJaWYgKGN0eHQtPmF0dHJJbmZvLT52YWx1ZSAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVWYWx1ZShjdHh0LT5hdHRySW5mby0+dmFsdWUpOwoJCSAgICBjdHh0LT5hdHRySW5mby0+dmFsdWUgPSBOVUxMOwoJCX0KCQlpZiAocmV0ID4gMCkgewoJCSAgICAvKgoJCSAgICAqIElEQ3Mgd2lsbCBjb25zdW1lIHRoZSBwcmVjb21wdXRlZCBkZWZhdWx0IHZhbHVlLAoJCSAgICAqIHNvIHdlIG5lZWQgdG8gY2xvbmUgaXQgc29tZWhvdy4KCQkgICAgKi8KCQkgICAgLyoKCQkgICAgKiBzdHJpbmcgb3IgYW55U2ltcGxlVHlwZSBkb2VzIG5vdCBjcmVhdGUgYSBwcmVjb21wdXRlZCB2YWx1ZQoJCSAgICAqIGJ5IGRlZmF1bHQsIHNvIGl0IHdpbGwgYmUgY3JlYXRlZCBoZXJlIG9uIGRlbWFuZC4KCQkgICAgKiBUT0RPOiBkZWZhdWx0L2ZpeGVkIGF0dHJpYnV0ZXMgYXJlIGEgYml0IHVub3B0aW1pemVkOgoJCSAgICAqIHRoZSBzdHJpbmcgdmFsdWUgd2lsbCBiZSBob2xkIGJ5IC0+ZGVmVmFsdWUgYW5kIGluc2lkZQoJCSAgICAqIHRoZSBwcmVjb21wdXRlZCB2YWx1ZS4KCQkgICAgKi8KCQkgICAgaWYgKGF0dHJEZWNsLT5kZWZWYWwgPT0gTlVMTCkgewoJCQl4bWxDaGFyICpzdHIgPSB4bWxTdHJkdXAoYXR0ckRlY2wtPmRlZlZhbHVlKTsKCgkJCWlmICh4bWxTY2hlbWFQb3N0Q3JlYXRlVmFsKGN0eHQsCgkJCSAgICBzdHIsCgkJCSAgICAmKGF0dHJEZWNsLT5kZWZWYWwpKSA9PSAtMSkgewoJCQkgICAgRlJFRV9BTkRfTlVMTChzdHIpCgkJCSAgICBnb3RvIGZhdGFsX2V4aXQ7CgkJCX0JCQkKCQkgICAgfQoJCSAgICBjdHh0LT5hdHRySW5mby0+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+YXR0ckluZm8tPnZhbHVlICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPmF0dHJJbmZvLT52YWx1ZSk7Cgl4bWxGcmVlKGN0eHQtPmF0dHJJbmZvKTsKICAgIH0KICAgIGlmIChjdHh0LT5lbGVtSW5mb3MgIT0gTlVMTCkgewoJaW50IGk7Cgl4bWxTY2hlbWFOb2RlSW5mb1B0ciBpbmZvOwoJCglmb3IgKGkgPSAwOyBpIDwgY3R4dC0+c2l6ZUVsZW1JbmZvczsgaSsrKSB7CgkgICAgaW5mbyA9IGN0eHQtPmVsZW1JbmZvc1tpXTsKCSAgICBpZiAoaW5mbyA9PSBOVUxMKQoJCWNvbnRpbnVlOwoJICAgIGlmIChpbmZvLT52YWx1ZSAhPSBOVUxMKQoJCXhtbFNjaGVtYUZyZWVWYWx1ZShpbmZvLT52YWx1ZSk7CiNpZmRlZiBJRENfRU5BQkxFRAoJICAgIGlmIChpbmZvLT5pZGNNYXRjaGVycyAhPSBOVUxMKQoJCXhtbFNjaGVtYUlEQ0ZyZWVNYXRjaGVyTGlzdChpbmZvLT5pZGNNYXRjaGVycyk7CiNlbmRpZgoJICAgIC8qCgkgICAgKiAgVE9ETzogRnJlZSB0aGUgSURDIHRhYmxlIGlmIHN0aWxsIGV4aXN0ZW50LgoJICAgICovCgoJICAgIC8qCgkgICAgeG1sRnJlZShpbmZvLT5sb2NhbE5hbWUpOwoJICAgIGlmIChpbmZvLT5uYW1lc3BhY2VOYW1lICE9IE5VTEwpCgkJeG1sRnJlZShpbmZvLT5uYW1lc3BhY2VOYW1lKTsKCSAgICAqLwoJICAgIHhtbEZyZWUoaW5mbyk7Cgl9Cgl4bWxGcmVlKGN0eHQtPmVsZW1JbmZvcyk7CiAgICB9CiNlbmRpZgogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGZ1bmN0aW9uCiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbgogKiBAY3R4OiB0aGUgZnVuY3Rpb25zIGNvbnRleHQKICoKICogU2V0IHRoZSBlcnJvciBhbmQgd2FybmluZyBjYWxsYmFjayBpbmZvcm1hdGlvbnMKICovCnZvaWQKeG1sU2NoZW1hU2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVyciwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuLCB2b2lkICpjdHgpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgY3R4dC0+ZXJyb3IgPSBlcnI7CiAgICBjdHh0LT53YXJuaW5nID0gd2FybjsKICAgIGN0eHQtPnVzZXJEYXRhID0gY3R4OwogICAgaWYgKGN0eHQtPnBjdHh0ICE9IE5VTEwpCgl4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMoY3R4dC0+cGN0eHQsIGVyciwgd2FybiwgY3R4KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUdldFZhbGlkRXJyb3JzOgogKiBAY3R4dDoJYSBYTUwtU2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiB0aGUgZXJyb3IgZnVuY3Rpb24gcmVzdWx0CiAqIEB3YXJuOiB0aGUgd2FybmluZyBmdW5jdGlvbiByZXN1bHQKICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0IHJlc3VsdAogKgogKiBHZXQgdGhlIGVycm9yIGFuZCB3YXJuaW5nIGNhbGxiYWNrIGluZm9ybWF0aW9ucwogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDAgb3RoZXJ3aXNlCiAqLwppbnQKeG1sU2NoZW1hR2V0VmFsaWRFcnJvcnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCQkJCXhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jICogZXJyLAoJCQkJCQl4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jICogd2Fybiwgdm9pZCAqKmN0eCkKewoJaWYgKGN0eHQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCWlmIChlcnIgIT0gTlVMTCkKCQkqZXJyID0gY3R4dC0+ZXJyb3I7CglpZiAod2FybiAhPSBOVUxMKQoJCSp3YXJuID0gY3R4dC0+d2FybmluZzsKCWlmIChjdHggIT0gTlVMTCkKCQkqY3R4ID0gY3R4dC0+dXNlckRhdGE7CglyZXR1cm4gKDApOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVNldFZhbGlkT3B0aW9uczoKICogQGN0eHQ6CWEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAb3B0aW9uczogYSBjb21iaW5hdGlvbiBvZiB4bWxTY2hlbWFWYWxpZE9wdGlvbgogKgogKiBTZXRzIHRoZSBvcHRpb25zIHRvIGJlIHVzZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uLgogKgogKiBSZXR1cm5zIDAgaW4gY2FzZSBvZiBzdWNjZXNzLCAtMSBpbiBjYXNlIG9mIGFuCiAqIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFTZXRWYWxpZE9wdGlvbnMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCgkJCSBpbnQgb3B0aW9ucykKCQkJCQkKewogICAgaW50IGk7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKCXJldHVybiAoLTEpOwogICAgLyoKICAgICogV0FSTklORzogQ2hhbmdlIHRoZSBzdGFydCB2YWx1ZSBpZiBhZGRpbmcgdG8gdGhlCiAgICAqIHhtbFNjaGVtYVZhbGlkT3B0aW9uLgogICAgKiBUT0RPOiBJcyB0aGVyZSBhbiBvdGhlciwgbW9yZSBlYXN5IHRvIG1haW50YWluLAogICAgKiB3YXk/CiAgICAqLwogICAgZm9yIChpID0gMTsgaSA8IChpbnQpIHNpemVvZihpbnQpICogODsgaSsrKSB7CiAgICAgICAgaWYgKG9wdGlvbnMgJiAxPDxpKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBOVUxMLAoJCVhNTF9TQ0hFTUFWX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hU2V0VmFsaWRPcHRpb25zLCAiCgkJImludmFsaWQgb3B0aW9uIGFyZ3VtZW50LlxuIiwgTlVMTCwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7ICAgCiAgICAgICAgfQkKICAgIH0KICAgIGN0eHQtPm9wdGlvbnMgPSBvcHRpb25zOwogICAgcmV0dXJuICgwKTsgICAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dEdldE9wdGlvbnM6CiAqIEBjdHh0OglhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQgCiAqCiAqIEdldCB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9wdGlvbnMuCiAqIAogKiBSZXR1cm5zIHRoZSBvcHRpb24gY29tYmluYXRpb24gb3IgLTEgb24gZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRDdHh0R2V0T3B0aW9ucyh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCkKCQkJCQkKeyAgICAKICAgIGlmIChjdHh0ID09IE5VTEwpCglyZXR1cm4gKC0xKTsKICAgIGVsc2UgCglyZXR1cm4gKGN0eHQtPm9wdGlvbnMpOyAgICAKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvYzoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGRvYzogIGEgcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogVmFsaWRhdGUgYSBkb2N1bWVudCB0cmVlIGluIG1lbW9yeS4KICoKICogUmV0dXJucyAwIGlmIHRoZSBkb2N1bWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8KaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxEb2NQdHIgZG9jKQp7CiAgICBpbnQgcmV0OwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoZG9jID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIGN0eHQtPmRvYyA9IGRvYzsKICAgIGN0eHQtPmVyciA9IDA7IAogICAgY3R4dC0+bmJlcnJvcnMgPSAwOwogICAgCiAgICAvKgogICAgaWYgKGN0eHQtPnNjaGVtYSA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIE5VTEwsCgkgICAgWE1MX1NDSEVNQVZfSU5URVJOQUwsCgkgICAgIkFQSSBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVEb2MsICIKCSAgICAibm8gc2NoZW1hIHNwZWNpZmllZCBhbmQgYXNzZW1ibGluZyBvZiBzY2hlbWF0YSAiCgkgICAgInVzaW5nIHhzaTpzY2hlbWFMb2NhdGlvbiBhbmQgeHNpOm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24gIgoJICAgICJpcyBub3QgZW5hYmxlZC5cbiIsIE5VTEwsIE5VTEwpOwoJcmV0dXJuICgtMSk7CiAgICB9CiAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudChjdHh0LCBkb2MpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW06CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpbnB1dDogIHRoZSBpbnB1dCB0byB1c2UgZm9yIHJlYWRpbmcgdGhlIGRhdGEKICogQGVuYzogIGFuIG9wdGlvbmFsIGVuY29kaW5nIGluZm9ybWF0aW9uCiAqIEBzYXg6ICBhIFNBWCBoYW5kbGVyIGZvciB0aGUgcmVzdWx0aW5nIGV2ZW50cwogKiBAdXNlcl9kYXRhOiAgdGhlIGNvbnRleHQgdG8gcHJvdmlkZSB0byB0aGUgU0FYIGhhbmRsZXIuCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQsIHhtbENoYXJFbmNvZGluZyBlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4LCB2b2lkICp1c2VyX2RhdGEpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5wdXQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwogICAgY3R4dC0+ZW5jID0gZW5jOwogICAgY3R4dC0+c2F4ID0gc2F4OwogICAgY3R4dC0+dXNlcl9kYXRhID0gdXNlcl9kYXRhOwogICAgVE9ETyByZXR1cm4gKDApOwp9CgojZW5kaWYgLyogTElCWE1MX1NDSEVNQVNfRU5BQkxFRCAqLwo=